Merge pull request #18452 from sledgehammer999/stage_v4_5_x

Backports for v4_5_x part 2
This commit is contained in:
sledgehammer999
2023-02-12 00:54:37 +02:00
committed by GitHub
36 changed files with 151 additions and 298 deletions

View File

@@ -88,6 +88,7 @@
#include "base/version.h"
#include "applicationinstancemanager.h"
#include "filelogger.h"
#include "upgrade.h"
#ifndef DISABLE_GUI
#include "gui/addnewtorrentdialog.h"
@@ -171,6 +172,18 @@ Application::Application(int &argc, char **argv)
SettingsStorage::initInstance();
Preferences::initInstance();
const bool firstTimeUser = !Preferences::instance()->getAcceptedLegal();
if (!firstTimeUser)
{
if (!upgrade())
throw RuntimeError(u"Failed migration of old settings"_qs); // Not translatable. Translation isn't configured yet.
handleChangedDefaults(DefaultPreferencesMode::Legacy);
}
else
{
handleChangedDefaults(DefaultPreferencesMode::Current);
}
initializeTranslation();
connect(this, &QCoreApplication::aboutToQuit, this, &Application::cleanup);

View File

@@ -118,6 +118,17 @@ int main(int argc, char *argv[])
// Create Application
auto app = std::make_unique<Application>(argc, argv);
#ifdef Q_OS_WIN
// QCoreApplication::applicationDirPath() needs an Application object instantiated first
// Let's hope that there won't be a crash before this line
const char *envName = "_NT_SYMBOL_PATH";
const QString envValue = qEnvironmentVariable(envName);
if (envValue.isEmpty())
qputenv(envName, Application::applicationDirPath().toLocal8Bit());
else
qputenv(envName, u"%1;%2"_qs.arg(envValue, Application::applicationDirPath()).toLocal8Bit());
#endif
const QBtCommandLineParameters params = app->commandLineArgs();
if (!params.unknownParameter.isEmpty())
{
@@ -221,26 +232,6 @@ int main(int argc, char *argv[])
app->setAttribute(Qt::AA_DontShowIconsInMenus);
#endif
if (!firstTimeUser)
{
handleChangedDefaults(DefaultPreferencesMode::Legacy);
#ifndef DISABLE_GUI
if (!upgrade()) return EXIT_FAILURE;
#elif defined(Q_OS_WIN)
if (!upgrade(_isatty(_fileno(stdin))
&& _isatty(_fileno(stdout)))) return EXIT_FAILURE;
#else
if (!upgrade(!params.shouldDaemonize
&& isatty(fileno(stdin))
&& isatty(fileno(stdout)))) return EXIT_FAILURE;
#endif
}
else
{
handleChangedDefaults(DefaultPreferencesMode::Current);
}
#if defined(DISABLE_GUI) && !defined(Q_OS_WIN)
if (params.shouldDaemonize)
{
@@ -274,6 +265,11 @@ int main(int argc, char *argv[])
displayBadArgMessage(er.message());
return EXIT_FAILURE;
}
catch (const RuntimeError &er)
{
qDebug() << er.message();
return EXIT_FAILURE;
}
}
#if !defined(DISABLE_GUI)

View File

@@ -384,9 +384,21 @@ namespace
}
}
#endif
void migrateChineseLocale()
{
auto *settingsStorage = SettingsStorage::instance();
const auto key = u"Preferences/General/Locale"_qs;
if (settingsStorage->hasKey(key))
{
const auto locale = settingsStorage->loadValue<QString>(key);
if (locale.compare(u"zh"_qs, Qt::CaseInsensitive) == 0)
settingsStorage->storeValue(key, u"zh_CN"_qs);
}
}
}
bool upgrade(const bool /*ask*/)
bool upgrade()
{
CachedSettingValue<int> version {MIGRATION_VERSION_KEY, 0};
@@ -413,6 +425,9 @@ bool upgrade(const bool /*ask*/)
migrateMemoryPrioritySettings();
#endif
{
migrateChineseLocale();
}
version = MIGRATION_VERSION;
}

