void AdvancedSettings::loadAdvancedSettings() { const Preferences* const pref = Preferences::instance(); // add section headers QFont boldFont; boldFont.setBold(true); addRow(QBITTORRENT_HEADER, tr("qBittorrent Section"), &labelQbtLink); item(QBITTORRENT_HEADER, PROPERTY)->setFont(boldFont); labelQbtLink.setText(QString("<a href=\"%1\">%2</a>").arg("https://github.com/qbittorrent/qBittorrent/wiki/Explanation-of-Options-in-qBittorrent#Advanced").arg(tr("Open documentation"))); labelQbtLink.setOpenExternalLinks(true); addRow(LIBTORRENT_HEADER, tr("libtorrent Section"), &labelLibtorrentLink); item(LIBTORRENT_HEADER, PROPERTY)->setFont(boldFont); labelLibtorrentLink.setText(QString("<a href=\"%1\">%2</a>").arg("http://www.libtorrent.org/reference.html").arg(tr("Open documentation"))); labelLibtorrentLink.setOpenExternalLinks(true); // Disk write cache spin_cache.setMinimum(0); // When build as 32bit binary, set the maximum at less than 2GB to prevent crashes. // These macros may not be available on compilers other than MSVC and GCC #if defined(__x86_64__) || defined(_M_X64) spin_cache.setMaximum(4096); #else // allocate 1536MiB and leave 512MiB to the rest of program data in RAM spin_cache.setMaximum(1536); #endif spin_cache.setValue(pref->diskCacheSize()); updateCacheSpinSuffix(spin_cache.value()); addRow(DISK_CACHE, tr("Disk write cache size"), &spin_cache); // Disk cache expiry spin_cache_ttl.setMinimum(15); spin_cache_ttl.setMaximum(600); spin_cache_ttl.setValue(pref->diskCacheTTL()); spin_cache_ttl.setSuffix(tr(" s", " seconds")); addRow(DISK_CACHE_TTL, tr("Disk cache expiry interval"), &spin_cache_ttl); // Enable OS cache cb_os_cache.setChecked(pref->osCache()); addRow(OS_CACHE, tr("Enable OS cache"), &cb_os_cache); // Save resume data interval spin_save_resume_data_interval.setMinimum(1); spin_save_resume_data_interval.setMaximum(1440); spin_save_resume_data_interval.setValue(pref->saveResumeDataInterval()); spin_save_resume_data_interval.setSuffix(tr(" m", " minutes")); addRow(SAVE_RESUME_DATA_INTERVAL, tr("Save resume data interval", "How often the fastresume file is saved."), &spin_save_resume_data_interval); // Outgoing port Min outgoing_ports_min.setMinimum(0); outgoing_ports_min.setMaximum(65535); outgoing_ports_min.setValue(pref->outgoingPortsMin()); addRow(OUTGOING_PORT_MIN, tr("Outgoing ports (Min) [0: Disabled]"), &outgoing_ports_min); // Outgoing port Min outgoing_ports_max.setMinimum(0); outgoing_ports_max.setMaximum(65535); outgoing_ports_max.setValue(pref->outgoingPortsMax()); addRow(OUTGOING_PORT_MAX, tr("Outgoing ports (Max) [0: Disabled]"), &outgoing_ports_max); // Recheck completed torrents cb_recheck_completed.setChecked(pref->recheckTorrentsOnCompletion()); addRow(RECHECK_COMPLETED, tr("Recheck torrents on completion"), &cb_recheck_completed); // Transfer list refresh interval spin_list_refresh.setMinimum(30); spin_list_refresh.setMaximum(99999); spin_list_refresh.setValue(pref->getRefreshInterval()); spin_list_refresh.setSuffix(tr(" ms", " milliseconds")); addRow(LIST_REFRESH, tr("Transfer list refresh interval"), &spin_list_refresh); // Resolve Peer countries cb_resolve_countries.setChecked(pref->resolvePeerCountries()); addRow(RESOLVE_COUNTRIES, tr("Resolve peer countries (GeoIP)"), &cb_resolve_countries); // Resolve peer hosts cb_resolve_hosts.setChecked(pref->resolvePeerHostNames()); addRow(RESOLVE_HOSTS, tr("Resolve peer host names"), &cb_resolve_hosts); // Max Half Open connections spin_maxhalfopen.setMinimum(0); spin_maxhalfopen.setMaximum(99999); spin_maxhalfopen.setValue(pref->getMaxHalfOpenConnections()); addRow(MAX_HALF_OPEN, tr("Maximum number of half-open connections [0: Unlimited]"), &spin_maxhalfopen); // Super seeding cb_super_seeding.setChecked(pref->isSuperSeedingEnabled()); addRow(SUPER_SEEDING, tr("Strict super seeding"), &cb_super_seeding); // Network interface combo_iface.addItem(tr("Any interface", "i.e. Any network interface")); const QString current_iface = pref->getNetworkInterface(); bool interface_exists = current_iface.isEmpty(); int i = 1; foreach (const QNetworkInterface& iface, QNetworkInterface::allInterfaces()) { if (iface.flags() & QNetworkInterface::IsLoopBack) continue; combo_iface.addItem(iface.humanReadableName(), iface.name()); if (!current_iface.isEmpty() && (iface.name() == current_iface)) { combo_iface.setCurrentIndex(i); interface_exists = true; } ++i; } // Saved interface does not exist, show it anyway if (!interface_exists) { combo_iface.addItem(pref->getNetworkInterfaceName(), current_iface); combo_iface.setCurrentIndex(i); } addRow(NETWORK_IFACE, tr("Network Interface (requires restart)"), &combo_iface); // Listen on IPv6 address cb_listen_ipv6.setChecked(pref->getListenIPv6()); addRow(NETWORK_LISTEN_IPV6, tr("Listen on IPv6 address (requires restart)"), &cb_listen_ipv6); // Network address txt_network_address.setText(pref->getNetworkAddress()); addRow(NETWORK_ADDRESS, tr("IP Address to report to trackers (requires restart)"), &txt_network_address); // Program notifications cb_program_notifications.setChecked(pref->useProgramNotification()); addRow(PROGRAM_NOTIFICATIONS, tr("Display program on-screen notifications"), &cb_program_notifications); // Tracker State cb_tracker_status.setChecked(pref->isTrackerEnabled()); addRow(TRACKER_STATUS, tr("Enable embedded tracker"), &cb_tracker_status); // Tracker port spin_tracker_port.setMinimum(1); spin_tracker_port.setMaximum(65535); spin_tracker_port.setValue(pref->getTrackerPort()); addRow(TRACKER_PORT, tr("Embedded tracker port"), &spin_tracker_port); #if defined(Q_OS_WIN) || defined(Q_OS_MAC) cb_update_check.setChecked(pref->isUpdateCheckEnabled()); addRow(UPDATE_CHECK, tr("Check for software updates"), &cb_update_check); #endif #if (defined(Q_OS_UNIX) && !defined(Q_OS_MAC)) cb_use_icon_theme.setChecked(pref->useSystemIconTheme()); addRow(USE_ICON_THEME, tr("Use system icon theme"), &cb_use_icon_theme); #endif // Torrent recheck confirmation cb_confirm_torrent_recheck.setChecked(pref->confirmTorrentRecheck()); addRow(CONFIRM_RECHECK_TORRENT, tr("Confirm torrent recheck"), &cb_confirm_torrent_recheck); // Tracker exchange cb_enable_tracker_ext.setChecked(pref->trackerExchangeEnabled()); addRow(TRACKER_EXCHANGE, tr("Exchange trackers with other peers"), &cb_enable_tracker_ext); // Announce to all trackers cb_announce_all_trackers.setChecked(pref->announceToAllTrackers()); addRow(ANNOUNCE_ALL_TRACKERS, tr("Always announce to all trackers"), &cb_announce_all_trackers); }
void AdvancedSettings::loadAdvancedSettings() { const Preferences *const pref = Preferences::instance(); const BitTorrent::Session *const session = BitTorrent::Session::instance(); // add section headers QFont boldFont; boldFont.setBold(true); addRow(QBITTORRENT_HEADER, tr("qBittorrent Section"), &labelQbtLink); item(QBITTORRENT_HEADER, PROPERTY)->setFont(boldFont); labelQbtLink.setText(QString("<a href=\"%1\">%2</a>") .arg("https://github.com/qbittorrent/qBittorrent/wiki/Explanation-of-Options-in-qBittorrent#Advanced", tr("Open documentation"))); labelQbtLink.setOpenExternalLinks(true); addRow(LIBTORRENT_HEADER, tr("libtorrent Section"), &labelLibtorrentLink); item(LIBTORRENT_HEADER, PROPERTY)->setFont(boldFont); labelLibtorrentLink.setText(QString("<a href=\"%1\">%2</a>").arg("https://www.libtorrent.org/reference.html", tr("Open documentation"))); labelLibtorrentLink.setOpenExternalLinks(true); // Async IO threads spinBoxAsyncIOThreads.setMinimum(1); spinBoxAsyncIOThreads.setMaximum(1024); spinBoxAsyncIOThreads.setValue(session->asyncIOThreads()); addRow(ASYNC_IO_THREADS, tr("Asynchronous I/O threads"), &spinBoxAsyncIOThreads); // Checking Memory Usage spinBoxCheckingMemUsage.setMinimum(1); // When build as 32bit binary, set the maximum value lower to prevent crashes. #ifdef QBT_APP_64BIT spinBoxCheckingMemUsage.setMaximum(1024); #else // Allocate at most 128MiB out of the remaining 512MiB (see the cache part below) spinBoxCheckingMemUsage.setMaximum(128); #endif spinBoxCheckingMemUsage.setValue(session->checkingMemUsage()); spinBoxCheckingMemUsage.setSuffix(tr(" MiB")); addRow(CHECKING_MEM_USAGE, tr("Outstanding memory when checking torrents"), &spinBoxCheckingMemUsage); // Disk write cache spinBoxCache.setMinimum(-1); // When build as 32bit binary, set the maximum at less than 2GB to prevent crashes. // These macros may not be available on compilers other than MSVC and GCC #ifdef QBT_APP_64BIT spinBoxCache.setMaximum(4096); #else // allocate 1536MiB and leave 512MiB to the rest of program data in RAM spinBoxCache.setMaximum(1536); #endif spinBoxCache.setValue(session->diskCacheSize()); updateCacheSpinSuffix(spinBoxCache.value()); addRow(DISK_CACHE, tr("Disk cache"), &spinBoxCache); // Disk cache expiry spinBoxCacheTTL.setMinimum(15); spinBoxCacheTTL.setMaximum(600); spinBoxCacheTTL.setValue(session->diskCacheTTL()); spinBoxCacheTTL.setSuffix(tr(" s", " seconds")); addRow(DISK_CACHE_TTL, tr("Disk cache expiry interval"), &spinBoxCacheTTL); // Enable OS cache checkBoxOsCache.setChecked(session->useOSCache()); addRow(OS_CACHE, tr("Enable OS cache"), &checkBoxOsCache); // Guided read cache checkBoxGuidedReadCache.setChecked(session->isGuidedReadCacheEnabled()); addRow(GUIDED_READ_CACHE, tr("Guided read cache"), &checkBoxGuidedReadCache); // Coalesce reads & writes checkBoxCoalesceRW.setChecked(session->isCoalesceReadWriteEnabled()); addRow(COALESCE_RW, tr("Coalesce reads & writes"), &checkBoxCoalesceRW); // Suggest mode checkBoxSuggestMode.setChecked(session->isSuggestModeEnabled()); addRow(SUGGEST_MODE, tr("Send upload piece suggestions"), &checkBoxSuggestMode); // Send buffer watermark spinBoxSendBufferWatermark.setMinimum(1); spinBoxSendBufferWatermark.setMaximum(INT_MAX); spinBoxSendBufferWatermark.setSuffix(tr(" KiB")); spinBoxSendBufferWatermark.setValue(session->sendBufferWatermark()); addRow(SEND_BUF_WATERMARK, tr("Send buffer watermark"), &spinBoxSendBufferWatermark); spinBoxSendBufferLowWatermark.setMinimum(1); spinBoxSendBufferLowWatermark.setMaximum(INT_MAX); spinBoxSendBufferLowWatermark.setSuffix(tr(" KiB")); spinBoxSendBufferLowWatermark.setValue(session->sendBufferLowWatermark()); addRow(SEND_BUF_LOW_WATERMARK, tr("Send buffer low watermark"), &spinBoxSendBufferLowWatermark); spinBoxSendBufferWatermarkFactor.setMinimum(1); spinBoxSendBufferWatermarkFactor.setMaximum(INT_MAX); spinBoxSendBufferWatermarkFactor.setSuffix(" %"); spinBoxSendBufferWatermarkFactor.setValue(session->sendBufferWatermarkFactor()); addRow(SEND_BUF_WATERMARK_FACTOR, tr("Send buffer watermark factor"), &spinBoxSendBufferWatermarkFactor); // Save resume data interval spinBoxSaveResumeDataInterval.setMinimum(0); spinBoxSaveResumeDataInterval.setMaximum(std::numeric_limits<int>::max()); spinBoxSaveResumeDataInterval.setValue(session->saveResumeDataInterval()); updateSaveResumeDataIntervalSuffix(spinBoxSaveResumeDataInterval.value()); addRow(SAVE_RESUME_DATA_INTERVAL, tr("Save resume data interval", "How often the fastresume file is saved."), &spinBoxSaveResumeDataInterval); // Outgoing port Min spinBoxOutgoingPortsMin.setMinimum(0); spinBoxOutgoingPortsMin.setMaximum(65535); spinBoxOutgoingPortsMin.setValue(session->outgoingPortsMin()); addRow(OUTGOING_PORT_MIN, tr("Outgoing ports (Min) [0: Disabled]"), &spinBoxOutgoingPortsMin); // Outgoing port Min spinBoxOutgoingPortsMax.setMinimum(0); spinBoxOutgoingPortsMax.setMaximum(65535); spinBoxOutgoingPortsMax.setValue(session->outgoingPortsMax()); addRow(OUTGOING_PORT_MAX, tr("Outgoing ports (Max) [0: Disabled]"), &spinBoxOutgoingPortsMax); // uTP-TCP mixed mode comboBoxUtpMixedMode.addItems({tr("Prefer TCP"), tr("Peer proportional (throttles TCP)")}); comboBoxUtpMixedMode.setCurrentIndex(static_cast<int>(session->utpMixedMode())); addRow(UTP_MIX_MODE, tr("%1-TCP mixed mode algorithm", "uTP-TCP mixed mode algorithm").arg(C_UTP), &comboBoxUtpMixedMode); // multiple connections per IP checkBoxMultiConnectionsPerIp.setChecked(session->multiConnectionsPerIpEnabled()); addRow(MULTI_CONNECTIONS_PER_IP, tr("Allow multiple connections from the same IP address"), &checkBoxMultiConnectionsPerIp); // Recheck completed torrents checkBoxRecheckCompleted.setChecked(pref->recheckTorrentsOnCompletion()); addRow(RECHECK_COMPLETED, tr("Recheck torrents on completion"), &checkBoxRecheckCompleted); // Transfer list refresh interval spinBoxListRefresh.setMinimum(30); spinBoxListRefresh.setMaximum(99999); spinBoxListRefresh.setValue(session->refreshInterval()); spinBoxListRefresh.setSuffix(tr(" ms", " milliseconds")); addRow(LIST_REFRESH, tr("Transfer list refresh interval"), &spinBoxListRefresh); // Resolve Peer countries checkBoxResolveCountries.setChecked(pref->resolvePeerCountries()); addRow(RESOLVE_COUNTRIES, tr("Resolve peer countries (GeoIP)"), &checkBoxResolveCountries); // Resolve peer hosts checkBoxResolveHosts.setChecked(pref->resolvePeerHostNames()); addRow(RESOLVE_HOSTS, tr("Resolve peer host names"), &checkBoxResolveHosts); // Max Half Open connections spinBoxMaxHalfOpen.setMinimum(0); spinBoxMaxHalfOpen.setMaximum(99999); spinBoxMaxHalfOpen.setValue(session->maxHalfOpenConnections()); addRow(MAX_HALF_OPEN, tr("Maximum number of half-open connections [0: Unlimited]"), &spinBoxMaxHalfOpen); // Super seeding checkBoxSuperSeeding.setChecked(session->isSuperSeedingEnabled()); addRow(SUPER_SEEDING, tr("Strict super seeding"), &checkBoxSuperSeeding); // Network interface comboBoxInterface.addItem(tr("Any interface", "i.e. Any network interface")); const QString currentInterface = session->networkInterface(); bool interfaceExists = currentInterface.isEmpty(); int i = 1; for (const QNetworkInterface &iface : asConst(QNetworkInterface::allInterfaces())) { // 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; comboBoxInterface.addItem(iface.humanReadableName(), iface.name()); if (!currentInterface.isEmpty() && (iface.name() == currentInterface)) { comboBoxInterface.setCurrentIndex(i); interfaceExists = true; } ++i; } // Saved interface does not exist, show it anyway if (!interfaceExists) { comboBoxInterface.addItem(session->networkInterfaceName(), currentInterface); comboBoxInterface.setCurrentIndex(i); } addRow(NETWORK_IFACE, tr("Network Interface (requires restart)"), &comboBoxInterface); // Network interface address updateInterfaceAddressCombo(); addRow(NETWORK_IFACE_ADDRESS, tr("Optional IP Address to bind to (requires restart)"), &comboBoxInterfaceAddress); // Listen on IPv6 address checkBoxListenIPv6.setChecked(session->isIPv6Enabled()); addRow(NETWORK_LISTEN_IPV6, tr("Listen on IPv6 address (requires restart)"), &checkBoxListenIPv6); // Announce IP lineEditAnnounceIP.setText(session->announceIP()); addRow(ANNOUNCE_IP, tr("IP Address to report to trackers (requires restart)"), &lineEditAnnounceIP); // Program notifications const MainWindow *const mainWindow = static_cast<Application*>(QCoreApplication::instance())->mainWindow(); checkBoxProgramNotifications.setChecked(mainWindow->isNotificationsEnabled()); addRow(PROGRAM_NOTIFICATIONS, tr("Display notifications"), &checkBoxProgramNotifications); // Torrent added notifications checkBoxTorrentAddedNotifications.setChecked(mainWindow->isTorrentAddedNotificationsEnabled()); addRow(TORRENT_ADDED_NOTIFICATIONS, tr("Display notifications for added torrents"), &checkBoxTorrentAddedNotifications); // Download tracker's favicon checkBoxTrackerFavicon.setChecked(mainWindow->isDownloadTrackerFavicon()); addRow(DOWNLOAD_TRACKER_FAVICON, tr("Download tracker's favicon"), &checkBoxTrackerFavicon); // Save path history length spinBoxSavePathHistoryLength.setRange(AddNewTorrentDialog::minPathHistoryLength, AddNewTorrentDialog::maxPathHistoryLength); spinBoxSavePathHistoryLength.setValue(AddNewTorrentDialog::savePathHistoryLength()); addRow(SAVE_PATH_HISTORY_LENGTH, tr("Save path history length"), &spinBoxSavePathHistoryLength); // Enable speed graphs checkBoxSpeedWidgetEnabled.setChecked(pref->isSpeedWidgetEnabled()); addRow(ENABLE_SPEED_WIDGET, tr("Enable speed graphs"), &checkBoxSpeedWidgetEnabled); // Tracker State checkBoxTrackerStatus.setChecked(session->isTrackerEnabled()); addRow(TRACKER_STATUS, tr("Enable embedded tracker"), &checkBoxTrackerStatus); // Tracker port spinBoxTrackerPort.setMinimum(1); spinBoxTrackerPort.setMaximum(65535); spinBoxTrackerPort.setValue(pref->getTrackerPort()); addRow(TRACKER_PORT, tr("Embedded tracker port"), &spinBoxTrackerPort); // Choking algorithm comboBoxChokingAlgorithm.addItems({tr("Fixed slots"), tr("Upload rate based")}); comboBoxChokingAlgorithm.setCurrentIndex(static_cast<int>(session->chokingAlgorithm())); addRow(CHOKING_ALGORITHM, tr("Upload slots behavior"), &comboBoxChokingAlgorithm); // Seed choking algorithm comboBoxSeedChokingAlgorithm.addItems({tr("Round-robin"), tr("Fastest upload"), tr("Anti-leech")}); comboBoxSeedChokingAlgorithm.setCurrentIndex(static_cast<int>(session->seedChokingAlgorithm())); addRow(SEED_CHOKING_ALGORITHM, tr("Upload choking algorithm"), &comboBoxSeedChokingAlgorithm); #if defined(Q_OS_WIN) || defined(Q_OS_MAC) checkBoxUpdateCheck.setChecked(pref->isUpdateCheckEnabled()); addRow(UPDATE_CHECK, tr("Check for software updates"), &checkBoxUpdateCheck); #endif #if (defined(Q_OS_UNIX) && !defined(Q_OS_MAC)) checkBoxUseIconTheme.setChecked(pref->useSystemIconTheme()); addRow(USE_ICON_THEME, tr("Use system icon theme"), &checkBoxUseIconTheme); #endif // Torrent recheck confirmation checkBoxConfirmTorrentRecheck.setChecked(pref->confirmTorrentRecheck()); addRow(CONFIRM_RECHECK_TORRENT, tr("Confirm torrent recheck"), &checkBoxConfirmTorrentRecheck); // Remove all tags confirmation checkBoxConfirmRemoveAllTags.setChecked(pref->confirmRemoveAllTags()); addRow(CONFIRM_REMOVE_ALL_TAGS, tr("Confirm removal of all tags"), &checkBoxConfirmRemoveAllTags); // Announce to all trackers in a tier checkBoxAnnounceAllTrackers.setChecked(session->announceToAllTrackers()); addRow(ANNOUNCE_ALL_TRACKERS, tr("Always announce to all trackers in a tier"), &checkBoxAnnounceAllTrackers); // Announce to all tiers checkBoxAnnounceAllTiers.setChecked(session->announceToAllTiers()); addRow(ANNOUNCE_ALL_TIERS, tr("Always announce to all tiers"), &checkBoxAnnounceAllTiers); }