mirror of
https://github.com/qbittorrent/qBittorrent.git
synced 2024-10-22 10:46:04 +03:00
Display External IP Address in status bar
This change displays the last detected IPv4 and/or IPv6 address(es) in the GUI and WebUI's status bar. This does not yet handle systems with multiple addresses of the same type (e.g. multiple IPv6 addresses).
This commit is contained in:
parent
a23f45cc70
commit
b0b2fa20a0
16 changed files with 138 additions and 7 deletions
|
@ -467,6 +467,9 @@ namespace BitTorrent
|
|||
virtual void topTorrentsQueuePos(const QList<TorrentID> &ids) = 0;
|
||||
virtual void bottomTorrentsQueuePos(const QList<TorrentID> &ids) = 0;
|
||||
|
||||
virtual QString lastExternalIPv4Address() const = 0;
|
||||
virtual QString lastExternalIPv6Address() const = 0;
|
||||
|
||||
signals:
|
||||
void startupProgressUpdated(int progress);
|
||||
void addTorrentFailed(const InfoHash &infoHash, const QString &reason);
|
||||
|
|
|
@ -4945,6 +4945,16 @@ void SessionImpl::setTrackerFilteringEnabled(const bool enabled)
|
|||
}
|
||||
}
|
||||
|
||||
QString SessionImpl::lastExternalIPv4Address() const
|
||||
{
|
||||
return m_lastExternalIPv4Address;
|
||||
}
|
||||
|
||||
QString SessionImpl::lastExternalIPv6Address() const
|
||||
{
|
||||
return m_lastExternalIPv6Address;
|
||||
}
|
||||
|
||||
bool SessionImpl::isListening() const
|
||||
{
|
||||
return m_nativeSessionExtension->isSessionListening();
|
||||
|
@ -5932,11 +5942,19 @@ void SessionImpl::handleExternalIPAlert(const lt::external_ip_alert *alert)
|
|||
LogMsg(tr("Detected external IP. IP: \"%1\"")
|
||||
.arg(externalIP), Log::INFO);
|
||||
|
||||
if (m_lastExternalIP != externalIP)
|
||||
const bool isIPv6 = alert->external_address.is_v6();
|
||||
const bool isIPv4 = alert->external_address.is_v4();
|
||||
if (isIPv6 && (externalIP != m_lastExternalIPv6Address))
|
||||
{
|
||||
if (isReannounceWhenAddressChangedEnabled() && !m_lastExternalIP.isEmpty())
|
||||
if (isReannounceWhenAddressChangedEnabled() && !m_lastExternalIPv6Address.isEmpty())
|
||||
reannounceToAllTrackers();
|
||||
m_lastExternalIP = externalIP;
|
||||
m_lastExternalIPv6Address = externalIP;
|
||||
}
|
||||
else if (isIPv4 && (externalIP != m_lastExternalIPv4Address))
|
||||
{
|
||||
if (isReannounceWhenAddressChangedEnabled() && !m_lastExternalIPv4Address.isEmpty())
|
||||
reannounceToAllTrackers();
|
||||
m_lastExternalIPv4Address = externalIP;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -444,6 +444,9 @@ namespace BitTorrent
|
|||
void topTorrentsQueuePos(const QList<TorrentID> &ids) override;
|
||||
void bottomTorrentsQueuePos(const QList<TorrentID> &ids) override;
|
||||
|
||||
QString lastExternalIPv4Address() const override;
|
||||
QString lastExternalIPv6Address() const override;
|
||||
|
||||
// Torrent interface
|
||||
void handleTorrentResumeDataRequested(const TorrentImpl *torrent);
|
||||
void handleTorrentShareLimitChanged(TorrentImpl *torrent);
|
||||
|
@ -807,7 +810,8 @@ namespace BitTorrent
|
|||
|
||||
QList<MoveStorageJob> m_moveStorageQueue;
|
||||
|
||||
QString m_lastExternalIP;
|
||||
QString m_lastExternalIPv4Address;
|
||||
QString m_lastExternalIPv6Address;
|
||||
|
||||
bool m_needUpgradeDownloadPath = false;
|
||||
|
||||
|
|
|
@ -359,6 +359,19 @@ void Preferences::setStatusbarDisplayed(const bool displayed)
|
|||
setValue(u"Preferences/General/StatusbarDisplayed"_s, displayed);
|
||||
}
|
||||
|
||||
bool Preferences::isStatusbarExternalIPDisplayed() const
|
||||
{
|
||||
return value(u"Preferences/General/StatusbarExternalIPDisplayed"_s, true);
|
||||
}
|
||||
|
||||
void Preferences::setStatusbarExternalIPDisplayed(const bool displayed)
|
||||
{
|
||||
if (displayed == isStatusbarExternalIPDisplayed())
|
||||
return;
|
||||
|
||||
setValue(u"Preferences/General/StatusbarExternalIPDisplayed"_s, displayed);
|
||||
}
|
||||
|
||||
bool Preferences::isSplashScreenDisabled() const
|
||||
{
|
||||
return value(u"Preferences/General/NoSplashScreen"_s, true);
|
||||
|
|
|
@ -119,6 +119,8 @@ public:
|
|||
void setHideZeroComboValues(int n);
|
||||
bool isStatusbarDisplayed() const;
|
||||
void setStatusbarDisplayed(bool displayed);
|
||||
bool isStatusbarExternalIPDisplayed() const;
|
||||
void setStatusbarExternalIPDisplayed(bool displayed);
|
||||
bool isToolbarDisplayed() const;
|
||||
void setToolbarDisplayed(bool displayed);
|
||||
bool isSplashScreenDisabled() const;
|
||||
|
|
|
@ -1443,6 +1443,7 @@ void MainWindow::loadPreferences()
|
|||
}
|
||||
|
||||
showStatusBar(pref->isStatusbarDisplayed());
|
||||
m_statusBar->showStatusBarExternalIP(pref->isStatusbarExternalIPDisplayed());
|
||||
|
||||
m_transferListWidget->setAlternatingRowColors(pref->useAlternatingRowColors());
|
||||
m_propertiesWidget->getFilesList()->setAlternatingRowColors(pref->useAlternatingRowColors());
|
||||
|
|
|
@ -344,6 +344,7 @@ void OptionsDialog::loadBehaviorTabOptions()
|
|||
m_ui->checkFileLog->setChecked(app()->isFileLoggerEnabled());
|
||||
|
||||
m_ui->checkBoxPerformanceWarning->setChecked(session->isPerformanceWarningEnabled());
|
||||
m_ui->checkBoxExternalIPStatusBar->setChecked(pref->isStatusbarExternalIPDisplayed());
|
||||
|
||||
connect(m_ui->comboI18n, qComboBoxCurrentIndexChanged, this, &ThisType::enableApplyButton);
|
||||
|
||||
|
@ -423,6 +424,7 @@ void OptionsDialog::loadBehaviorTabOptions()
|
|||
connect(m_ui->comboFileLogAgeType, qComboBoxCurrentIndexChanged, this, &ThisType::enableApplyButton);
|
||||
|
||||
connect(m_ui->checkBoxPerformanceWarning, &QAbstractButton::toggled, this, &ThisType::enableApplyButton);
|
||||
connect(m_ui->checkBoxExternalIPStatusBar, &QAbstractButton::toggled, this, &ThisType::enableApplyButton);
|
||||
}
|
||||
|
||||
void OptionsDialog::saveBehaviorTabOptions() const
|
||||
|
@ -507,6 +509,7 @@ void OptionsDialog::saveBehaviorTabOptions() const
|
|||
app()->setStartUpWindowState(m_ui->windowStateComboBox->currentData().value<WindowState>());
|
||||
|
||||
session->setPerformanceWarningEnabled(m_ui->checkBoxPerformanceWarning->isChecked());
|
||||
pref->setStatusbarExternalIPDisplayed(m_ui->checkBoxExternalIPStatusBar->isChecked());
|
||||
}
|
||||
|
||||
void OptionsDialog::loadDownloadsTabOptions()
|
||||
|
|
|
@ -772,6 +772,13 @@
|
|||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="checkBoxExternalIPStatusBar">
|
||||
<property name="text">
|
||||
<string>Show external IP in status bar</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="checkBoxPerformanceWarning">
|
||||
<property name="text">
|
||||
|
|
|
@ -86,6 +86,9 @@ StatusBar::StatusBar(QWidget *parent)
|
|||
m_upSpeedLbl->setStyleSheet(u"text-align:left;"_s);
|
||||
m_upSpeedLbl->setMinimumWidth(200);
|
||||
|
||||
m_lastExternalIPsLbl = new QLabel(tr("External IP: N/A"));
|
||||
m_lastExternalIPsLbl->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Preferred);
|
||||
|
||||
m_DHTLbl = new QLabel(tr("DHT: %1 nodes").arg(0), this);
|
||||
m_DHTLbl->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Preferred);
|
||||
|
||||
|
@ -129,14 +132,21 @@ StatusBar::StatusBar(QWidget *parent)
|
|||
#ifndef Q_OS_MACOS
|
||||
statusSep4->setFrameShadow(QFrame::Raised);
|
||||
#endif
|
||||
layout->addWidget(m_DHTLbl);
|
||||
QFrame *statusSep5 = new QFrame(this);
|
||||
statusSep5->setFrameStyle(QFrame::VLine);
|
||||
#ifndef Q_OS_MACOS
|
||||
statusSep5->setFrameShadow(QFrame::Raised);
|
||||
#endif
|
||||
layout->addWidget(m_lastExternalIPsLbl);
|
||||
layout->addWidget(statusSep1);
|
||||
layout->addWidget(m_connecStatusLblIcon);
|
||||
layout->addWidget(m_DHTLbl);
|
||||
layout->addWidget(statusSep2);
|
||||
layout->addWidget(m_connecStatusLblIcon);
|
||||
layout->addWidget(statusSep3);
|
||||
layout->addWidget(m_altSpeedsBtn);
|
||||
layout->addWidget(statusSep4);
|
||||
layout->addWidget(m_dlSpeedLbl);
|
||||
layout->addWidget(statusSep3);
|
||||
layout->addWidget(statusSep5);
|
||||
layout->addWidget(m_upSpeedLbl);
|
||||
|
||||
addPermanentWidget(container);
|
||||
|
@ -170,6 +180,11 @@ void StatusBar::showRestartRequired()
|
|||
insertWidget(1, restartLbl);
|
||||
}
|
||||
|
||||
void StatusBar::showStatusBarExternalIP(const bool display)
|
||||
{
|
||||
m_lastExternalIPsLbl->setVisible(display);
|
||||
}
|
||||
|
||||
void StatusBar::updateConnectionStatus()
|
||||
{
|
||||
const BitTorrent::SessionStatus &sessionStatus = BitTorrent::Session::instance()->status();
|
||||
|
@ -212,6 +227,23 @@ void StatusBar::updateDHTNodesNumber()
|
|||
}
|
||||
}
|
||||
|
||||
void StatusBar::updateExternalAddressesLabel()
|
||||
{
|
||||
const QString lastExternalIPv4Address = BitTorrent::Session::instance()->lastExternalIPv4Address();
|
||||
const QString lastExternalIPv6Address = BitTorrent::Session::instance()->lastExternalIPv6Address();
|
||||
QString addressText = tr("External IP: N/A");
|
||||
|
||||
const bool hasIPv4Address = !lastExternalIPv4Address.isEmpty();
|
||||
const bool hasIPv6Address = !lastExternalIPv6Address.isEmpty();
|
||||
|
||||
if (hasIPv4Address && hasIPv6Address)
|
||||
addressText = tr("External IPs: %1, %2").arg(lastExternalIPv4Address, lastExternalIPv6Address);
|
||||
else if (hasIPv4Address || hasIPv6Address)
|
||||
addressText = tr("External IP: %1%2").arg(lastExternalIPv4Address, lastExternalIPv6Address);
|
||||
|
||||
m_lastExternalIPsLbl->setText(addressText);
|
||||
}
|
||||
|
||||
void StatusBar::updateSpeedLabels()
|
||||
{
|
||||
const BitTorrent::SessionStatus &sessionStatus = BitTorrent::Session::instance()->status();
|
||||
|
@ -235,6 +267,7 @@ void StatusBar::refresh()
|
|||
{
|
||||
updateConnectionStatus();
|
||||
updateDHTNodesNumber();
|
||||
updateExternalAddressesLabel();
|
||||
updateSpeedLabels();
|
||||
}
|
||||
|
||||
|
|
|
@ -47,6 +47,8 @@ public:
|
|||
StatusBar(QWidget *parent = nullptr);
|
||||
~StatusBar() override;
|
||||
|
||||
void showStatusBarExternalIP(bool display);
|
||||
|
||||
signals:
|
||||
void alternativeSpeedsButtonClicked();
|
||||
void connectionButtonClicked();
|
||||
|
@ -62,10 +64,12 @@ private slots:
|
|||
private:
|
||||
void updateConnectionStatus();
|
||||
void updateDHTNodesNumber();
|
||||
void updateExternalAddressesLabel();
|
||||
void updateSpeedLabels();
|
||||
|
||||
QPushButton *m_dlSpeedLbl = nullptr;
|
||||
QPushButton *m_upSpeedLbl = nullptr;
|
||||
QLabel *m_lastExternalIPsLbl = nullptr;
|
||||
QLabel *m_DHTLbl = nullptr;
|
||||
QPushButton *m_connecStatusLblIcon = nullptr;
|
||||
QPushButton *m_altSpeedsBtn = nullptr;
|
||||
|
|
|
@ -127,6 +127,7 @@ void AppController::preferencesAction()
|
|||
// Language
|
||||
data[u"locale"_s] = pref->getLocale();
|
||||
data[u"performance_warning"_s] = session->isPerformanceWarningEnabled();
|
||||
data[u"status_bar_external_ip"_s] = pref->isStatusbarExternalIPDisplayed();
|
||||
// Transfer List
|
||||
data[u"confirm_torrent_deletion"_s] = pref->confirmTorrentDeletion();
|
||||
// Log file
|
||||
|
@ -510,6 +511,8 @@ void AppController::setPreferencesAction()
|
|||
}
|
||||
if (hasKey(u"performance_warning"_s))
|
||||
session->setPerformanceWarningEnabled(it.value().toBool());
|
||||
if (hasKey(u"status_bar_external_ip"_s))
|
||||
pref->setStatusbarExternalIPDisplayed(it.value().toBool());
|
||||
// Transfer List
|
||||
if (hasKey(u"confirm_torrent_deletion"_s))
|
||||
pref->setConfirmTorrentDeletion(it.value().toBool());
|
||||
|
|
|
@ -87,6 +87,8 @@ namespace
|
|||
const QString KEY_TRANSFER_DLRATELIMIT = u"dl_rate_limit"_s;
|
||||
const QString KEY_TRANSFER_DLSPEED = u"dl_info_speed"_s;
|
||||
const QString KEY_TRANSFER_FREESPACEONDISK = u"free_space_on_disk"_s;
|
||||
const QString KEY_TRANSFER_LAST_EXTERNAL_ADDRESS_V4 = u"last_external_address_v4"_s;
|
||||
const QString KEY_TRANSFER_LAST_EXTERNAL_ADDRESS_V6 = u"last_external_address_v6"_s;
|
||||
const QString KEY_TRANSFER_UPDATA = u"up_info_data"_s;
|
||||
const QString KEY_TRANSFER_UPRATELIMIT = u"up_rate_limit"_s;
|
||||
const QString KEY_TRANSFER_UPSPEED = u"up_info_speed"_s;
|
||||
|
@ -161,6 +163,8 @@ namespace
|
|||
map[KEY_TRANSFER_AVERAGE_TIME_QUEUE] = cacheStatus.averageJobTime;
|
||||
map[KEY_TRANSFER_TOTAL_QUEUED_SIZE] = cacheStatus.queuedBytes;
|
||||
|
||||
map[KEY_TRANSFER_LAST_EXTERNAL_ADDRESS_V4] = session->lastExternalIPv4Address();
|
||||
map[KEY_TRANSFER_LAST_EXTERNAL_ADDRESS_V6] = session->lastExternalIPv6Address();
|
||||
map[KEY_TRANSFER_DHT_NODES] = sessionStatus.dhtNodes;
|
||||
map[KEY_TRANSFER_CONNECTION_STATUS] = session->isListening()
|
||||
? (sessionStatus.hasIncomingConnections ? u"connected"_s : u"firewalled"_s)
|
||||
|
@ -450,6 +454,8 @@ void SyncController::updateFreeDiskSpace(const qint64 freeDiskSpace)
|
|||
// - "dl_info_data": bytes downloaded
|
||||
// - "dl_info_speed": download speed
|
||||
// - "dl_rate_limit: download rate limit
|
||||
// - "last_external_address_v4": last external address v4
|
||||
// - "last_external_address_v6": last external address v6
|
||||
// - "up_info_data: bytes uploaded
|
||||
// - "up_info_speed: upload speed
|
||||
// - "up_rate_limit: upload speed limit
|
||||
|
|
|
@ -45,6 +45,8 @@ const QString KEY_TRANSFER_DLRATELIMIT = u"dl_rate_limit"_s;
|
|||
const QString KEY_TRANSFER_UPSPEED = u"up_info_speed"_s;
|
||||
const QString KEY_TRANSFER_UPDATA = u"up_info_data"_s;
|
||||
const QString KEY_TRANSFER_UPRATELIMIT = u"up_rate_limit"_s;
|
||||
const QString KEY_TRANSFER_LAST_EXTERNAL_ADDRESS_V4 = u"last_external_address_v4"_s;
|
||||
const QString KEY_TRANSFER_LAST_EXTERNAL_ADDRESS_V6 = u"last_external_address_v6"_s;
|
||||
const QString KEY_TRANSFER_DHT_NODES = u"dht_nodes"_s;
|
||||
const QString KEY_TRANSFER_CONNECTION_STATUS = u"connection_status"_s;
|
||||
|
||||
|
@ -57,6 +59,8 @@ const QString KEY_TRANSFER_CONNECTION_STATUS = u"connection_status"_s;
|
|||
// - "up_info_data": Data uploaded this session
|
||||
// - "dl_rate_limit": Download rate limit
|
||||
// - "up_rate_limit": Upload rate limit
|
||||
// - "last_external_address_v4": external IPv4 address
|
||||
// - "last_external_address_v6": external IPv6 address
|
||||
// - "dht_nodes": DHT nodes connected to
|
||||
// - "connection_status": Connection status
|
||||
void TransferController::infoAction()
|
||||
|
@ -71,6 +75,8 @@ void TransferController::infoAction()
|
|||
dict[KEY_TRANSFER_UPDATA] = static_cast<qint64>(sessionStatus.totalPayloadUpload);
|
||||
dict[KEY_TRANSFER_DLRATELIMIT] = BitTorrent::Session::instance()->downloadSpeedLimit();
|
||||
dict[KEY_TRANSFER_UPRATELIMIT] = BitTorrent::Session::instance()->uploadSpeedLimit();
|
||||
dict[KEY_TRANSFER_LAST_EXTERNAL_ADDRESS_V4] = BitTorrent::Session::instance()->lastExternalIPv4Address();
|
||||
dict[KEY_TRANSFER_LAST_EXTERNAL_ADDRESS_V6] = BitTorrent::Session::instance()->lastExternalIPv6Address();
|
||||
dict[KEY_TRANSFER_DHT_NODES] = static_cast<qint64>(sessionStatus.dhtNodes);
|
||||
if (!BitTorrent::Session::instance()->isListening())
|
||||
dict[KEY_TRANSFER_CONNECTION_STATUS] = u"disconnected"_s;
|
||||
|
|
|
@ -266,6 +266,8 @@
|
|||
<tbody>
|
||||
<tr>
|
||||
<td id="freeSpaceOnDisk"></td>
|
||||
<td class="statusBarSeparator invisible"></td>
|
||||
<td id="externalIPs" class="invisible"></td>
|
||||
<td class="statusBarSeparator"></td>
|
||||
<td id="DHTNodes"></td>
|
||||
<td class="statusBarSeparator"></td>
|
||||
|
|
|
@ -928,6 +928,25 @@ window.addEventListener("DOMContentLoaded", () => {
|
|||
|
||||
$("freeSpaceOnDisk").textContent = "QBT_TR(Free space: %1)QBT_TR[CONTEXT=HttpServer]".replace("%1", window.qBittorrent.Misc.friendlyUnit(serverState.free_space_on_disk));
|
||||
|
||||
if (window.qBittorrent.Cache.preferences.get().status_bar_external_ip) {
|
||||
const lastExternalAddressV4 = serverState.last_external_address_v4;
|
||||
const lastExternalAddressV6 = serverState.last_external_address_v6;
|
||||
const hasIPv4Address = lastExternalAddressV4 !== "";
|
||||
const hasIPv6Address = lastExternalAddressV6 !== "";
|
||||
let lastExternalAddressLabel = "QBT_TR(External IP: N/A)QBT_TR[CONTEXT=HttpServer]";
|
||||
if (hasIPv4Address && hasIPv6Address)
|
||||
lastExternalAddressLabel = "QBT_TR(External IPs: %1, %2)QBT_TR[CONTEXT=HttpServer]";
|
||||
else if (hasIPv4Address || hasIPv6Address)
|
||||
lastExternalAddressLabel = "QBT_TR(External IP: %1%2)QBT_TR[CONTEXT=HttpServer]";
|
||||
// replace in reverse order ('%2' before '%1') in case address contains a % character.
|
||||
// for example, see https://en.wikipedia.org/wiki/IPv6_address#Scoped_literal_IPv6_addresses_(with_zone_index)
|
||||
$("externalIPs").textContent = lastExternalAddressLabel.replace("%2", lastExternalAddressV6).replace("%1", lastExternalAddressV4);
|
||||
|
||||
const elem = document.getElementById("externalIPs");
|
||||
elem.classList.remove("invisible");
|
||||
elem.previousElementSibling.classList.remove("invisible");
|
||||
}
|
||||
|
||||
const dhtElement = document.getElementById("DHTNodes");
|
||||
if (window.qBittorrent.Cache.preferences.get().dht) {
|
||||
dhtElement.textContent = "QBT_TR(DHT: %1 nodes)QBT_TR[CONTEXT=StatusBar]".replace("%1", serverState.dht_nodes);
|
||||
|
|
|
@ -80,6 +80,11 @@
|
|||
</table>
|
||||
</fieldset>
|
||||
|
||||
<div class="formRow" style="margin-bottom: 3px;">
|
||||
<input type="checkbox" id="statusBarExternalIP">
|
||||
<label for="statusBarExternalIP">QBT_TR(Show external IP in status bar)QBT_TR[CONTEXT=OptionsDialog]</label>
|
||||
</div>
|
||||
|
||||
<div class="formRow" style="margin-bottom: 5px;">
|
||||
<input type="checkbox" id="performanceWarning">
|
||||
<label for="performanceWarning">QBT_TR(Log performance warnings)QBT_TR[CONTEXT=OptionsDialog]</label>
|
||||
|
@ -2411,6 +2416,7 @@ Use ';' to split multiple entries. Can use wildcard '*'.)QBT_TR[CONTEXT=OptionsD
|
|||
// Language
|
||||
updateWebuiLocaleSelect(pref.locale);
|
||||
$("performanceWarning").checked = pref.performance_warning;
|
||||
$("statusBarExternalIP").checked = pref.status_bar_external_ip;
|
||||
|
||||
// HTTP Server
|
||||
$("webui_domain_textarea").value = pref.web_ui_domain_list;
|
||||
|
@ -2836,6 +2842,7 @@ Use ';' to split multiple entries. Can use wildcard '*'.)QBT_TR[CONTEXT=OptionsD
|
|||
// Language
|
||||
settings["locale"] = $("locale_select").value;
|
||||
settings["performance_warning"] = $("performanceWarning").checked;
|
||||
settings["status_bar_external_ip"] = $("statusBarExternalIP").checked;
|
||||
|
||||
// HTTP Server
|
||||
settings["web_ui_domain_list"] = $("webui_domain_textarea").value;
|
||||
|
|
Loading…
Reference in a new issue