2 * This file Copyright (C) 2009-2014 Mnemosyne LLC
4 * It may be used under the GNU Public License v2 or v3 licenses,
5 * or any future license endorsed by Mnemosyne LLC.
7 * $Id: prefs-dialog.cc 14225 2014-01-19 01:09:44Z jordan $
11 #include <climits> /* INT_MAX */
16 #include <QCoreApplication>
17 #include <QDialogButtonBox>
18 #include <QDoubleSpinBox>
19 #include <QFileIconProvider>
21 #include <QHBoxLayout>
26 #include <QMessageBox>
27 #include <QPushButton>
34 #include <QVBoxLayout>
36 #include "freespace-label.h"
37 #include "formatter.h"
40 #include "prefs-dialog.h"
50 const char * PREF_KEY ("pref-key");
54 PrefsDialog :: checkBoxToggled (bool checked
)
56 const int key (sender ()->property (PREF_KEY
).toInt ());
57 setPref (key
, checked
);
61 PrefsDialog :: checkBoxNew (const QString
& text
, int key
)
63 QCheckBox
* box
= new QCheckBox (text
);
64 box
->setChecked (myPrefs
.getBool (key
));
65 box
->setProperty (PREF_KEY
, key
);
66 connect (box
, SIGNAL(toggled(bool)), this, SLOT(checkBoxToggled(bool)));
67 myWidgets
.insert (key
, box
);
72 PrefsDialog :: enableBuddyWhenChecked (QCheckBox
* box
, QWidget
* buddy
)
74 connect (box
, SIGNAL(toggled(bool)), buddy
, SLOT(setEnabled(bool)));
75 buddy
->setEnabled (box
->isChecked ());
79 PrefsDialog :: spinBoxEditingFinished()
81 const QObject
* spin
= sender();
82 const int key
= spin
->property (PREF_KEY
).toInt ();
83 const QDoubleSpinBox
* d
= qobject_cast
<const QDoubleSpinBox
*> (spin
);
86 setPref (key
, d
->value ());
88 setPref (key
, qobject_cast
<const QSpinBox
*>(spin
)->value ());
92 PrefsDialog :: spinBoxNew (int key
, int low
, int high
, int step
)
94 QSpinBox
* spin
= new QSpinBox ();
95 spin
->setRange (low
, high
);
96 spin
->setSingleStep (step
);
97 spin
->setValue (myPrefs
.getInt (key
));
98 spin
->setProperty (PREF_KEY
, key
);
99 connect (spin
, SIGNAL(editingFinished()), this, SLOT(spinBoxEditingFinished()));
100 myWidgets
.insert (key
, spin
);
105 PrefsDialog :: doubleSpinBoxNew (int key
, double low
, double high
, double step
, int decimals
)
107 QDoubleSpinBox
* spin
= new QDoubleSpinBox ();
108 spin
->setRange (low
, high
);
109 spin
->setSingleStep (step
);
110 spin
->setDecimals (decimals
);
111 spin
->setValue (myPrefs
.getDouble (key
));
112 spin
->setProperty (PREF_KEY
, key
);
113 connect (spin
, SIGNAL(editingFinished()), this, SLOT(spinBoxEditingFinished()));
114 myWidgets
.insert (key
, spin
);
119 PrefsDialog :: timeEditingFinished ()
121 QTimeEdit
* e
= qobject_cast
<QTimeEdit
*>(sender());
124 const int key (e
->property (PREF_KEY
).toInt ());
125 const QTime
time (e
->time ());
126 const int seconds (QTime().secsTo (time
));
127 setPref (key
, seconds
/ 60);
132 PrefsDialog :: timeEditNew (int key
)
134 const int minutes (myPrefs
.getInt (key
));
135 QTimeEdit
* e
= new QTimeEdit ();
136 e
->setDisplayFormat (QString::fromUtf8 ("hh:mm"));
137 e
->setProperty (PREF_KEY
, key
);
138 e
->setTime (QTime().addSecs (minutes
* 60));
139 myWidgets
.insert (key
, e
);
140 connect (e
, SIGNAL(editingFinished()), this, SLOT(timeEditingFinished()));
145 PrefsDialog :: lineEditingFinished ()
147 QLineEdit
* e
= qobject_cast
<QLineEdit
*>(sender());
148 if (e
&& e
->isModified ())
150 const int key (e
->property (PREF_KEY
).toInt ());
151 const QString
text (e
->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 :: createRemoteTab (Session
& session
)
174 HIG
* hig
= new HIG (this);
175 hig
->addSectionTitle (tr ("Remote Control"));
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
));
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
));
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 ("&Upload (%1):").arg (speed_K_str
), Prefs::USPEED_ENABLED
);
222 r
= spinBoxNew (Prefs::USPEED
, 0, INT_MAX
, 5);
224 enableBuddyWhenChecked (qobject_cast
<QCheckBox
*>(l
), r
);
226 l
= checkBoxNew (tr ("&Download (%1):").arg (speed_K_str
), Prefs::DSPEED_ENABLED
);
227 r
= spinBoxNew (Prefs::DSPEED
, 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 (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
);
244 QString s
= tr ("<small>Override normal speed limits manually or at scheduled times</small>");
245 hig
->addWideControl (new QLabel (s
));
247 s
= tr ("U&pload (%1):").arg (speed_K_str
);
248 r
= spinBoxNew (Prefs :: ALT_SPEED_LIMIT_UP
, 0, INT_MAX
, 5);
251 s
= tr ("Do&wnload (%1):").arg (speed_K_str
);
252 r
= spinBoxNew (Prefs :: ALT_SPEED_LIMIT_DOWN
, 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
);
261 QLabel
* nd
= new QLabel (tr("&to"));
263 mySchedWidgets
<< nd
;
264 w
= timeEditNew (Prefs :: ALT_SPEED_LIMIT_TIME_END
);
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 ("Start &minimized in notification area"), Prefs::START_MINIMIZED
));
305 hig
->addSectionDivider ();
306 hig
->addSectionTitle (tr ("Notification"));
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
));
321 PrefsDialog :: onPortTested (bool isOpen
)
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>"));
330 PrefsDialog :: onPortTest ()
332 myPortLabel
->setText (tr ("Testing TCP Port..."));
333 myPortButton
->setEnabled (false);
334 myWidgets
[Prefs::PEER_PORT
]->setEnabled (false);
335 mySession
.portTest ();
339 PrefsDialog :: createNetworkTab ()
341 HIG
* hig
= new HIG (this);
342 hig
->addSectionTitle (tr ("Incoming Peers"));
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"));
349 h
->addSpacing (HIG :: PAD_BIG
);
351 h
->setStretchFactor (l
, 1);
352 connect (b
, SIGNAL(clicked(bool)), this, SLOT(onPortTest()));
353 connect (&mySession
, SIGNAL(portTested(bool)), this, SLOT(onPortTested(bool)));
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
));
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));
365 hig
->addSectionDivider ();
366 hig
->addSectionTitle (tr ("Options"));
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."));
387 PrefsDialog :: onBlocklistDialogDestroyed (QObject
* o
)
391 myBlocklistDialog
= 0;
395 PrefsDialog :: onUpdateBlocklistCancelled ()
397 disconnect (&mySession
, SIGNAL(blocklistUpdated(int)), this, SLOT(onBlocklistUpdated(int)));
398 myBlocklistDialog
->deleteLater ();
402 PrefsDialog :: onBlocklistUpdated (int n
)
404 myBlocklistDialog
->setText (tr ("<b>Update succeeded!</b><p>Blocklist now has %Ln rules.", 0, n
));
405 myBlocklistDialog
->setTextFormat (Qt::RichText
);
409 PrefsDialog :: onUpdateBlocklistClicked ()
411 myBlocklistDialog
= new QMessageBox (QMessageBox::Information
,
413 tr ("<b>Update Blocklist</b><p>Getting new blocklist..."),
416 connect (myBlocklistDialog
, SIGNAL(rejected()), this, SLOT(onUpdateBlocklistCancelled()));
417 connect (&mySession
, SIGNAL(blocklistUpdated(int)), this, SLOT(onBlocklistUpdated(int)));
418 myBlocklistDialog
->show ();
419 mySession
.updateBlocklist ();
423 PrefsDialog :: encryptionEdited (int i
)
425 const int value (qobject_cast
<QComboBox
*>(sender())->itemData(i
).toInt ());
426 setPref (Prefs::ENCRYPTION
, value
);
430 PrefsDialog :: createPrivacyTab ()
433 HIG
* hig
= new HIG (this);
435 hig
->addSectionTitle (tr ("Encryption"));
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)));
444 hig
->addRow (tr ("&Encryption mode:"), box
);
446 hig
->addSectionDivider ();
447 hig
->addSectionTitle (tr ("Blocklist"));
449 QWidget
* l
= checkBoxNew (tr("Enable &blocklist:"), Prefs::BLOCKLIST_ENABLED
);
450 QWidget
* e
= lineEditNew (Prefs::BLOCKLIST_URL
);
454 l
= myBlocklistLabel
= new QLabel ();
456 w
= new QPushButton (tr ("&Update"));
457 connect (w
, SIGNAL(clicked(bool)), this, SLOT(onUpdateBlocklistClicked()));
459 QHBoxLayout
* h
= new QHBoxLayout ();
463 hig
->addWideControl (h
);
465 l
= checkBoxNew (tr ("Enable &automatic updates"), Prefs::BLOCKLIST_UPDATES_ENABLED
);
467 hig
->addWideControl (l
);
470 updateBlocklistLabel ();
479 PrefsDialog :: onScriptClicked (void)
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());
486 onLocationSelected (path
, Prefs::SCRIPT_TORRENT_DONE_FILENAME
);
490 PrefsDialog :: onIncompleteClicked (void)
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());
497 onLocationSelected (path
, Prefs::INCOMPLETE_DIR
);
501 PrefsDialog :: onWatchClicked (void)
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);
508 onLocationSelected (path
, Prefs::DIR_WATCH
);
512 PrefsDialog :: onDestinationClicked (void)
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());
519 onLocationSelected (path
, Prefs::DOWNLOAD_DIR
);
523 PrefsDialog :: onLocationSelected (const QString
& path
, int key
)
529 PrefsDialog :: createSeedingTab ()
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
);
539 HIG
* hig
= new HIG (this);
540 hig
->addSectionTitle (tr ("Limits"));
542 l
= checkBoxNew (tr ("Stop seeding at &ratio:"), Prefs::RATIO_ENABLED
);
543 r
= doubleSpinBoxNew (Prefs::RATIO
, 0, INT_MAX
, 0.5, 2);
545 enableBuddyWhenChecked (qobject_cast
<QCheckBox
*>(l
), r
);
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);
550 enableBuddyWhenChecked (qobject_cast
<QCheckBox
*>(l
), r
);
557 PrefsDialog :: createDownloadingTab ()
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
);
568 HIG
* hig
= new HIG (this);
569 hig
->addSectionTitle (tr ("Adding"));
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)));
577 enableBuddyWhenChecked (qobject_cast
<QCheckBox
*>(l
), b
);
579 hig
->addWideControl (checkBoxNew (tr ("Show the Torrent Options &dialog"), Prefs::OPTIONS_PROMPT
));
581 hig
->addWideControl (checkBoxNew (tr ("&Start added torrents"), Prefs::START
));
583 hig
->addWideControl (checkBoxNew (tr ("Mo&ve the .torrent file to the trash"), Prefs::TRASH_ORIGINAL
));
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
);
591 const QString
downloadDir (myPrefs
.getString(Prefs::DOWNLOAD_DIR
));
592 l
= myFreespaceLabel
= new FreespaceLabel (mySession
, downloadDir
, this);
593 QHBoxLayout
* h
= new QHBoxLayout ();
596 hig
->addWideControl (h
);
598 hig
->addSectionDivider ();
599 hig
->addSectionTitle (tr ("Download Queue"));
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));
604 hig
->addSectionDivider ();
605 hig
->addSectionTitle (tr ("Incomplete"));
607 hig
->addWideControl (checkBoxNew (tr ("Append \".&part\" to incomplete files' names"), Prefs::RENAME_PARTIAL_FILES
));
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
);
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
);
633 PrefsDialog :: PrefsDialog (Session
& session
, Prefs
& prefs
, QWidget
* parent
):
635 myIsServer (session
.isServer ()),
638 myLayout (new QVBoxLayout (this))
640 setWindowTitle (tr ("Transmission Preferences"));
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
);
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);
657 connect (&mySession
, SIGNAL(sessionUpdated()), this, SLOT(sessionUpdated()));
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
)
673 // if it's a remote session, disable the preferences
674 // that don't work in remote sessions
677 foreach (QWidget
* w
, myUnsupportedWhenRemote
)
679 w
->setToolTip (tr ("Not supported by remote sessions"));
680 w
->setEnabled (false);
685 PrefsDialog :: ~PrefsDialog ()
690 PrefsDialog :: setPref (int key
, const QVariant
& v
)
692 myPrefs
.set (key
, v
);
701 PrefsDialog :: sessionUpdated ()
703 updateBlocklistLabel ();
707 PrefsDialog :: updateBlocklistLabel ()
709 const int n
= mySession
.blocklistSize ();
710 myBlocklistLabel
->setText (tr ("<i>Blocklist contains %Ln rules</i>", 0, n
));
714 PrefsDialog :: refreshPref (int key
)
718 case Prefs :: RPC_ENABLED
:
719 case Prefs :: RPC_WHITELIST_ENABLED
:
720 case Prefs :: RPC_AUTH_REQUIRED
:
722 const bool enabled (myPrefs
.getBool (Prefs::RPC_ENABLED
));
723 const bool whitelist (myPrefs
.getBool (Prefs::RPC_WHITELIST_ENABLED
));
724 const bool auth (myPrefs
.getBool (Prefs::RPC_AUTH_REQUIRED
));
725 foreach (QWidget
* w
, myWebWhitelistWidgets
)w
->setEnabled (enabled
&& whitelist
);
726 foreach (QWidget
* w
, myWebAuthWidgets
)w
->setEnabled (enabled
&& auth
);
727 foreach (QWidget
* w
, myWebWidgets
)w
->setEnabled (enabled
);
731 case Prefs :: ALT_SPEED_LIMIT_TIME_ENABLED
:
733 const bool enabled
= myPrefs
.getBool (key
);
734 foreach (QWidget
* w
, mySchedWidgets
)w
->setEnabled (enabled
);
738 case Prefs :: BLOCKLIST_ENABLED
:
740 const bool enabled
= myPrefs
.getBool (key
);
741 foreach (QWidget
* w
, myBlockWidgets
)w
->setEnabled (enabled
);
745 case Prefs :: DIR_WATCH
:
746 myWatchButton
->setText (QFileInfo(myPrefs
.getString(Prefs::DIR_WATCH
)).fileName());
749 case Prefs :: SCRIPT_TORRENT_DONE_FILENAME
:
751 const QString
path (myPrefs
.getString (key
));
752 myTorrentDoneScriptButton
->setText (QFileInfo(path
).fileName());
756 case Prefs :: PEER_PORT
:
757 myPortLabel
->setText (tr ("Status unknown"));
758 myPortButton
->setEnabled (true);
761 case Prefs :: DOWNLOAD_DIR
:
763 const QString
path (myPrefs
.getString (key
));
764 myDestinationButton
->setText (QFileInfo(path
).fileName());
765 myFreespaceLabel
->setPath (path
);
769 case Prefs :: INCOMPLETE_DIR
:
771 QString
path (myPrefs
.getString (key
));
772 myIncompleteButton
->setText (QFileInfo(path
).fileName());
776 case Prefs :: INCOMPLETE_DIR_ENABLED
:
778 const bool enabled
= myPrefs
.getBool (key
);
779 myIncompleteButton
->setEnabled (enabled
);
787 key2widget_t::iterator
it (myWidgets
.find (key
));
788 if (it
!= myWidgets
.end ())
790 QWidget
* w (it
.value ());
791 QCheckBox
* checkBox
;
793 QDoubleSpinBox
* doubleSpin
;
794 QTimeEdit
* timeEdit
;
795 QLineEdit
* lineEdit
;
797 if ((checkBox
= qobject_cast
<QCheckBox
*>(w
)))
799 checkBox
->setChecked (myPrefs
.getBool (key
));
801 else if ((spin
= qobject_cast
<QSpinBox
*>(w
)))
803 spin
->setValue (myPrefs
.getInt (key
));
805 else if ((doubleSpin
= qobject_cast
<QDoubleSpinBox
*>(w
)))
807 doubleSpin
->setValue (myPrefs
.getDouble (key
));
809 else if ((timeEdit
= qobject_cast
<QTimeEdit
*>(w
)))
811 const int minutes (myPrefs
.getInt (key
));
812 timeEdit
->setTime (QTime().addSecs (minutes
* 60));
814 else if ((lineEdit
= qobject_cast
<QLineEdit
*>(w
)))
816 lineEdit
->setText (myPrefs
.getString (key
));
818 else if (key
== Prefs::ENCRYPTION
)
820 QComboBox
* comboBox (qobject_cast
<QComboBox
*> (w
));
821 const int index
= comboBox
->findData (myPrefs
.getInt (key
));
822 comboBox
->setCurrentIndex (index
);
828 PrefsDialog :: isAllowed (int key
) const