mirror of
https://github.com/qbittorrent/qBittorrent.git
synced 2024-11-27 11:40:33 +00:00
Allow to set custom suffix to window title
This is to allow users to differentiate qbt instances when there are multiple running. PR #20429. Closes #17905.
This commit is contained in:
parent
364bcf73ee
commit
46e8ee50c8
@ -226,6 +226,7 @@ namespace
|
||||
Application::Application(int &argc, char **argv)
|
||||
: BaseApplication(argc, argv)
|
||||
, m_commandLineArgs(parseCommandLine(Application::arguments()))
|
||||
, m_storeInstanceName(SETTINGS_KEY(u"InstanceName"_s))
|
||||
, m_storeFileLoggerEnabled(FILELOGGER_SETTINGS_KEY(u"Enabled"_s))
|
||||
, m_storeFileLoggerBackup(FILELOGGER_SETTINGS_KEY(u"Backup"_s))
|
||||
, m_storeFileLoggerDeleteOld(FILELOGGER_SETTINGS_KEY(u"DeleteOld"_s))
|
||||
@ -360,6 +361,23 @@ const QBtCommandLineParameters &Application::commandLineArgs() const
|
||||
return m_commandLineArgs;
|
||||
}
|
||||
|
||||
QString Application::instanceName() const
|
||||
{
|
||||
return m_storeInstanceName;
|
||||
}
|
||||
|
||||
void Application::setInstanceName(const QString &name)
|
||||
{
|
||||
if (name == instanceName())
|
||||
return;
|
||||
|
||||
m_storeInstanceName = name;
|
||||
#ifndef DISABLE_GUI
|
||||
if (MainWindow *mw = mainWindow())
|
||||
mw->setTitleSuffix(name);
|
||||
#endif
|
||||
}
|
||||
|
||||
int Application::memoryWorkingSetLimit() const
|
||||
{
|
||||
return m_storeMemoryWorkingSetLimit.get(512);
|
||||
@ -880,7 +898,8 @@ int Application::exec()
|
||||
const WindowState windowState = (m_startupProgressDialog->windowState() & Qt::WindowMinimized)
|
||||
? WindowState::Minimized : WindowState::Normal;
|
||||
#endif
|
||||
m_window = new MainWindow(this, windowState);
|
||||
m_window = new MainWindow(this, windowState, instanceName());
|
||||
|
||||
delete m_startupProgressDialog;
|
||||
#endif // DISABLE_GUI
|
||||
|
||||
|
@ -105,6 +105,9 @@ public:
|
||||
bool callMainInstance();
|
||||
const QBtCommandLineParameters &commandLineArgs() const;
|
||||
|
||||
QString instanceName() const override;
|
||||
void setInstanceName(const QString &name) override;
|
||||
|
||||
// FileLogger properties
|
||||
bool isFileLoggerEnabled() const override;
|
||||
void setFileLoggerEnabled(bool value) override;
|
||||
@ -194,6 +197,7 @@ private:
|
||||
|
||||
QList<QBtCommandLineParameters> m_paramsQueue;
|
||||
|
||||
SettingValue<QString> m_storeInstanceName;
|
||||
SettingValue<bool> m_storeFileLoggerEnabled;
|
||||
SettingValue<bool> m_storeFileLoggerBackup;
|
||||
SettingValue<bool> m_storeFileLoggerDeleteOld;
|
||||
|
@ -61,6 +61,9 @@ class IApplication
|
||||
public:
|
||||
virtual ~IApplication() = default;
|
||||
|
||||
virtual QString instanceName() const = 0;
|
||||
virtual void setInstanceName(const QString &name) = 0;
|
||||
|
||||
// FileLogger properties
|
||||
virtual bool isFileLoggerEnabled() const = 0;
|
||||
virtual void setFileLoggerEnabled(bool value) = 0;
|
||||
|
@ -79,6 +79,7 @@ namespace
|
||||
CONFIRM_RECHECK_TORRENT,
|
||||
RECHECK_COMPLETED,
|
||||
// UI related
|
||||
APP_INSTANCE_NAME,
|
||||
LIST_REFRESH,
|
||||
RESOLVE_HOSTS,
|
||||
RESOLVE_COUNTRIES,
|
||||
@ -280,6 +281,8 @@ void AdvancedSettings::saveAdvancedSettings() const
|
||||
session->setBlockPeersOnPrivilegedPorts(m_checkBoxBlockPeersOnPrivilegedPorts.isChecked());
|
||||
// Recheck torrents on completion
|
||||
pref->recheckTorrentsOnCompletion(m_checkBoxRecheckCompleted.isChecked());
|
||||
// Customize application instance name
|
||||
app()->setInstanceName(m_lineEditAppInstanceName.text());
|
||||
// Transfer list refresh interval
|
||||
session->setRefreshInterval(m_spinBoxListRefresh.value());
|
||||
// Peer resolution
|
||||
@ -723,6 +726,10 @@ void AdvancedSettings::loadAdvancedSettings()
|
||||
// Recheck completed torrents
|
||||
m_checkBoxRecheckCompleted.setChecked(pref->recheckTorrentsOnCompletion());
|
||||
addRow(RECHECK_COMPLETED, tr("Recheck torrents on completion"), &m_checkBoxRecheckCompleted);
|
||||
// Customize application instance name
|
||||
m_lineEditAppInstanceName.setText(app()->instanceName());
|
||||
m_lineEditAppInstanceName.setToolTip(tr("It appends the text to the window title to help distinguish qBittorent instances"));
|
||||
addRow(APP_INSTANCE_NAME, tr("Customize application instance name"), &m_lineEditAppInstanceName);
|
||||
// Refresh interval
|
||||
m_spinBoxListRefresh.setMinimum(30);
|
||||
m_spinBoxListRefresh.setMaximum(99999);
|
||||
|
@ -82,7 +82,7 @@ private:
|
||||
m_checkBoxSuggestMode, m_checkBoxSpeedWidgetEnabled, m_checkBoxIDNSupport, m_checkBoxConfirmRemoveTrackerFromAllTorrents;
|
||||
QComboBox m_comboBoxInterface, m_comboBoxInterfaceAddress, m_comboBoxDiskIOReadMode, m_comboBoxDiskIOWriteMode, m_comboBoxUtpMixedMode, m_comboBoxChokingAlgorithm,
|
||||
m_comboBoxSeedChokingAlgorithm, m_comboBoxResumeDataStorage;
|
||||
QLineEdit m_pythonExecutablePath, m_lineEditAnnounceIP, m_lineEditDHTBootstrapNodes;
|
||||
QLineEdit m_lineEditAppInstanceName, m_pythonExecutablePath, m_lineEditAnnounceIP, m_lineEditDHTBootstrapNodes;
|
||||
|
||||
#ifndef QBT_USES_LIBTORRENT2
|
||||
QSpinBox m_spinBoxCache, m_spinBoxCacheTTL;
|
||||
|
@ -122,7 +122,7 @@ namespace
|
||||
}
|
||||
}
|
||||
|
||||
MainWindow::MainWindow(IGUIApplication *app, WindowState initialState)
|
||||
MainWindow::MainWindow(IGUIApplication *app, const WindowState initialState, const QString &titleSuffix)
|
||||
: GUIApplicationComponent(app)
|
||||
, m_ui(new Ui::MainWindow)
|
||||
, m_storeExecutionLogEnabled(EXECUTIONLOG_SETTINGS_KEY(u"Enabled"_s))
|
||||
@ -134,9 +134,10 @@ MainWindow::MainWindow(IGUIApplication *app, WindowState initialState)
|
||||
{
|
||||
m_ui->setupUi(this);
|
||||
|
||||
setTitleSuffix(titleSuffix);
|
||||
|
||||
Preferences *const pref = Preferences::instance();
|
||||
m_uiLocked = pref->isUILocked();
|
||||
setWindowTitle(QStringLiteral("qBittorrent " QBT_VERSION));
|
||||
m_displaySpeedInTitle = pref->speedInTitleBar();
|
||||
// Setting icons
|
||||
#ifndef Q_OS_MACOS
|
||||
@ -524,6 +525,16 @@ void MainWindow::setDownloadTrackerFavicon(const bool value)
|
||||
m_storeDownloadTrackerFavicon = value;
|
||||
}
|
||||
|
||||
void MainWindow::setTitleSuffix(const QString &suffix)
|
||||
{
|
||||
const auto emDash = QChar(0x2014);
|
||||
const QString separator = u' ' + emDash + u' ';
|
||||
m_windowTitle = QStringLiteral("qBittorrent " QBT_VERSION)
|
||||
+ (!suffix.isEmpty() ? (separator + suffix) : QString());
|
||||
|
||||
setWindowTitle(m_windowTitle);
|
||||
}
|
||||
|
||||
void MainWindow::addToolbarContextMenu()
|
||||
{
|
||||
const Preferences *const pref = Preferences::instance();
|
||||
@ -1485,23 +1496,24 @@ void MainWindow::loadPreferences()
|
||||
void MainWindow::reloadSessionStats()
|
||||
{
|
||||
const BitTorrent::SessionStatus &status = BitTorrent::Session::instance()->status();
|
||||
const QString downloadRate = Utils::Misc::friendlyUnit(status.payloadDownloadRate, true);
|
||||
const QString uploadRate = Utils::Misc::friendlyUnit(status.payloadUploadRate, true);
|
||||
|
||||
// update global information
|
||||
#ifdef Q_OS_MACOS
|
||||
m_badger->updateSpeed(status.payloadDownloadRate, status.payloadUploadRate);
|
||||
#else
|
||||
const auto toolTip = u"%1\n%2"_s.arg(
|
||||
tr("DL speed: %1", "e.g: Download speed: 10 KiB/s").arg(Utils::Misc::friendlyUnit(status.payloadDownloadRate, true))
|
||||
, tr("UP speed: %1", "e.g: Upload speed: 10 KiB/s").arg(Utils::Misc::friendlyUnit(status.payloadUploadRate, true)));
|
||||
tr("DL speed: %1", "e.g: Download speed: 10 KiB/s").arg(downloadRate)
|
||||
, tr("UP speed: %1", "e.g: Upload speed: 10 KiB/s").arg(uploadRate));
|
||||
app()->desktopIntegration()->setToolTip(toolTip); // tray icon
|
||||
#endif // Q_OS_MACOS
|
||||
|
||||
if (m_displaySpeedInTitle)
|
||||
{
|
||||
setWindowTitle(tr("[D: %1, U: %2] qBittorrent %3", "D = Download; U = Upload; %3 is qBittorrent version")
|
||||
.arg(Utils::Misc::friendlyUnit(status.payloadDownloadRate, true)
|
||||
, Utils::Misc::friendlyUnit(status.payloadUploadRate, true)
|
||||
, QStringLiteral(QBT_VERSION)));
|
||||
const QString title = tr("[D: %1, U: %2] %3", "D = Download; U = Upload; %3 is the rest of the window title")
|
||||
.arg(downloadRate, uploadRate, m_windowTitle);
|
||||
setWindowTitle(title);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1621,7 +1633,7 @@ void MainWindow::on_actionSpeedInTitleBar_triggered()
|
||||
if (m_displaySpeedInTitle)
|
||||
reloadSessionStats();
|
||||
else
|
||||
setWindowTitle(QStringLiteral("qBittorrent " QBT_VERSION));
|
||||
setWindowTitle(m_windowTitle);
|
||||
}
|
||||
|
||||
void MainWindow::on_actionRSSReader_triggered()
|
||||
|
@ -84,7 +84,7 @@ class MainWindow final : public GUIApplicationComponent<QMainWindow>
|
||||
Q_DISABLE_COPY_MOVE(MainWindow)
|
||||
|
||||
public:
|
||||
explicit MainWindow(IGUIApplication *app, WindowState initialState = WindowState::Normal);
|
||||
explicit MainWindow(IGUIApplication *app, WindowState initialState = WindowState::Normal, const QString &titleSuffix = {});
|
||||
~MainWindow() override;
|
||||
|
||||
QWidget *currentTabWidget() const;
|
||||
@ -97,12 +97,12 @@ public:
|
||||
Log::MsgTypes executionLogMsgTypes() const;
|
||||
void setExecutionLogMsgTypes(Log::MsgTypes value);
|
||||
|
||||
// Notifications properties
|
||||
|
||||
// Misc properties
|
||||
bool isDownloadTrackerFavicon() const;
|
||||
void setDownloadTrackerFavicon(bool value);
|
||||
|
||||
void setTitleSuffix(const QString &suffix);
|
||||
|
||||
void activate();
|
||||
void cleanup();
|
||||
|
||||
@ -207,6 +207,7 @@ private:
|
||||
|
||||
QFileSystemWatcher *m_executableWatcher = nullptr;
|
||||
// GUI related
|
||||
QString m_windowTitle;
|
||||
bool m_posInitialized = false;
|
||||
bool m_neverShown = true;
|
||||
QPointer<QTabWidget> m_tabs;
|
||||
|
@ -361,6 +361,8 @@ void AppController::preferencesAction()
|
||||
data[u"torrent_file_size_limit"_s] = pref->getTorrentFileSizeLimit();
|
||||
// Recheck completed torrents
|
||||
data[u"recheck_completed_torrents"_s] = pref->recheckTorrentsOnCompletion();
|
||||
// Customize application instance name
|
||||
data[u"app_instance_name"_s] = app()->instanceName();
|
||||
// Refresh interval
|
||||
data[u"refresh_interval"_s] = session->refreshInterval();
|
||||
// Resolve peer countries
|
||||
@ -943,6 +945,9 @@ void AppController::setPreferencesAction()
|
||||
// Recheck completed torrents
|
||||
if (hasKey(u"recheck_completed_torrents"_s))
|
||||
pref->recheckTorrentsOnCompletion(it.value().toBool());
|
||||
// Customize application instance name
|
||||
if (hasKey(u"app_instance_name"_s))
|
||||
app()->setInstanceName(it.value().toString());
|
||||
// Refresh interval
|
||||
if (hasKey(u"refresh_interval"_s))
|
||||
session->setRefreshInterval(it.value().toInt());
|
||||
|
@ -53,7 +53,7 @@
|
||||
#include "base/utils/version.h"
|
||||
#include "api/isessionmanager.h"
|
||||
|
||||
inline const Utils::Version<3, 2> API_VERSION {2, 10, 3};
|
||||
inline const Utils::Version<3, 2> API_VERSION {2, 10, 4};
|
||||
|
||||
class QTimer;
|
||||
|
||||
|
@ -241,7 +241,7 @@ a.propButton img {
|
||||
.contextMenu li a {
|
||||
color: var(--color-text-default);
|
||||
display: block;
|
||||
font-family: tahoma, arial, sans-serif;
|
||||
font-family: Tahoma, Arial, sans-serif;
|
||||
font-size: 12px;
|
||||
padding: 5px 20px 5px 5px;
|
||||
text-decoration: none;
|
||||
|
@ -36,7 +36,8 @@ window.qBittorrent.Client = (() => {
|
||||
genHash: genHash,
|
||||
getSyncMainDataInterval: getSyncMainDataInterval,
|
||||
isStopped: isStopped,
|
||||
stop: stop
|
||||
stop: stop,
|
||||
mainTitle: mainTitle
|
||||
};
|
||||
};
|
||||
|
||||
@ -67,6 +68,15 @@ window.qBittorrent.Client = (() => {
|
||||
stopped = true;
|
||||
};
|
||||
|
||||
const mainTitle = () => {
|
||||
const emDash = '\u2014';
|
||||
const qbtVersion = window.qBittorrent.Cache.qbtVersion.get();
|
||||
const suffix = window.qBittorrent.Cache.preferences.get()['app_instance_name'] || '';
|
||||
const title = `qBittorrent ${qbtVersion} QBT_TR(WebUI)QBT_TR[CONTEXT=OptionsDialog]`
|
||||
+ ((suffix.length > 0) ? ` ${emDash} ${suffix}` : '');
|
||||
return title;
|
||||
};
|
||||
|
||||
return exports();
|
||||
})();
|
||||
Object.freeze(window.qBittorrent.Client);
|
||||
@ -275,7 +285,7 @@ window.addEventListener("DOMContentLoaded", function() {
|
||||
initializeWindows();
|
||||
|
||||
// Show Top Toolbar is enabled by default
|
||||
let showTopToolbar = LocalPreferences.get('show_top_toolbar', 'true') == "true";
|
||||
let showTopToolbar = LocalPreferences.get('show_top_toolbar', 'true') === "true";
|
||||
if (!showTopToolbar) {
|
||||
$('showTopToolbarLink').firstChild.style.opacity = '0';
|
||||
$('mochaToolbar').addClass('invisible');
|
||||
@ -296,7 +306,7 @@ window.addEventListener("DOMContentLoaded", function() {
|
||||
$('filtersColumn_handle').addClass('invisible');
|
||||
}
|
||||
|
||||
let speedInTitle = LocalPreferences.get('speed_in_browser_title_bar') == "true";
|
||||
let speedInTitle = LocalPreferences.get('speed_in_browser_title_bar') === "true";
|
||||
if (!speedInTitle)
|
||||
$('speedInBrowserTitleBarLink').firstChild.style.opacity = '0';
|
||||
|
||||
@ -873,14 +883,13 @@ window.addEventListener("DOMContentLoaded", function() {
|
||||
transfer_info += " (" + window.qBittorrent.Misc.friendlyUnit(serverState.up_info_data, false) + ")";
|
||||
$("UpInfos").set('html', transfer_info);
|
||||
|
||||
const qbtVersion = window.qBittorrent.Cache.qbtVersion.get();
|
||||
document.title = (speedInTitle
|
||||
? (`QBT_TR([D: %1, U: %2])QBT_TR[CONTEXT=MainWindow] `
|
||||
.replace("%1", window.qBittorrent.Misc.friendlyUnit(serverState.dl_info_speed, true))
|
||||
.replace("%2", window.qBittorrent.Misc.friendlyUnit(serverState.up_info_speed, true)))
|
||||
: '')
|
||||
+ window.qBittorrent.Client.mainTitle();
|
||||
|
||||
if (speedInTitle) {
|
||||
document.title = "QBT_TR([D: %1, U: %2] qBittorrent %3)QBT_TR[CONTEXT=MainWindow]".replace("%1", window.qBittorrent.Misc.friendlyUnit(serverState.dl_info_speed, true)).replace("%2", window.qBittorrent.Misc.friendlyUnit(serverState.up_info_speed, true)).replace("%3", qbtVersion);
|
||||
document.title += " QBT_TR(Web UI)QBT_TR[CONTEXT=OptionsDialog]";
|
||||
}
|
||||
else
|
||||
document.title = ("qBittorrent " + qbtVersion + " QBT_TR(Web UI)QBT_TR[CONTEXT=OptionsDialog]");
|
||||
$('freeSpaceOnDisk').set('html', 'QBT_TR(Free space: %1)QBT_TR[CONTEXT=HttpServer]'.replace("%1", window.qBittorrent.Misc.friendlyUnit(serverState.free_space_on_disk)));
|
||||
$('DHTNodes').set('html', 'QBT_TR(DHT: %1 nodes)QBT_TR[CONTEXT=StatusBar]'.replace("%1", serverState.dht_nodes));
|
||||
|
||||
|
@ -1157,7 +1157,8 @@ const initializeWindows = function() {
|
||||
url: 'api/v2/app/shutdown',
|
||||
method: 'post',
|
||||
onSuccess: function() {
|
||||
document.write('<!doctype html><html lang="${LANG}"><head> <meta charset="UTF-8"> <meta name="color-scheme" content="light dark" /> <title>QBT_TR(qBittorrent has been shutdown)QBT_TR[CONTEXT=HttpServer]</title></head><body> <h1 style="text-align: center;">QBT_TR(qBittorrent has been shutdown)QBT_TR[CONTEXT=HttpServer]</h1></body></html>');
|
||||
const shutdownMessage = 'QBT_TR(%1 has been shutdown)QBT_TR[CONTEXT=HttpServer]'.replace("%1", window.qBittorrent.Client.mainTitle());
|
||||
document.write(`<!doctype html><html lang="${LANG}"><head> <meta charset="UTF-8"> <meta name="color-scheme" content="light dark"> <title>${shutdownMessage}</title> <style>* {font-family: Arial, Helvetica, sans-serif;}</style></head><body> <h1 style="text-align: center;">${shutdownMessage}</h1></body></html>`);
|
||||
document.close();
|
||||
window.stop();
|
||||
window.qBittorrent.Client.stop();
|
||||
|
@ -1043,6 +1043,14 @@ Use ';' to split multiple entries. Can use wildcard '*'.)QBT_TR[CONTEXT=OptionsD
|
||||
<input type="checkbox" id="recheckTorrentsOnCompletion">
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<label for="appInstanceName">QBT_TR(Customize application instance name:)QBT_TR[CONTEXT=OptionsDialog]</label>
|
||||
</td>
|
||||
<td>
|
||||
<input type="text" id="appInstanceName" style="width: 15em;" title="QBT_TR(It appends the text to the window title to help distinguish qBittorent instances)QBT_TR[CONTEXT=OptionsDialog]" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<label for="refreshInterval">QBT_TR(Refresh interval:)QBT_TR[CONTEXT=OptionsDialog]</label>
|
||||
@ -2301,6 +2309,7 @@ Use ';' to split multiple entries. Can use wildcard '*'.)QBT_TR[CONTEXT=OptionsD
|
||||
$('saveResumeDataInterval').setProperty('value', pref.save_resume_data_interval);
|
||||
$('torrentFileSizeLimit').setProperty('value', (pref.torrent_file_size_limit / 1024 / 1024));
|
||||
$('recheckTorrentsOnCompletion').setProperty('checked', pref.recheck_completed_torrents);
|
||||
$('appInstanceName').setProperty('value', pref.app_instance_name);
|
||||
$('refreshInterval').setProperty('value', pref.refresh_interval);
|
||||
$('resolvePeerCountries').setProperty('checked', pref.resolve_peer_countries);
|
||||
$('reannounceWhenAddressChanged').setProperty('checked', pref.reannounce_when_address_changed);
|
||||
@ -2746,6 +2755,7 @@ Use ';' to split multiple entries. Can use wildcard '*'.)QBT_TR[CONTEXT=OptionsD
|
||||
settings['save_resume_data_interval'] = Number($('saveResumeDataInterval').getProperty('value'));
|
||||
settings['torrent_file_size_limit'] = ($('torrentFileSizeLimit').getProperty('value') * 1024 * 1024);
|
||||
settings['recheck_completed_torrents'] = $('recheckTorrentsOnCompletion').getProperty('checked');
|
||||
settings['app_instance_name'] = $('appInstanceName').getProperty('value');
|
||||
settings['refresh_interval'] = Number($('refreshInterval').getProperty('value'));
|
||||
settings['resolve_peer_countries'] = $('resolvePeerCountries').getProperty('checked');
|
||||
settings['reannounce_when_address_changed'] = $('reannounceWhenAddressChanged').getProperty('checked');
|
||||
|
Loading…
Reference in New Issue
Block a user