View File

@@ -35,5 +35,5 @@ enum class DefaultPreferencesMode
};
void handleChangedDefaults(DefaultPreferencesMode mode);
bool upgrade(bool ask = true);
bool upgrade();
void setCurrentMigrationVersion();

View File

@@ -50,10 +50,6 @@
#include <QtGlobal>
#include <QTimer>
#ifdef QBT_USES_CUSTOMDBUSNOTIFICATIONS
#include "notifications/dbusnotifier.h"
#endif
#include "base/bittorrent/session.h"
#include "base/bittorrent/sessionstatus.h"
#include "base/global.h"

View File

@@ -68,11 +68,6 @@ namespace Ui
class MainWindow;
}
#if (defined(Q_OS_UNIX) && !defined(Q_OS_MACOS)) && defined(QT_DBUS_LIB)
#define QBT_USES_CUSTOMDBUSNOTIFICATIONS
class DBusNotifier;
#endif
class MainWindow final : public QMainWindow, public GUIApplicationComponent
{
Q_OBJECT

View File

@@ -188,7 +188,7 @@ StatusFilterWidget::StatusFilterWidget(QWidget *parent, TransferListWidget *tran
resumed->setData(Qt::DecorationRole, UIThemeManager::instance()->getIcon(u"torrent-start"_qs, u"media-playback-start"_qs));
auto *paused = new QListWidgetItem(this);
paused->setData(Qt::DisplayRole, tr("Paused (0)"));
paused->setData(Qt::DecorationRole, UIThemeManager::instance()->getIcon(u"torrent-stop"_qs, u"media-playback-pause"_qs));
paused->setData(Qt::DecorationRole, UIThemeManager::instance()->getIcon(u"stopped"_qs, u"media-playback-pause"_qs));
auto *active = new QListWidgetItem(this);
active->setData(Qt::DisplayRole, tr("Active (0)"));
active->setData(Qt::DecorationRole, UIThemeManager::instance()->getIcon(u"filter-active"_qs, u"filteractive"_qs));

View File

@@ -162,7 +162,7 @@ TransferListModel::TransferListModel(QObject *parent)
, m_completedIcon {UIThemeManager::instance()->getIcon(u"checked-completed"_qs, u"completed"_qs)}
, m_downloadingIcon {UIThemeManager::instance()->getIcon(u"downloading"_qs)}
, m_errorIcon {UIThemeManager::instance()->getIcon(u"error"_qs)}
, m_pausedIcon {UIThemeManager::instance()->getIcon(u"torrent-stop"_qs, u"media-playback-pause"_qs)}
, m_pausedIcon {UIThemeManager::instance()->getIcon(u"stopped"_qs, u"media-playback-pause"_qs)}
, m_queuedIcon {UIThemeManager::instance()->getIcon(u"queued"_qs)}
, m_stalledDLIcon {UIThemeManager::instance()->getIcon(u"stalledDL"_qs)}
, m_stalledUPIcon {UIThemeManager::instance()->getIcon(u"stalledUP"_qs)}

View File

@@ -336,6 +336,7 @@
<file>splash.png</file>
<file>stalledDL.svg</file>
<file>stalledUP.svg</file>
<file>stopped.svg</file>
<file>system-log-out.svg</file>
<file>tags.svg</file>
<file>task-complete.svg</file>

1
src/icons/stopped.svg Normal file
View File

@@ -0,0 +1 @@
<svg height="32" viewBox="0 0 32 32" width="32" xmlns="http://www.w3.org/2000/svg"><g fill="#808080" stroke="#808080" stroke-linecap="round" stroke-linejoin="round" stroke-width="3.458" transform="matrix(1.3141898 0 0 1.0646346 -4.824252 -1.566469)"><path d="m8.1321547 5.07899h2.4210093c.67062 0 1.210505.6702329 1.210505 1.5027643v19.8364877c0 .832531-.539885 1.502764-1.210505 1.502764h-2.4210093c-.6706196 0-1.2105048-.670233-1.2105048-1.502764v-19.8364877c0-.8325314.5398852-1.5027643 1.2105048-1.5027643z"/><path d="m21.138228 5.07899h2.421009c.67062 0 1.210505.6702329 1.210505 1.5027643v19.8364877c0 .832531-.539885 1.502764-1.210505 1.502764h-2.421009c-.67062 0-1.210505-.670233-1.210505-1.502764v-19.8364877c0-.8325314.539885-1.5027643 1.210505-1.5027643z"/></g></svg>

After

Width:  |  Height:  |  Size: 779 B

View File

@@ -1 +1 @@
<svg height="32" viewBox="0 0 32 32" width="32" xmlns="http://www.w3.org/2000/svg"><g fill="#808080" stroke="#808080" stroke-linecap="round" stroke-linejoin="round" stroke-width="3.458" transform="matrix(1.3141898 0 0 1.0646346 -4.824252 -1.566469)"><path d="m8.1321547 5.07899h2.4210093c.67062 0 1.210505.6702329 1.210505 1.5027643v19.8364877c0 .832531-.539885 1.502764-1.210505 1.502764h-2.4210093c-.6706196 0-1.2105048-.670233-1.2105048-1.502764v-19.8364877c0-.8325314.5398852-1.5027643 1.2105048-1.5027643z"/><path d="m21.138228 5.07899h2.421009c.67062 0 1.210505.6702329 1.210505 1.5027643v19.8364877c0 .832531-.539885 1.502764-1.210505 1.502764h-2.421009c-.67062 0-1.210505-.670233-1.210505-1.502764v-19.8364877c0-.8325314.539885-1.5027643 1.210505-1.5027643z"/></g></svg>
<svg height="32" viewBox="0 0 32 32" width="32" xmlns="http://www.w3.org/2000/svg"><g fill="#ff8c00" stroke="#ff8c00" stroke-linecap="round" stroke-linejoin="round" stroke-width="3.458" transform="matrix(1.3141898 0 0 1.0646346 -4.824252 -1.566469)"><path d="m8.1321547 5.07899h2.4210093c.67062 0 1.210505.6702329 1.210505 1.5027643v19.8364877c0 .832531-.539885 1.502764-1.210505 1.502764h-2.4210093c-.6706196 0-1.2105048-.670233-1.2105048-1.502764v-19.8364877c0-.8325314.5398852-1.5027643 1.2105048-1.5027643z"/><path d="m21.138228 5.07899h2.421009c.67062 0 1.210505.6702329 1.210505 1.5027643v19.8364877c0 .832531-.539885 1.502764-1.210505 1.502764h-2.421009c-.67062 0-1.210505-.670233-1.210505-1.502764v-19.8364877c0-.8325314.539885-1.5027643 1.210505-1.5027643z"/></g></svg>

Before

Width:  |  Height:  |  Size: 778 B

After

Width:  |  Height:  |  Size: 779 B

View File

@@ -104,6 +104,7 @@ const QString KEY_PROP_CREATION_DATE = u"creation_date"_qs;
const QString KEY_PROP_SAVE_PATH = u"save_path"_qs;
const QString KEY_PROP_DOWNLOAD_PATH = u"download_path"_qs;
const QString KEY_PROP_COMMENT = u"comment"_qs;
const QString KEY_PROP_ISPRIVATE = u"is_private"_qs;
// File keys
const QString KEY_FILE_INDEX = u"index"_qs;
@@ -387,6 +388,10 @@ void TorrentsController::infoAction()
// - "save_path": Torrent save path
// - "download_path": Torrent download path
// - "comment": Torrent comment
// - "infohash_v1": Torrent v1 infohash (or empty string for v2 torrents)
// - "infohash_v2": Torrent v2 infohash (or empty string for v1 torrents)
// - "hash": Torrent TorrentID (infohashv1 for v1 torrents, truncated infohashv2 for v2/hybrid torrents)
// - "name": Torrent name
void TorrentsController::propertiesAction()
{
requireParams({u"hash"_qs});
@@ -400,6 +405,8 @@ void TorrentsController::propertiesAction()
dataDict[KEY_TORRENT_INFOHASHV1] = torrent->infoHash().v1().toString();
dataDict[KEY_TORRENT_INFOHASHV2] = torrent->infoHash().v2().toString();
dataDict[KEY_TORRENT_NAME] = torrent->name();
dataDict[KEY_TORRENT_ID] = torrent->id().toString();
dataDict[KEY_PROP_TIME_ELAPSED] = torrent->activeTime();
dataDict[KEY_PROP_SEEDING_TIME] = torrent->finishedTime();
dataDict[KEY_PROP_ETA] = static_cast<double>(torrent->eta());
@@ -430,6 +437,7 @@ void TorrentsController::propertiesAction()
dataDict[KEY_PROP_PIECE_SIZE] = torrent->pieceLength();
dataDict[KEY_PROP_PIECES_HAVE] = torrent->piecesHave();
dataDict[KEY_PROP_CREATED_BY] = torrent->creator();
dataDict[KEY_PROP_ISPRIVATE] = torrent->isPrivate();
dataDict[KEY_PROP_ADDITION_DATE] = static_cast<double>(torrent->addedTime().toSecsSinceEpoch());
if (torrent->hasMetadata())
{

View File

@@ -0,0 +1 @@
<svg height="32" viewBox="0 0 32 32" width="32" xmlns="http://www.w3.org/2000/svg"><g fill="#808080" stroke="#808080" stroke-linecap="round" stroke-linejoin="round" stroke-width="3.458" transform="matrix(1.3141898 0 0 1.0646346 -4.824252 -1.566469)"><path d="m8.1321547 5.07899h2.4210093c.67062 0 1.210505.6702329 1.210505 1.5027643v19.8364877c0 .832531-.539885 1.502764-1.210505 1.502764h-2.4210093c-.6706196 0-1.2105048-.670233-1.2105048-1.502764v-19.8364877c0-.8325314.5398852-1.5027643 1.2105048-1.5027643z"/><path d="m21.138228 5.07899h2.421009c.67062 0 1.210505.6702329 1.210505 1.5027643v19.8364877c0 .832531-.539885 1.502764-1.210505 1.502764h-2.421009c-.67062 0-1.210505-.670233-1.210505-1.502764v-19.8364877c0-.8325314.539885-1.5027643 1.210505-1.5027643z"/></g></svg>

After

Width:  |  Height:  |  Size: 779 B

View File

@@ -1 +1 @@
<svg height="32" viewBox="0 0 32 32" width="32" xmlns="http://www.w3.org/2000/svg"><g fill="#808080" stroke="#808080" stroke-linecap="round" stroke-linejoin="round" stroke-width="3.458" transform="matrix(1.3141898 0 0 1.0646346 -4.824252 -1.566469)"><path d="m8.1321547 5.07899h2.4210093c.67062 0 1.210505.6702329 1.210505 1.5027643v19.8364877c0 .832531-.539885 1.502764-1.210505 1.502764h-2.4210093c-.6706196 0-1.2105048-.670233-1.2105048-1.502764v-19.8364877c0-.8325314.5398852-1.5027643 1.2105048-1.5027643z"/><path d="m21.138228 5.07899h2.421009c.67062 0 1.210505.6702329 1.210505 1.5027643v19.8364877c0 .832531-.539885 1.502764-1.210505 1.502764h-2.421009c-.67062 0-1.210505-.670233-1.210505-1.502764v-19.8364877c0-.8325314.539885-1.5027643 1.210505-1.5027643z"/></g></svg>
<svg height="32" viewBox="0 0 32 32" width="32" xmlns="http://www.w3.org/2000/svg"><g fill="#ff8c00" stroke="#ff8c00" stroke-linecap="round" stroke-linejoin="round" stroke-width="3.458" transform="matrix(1.3141898 0 0 1.0646346 -4.824252 -1.566469)"><path d="m8.1321547 5.07899h2.4210093c.67062 0 1.210505.6702329 1.210505 1.5027643v19.8364877c0 .832531-.539885 1.502764-1.210505 1.502764h-2.4210093c-.6706196 0-1.2105048-.670233-1.2105048-1.502764v-19.8364877c0-.8325314.5398852-1.5027643 1.2105048-1.5027643z"/><path d="m21.138228 5.07899h2.421009c.67062 0 1.210505.6702329 1.210505 1.5027643v19.8364877c0 .832531-.539885 1.502764-1.210505 1.502764h-2.421009c-.67062 0-1.210505-.670233-1.210505-1.502764v-19.8364877c0-.8325314.539885-1.5027643 1.210505-1.5027643z"/></g></svg>

Before

Width:  |  Height:  |  Size: 778 B

After

Width:  |  Height:  |  Size: 779 B

View File

@@ -85,7 +85,7 @@
<body>
<div style="padding: 10px 10px 0px 10px;">
<p style="font-weight: bold;">QBT_TR(New name:)QBT_TR[CONTEXT=TorrentContentTreeView]</p>
<input type="text" id="rename" style="width: 220px;" />
<input type="text" id="rename" style="width: 99%;" />
<div style="text-align: center; padding-top: 10px;">
<input type="button" value="QBT_TR(Save)QBT_TR[CONTEXT=HttpServer]" id="renameButton" />
</div>

View File

@@ -1350,14 +1350,26 @@ new Keyboard({
defaultEventType: 'keydown',
events: {
'ctrl+a': function(event) {
if (event.target.nodeName == "INPUT" || event.target.nodeName == "TEXTAREA")
return;
if (event.target.isContentEditable)
return;
torrentsTable.selectAll();
event.preventDefault();
},
'delete': function(event) {
if (event.target.nodeName == "INPUT" || event.target.nodeName == "TEXTAREA")
return;
if (event.target.isContentEditable)
return;
deleteFN();
event.preventDefault();
},
'shift+delete': (event) => {
if (event.target.nodeName == "INPUT" || event.target.nodeName == "TEXTAREA")
return;
if (event.target.isContentEditable)
return;
deleteFN(true);
event.preventDefault();
}

View File

@@ -970,7 +970,7 @@ window.qBittorrent.DynamicTable = (function() {
break;
case "pausedDL":
state = "torrent-stop";
img_path = "images/torrent-stop.svg";
img_path = "images/stopped.svg";
break;
case "pausedUP":
state = "checked-completed";

View File

@@ -561,11 +561,11 @@ window.qBittorrent.PropFiles = (function() {
contentURL: 'rename_file.html?hash=' + hash + '&isFolder=' + node.isFolder
+ '&path=' + encodeURIComponent(path),
scrollbars: false,
resizable: false,
resizable: true,
maximizable: false,
paddingVertical: 0,
paddingHorizontal: 0,
width: 250,
width: 400,
height: 100
});
},

View File

@@ -8,7 +8,7 @@
<li id="seeding_filter"><a href="#" onclick="setFilter('seeding');return false;"><img src="images/upload.svg" alt="Seeding" />QBT_TR(Seeding (0))QBT_TR[CONTEXT=StatusFilterWidget]</a></li>
<li id="completed_filter"><a href="#" onclick="setFilter('completed');return false;"><img src="images/checked-completed.svg" alt="Completed" />QBT_TR(Completed (0))QBT_TR[CONTEXT=StatusFilterWidget]</a></li>
<li id="resumed_filter"><a href="#" onclick="setFilter('resumed');return false;"><img src="images/torrent-start.svg" alt="Resumed" />QBT_TR(Resumed (0))QBT_TR[CONTEXT=StatusFilterWidget]</a></li>
<li id="paused_filter"><a href="#" onclick="setFilter('paused');return false;"><img src="images/torrent-stop.svg" alt="Paused" />QBT_TR(Paused (0))QBT_TR[CONTEXT=StatusFilterWidget]</a></li>
<li id="paused_filter"><a href="#" onclick="setFilter('paused');return false;"><img src="images/stopped.svg" alt="Paused" />QBT_TR(Paused (0))QBT_TR[CONTEXT=StatusFilterWidget]</a></li>
<li id="active_filter"><a href="#" onclick="setFilter('active');return false;"><img src="images/filter-active.svg" alt="Active" />QBT_TR(Active (0))QBT_TR[CONTEXT=StatusFilterWidget]</a></li>
<li id="inactive_filter"><a href="#" onclick="setFilter('inactive');return false;"><img src="images/filter-inactive.svg" alt="Inactive" />QBT_TR(Inactive (0))QBT_TR[CONTEXT=StatusFilterWidget]</a></li>
<li id="stalled_filter"><a href="#" onclick="setFilter('stalled');return false;"><img src="images/filter-stalled.svg" alt="Stalled" />QBT_TR(Stalled (0))QBT_TR[CONTEXT=StatusFilterWidget]</a></li>

View File

@@ -1,7 +1,7 @@
<div id="prop_general" class="propertiesTabContent">
<table style="width: 100%; padding: 0 3px">
<tr>
<td style="text-align: right">QBT_TR(Progress:)QBT_TR[CONTEXT=PropertiesWidget]</td>
<td style="text-align: right; white-space: nowrap">QBT_TR(Progress:)QBT_TR[CONTEXT=PropertiesWidget]</td>
<td id="progress" style="width: 100%"></td>
</tr>
</table>

View File

@@ -80,7 +80,7 @@
<div id="searchResults">
<div style="overflow: hidden; height: 70px;">
<div style="margin: 20px 0; height: 30px;">
<input type="text" id="searchPattern" class="searchInputField" placeholder="QBT_TR(Search)QBT_TR[CONTEXT=SearchEngineWidget]" autocorrect="off" autocapitalize="none" />
<input type="text" id="searchPattern" class="searchInputField" placeholder="QBT_TR(Search)QBT_TR[CONTEXT=SearchEngineWidget]" autocorrect="off" autocomplete="off" autocapitalize="none" />
<select id="categorySelect" class="searchInputField" onchange="qBittorrent.Search.categorySelected()"></select>
<select id="pluginsSelect" class="searchInputField" onchange="qBittorrent.Search.pluginSelected()"></select>
<button id="startSearchButton" class="searchInputField" onclick="qBittorrent.Search.startStopSearch()">QBT_TR(Search)QBT_TR[CONTEXT=SearchEngineWidget]</button>

View File

@@ -1598,8 +1598,7 @@ Use ';' to split multiple entries. Can use wildcard '*'.</source>
U svrhu obrane od napada ponovnog povezivanja DNS-a,
trebali biste unijeti nazive domena koje koristi WebUI poslužitelj.
Koristite ';' za razdvajanje više unosa. Može koristiti zamjenski znak '*'.
</translation>
Koristite ';' za razdvajanje više unosa. Može koristiti zamjenski znak '*'.</translation>
</message>
<message>
<source>Run external program on torrent added</source>

View File

@@ -345,6 +345,7 @@
<file>private/images/spinner.gif</file>
<file>private/images/stalledDL.svg</file>
<file>private/images/stalledUP.svg</file>
<file>private/images/stopped.svg</file>
<file>private/images/system-log-out.svg</file>
<file>private/images/tabs.gif</file>
<file>private/images/tags.svg</file>