miniupnpd 1.9 (20160113)
[tomato.git] / release / src / router / transmission / qt / prefs-dialog.cc
blobfecf9057ddfb726e2b095b81aa3b0df2a58dc8d2
1 /*
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 $
8 */
10 #include <cassert>
11 #include <climits> /* INT_MAX */
12 #include <iostream>
14 #include <QCheckBox>
15 #include <QComboBox>
16 #include <QCoreApplication>
17 #include <QDialogButtonBox>
18 #include <QDoubleSpinBox>
19 #include <QFileIconProvider>
20 #include <QFileInfo>
21 #include <QHBoxLayout>
22 #include <QIcon>
23 #include <QLabel>
24 #include <QLineEdit>
25 #include <QList>
26 #include <QMessageBox>
27 #include <QPushButton>
28 #include <QSpinBox>
29 #include <QStyle>
30 #include <QTabWidget>
31 #include <QTime>
32 #include <QTimeEdit>
33 #include <QTimer>
34 #include <QVBoxLayout>
36 #include "freespace-label.h"
37 #include "formatter.h"
38 #include "hig.h"
39 #include "prefs.h"
40 #include "prefs-dialog.h"
41 #include "session.h"
42 #include "utils.h"
44 /***
45 ****
46 ***/
48 namespace
50 const char * PREF_KEY ("pref-key");
53 void
54 PrefsDialog :: checkBoxToggled (bool checked)
56 const int key (sender ()->property (PREF_KEY).toInt ());
57 setPref (key, checked);
60 QCheckBox *
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);
68 return box;
71 void
72 PrefsDialog :: enableBuddyWhenChecked (QCheckBox * box, QWidget * buddy)
74 connect (box, SIGNAL(toggled(bool)), buddy, SLOT(setEnabled(bool)));
75 buddy->setEnabled (box->isChecked ());
78 void
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);
85 if (d)
86 setPref (key, d->value ());
87 else
88 setPref (key, qobject_cast<const QSpinBox*>(spin)->value ());
91 QSpinBox *
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);
101 return spin;
104 QDoubleSpinBox *
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);
115 return spin;
118 void
119 PrefsDialog :: timeEditingFinished ()
121 QTimeEdit * e = qobject_cast<QTimeEdit*>(sender());
122 if (e)
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);
131 QTimeEdit*
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()));
141 return e;
144 void
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());
152 setPref (key, text);
156 QLineEdit*
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()));
164 return e;
167 /***
168 ****
169 ***/
171 QWidget *
172 PrefsDialog :: createRemoteTab (Session& session)
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;
201 /***
202 ****
203 ***/
205 void
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);
213 QWidget *
214 PrefsDialog :: createSpeedTab ()
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);
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);
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);
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);
249 hig->addRow (s, r);
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);
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);
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;
288 hig->finish ();
289 return hig;
292 /***
293 ****
294 ***/
296 QWidget *
297 PrefsDialog :: createDesktopTab ()
299 HIG * hig = new HIG (this);
300 hig->addSectionTitle (tr ("Desktop"));
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));
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));
312 hig->finish ();
313 return hig;
316 /***
317 ****
318 ***/
320 void
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>"));
329 void
330 PrefsDialog :: onPortTest ()
332 myPortLabel->setText (tr ("Testing TCP Port..."));
333 myPortButton->setEnabled (false);
334 myWidgets[Prefs::PEER_PORT]->setEnabled (false);
335 mySession.portTest ();
338 QWidget *
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"));
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)));
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"));
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."));
378 hig->finish ();
379 return hig;
382 /***
383 ****
384 ***/
386 void
387 PrefsDialog :: onBlocklistDialogDestroyed (QObject * o)
389 Q_UNUSED (o);
391 myBlocklistDialog = 0;
394 void
395 PrefsDialog :: onUpdateBlocklistCancelled ()
397 disconnect (&mySession, SIGNAL(blocklistUpdated(int)), this, SLOT(onBlocklistUpdated(int)));
398 myBlocklistDialog->deleteLater ();
401 void
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);
408 void
409 PrefsDialog :: onUpdateBlocklistClicked ()
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 ();
422 void
423 PrefsDialog :: encryptionEdited (int i)
425 const int value (qobject_cast<QComboBox*>(sender())->itemData(i).toInt ());
426 setPref (Prefs::ENCRYPTION, value);
429 QWidget *
430 PrefsDialog :: createPrivacyTab ()
432 QWidget * w;
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);
451 myBlockWidgets << e;
452 hig->addRow (l, e);
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);
465 l = checkBoxNew (tr ("Enable &automatic updates"), Prefs::BLOCKLIST_UPDATES_ENABLED);
466 myBlockWidgets << l;
467 hig->addWideControl (l);
469 hig->finish ();
470 updateBlocklistLabel ();
471 return hig;
474 /***
475 ****
476 ***/
478 void
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());
485 if (!path.isEmpty())
486 onLocationSelected (path, Prefs::SCRIPT_TORRENT_DONE_FILENAME);
489 void
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());
496 if (!path.isEmpty())
497 onLocationSelected (path, Prefs::INCOMPLETE_DIR);
500 void
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);
507 if (!path.isEmpty())
508 onLocationSelected (path, Prefs::DIR_WATCH);
511 void
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());
518 if (!path.isEmpty())
519 onLocationSelected (path, Prefs::DOWNLOAD_DIR);
522 void
523 PrefsDialog :: onLocationSelected (const QString& path, int key)
525 setPref (key, path);
528 QWidget *
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);
538 QWidget *l, *r;
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);
544 hig->addRow (l, r);
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);
549 hig->addRow (l, r);
550 enableBuddyWhenChecked (qobject_cast<QCheckBox*>(l), r);
552 hig->finish ();
553 return hig;
556 QWidget *
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);
566 QWidget * l;
567 QPushButton * b;
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)));
576 hig->addRow (l, b);
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 ();
594 h->addStretch (1);
595 h->addWidget (l);
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);
625 hig->finish ();
626 return hig;
629 /***
630 ****
631 ***/
633 PrefsDialog :: 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))
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()));
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);
673 // if it's a remote session, disable the preferences
674 // that don't work in remote sessions
675 if (!myIsServer)
677 foreach (QWidget * w, myUnsupportedWhenRemote)
679 w->setToolTip (tr ("Not supported by remote sessions"));
680 w->setEnabled (false);
685 PrefsDialog :: ~PrefsDialog ()
689 void
690 PrefsDialog :: setPref (int key, const QVariant& v)
692 myPrefs.set (key, v);
693 refreshPref (key);
696 /***
697 ****
698 ***/
700 void
701 PrefsDialog :: sessionUpdated ()
703 updateBlocklistLabel ();
706 void
707 PrefsDialog :: updateBlocklistLabel ()
709 const int n = mySession.blocklistSize ();
710 myBlocklistLabel->setText (tr ("<i>Blocklist contains %Ln rules</i>", 0, n));
713 void
714 PrefsDialog :: refreshPref (int key)
716 switch (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);
728 break;
731 case Prefs :: ALT_SPEED_LIMIT_TIME_ENABLED:
733 const bool enabled = myPrefs.getBool (key);
734 foreach (QWidget * w, mySchedWidgets)w->setEnabled (enabled);
735 break;
738 case Prefs :: BLOCKLIST_ENABLED:
740 const bool enabled = myPrefs.getBool (key);
741 foreach (QWidget * w, myBlockWidgets)w->setEnabled (enabled);
742 break;
745 case Prefs :: DIR_WATCH:
746 myWatchButton->setText (QFileInfo(myPrefs.getString(Prefs::DIR_WATCH)).fileName());
747 break;
749 case Prefs :: SCRIPT_TORRENT_DONE_FILENAME:
751 const QString path (myPrefs.getString (key));
752 myTorrentDoneScriptButton->setText (QFileInfo(path).fileName());
753 break;
756 case Prefs :: PEER_PORT:
757 myPortLabel->setText (tr ("Status unknown"));
758 myPortButton->setEnabled (true);
759 break;
761 case Prefs :: DOWNLOAD_DIR:
763 const QString path (myPrefs.getString (key));
764 myDestinationButton->setText (QFileInfo(path).fileName());
765 myFreespaceLabel->setPath (path);
766 break;
769 case Prefs :: INCOMPLETE_DIR:
771 QString path (myPrefs.getString (key));
772 myIncompleteButton->setText (QFileInfo(path).fileName());
773 break;
776 case Prefs :: INCOMPLETE_DIR_ENABLED:
778 const bool enabled = myPrefs.getBool (key);
779 myIncompleteButton->setEnabled (enabled);
780 break;
783 default:
784 break;
787 key2widget_t::iterator it (myWidgets.find (key));
788 if (it != myWidgets.end ())
790 QWidget * w (it.value ());
791 QCheckBox * checkBox;
792 QSpinBox * spin;
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);
827 bool
828 PrefsDialog :: isAllowed (int key) const
830 Q_UNUSED (key);
832 return true;