2015-11-15 08:48:10 +03:00
/*
* Bittorrent Client using Qt and libtorrent .
* Copyright ( C ) 2016 qBittorrent project
*
* This program is free software ; you can redistribute it and / or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation ; either version 2
* of the License , or ( at your option ) any later version .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
* along with this program ; if not , write to the Free Software
* Foundation , Inc . , 51 Franklin Street , Fifth Floor , Boston , MA 02110 - 1301 , USA .
*
* In addition , as a special exception , the copyright holders give permission to
* link this program with the OpenSSL project ' s " OpenSSL " library ( or with
* modified versions of it that use the same license as the " OpenSSL " library ) ,
* and distribute the linked executables . You must obey the GNU General Public
* License in all respects for all of the code used other than " OpenSSL " . If you
* modify file ( s ) , you may extend this exception to your version of the file ( s ) ,
* but you are not obligated to do so . If you do not wish to do so , delete this
* exception statement from your version .
*/
# include "advancedsettings.h"
2016-05-01 11:05:52 +03:00
2018-07-04 09:02:05 +03:00
# include <limits>
2015-11-15 08:48:10 +03:00
# include <QHeaderView>
# include <QHostAddress>
# include <QNetworkInterface>
2016-05-01 11:05:52 +03:00
# include "base/bittorrent/session.h"
2018-11-18 21:40:37 +03:00
# include "base/global.h"
2015-11-15 08:48:10 +03:00
# include "base/preferences.h"
2017-09-13 23:29:54 +03:00
# include "base/unicodestrings.h"
2018-06-06 16:48:17 +03:00
# include "app/application.h"
2017-10-16 16:10:25 +03:00
# include "gui/addnewtorrentdialog.h"
2016-04-17 22:56:51 +03:00
# include "gui/mainwindow.h"
2015-11-15 08:48:10 +03:00
2019-03-09 18:21:02 +03:00
namespace
{
QString makeLink ( const QString & url , const QString & linkLabel )
{
return QStringLiteral ( " <a href= \" %1 \" >%2</a> " ) . arg ( url , linkLabel ) ;
}
}
2015-11-15 08:48:10 +03:00
enum AdvSettingsCols
{
PROPERTY ,
2015-11-15 10:03:43 +03:00
VALUE ,
COL_COUNT
2015-11-15 08:48:10 +03:00
} ;
enum AdvSettingsRows
{
2015-11-15 10:03:43 +03:00
// qBittorrent section
QBITTORRENT_HEADER ,
// network interface
2015-11-15 08:48:10 +03:00
NETWORK_IFACE ,
2016-04-13 11:51:29 +03:00
//Optional network address
NETWORK_IFACE_ADDRESS ,
2015-11-15 08:48:10 +03:00
NETWORK_LISTEN_IPV6 ,
2015-11-15 10:03:43 +03:00
// behavior
SAVE_RESUME_DATA_INTERVAL ,
CONFIRM_RECHECK_TORRENT ,
RECHECK_COMPLETED ,
2015-11-15 08:48:10 +03:00
# if defined(Q_OS_WIN) || defined(Q_OS_MAC)
UPDATE_CHECK ,
# endif
2015-11-15 10:03:43 +03:00
// UI related
LIST_REFRESH ,
RESOLVE_HOSTS ,
RESOLVE_COUNTRIES ,
PROGRAM_NOTIFICATIONS ,
2016-04-17 22:56:51 +03:00
TORRENT_ADDED_NOTIFICATIONS ,
2017-06-05 03:22:17 +03:00
CONFIRM_REMOVE_ALL_TAGS ,
2016-11-13 23:46:17 +03:00
DOWNLOAD_TRACKER_FAVICON ,
2017-10-16 16:10:25 +03:00
SAVE_PATH_HISTORY_LENGTH ,
2018-09-23 09:20:05 +03:00
ENABLE_SPEED_WIDGET ,
2015-11-15 08:48:10 +03:00
# if (defined(Q_OS_UNIX) && !defined(Q_OS_MAC))
USE_ICON_THEME ,
# endif
2015-11-15 10:03:43 +03:00
// libtorrent section
LIBTORRENT_HEADER ,
2018-06-18 19:10:57 +03:00
ASYNC_IO_THREADS ,
2018-08-28 13:18:07 +03:00
CHECKING_MEM_USAGE ,
2015-11-15 10:03:43 +03:00
// cache
DISK_CACHE ,
DISK_CACHE_TTL ,
OS_CACHE ,
2017-08-11 10:50:56 +03:00
GUIDED_READ_CACHE ,
2018-01-29 12:03:14 +03:00
COALESCE_RW ,
2017-08-11 14:15:18 +03:00
SUGGEST_MODE ,
2017-08-11 14:48:58 +03:00
SEND_BUF_WATERMARK ,
SEND_BUF_LOW_WATERMARK ,
SEND_BUF_WATERMARK_FACTOR ,
2015-11-15 10:03:43 +03:00
// ports
OUTGOING_PORT_MIN ,
OUTGOING_PORT_MAX ,
2017-08-11 11:28:52 +03:00
UTP_MIX_MODE ,
2017-08-11 11:37:32 +03:00
MULTI_CONNECTIONS_PER_IP ,
2015-11-15 10:03:43 +03:00
// embedded tracker
TRACKER_STATUS ,
TRACKER_PORT ,
// seeding
2017-08-11 12:06:31 +03:00
CHOKING_ALGORITHM ,
SEED_CHOKING_ALGORITHM ,
2015-11-15 10:03:43 +03:00
SUPER_SEEDING ,
// tracker
2015-11-15 08:48:10 +03:00
ANNOUNCE_ALL_TRACKERS ,
2017-10-30 21:04:14 +03:00
ANNOUNCE_ALL_TIERS ,
2016-10-31 02:22:11 +03:00
ANNOUNCE_IP ,
2015-11-15 10:03:43 +03:00
2015-11-15 08:48:10 +03:00
ROW_COUNT
} ;
AdvancedSettings : : AdvancedSettings ( QWidget * parent )
: QTableWidget ( parent )
{
2015-11-15 09:08:22 +03:00
// column
2015-11-15 10:03:43 +03:00
setColumnCount ( COL_COUNT ) ;
2018-04-14 22:53:45 +03:00
QStringList header = { tr ( " Setting " ) , tr ( " Value " , " Value set for this setting " ) } ;
2015-11-15 08:48:10 +03:00
setHorizontalHeaderLabels ( header ) ;
2015-11-15 09:08:22 +03:00
// row
2015-11-15 08:48:10 +03:00
setRowCount ( ROW_COUNT ) ;
2015-11-15 09:08:22 +03:00
verticalHeader ( ) - > setVisible ( false ) ;
// etc.
setAlternatingRowColors ( true ) ;
2016-01-31 09:13:21 +03:00
setSelectionMode ( QAbstractItemView : : NoSelection ) ;
2015-11-15 09:08:22 +03:00
setEditTriggers ( QAbstractItemView : : NoEditTriggers ) ;
2015-11-15 08:48:10 +03:00
// Signals
2018-06-14 12:38:18 +03:00
connect ( & spinBoxCache , static_cast < void ( QSpinBox : : * ) ( int ) > ( & QSpinBox : : valueChanged )
2018-04-18 16:59:41 +03:00
, this , & AdvancedSettings : : updateCacheSpinSuffix ) ;
2018-06-14 12:38:18 +03:00
connect ( & comboBoxInterface , static_cast < void ( QComboBox : : * ) ( int ) > ( & QComboBox : : currentIndexChanged )
2018-04-18 16:59:41 +03:00
, this , & AdvancedSettings : : updateInterfaceAddressCombo ) ;
2018-07-04 09:02:05 +03:00
connect ( & spinBoxSaveResumeDataInterval , static_cast < void ( QSpinBox : : * ) ( int ) > ( & QSpinBox : : valueChanged )
, this , & AdvancedSettings : : updateSaveResumeDataIntervalSuffix ) ;
2015-11-15 08:48:10 +03:00
// Load settings
loadAdvancedSettings ( ) ;
2015-11-15 09:08:22 +03:00
resizeColumnToContents ( 0 ) ;
horizontalHeader ( ) - > setStretchLastSection ( true ) ;
2015-11-15 08:48:10 +03:00
}
void AdvancedSettings : : saveAdvancedSettings ( )
{
2018-06-06 16:48:17 +03:00
Preferences * const pref = Preferences : : instance ( ) ;
2016-05-01 11:05:52 +03:00
BitTorrent : : Session * const session = BitTorrent : : Session : : instance ( ) ;
2018-06-18 19:10:57 +03:00
// Async IO threads
session - > setAsyncIOThreads ( spinBoxAsyncIOThreads . value ( ) ) ;
2018-08-28 13:18:07 +03:00
// Checking Memory Usage
session - > setCheckingMemUsage ( spinBoxCheckingMemUsage . value ( ) ) ;
2015-11-15 08:48:10 +03:00
// Disk write cache
2018-06-14 12:38:18 +03:00
session - > setDiskCacheSize ( spinBoxCache . value ( ) ) ;
session - > setDiskCacheTTL ( spinBoxCacheTTL . value ( ) ) ;
2015-11-15 08:48:10 +03:00
// Enable OS cache
2018-06-14 12:38:18 +03:00
session - > setUseOSCache ( checkBoxOsCache . isChecked ( ) ) ;
2017-08-11 10:50:56 +03:00
// Guided read cache
2018-06-14 12:38:18 +03:00
session - > setGuidedReadCacheEnabled ( checkBoxGuidedReadCache . isChecked ( ) ) ;
2018-01-29 12:03:14 +03:00
// Coalesce reads & writes
2018-06-14 12:38:18 +03:00
session - > setCoalesceReadWriteEnabled ( checkBoxCoalesceRW . isChecked ( ) ) ;
2017-08-11 14:15:18 +03:00
// Suggest mode
2018-06-14 12:38:18 +03:00
session - > setSuggestMode ( checkBoxSuggestMode . isChecked ( ) ) ;
2017-08-11 14:48:58 +03:00
// Send buffer watermark
2018-06-14 12:38:18 +03:00
session - > setSendBufferWatermark ( spinBoxSendBufferWatermark . value ( ) ) ;
session - > setSendBufferLowWatermark ( spinBoxSendBufferLowWatermark . value ( ) ) ;
session - > setSendBufferWatermarkFactor ( spinBoxSendBufferWatermarkFactor . value ( ) ) ;
2015-11-15 08:48:10 +03:00
// Save resume data interval
2018-06-14 12:38:18 +03:00
session - > setSaveResumeDataInterval ( spinBoxSaveResumeDataInterval . value ( ) ) ;
2015-11-15 08:48:10 +03:00
// Outgoing ports
2018-06-14 12:38:18 +03:00
session - > setOutgoingPortsMin ( spinBoxOutgoingPortsMin . value ( ) ) ;
session - > setOutgoingPortsMax ( spinBoxOutgoingPortsMax . value ( ) ) ;
2017-08-11 11:28:52 +03:00
// uTP-TCP mixed mode
2018-06-14 12:38:18 +03:00
session - > setUtpMixedMode ( static_cast < BitTorrent : : MixedModeAlgorithm > ( comboBoxUtpMixedMode . currentIndex ( ) ) ) ;
2017-08-11 11:37:32 +03:00
// multiple connections per IP
2018-06-14 12:38:18 +03:00
session - > setMultiConnectionsPerIpEnabled ( checkBoxMultiConnectionsPerIp . isChecked ( ) ) ;
2015-11-15 08:48:10 +03:00
// Recheck torrents on completion
2018-06-14 12:38:18 +03:00
pref - > recheckTorrentsOnCompletion ( checkBoxRecheckCompleted . isChecked ( ) ) ;
2015-11-15 08:48:10 +03:00
// Transfer list refresh interval
2018-06-14 12:38:18 +03:00
session - > setRefreshInterval ( spinBoxListRefresh . value ( ) ) ;
2015-11-15 08:48:10 +03:00
// Peer resolution
2018-06-14 12:38:18 +03:00
pref - > resolvePeerCountries ( checkBoxResolveCountries . isChecked ( ) ) ;
pref - > resolvePeerHostNames ( checkBoxResolveHosts . isChecked ( ) ) ;
2015-11-15 08:48:10 +03:00
// Super seeding
2018-06-14 12:38:18 +03:00
session - > setSuperSeedingEnabled ( checkBoxSuperSeeding . isChecked ( ) ) ;
2015-11-15 08:48:10 +03:00
// Network interface
2018-06-14 12:38:18 +03:00
if ( comboBoxInterface . currentIndex ( ) = = 0 ) {
2015-11-15 08:48:10 +03:00
// All interfaces (default)
2016-05-01 11:05:52 +03:00
session - > setNetworkInterface ( QString ( ) ) ;
2016-10-31 02:40:26 +03:00
session - > setNetworkInterfaceName ( QString ( ) ) ;
2015-11-15 08:48:10 +03:00
}
else {
2018-06-14 12:38:18 +03:00
session - > setNetworkInterface ( comboBoxInterface . itemData ( comboBoxInterface . currentIndex ( ) ) . toString ( ) ) ;
session - > setNetworkInterfaceName ( comboBoxInterface . currentText ( ) ) ;
2015-11-15 08:48:10 +03:00
}
2016-05-01 11:05:52 +03:00
2016-04-13 11:51:29 +03:00
// Interface address
2018-06-14 12:38:18 +03:00
if ( comboBoxInterfaceAddress . currentIndex ( ) = = 0 ) {
2016-04-21 19:21:49 +03:00
// All addresses (default)
2019-02-27 11:06:05 +03:00
session - > setNetworkInterfaceAddress ( { } ) ;
2016-04-21 19:21:49 +03:00
}
else {
2018-06-14 12:38:18 +03:00
QHostAddress ifaceAddr ( comboBoxInterfaceAddress . currentText ( ) . trimmed ( ) ) ;
2019-02-27 11:06:05 +03:00
ifaceAddr . isNull ( ) ? session - > setNetworkInterfaceAddress ( { } ) : session - > setNetworkInterfaceAddress ( ifaceAddr . toString ( ) ) ;
2016-04-21 19:21:49 +03:00
}
2018-06-14 12:38:18 +03:00
session - > setIPv6Enabled ( checkBoxListenIPv6 . isChecked ( ) ) ;
2016-10-31 02:22:11 +03:00
// Announce IP
2018-06-14 12:38:18 +03:00
QHostAddress addr ( lineEditAnnounceIP . text ( ) . trimmed ( ) ) ;
2016-10-31 02:22:11 +03:00
session - > setAnnounceIP ( addr . isNull ( ) ? " " : addr . toString ( ) ) ;
2016-04-09 19:19:22 +03:00
2015-11-15 08:48:10 +03:00
// Program notification
2018-06-06 16:48:17 +03:00
MainWindow * const mainWindow = static_cast < Application * > ( QCoreApplication : : instance ( ) ) - > mainWindow ( ) ;
2018-06-14 12:38:18 +03:00
mainWindow - > setNotificationsEnabled ( checkBoxProgramNotifications . isChecked ( ) ) ;
mainWindow - > setTorrentAddedNotificationsEnabled ( checkBoxTorrentAddedNotifications . isChecked ( ) ) ;
2016-11-13 23:46:17 +03:00
// Misc GUI properties
2018-06-14 12:38:18 +03:00
mainWindow - > setDownloadTrackerFavicon ( checkBoxTrackerFavicon . isChecked ( ) ) ;
AddNewTorrentDialog : : setSavePathHistoryLength ( spinBoxSavePathHistoryLength . value ( ) ) ;
2018-09-23 09:20:05 +03:00
pref - > setSpeedWidgetEnabled ( checkBoxSpeedWidgetEnabled . isChecked ( ) ) ;
2016-05-01 11:05:52 +03:00
2015-11-15 08:48:10 +03:00
// Tracker
2018-06-14 12:38:18 +03:00
session - > setTrackerEnabled ( checkBoxTrackerStatus . isChecked ( ) ) ;
pref - > setTrackerPort ( spinBoxTrackerPort . value ( ) ) ;
2017-08-11 12:06:31 +03:00
// Choking algorithm
2018-06-14 12:38:18 +03:00
session - > setChokingAlgorithm ( static_cast < BitTorrent : : ChokingAlgorithm > ( comboBoxChokingAlgorithm . currentIndex ( ) ) ) ;
2017-08-11 12:06:31 +03:00
// Seed choking algorithm
2018-06-14 12:38:18 +03:00
session - > setSeedChokingAlgorithm ( static_cast < BitTorrent : : SeedChokingAlgorithm > ( comboBoxSeedChokingAlgorithm . currentIndex ( ) ) ) ;
2017-08-11 12:06:31 +03:00
2015-11-15 08:48:10 +03:00
# if defined(Q_OS_WIN) || defined(Q_OS_MAC)
2018-06-14 12:38:18 +03:00
pref - > setUpdateCheckEnabled ( checkBoxUpdateCheck . isChecked ( ) ) ;
2015-11-15 08:48:10 +03:00
# endif
// Icon theme
# if (defined(Q_OS_UNIX) && !defined(Q_OS_MAC))
2018-06-14 12:38:18 +03:00
pref - > useSystemIconTheme ( checkBoxUseIconTheme . isChecked ( ) ) ;
2015-11-15 08:48:10 +03:00
# endif
2018-06-14 12:38:18 +03:00
pref - > setConfirmTorrentRecheck ( checkBoxConfirmTorrentRecheck . isChecked ( ) ) ;
2017-06-05 03:22:17 +03:00
2018-06-14 12:38:18 +03:00
pref - > setConfirmRemoveAllTags ( checkBoxConfirmRemoveAllTags . isChecked ( ) ) ;
2017-06-05 03:22:17 +03:00
2018-06-14 12:38:18 +03:00
session - > setAnnounceToAllTrackers ( checkBoxAnnounceAllTrackers . isChecked ( ) ) ;
session - > setAnnounceToAllTiers ( checkBoxAnnounceAllTiers . isChecked ( ) ) ;
2015-11-15 08:48:10 +03:00
}
void AdvancedSettings : : updateCacheSpinSuffix ( int value )
{
2017-08-18 03:05:36 +03:00
if ( value = = 0 )
2018-06-14 12:38:18 +03:00
spinBoxCache . setSuffix ( tr ( " (disabled) " ) ) ;
2017-08-18 03:05:36 +03:00
else if ( value < 0 )
2018-06-14 12:38:18 +03:00
spinBoxCache . setSuffix ( tr ( " (auto) " ) ) ;
2015-11-15 08:48:10 +03:00
else
2018-06-14 12:38:18 +03:00
spinBoxCache . setSuffix ( tr ( " MiB " ) ) ;
2015-11-15 08:48:10 +03:00
}
2018-07-04 09:02:05 +03:00
void AdvancedSettings : : updateSaveResumeDataIntervalSuffix ( const int value )
{
if ( value > 0 )
spinBoxSaveResumeDataInterval . setSuffix ( tr ( " min " , " minutes " ) ) ;
else
spinBoxSaveResumeDataInterval . setSuffix ( tr ( " (disabled) " ) ) ;
}
2016-05-27 01:35:58 +03:00
void AdvancedSettings : : updateInterfaceAddressCombo ( )
{
// Try to get the currently selected interface name
2018-06-14 12:38:18 +03:00
const QString ifaceName = comboBoxInterface . itemData ( comboBoxInterface . currentIndex ( ) ) . toString ( ) ; // Empty string for the first element
2016-10-31 02:32:08 +03:00
const QString currentAddress = BitTorrent : : Session : : instance ( ) - > networkInterfaceAddress ( ) ;
2016-04-21 19:21:49 +03:00
2018-06-06 16:48:17 +03:00
// Clear all items and reinsert them, default to all
2018-06-14 12:38:18 +03:00
comboBoxInterfaceAddress . clear ( ) ;
comboBoxInterfaceAddress . addItem ( tr ( " All addresses " ) ) ;
comboBoxInterfaceAddress . setCurrentIndex ( 0 ) ;
2016-04-21 19:21:49 +03:00
2016-05-27 01:35:58 +03:00
auto populateCombo = [ this , & currentAddress ] ( const QString & ip , const QAbstractSocket : : NetworkLayerProtocol & protocol )
{
2018-06-06 16:48:17 +03:00
Q_ASSERT ( ( protocol = = QAbstractSocket : : IPv4Protocol ) | | ( protocol = = QAbstractSocket : : IPv6Protocol ) ) ;
// Only take ipv4 for now?
if ( ( protocol ! = QAbstractSocket : : IPv4Protocol ) & & ( protocol ! = QAbstractSocket : : IPv6Protocol ) )
2016-05-27 01:35:58 +03:00
return ;
2018-06-14 12:38:18 +03:00
comboBoxInterfaceAddress . addItem ( ip ) ;
2016-04-21 19:21:49 +03:00
//Try to select the last added one
2016-05-27 01:35:58 +03:00
if ( ip = = currentAddress )
2018-06-14 12:38:18 +03:00
comboBoxInterfaceAddress . setCurrentIndex ( comboBoxInterfaceAddress . count ( ) - 1 ) ;
2016-05-27 01:35:58 +03:00
} ;
if ( ifaceName . isEmpty ( ) ) {
2018-11-27 23:15:04 +03:00
for ( const QHostAddress & ip : asConst ( QNetworkInterface : : allAddresses ( ) ) )
2016-05-27 01:35:58 +03:00
populateCombo ( ip . toString ( ) , ip . protocol ( ) ) ;
}
else {
const QNetworkInterface iface = QNetworkInterface : : interfaceFromName ( ifaceName ) ;
const QList < QNetworkAddressEntry > addresses = iface . addressEntries ( ) ;
2018-11-18 21:40:37 +03:00
for ( const QNetworkAddressEntry & entry : addresses ) {
2016-05-27 01:35:58 +03:00
const QHostAddress ip = entry . ip ( ) ;
populateCombo ( ip . toString ( ) , ip . protocol ( ) ) ;
2016-04-21 19:21:49 +03:00
}
}
}
2015-11-15 08:48:10 +03:00
void AdvancedSettings : : loadAdvancedSettings ( )
{
2018-06-06 16:48:17 +03:00
const Preferences * const pref = Preferences : : instance ( ) ;
2016-10-30 00:11:52 +03:00
const BitTorrent : : Session * const session = BitTorrent : : Session : : instance ( ) ;
2016-05-01 11:05:52 +03:00
2015-11-15 10:03:43 +03:00
// add section headers
2019-03-09 18:21:02 +03:00
labelQbtLink . setText ( makeLink ( " https://github.com/qbittorrent/qBittorrent/wiki/Explanation-of-Options-in-qBittorrent#Advanced "
, tr ( " Open documentation " ) ) ) ;
2015-11-15 10:03:43 +03:00
labelQbtLink . setOpenExternalLinks ( true ) ;
2019-03-07 10:31:50 +03:00
addRow ( QBITTORRENT_HEADER , QString ( " <b>%1</b> " ) . arg ( tr ( " qBittorrent Section " ) ) , & labelQbtLink ) ;
2019-03-09 18:25:39 +03:00
static_cast < QLabel * > ( cellWidget ( QBITTORRENT_HEADER , PROPERTY ) ) - > setAlignment ( Qt : : AlignCenter | Qt : : AlignVCenter ) ;
2015-11-15 10:03:43 +03:00
2019-03-09 18:21:02 +03:00
labelLibtorrentLink . setText ( makeLink ( " https://www.libtorrent.org/reference.html " , tr ( " Open documentation " ) ) ) ;
2015-11-15 10:03:43 +03:00
labelLibtorrentLink . setOpenExternalLinks ( true ) ;
2019-03-07 10:31:50 +03:00
addRow ( LIBTORRENT_HEADER , QString ( " <b>%1</b> " ) . arg ( tr ( " libtorrent Section " ) ) , & labelLibtorrentLink ) ;
2019-03-09 18:25:39 +03:00
static_cast < QLabel * > ( cellWidget ( LIBTORRENT_HEADER , PROPERTY ) ) - > setAlignment ( Qt : : AlignCenter | Qt : : AlignVCenter ) ;
2018-06-18 19:10:57 +03:00
// Async IO threads
spinBoxAsyncIOThreads . setMinimum ( 1 ) ;
spinBoxAsyncIOThreads . setMaximum ( 1024 ) ;
spinBoxAsyncIOThreads . setValue ( session - > asyncIOThreads ( ) ) ;
2019-03-09 18:21:02 +03:00
addRow ( ASYNC_IO_THREADS , ( tr ( " Asynchronous I/O threads " ) + ' ' + makeLink ( " https://www.libtorrent.org/reference-Settings.html#aio_threads " , " (?) " ) )
, & spinBoxAsyncIOThreads ) ;
2018-08-28 13:18:07 +03:00
// Checking Memory Usage
spinBoxCheckingMemUsage . setMinimum ( 1 ) ;
2019-01-16 09:23:21 +03:00
// When build as 32bit binary, set the maximum value lower to prevent crashes.
2019-01-16 07:52:41 +03:00
# ifdef QBT_APP_64BIT
2019-01-16 09:23:21 +03:00
spinBoxCheckingMemUsage . setMaximum ( 1024 ) ;
# else
// Allocate at most 128MiB out of the remaining 512MiB (see the cache part below)
spinBoxCheckingMemUsage . setMaximum ( 128 ) ;
# endif
2018-08-28 13:18:07 +03:00
spinBoxCheckingMemUsage . setValue ( session - > checkingMemUsage ( ) ) ;
spinBoxCheckingMemUsage . setSuffix ( tr ( " MiB " ) ) ;
2019-03-09 18:21:02 +03:00
addRow ( CHECKING_MEM_USAGE , ( tr ( " Outstanding memory when checking torrents " ) + ' ' + makeLink ( " https://www.libtorrent.org/reference-Settings.html#checking_mem_usage " , " (?) " ) )
, & spinBoxCheckingMemUsage ) ;
2018-08-28 13:18:07 +03:00
2015-11-15 08:48:10 +03:00
// Disk write cache
2018-06-14 12:38:18 +03:00
spinBoxCache . setMinimum ( - 1 ) ;
2015-11-15 08:48:10 +03:00
// When build as 32bit binary, set the maximum at less than 2GB to prevent crashes.
2019-01-16 07:52:41 +03:00
# ifdef QBT_APP_64BIT
2019-06-19 17:01:25 +03:00
spinBoxCache . setMaximum ( 33554431 ) ; // 32768GiB
2015-11-15 08:48:10 +03:00
# else
// allocate 1536MiB and leave 512MiB to the rest of program data in RAM
2018-06-14 12:38:18 +03:00
spinBoxCache . setMaximum ( 1536 ) ;
2015-11-15 08:48:10 +03:00
# endif
2018-06-14 12:38:18 +03:00
spinBoxCache . setValue ( session - > diskCacheSize ( ) ) ;
updateCacheSpinSuffix ( spinBoxCache . value ( ) ) ;
2019-03-09 18:21:02 +03:00
addRow ( DISK_CACHE , ( tr ( " Disk cache " ) + ' ' + makeLink ( " https://www.libtorrent.org/reference-Settings.html#cache_size " , " (?) " ) )
, & spinBoxCache ) ;
2015-11-15 08:48:10 +03:00
// Disk cache expiry
2019-06-19 17:15:58 +03:00
spinBoxCacheTTL . setMinimum ( 1 ) ;
spinBoxCacheTTL . setMaximum ( std : : numeric_limits < int > : : max ( ) ) ;
2018-06-14 12:38:18 +03:00
spinBoxCacheTTL . setValue ( session - > diskCacheTTL ( ) ) ;
spinBoxCacheTTL . setSuffix ( tr ( " s " , " seconds " ) ) ;
2019-03-09 18:21:02 +03:00
addRow ( DISK_CACHE_TTL , ( tr ( " Disk cache expiry interval " ) + ' ' + makeLink ( " https://www.libtorrent.org/reference-Settings.html#cache_expiry " , " (?) " ) )
, & spinBoxCacheTTL ) ;
2015-11-15 08:48:10 +03:00
// Enable OS cache
2018-06-14 12:38:18 +03:00
checkBoxOsCache . setChecked ( session - > useOSCache ( ) ) ;
2019-03-09 18:21:02 +03:00
addRow ( OS_CACHE , ( tr ( " Enable OS cache " ) + ' ' + makeLink ( " https://www.libtorrent.org/reference-Settings.html#disk_io_write_mode " , " (?) " ) )
, & checkBoxOsCache ) ;
2017-08-11 10:50:56 +03:00
// Guided read cache
2018-06-14 12:38:18 +03:00
checkBoxGuidedReadCache . setChecked ( session - > isGuidedReadCacheEnabled ( ) ) ;
2019-03-09 18:21:02 +03:00
addRow ( GUIDED_READ_CACHE , ( tr ( " Guided read cache " ) + ' ' + makeLink ( " https://www.libtorrent.org/reference-Settings.html#guided_read_cache " , " (?) " ) )
, & checkBoxGuidedReadCache ) ;
2018-01-29 12:03:14 +03:00
// Coalesce reads & writes
2018-06-14 12:38:18 +03:00
checkBoxCoalesceRW . setChecked ( session - > isCoalesceReadWriteEnabled ( ) ) ;
2019-03-09 18:21:02 +03:00
addRow ( COALESCE_RW , ( tr ( " Coalesce reads & writes " ) + ' ' + makeLink ( " https://www.libtorrent.org/reference-Settings.html#coalesce_reads " , " (?) " ) )
, & checkBoxCoalesceRW ) ;
2017-08-11 14:15:18 +03:00
// Suggest mode
2018-06-14 12:38:18 +03:00
checkBoxSuggestMode . setChecked ( session - > isSuggestModeEnabled ( ) ) ;
2019-03-09 18:21:02 +03:00
addRow ( SUGGEST_MODE , ( tr ( " Send upload piece suggestions " ) + ' ' + makeLink ( " https://www.libtorrent.org/reference-Settings.html#suggest_mode " , " (?) " ) )
, & checkBoxSuggestMode ) ;
2017-08-11 14:48:58 +03:00
// Send buffer watermark
2018-06-14 12:38:18 +03:00
spinBoxSendBufferWatermark . setMinimum ( 1 ) ;
2019-06-19 17:23:58 +03:00
spinBoxSendBufferWatermark . setMaximum ( std : : numeric_limits < int > : : max ( ) ) ;
2018-06-14 12:38:18 +03:00
spinBoxSendBufferWatermark . setSuffix ( tr ( " KiB " ) ) ;
spinBoxSendBufferWatermark . setValue ( session - > sendBufferWatermark ( ) ) ;
2019-03-09 18:21:02 +03:00
addRow ( SEND_BUF_WATERMARK , ( tr ( " Send buffer watermark " ) + ' ' + makeLink ( " https://www.libtorrent.org/reference-Settings.html#send_buffer_watermark " , " (?) " ) )
, & spinBoxSendBufferWatermark ) ;
2018-06-14 12:38:18 +03:00
spinBoxSendBufferLowWatermark . setMinimum ( 1 ) ;
2019-06-19 17:23:58 +03:00
spinBoxSendBufferLowWatermark . setMaximum ( std : : numeric_limits < int > : : max ( ) ) ;
2018-06-14 12:38:18 +03:00
spinBoxSendBufferLowWatermark . setSuffix ( tr ( " KiB " ) ) ;
spinBoxSendBufferLowWatermark . setValue ( session - > sendBufferLowWatermark ( ) ) ;
2019-03-09 18:21:02 +03:00
addRow ( SEND_BUF_LOW_WATERMARK , ( tr ( " Send buffer low watermark " ) + ' ' + makeLink ( " https://www.libtorrent.org/reference-Settings.html#send_buffer_low_watermark " , " (?) " ) )
, & spinBoxSendBufferLowWatermark ) ;
2018-06-14 12:38:18 +03:00
spinBoxSendBufferWatermarkFactor . setMinimum ( 1 ) ;
2019-06-19 17:23:58 +03:00
spinBoxSendBufferWatermarkFactor . setMaximum ( std : : numeric_limits < int > : : max ( ) ) ;
2018-06-14 12:38:18 +03:00
spinBoxSendBufferWatermarkFactor . setSuffix ( " % " ) ;
spinBoxSendBufferWatermarkFactor . setValue ( session - > sendBufferWatermarkFactor ( ) ) ;
2019-03-09 18:21:02 +03:00
addRow ( SEND_BUF_WATERMARK_FACTOR , ( tr ( " Send buffer watermark factor " ) + ' ' + makeLink ( " https://www.libtorrent.org/reference-Settings.html#send_buffer_watermark_factor " , " (?) " ) )
, & spinBoxSendBufferWatermarkFactor ) ;
2015-11-15 08:48:10 +03:00
// Save resume data interval
2018-07-04 09:02:05 +03:00
spinBoxSaveResumeDataInterval . setMinimum ( 0 ) ;
spinBoxSaveResumeDataInterval . setMaximum ( std : : numeric_limits < int > : : max ( ) ) ;
2018-06-14 12:38:18 +03:00
spinBoxSaveResumeDataInterval . setValue ( session - > saveResumeDataInterval ( ) ) ;
2018-07-04 09:02:05 +03:00
updateSaveResumeDataIntervalSuffix ( spinBoxSaveResumeDataInterval . value ( ) ) ;
2018-06-14 12:38:18 +03:00
addRow ( SAVE_RESUME_DATA_INTERVAL , tr ( " Save resume data interval " , " How often the fastresume file is saved. " ) , & spinBoxSaveResumeDataInterval ) ;
2015-11-15 08:48:10 +03:00
// Outgoing port Min
2018-06-14 12:38:18 +03:00
spinBoxOutgoingPortsMin . setMinimum ( 0 ) ;
spinBoxOutgoingPortsMin . setMaximum ( 65535 ) ;
spinBoxOutgoingPortsMin . setValue ( session - > outgoingPortsMin ( ) ) ;
addRow ( OUTGOING_PORT_MIN , tr ( " Outgoing ports (Min) [0: Disabled] " ) , & spinBoxOutgoingPortsMin ) ;
2015-11-15 08:48:10 +03:00
// Outgoing port Min
2018-06-14 12:38:18 +03:00
spinBoxOutgoingPortsMax . setMinimum ( 0 ) ;
spinBoxOutgoingPortsMax . setMaximum ( 65535 ) ;
spinBoxOutgoingPortsMax . setValue ( session - > outgoingPortsMax ( ) ) ;
addRow ( OUTGOING_PORT_MAX , tr ( " Outgoing ports (Max) [0: Disabled] " ) , & spinBoxOutgoingPortsMax ) ;
2017-08-11 11:28:52 +03:00
// uTP-TCP mixed mode
2018-06-14 12:38:18 +03:00
comboBoxUtpMixedMode . addItems ( { tr ( " Prefer TCP " ) , tr ( " Peer proportional (throttles TCP) " ) } ) ;
comboBoxUtpMixedMode . setCurrentIndex ( static_cast < int > ( session - > utpMixedMode ( ) ) ) ;
2019-03-09 18:21:02 +03:00
addRow ( UTP_MIX_MODE , ( tr ( " %1-TCP mixed mode algorithm " , " uTP-TCP mixed mode algorithm " ) . arg ( C_UTP )
+ ' ' + makeLink ( " https://www.libtorrent.org/reference-Settings.html#mixed_mode_algorithm " , " (?) " ) )
, & comboBoxUtpMixedMode ) ;
2017-08-11 11:37:32 +03:00
// multiple connections per IP
2018-06-14 12:38:18 +03:00
checkBoxMultiConnectionsPerIp . setChecked ( session - > multiConnectionsPerIpEnabled ( ) ) ;
addRow ( MULTI_CONNECTIONS_PER_IP , tr ( " Allow multiple connections from the same IP address " ) , & checkBoxMultiConnectionsPerIp ) ;
2015-11-15 08:48:10 +03:00
// Recheck completed torrents
2018-06-14 12:38:18 +03:00
checkBoxRecheckCompleted . setChecked ( pref - > recheckTorrentsOnCompletion ( ) ) ;
addRow ( RECHECK_COMPLETED , tr ( " Recheck torrents on completion " ) , & checkBoxRecheckCompleted ) ;
2015-11-15 08:48:10 +03:00
// Transfer list refresh interval
2018-06-14 12:38:18 +03:00
spinBoxListRefresh . setMinimum ( 30 ) ;
spinBoxListRefresh . setMaximum ( 99999 ) ;
spinBoxListRefresh . setValue ( session - > refreshInterval ( ) ) ;
spinBoxListRefresh . setSuffix ( tr ( " ms " , " milliseconds " ) ) ;
addRow ( LIST_REFRESH , tr ( " Transfer list refresh interval " ) , & spinBoxListRefresh ) ;
2015-11-15 08:48:10 +03:00
// Resolve Peer countries
2018-06-14 12:38:18 +03:00
checkBoxResolveCountries . setChecked ( pref - > resolvePeerCountries ( ) ) ;
addRow ( RESOLVE_COUNTRIES , tr ( " Resolve peer countries (GeoIP) " ) , & checkBoxResolveCountries ) ;
2015-11-15 08:48:10 +03:00
// Resolve peer hosts
2018-06-14 12:38:18 +03:00
checkBoxResolveHosts . setChecked ( pref - > resolvePeerHostNames ( ) ) ;
addRow ( RESOLVE_HOSTS , tr ( " Resolve peer host names " ) , & checkBoxResolveHosts ) ;
2015-11-15 08:48:10 +03:00
// Super seeding
2018-06-14 12:38:18 +03:00
checkBoxSuperSeeding . setChecked ( session - > isSuperSeedingEnabled ( ) ) ;
2019-03-09 18:21:02 +03:00
addRow ( SUPER_SEEDING , ( tr ( " Strict super seeding " ) + ' ' + makeLink ( " https://www.libtorrent.org/reference-Settings.html#strict_super_seeding " , " (?) " ) )
, & checkBoxSuperSeeding ) ;
2015-11-15 08:48:10 +03:00
// Network interface
2018-06-14 12:38:18 +03:00
comboBoxInterface . addItem ( tr ( " Any interface " , " i.e. Any network interface " ) ) ;
2018-06-14 14:46:50 +03:00
const QString currentInterface = session - > networkInterface ( ) ;
bool interfaceExists = currentInterface . isEmpty ( ) ;
2015-11-15 08:48:10 +03:00
int i = 1 ;
2018-11-27 23:15:04 +03:00
for ( const QNetworkInterface & iface : asConst ( QNetworkInterface : : allInterfaces ( ) ) ) {
2016-04-17 21:55:01 +03:00
// This line fixes a Qt bug => https://bugreports.qt.io/browse/QTBUG-52633
// Tested in Qt 5.6.0. For more info see:
// https://github.com/qbittorrent/qBittorrent/issues/5131
// https://github.com/qbittorrent/qBittorrent/pull/5135
if ( iface . addressEntries ( ) . isEmpty ( ) ) continue ;
2018-06-14 12:38:18 +03:00
comboBoxInterface . addItem ( iface . humanReadableName ( ) , iface . name ( ) ) ;
2018-06-14 14:46:50 +03:00
if ( ! currentInterface . isEmpty ( ) & & ( iface . name ( ) = = currentInterface ) ) {
2018-06-14 12:38:18 +03:00
comboBoxInterface . setCurrentIndex ( i ) ;
2018-06-14 14:46:50 +03:00
interfaceExists = true ;
2015-11-15 08:48:10 +03:00
}
+ + i ;
}
// Saved interface does not exist, show it anyway
2018-06-14 14:46:50 +03:00
if ( ! interfaceExists ) {
comboBoxInterface . addItem ( session - > networkInterfaceName ( ) , currentInterface ) ;
2018-06-14 12:38:18 +03:00
comboBoxInterface . setCurrentIndex ( i ) ;
2015-11-15 08:48:10 +03:00
}
2018-06-14 12:38:18 +03:00
addRow ( NETWORK_IFACE , tr ( " Network Interface (requires restart) " ) , & comboBoxInterface ) ;
2016-04-21 19:21:49 +03:00
// Network interface address
2016-05-27 01:35:58 +03:00
updateInterfaceAddressCombo ( ) ;
2018-06-14 12:38:18 +03:00
addRow ( NETWORK_IFACE_ADDRESS , tr ( " Optional IP Address to bind to (requires restart) " ) , & comboBoxInterfaceAddress ) ;
2015-11-15 08:48:10 +03:00
// Listen on IPv6 address
2018-06-14 12:38:18 +03:00
checkBoxListenIPv6 . setChecked ( session - > isIPv6Enabled ( ) ) ;
addRow ( NETWORK_LISTEN_IPV6 , tr ( " Listen on IPv6 address (requires restart) " ) , & checkBoxListenIPv6 ) ;
2016-10-31 02:22:11 +03:00
// Announce IP
2018-06-14 12:38:18 +03:00
lineEditAnnounceIP . setText ( session - > announceIP ( ) ) ;
addRow ( ANNOUNCE_IP , tr ( " IP Address to report to trackers (requires restart) " ) , & lineEditAnnounceIP ) ;
2016-04-09 19:19:22 +03:00
2015-11-15 08:48:10 +03:00
// Program notifications
2018-06-14 14:46:50 +03:00
const MainWindow * const mainWindow = static_cast < Application * > ( QCoreApplication : : instance ( ) ) - > mainWindow ( ) ;
2018-06-14 12:38:18 +03:00
checkBoxProgramNotifications . setChecked ( mainWindow - > isNotificationsEnabled ( ) ) ;
addRow ( PROGRAM_NOTIFICATIONS , tr ( " Display notifications " ) , & checkBoxProgramNotifications ) ;
2016-04-17 22:56:51 +03:00
// Torrent added notifications
2018-06-14 12:38:18 +03:00
checkBoxTorrentAddedNotifications . setChecked ( mainWindow - > isTorrentAddedNotificationsEnabled ( ) ) ;
addRow ( TORRENT_ADDED_NOTIFICATIONS , tr ( " Display notifications for added torrents " ) , & checkBoxTorrentAddedNotifications ) ;
2016-11-13 23:46:17 +03:00
// Download tracker's favicon
2018-06-14 12:38:18 +03:00
checkBoxTrackerFavicon . setChecked ( mainWindow - > isDownloadTrackerFavicon ( ) ) ;
addRow ( DOWNLOAD_TRACKER_FAVICON , tr ( " Download tracker's favicon " ) , & checkBoxTrackerFavicon ) ;
2017-10-16 16:10:25 +03:00
// Save path history length
2018-06-14 12:38:18 +03:00
spinBoxSavePathHistoryLength . setRange ( AddNewTorrentDialog : : minPathHistoryLength , AddNewTorrentDialog : : maxPathHistoryLength ) ;
spinBoxSavePathHistoryLength . setValue ( AddNewTorrentDialog : : savePathHistoryLength ( ) ) ;
addRow ( SAVE_PATH_HISTORY_LENGTH , tr ( " Save path history length " ) , & spinBoxSavePathHistoryLength ) ;
2018-09-23 09:20:05 +03:00
// Enable speed graphs
checkBoxSpeedWidgetEnabled . setChecked ( pref - > isSpeedWidgetEnabled ( ) ) ;
addRow ( ENABLE_SPEED_WIDGET , tr ( " Enable speed graphs " ) , & checkBoxSpeedWidgetEnabled ) ;
2015-11-15 08:48:10 +03:00
// Tracker State
2018-06-14 12:38:18 +03:00
checkBoxTrackerStatus . setChecked ( session - > isTrackerEnabled ( ) ) ;
addRow ( TRACKER_STATUS , tr ( " Enable embedded tracker " ) , & checkBoxTrackerStatus ) ;
2015-11-15 08:48:10 +03:00
// Tracker port
2018-06-14 12:38:18 +03:00
spinBoxTrackerPort . setMinimum ( 1 ) ;
spinBoxTrackerPort . setMaximum ( 65535 ) ;
spinBoxTrackerPort . setValue ( pref - > getTrackerPort ( ) ) ;
addRow ( TRACKER_PORT , tr ( " Embedded tracker port " ) , & spinBoxTrackerPort ) ;
2017-08-11 12:06:31 +03:00
// Choking algorithm
2018-06-14 12:38:18 +03:00
comboBoxChokingAlgorithm . addItems ( { tr ( " Fixed slots " ) , tr ( " Upload rate based " ) } ) ;
comboBoxChokingAlgorithm . setCurrentIndex ( static_cast < int > ( session - > chokingAlgorithm ( ) ) ) ;
2019-03-09 18:21:02 +03:00
addRow ( CHOKING_ALGORITHM , ( tr ( " Upload slots behavior " ) + ' ' + makeLink ( " https://www.libtorrent.org/reference-Settings.html#choking_algorithm " , " (?) " ) )
, & comboBoxChokingAlgorithm ) ;
2017-08-11 12:06:31 +03:00
// Seed choking algorithm
2018-06-14 12:38:18 +03:00
comboBoxSeedChokingAlgorithm . addItems ( { tr ( " Round-robin " ) , tr ( " Fastest upload " ) , tr ( " Anti-leech " ) } ) ;
comboBoxSeedChokingAlgorithm . setCurrentIndex ( static_cast < int > ( session - > seedChokingAlgorithm ( ) ) ) ;
2019-03-09 18:21:02 +03:00
addRow ( SEED_CHOKING_ALGORITHM , ( tr ( " Upload choking algorithm " ) + ' ' + makeLink ( " https://www.libtorrent.org/reference-Settings.html#seed_choking_algorithm " , " (?) " ) )
, & comboBoxSeedChokingAlgorithm ) ;
2017-08-11 12:06:31 +03:00
2015-11-15 08:48:10 +03:00
# if defined(Q_OS_WIN) || defined(Q_OS_MAC)
2018-06-14 12:38:18 +03:00
checkBoxUpdateCheck . setChecked ( pref - > isUpdateCheckEnabled ( ) ) ;
addRow ( UPDATE_CHECK , tr ( " Check for software updates " ) , & checkBoxUpdateCheck ) ;
2015-11-15 08:48:10 +03:00
# endif
# if (defined(Q_OS_UNIX) && !defined(Q_OS_MAC))
2018-06-14 12:38:18 +03:00
checkBoxUseIconTheme . setChecked ( pref - > useSystemIconTheme ( ) ) ;
addRow ( USE_ICON_THEME , tr ( " Use system icon theme " ) , & checkBoxUseIconTheme ) ;
2015-11-15 08:48:10 +03:00
# endif
// Torrent recheck confirmation
2018-06-14 12:38:18 +03:00
checkBoxConfirmTorrentRecheck . setChecked ( pref - > confirmTorrentRecheck ( ) ) ;
addRow ( CONFIRM_RECHECK_TORRENT , tr ( " Confirm torrent recheck " ) , & checkBoxConfirmTorrentRecheck ) ;
2017-06-05 03:22:17 +03:00
// Remove all tags confirmation
2018-06-14 12:38:18 +03:00
checkBoxConfirmRemoveAllTags . setChecked ( pref - > confirmRemoveAllTags ( ) ) ;
addRow ( CONFIRM_REMOVE_ALL_TAGS , tr ( " Confirm removal of all tags " ) , & checkBoxConfirmRemoveAllTags ) ;
2017-06-05 03:22:17 +03:00
2017-10-30 21:04:14 +03:00
// Announce to all trackers in a tier
2018-06-14 12:38:18 +03:00
checkBoxAnnounceAllTrackers . setChecked ( session - > announceToAllTrackers ( ) ) ;
addRow ( ANNOUNCE_ALL_TRACKERS , tr ( " Always announce to all trackers in a tier " ) , & checkBoxAnnounceAllTrackers ) ;
2017-10-30 21:04:14 +03:00
// Announce to all tiers
2018-06-14 12:38:18 +03:00
checkBoxAnnounceAllTiers . setChecked ( session - > announceToAllTiers ( ) ) ;
addRow ( ANNOUNCE_ALL_TIERS , tr ( " Always announce to all tiers " ) , & checkBoxAnnounceAllTiers ) ;
2015-11-15 09:56:39 +03:00
}
template < typename T >
2019-03-07 10:31:50 +03:00
void AdvancedSettings : : addRow ( const int row , const QString & text , T * widget )
2015-11-15 09:56:39 +03:00
{
2019-03-07 10:31:50 +03:00
auto label = new QLabel ( text ) ;
label - > setOpenExternalLinks ( true ) ;
setCellWidget ( row , PROPERTY , label ) ;
2015-11-15 09:56:39 +03:00
setCellWidget ( row , VALUE , widget ) ;
if ( std : : is_same < T , QCheckBox > : : value )
2019-03-07 10:31:50 +03:00
connect ( widget , SIGNAL ( stateChanged ( int ) ) , this , SIGNAL ( settingsChanged ( ) ) ) ;
2015-11-15 09:56:39 +03:00
else if ( std : : is_same < T , QSpinBox > : : value )
2019-03-07 10:31:50 +03:00
connect ( widget , SIGNAL ( valueChanged ( int ) ) , this , SIGNAL ( settingsChanged ( ) ) ) ;
2015-11-15 09:56:39 +03:00
else if ( std : : is_same < T , QComboBox > : : value )
2019-03-07 10:31:50 +03:00
connect ( widget , SIGNAL ( currentIndexChanged ( int ) ) , this , SIGNAL ( settingsChanged ( ) ) ) ;
2015-11-15 09:56:39 +03:00
else if ( std : : is_same < T , QLineEdit > : : value )
2019-03-07 10:31:50 +03:00
connect ( widget , SIGNAL ( textChanged ( QString ) ) , this , SIGNAL ( settingsChanged ( ) ) ) ;
2015-11-15 08:48:10 +03:00
}