Improve coding style

This commit is contained in:
Vladimir Golovnev (Glassez)
2020-11-16 10:02:11 +03:00
committed by sledgehammer999
parent d3f46452a9
commit 1728c16580
147 changed files with 4454 additions and 2227 deletions

View File

@@ -70,21 +70,24 @@ AboutDialog::AboutDialog(QWidget *parent)
// Thanks
QFile thanksfile(":/thanks.html");
if (thanksfile.open(QIODevice::ReadOnly | QIODevice::Text)) {
if (thanksfile.open(QIODevice::ReadOnly | QIODevice::Text))
{
m_ui->textBrowserThanks->setHtml(QString::fromUtf8(thanksfile.readAll().constData()));
thanksfile.close();
}
// Translation
QFile translatorsfile(":/translators.html");
if (translatorsfile.open(QIODevice::ReadOnly | QIODevice::Text)) {
if (translatorsfile.open(QIODevice::ReadOnly | QIODevice::Text))
{
m_ui->textBrowserTranslation->setHtml(QString::fromUtf8(translatorsfile.readAll().constData()));
translatorsfile.close();
}
// License
QFile licensefile(":/gpl.html");
if (licensefile.open(QIODevice::ReadOnly | QIODevice::Text)) {
if (licensefile.open(QIODevice::ReadOnly | QIODevice::Text))
{
m_ui->textBrowserLicense->setHtml(QString::fromUtf8(licensefile.readAll().constData()));
licensefile.close();
}

View File

@@ -230,7 +230,8 @@ void AddNewTorrentDialog::show(const QString &source, const BitTorrent::AddTorre
{
auto *dlg = new AddNewTorrentDialog(inParams, parent);
if (Net::DownloadManager::hasSupportedScheme(source)) {
if (Net::DownloadManager::hasSupportedScheme(source))
{
// Launch downloader
Net::DownloadManager::instance()->download(
Net::DownloadRequest(source).limit(MAX_TORRENT_SIZE)
@@ -262,7 +263,8 @@ bool AddNewTorrentDialog::loadTorrentFile(const QString &torrentPath)
QString error;
m_torrentInfo = BitTorrent::TorrentInfo::loadFromFile(decodedPath, &error);
if (!m_torrentInfo.isValid()) {
if (!m_torrentInfo.isValid())
{
RaisedMessageBox::critical(this, tr("Invalid torrent")
, tr("Failed to load the torrent: %1.\nError: %2", "Don't remove the '\n' characters. They insert a newline.")
.arg(Utils::Fs::toNativePath(decodedPath), error));
@@ -280,19 +282,24 @@ bool AddNewTorrentDialog::loadTorrentImpl()
const BitTorrent::InfoHash infoHash = m_torrentInfo.hash();
// Prevent showing the dialog if download is already present
if (BitTorrent::Session::instance()->isKnownTorrent(infoHash)) {
if (BitTorrent::Session::instance()->isKnownTorrent(infoHash))
{
BitTorrent::TorrentHandle *const torrent = BitTorrent::Session::instance()->findTorrent(infoHash);
if (torrent) {
if (torrent->isPrivate() || m_torrentInfo.isPrivate()) {
if (torrent)
{
if (torrent->isPrivate() || m_torrentInfo.isPrivate())
{
RaisedMessageBox::warning(this, tr("Torrent is already present"), tr("Torrent '%1' is already in the transfer list. Trackers haven't been merged because it is a private torrent.").arg(torrent->name()), QMessageBox::Ok);
}
else {
else
{
torrent->addTrackers(m_torrentInfo.trackers());
torrent->addUrlSeeds(m_torrentInfo.urlSeeds());
RaisedMessageBox::information(this, tr("Torrent is already present"), tr("Torrent '%1' is already in the transfer list. Trackers have been merged.").arg(torrent->name()), QMessageBox::Ok);
}
}
else {
else
{
RaisedMessageBox::information(this, tr("Torrent is already present"), tr("Torrent is already queued for processing."), QMessageBox::Ok);
}
return false;
@@ -307,7 +314,8 @@ bool AddNewTorrentDialog::loadTorrentImpl()
bool AddNewTorrentDialog::loadMagnet(const BitTorrent::MagnetUri &magnetUri)
{
if (!magnetUri.isValid()) {
if (!magnetUri.isValid())
{
RaisedMessageBox::critical(this, tr("Invalid magnet link"), tr("This magnet link was not recognized"));
return false;
}
@@ -316,19 +324,24 @@ bool AddNewTorrentDialog::loadMagnet(const BitTorrent::MagnetUri &magnetUri)
const BitTorrent::InfoHash infoHash = magnetUri.hash();
// Prevent showing the dialog if download is already present
if (BitTorrent::Session::instance()->isKnownTorrent(infoHash)) {
if (BitTorrent::Session::instance()->isKnownTorrent(infoHash))
{
BitTorrent::TorrentHandle *const torrent = BitTorrent::Session::instance()->findTorrent(infoHash);
if (torrent) {
if (torrent->isPrivate()) {
if (torrent)
{
if (torrent->isPrivate())
{
RaisedMessageBox::warning(this, tr("Torrent is already present"), tr("Torrent '%1' is already in the transfer list. Trackers haven't been merged because it is a private torrent.").arg(torrent->name()), QMessageBox::Ok);
}
else {
else
{
torrent->addTrackers(magnetUri.trackers());
torrent->addUrlSeeds(magnetUri.urlSeeds());
RaisedMessageBox::information(this, tr("Torrent is already present"), tr("Magnet link '%1' is already in the transfer list. Trackers have been merged.").arg(torrent->name()), QMessageBox::Ok);
}
}
else {
else
{
RaisedMessageBox::information(this, tr("Torrent is already present"), tr("Magnet link is already queued for processing."), QMessageBox::Ok);
}
return false;
@@ -395,15 +408,18 @@ void AddNewTorrentDialog::updateDiskSpaceLabel()
// Determine torrent size
qlonglong torrentSize = 0;
if (m_hasMetadata) {
if (m_contentModel) {
if (m_hasMetadata)
{
if (m_contentModel)
{
const QVector<BitTorrent::DownloadPriority> priorities = m_contentModel->model()->getFilePriorities();
Q_ASSERT(priorities.size() == m_torrentInfo.filesCount());
for (int i = 0; i < priorities.size(); ++i)
if (priorities[i] > BitTorrent::DownloadPriority::Ignored)
torrentSize += m_torrentInfo.fileSize(i);
}
else {
else
{
torrentSize = m_torrentInfo.totalSize();
}
}
@@ -426,7 +442,8 @@ void AddNewTorrentDialog::categoryChanged(int index)
{
Q_UNUSED(index);
if (m_ui->comboTTM->currentIndex() == 1) {
if (m_ui->comboTTM->currentIndex() == 1)
{
QString savePath = BitTorrent::Session::instance()->categorySavePath(m_ui->categoryComboBox->currentText());
m_ui->savePath->setSelectedPath(Utils::Fs::toNativePath(savePath));
updateDiskSpaceLabel();
@@ -436,7 +453,8 @@ void AddNewTorrentDialog::categoryChanged(int index)
void AddNewTorrentDialog::setSavePath(const QString &newPath)
{
int existingIndex = indexOfSavePath(newPath);
if (existingIndex < 0) {
if (existingIndex < 0)
{
// New path, prepend to combo box
m_ui->savePath->insertItem(0, newPath);
existingIndex = 0;
@@ -461,10 +479,12 @@ void AddNewTorrentDialog::saveTorrentFile()
if (!path.endsWith(torrentFileExtension, Qt::CaseInsensitive))
path += torrentFileExtension;
try {
try
{
m_torrentInfo.saveToFile(path);
}
catch (const RuntimeError &err) {
catch (const RuntimeError &err)
{
QMessageBox::critical(this, tr("I/O Error"), err.message());
}
}
@@ -494,7 +514,8 @@ void AddNewTorrentDialog::displayContentTreeMenu(const QPoint &)
const auto applyPriorities = [this, selectedRows](const BitTorrent::DownloadPriority prio)
{
for (const QModelIndex &index : selectedRows) {
for (const QModelIndex &index : selectedRows)
{
m_contentModel->setData(
m_contentModel->index(index.row(), PRIORITY, index.parent())
, static_cast<int>(prio));
@@ -504,7 +525,8 @@ void AddNewTorrentDialog::displayContentTreeMenu(const QPoint &)
QMenu *menu = new QMenu(this);
menu->setAttribute(Qt::WA_DeleteOnClose);
if (selectedRows.size() == 1) {
if (selectedRows.size() == 1)
{
QAction *actRename = menu->addAction(UIThemeManager::instance()->getIcon("edit-rename"), tr("Rename..."));
connect(actRename, &QAction::triggered, this, [this]() { m_ui->contentTreeView->renameSelectedFile(m_torrentInfo); });
@@ -563,12 +585,14 @@ void AddNewTorrentDialog::accept()
m_torrentParams.firstLastPiecePriority = m_ui->firstLastCheckBox->isChecked();
QString savePath = m_ui->savePath->selectedPath();
if (m_ui->comboTTM->currentIndex() != 1) { // 0 is Manual mode and 1 is Automatic mode. Handle all non 1 values as manual mode.
if (m_ui->comboTTM->currentIndex() != 1)
{ // 0 is Manual mode and 1 is Automatic mode. Handle all non 1 values as manual mode.
m_torrentParams.useAutoTMM = TriStateBool::False;
m_torrentParams.savePath = savePath;
saveSavePathHistory();
}
else {
else
{
m_torrentParams.useAutoTMM = TriStateBool::True;
}
@@ -586,7 +610,8 @@ void AddNewTorrentDialog::accept()
void AddNewTorrentDialog::reject()
{
if (!m_hasMetadata) {
if (!m_hasMetadata)
{
setMetadataProgressIndicator(false);
BitTorrent::Session::instance()->cancelLoadMetadata(m_magnetURI.hash());
}
@@ -600,7 +625,8 @@ void AddNewTorrentDialog::updateMetadata(const BitTorrent::TorrentInfo &metadata
disconnect(BitTorrent::Session::instance(), &BitTorrent::Session::metadataLoaded, this, &AddNewTorrentDialog::updateMetadata);
if (!metadata.isValid()) {
if (!metadata.isValid())
{
RaisedMessageBox::critical(this, tr("I/O Error"), ("Invalid metadata."));
setMetadataProgressIndicator(false, tr("Invalid metadata"));
return;
@@ -628,11 +654,13 @@ void AddNewTorrentDialog::setMetadataProgressIndicator(bool visibleIndicator, co
void AddNewTorrentDialog::setupTreeview()
{
if (!m_hasMetadata) {
if (!m_hasMetadata)
{
m_ui->labelCommentData->setText(tr("Not Available", "This comment is unavailable"));
m_ui->labelDateData->setText(tr("Not Available", "This date is unavailable"));
}
else {
else
{
// Set dialog title
setWindowTitle(m_torrentInfo.name());
@@ -662,7 +690,8 @@ void AddNewTorrentDialog::setupTreeview()
// Expand single-item folders recursively
QModelIndex currentIndex;
while (m_contentModel->rowCount(currentIndex) == 1) {
while (m_contentModel->rowCount(currentIndex) == 1)
{
currentIndex = m_contentModel->index(0, 0, currentIndex);
m_ui->contentTreeView->setExpanded(currentIndex, true);
}
@@ -674,10 +703,12 @@ void AddNewTorrentDialog::setupTreeview()
void AddNewTorrentDialog::handleDownloadFinished(const Net::DownloadResult &result)
{
QString error;
switch (result.status) {
switch (result.status)
{
case Net::DownloadStatus::Success:
m_torrentInfo = BitTorrent::TorrentInfo::load(result.data, &error);
if (!m_torrentInfo.isValid()) {
if (!m_torrentInfo.isValid())
{
RaisedMessageBox::critical(this, tr("Invalid torrent"), tr("Failed to load from URL: %1.\nError: %2")
.arg(result.url, error));
return;
@@ -705,13 +736,15 @@ void AddNewTorrentDialog::handleDownloadFinished(const Net::DownloadResult &resu
void AddNewTorrentDialog::TMMChanged(int index)
{
if (index != 1) { // 0 is Manual mode and 1 is Automatic mode. Handle all non 1 values as manual mode.
if (index != 1)
{ // 0 is Manual mode and 1 is Automatic mode. Handle all non 1 values as manual mode.
populateSavePathComboBox();
m_ui->groupBoxSavePath->setEnabled(true);
m_ui->savePath->blockSignals(false);
m_ui->savePath->setCurrentIndex(m_oldIndex < m_ui->savePath->count() ? m_oldIndex : m_ui->savePath->count() - 1);
}
else {
else
{
m_ui->groupBoxSavePath->setEnabled(false);
m_ui->savePath->blockSignals(true);
m_ui->savePath->clear();

View File

@@ -168,7 +168,8 @@ void AdvancedSettings::saveAdvancedSettings()
#if defined(Q_OS_WIN)
BitTorrent::OSMemoryPriority prio = BitTorrent::OSMemoryPriority::Normal;
switch (m_comboBoxOSMemoryPriority.currentIndex()) {
switch (m_comboBoxOSMemoryPriority.currentIndex())
{
case 0:
default:
prio = BitTorrent::OSMemoryPriority::Normal;
@@ -248,12 +249,14 @@ void AdvancedSettings::saveAdvancedSettings()
pref->resolvePeerCountries(m_checkBoxResolveCountries.isChecked());
pref->resolvePeerHostNames(m_checkBoxResolveHosts.isChecked());
// Network interface
if (m_comboBoxInterface.currentIndex() == 0) {
if (m_comboBoxInterface.currentIndex() == 0)
{
// All interfaces (default)
session->setNetworkInterface(QString());
session->setNetworkInterfaceName(QString());
}
else {
else
{
session->setNetworkInterface(m_comboBoxInterface.itemData(m_comboBoxInterface.currentIndex()).toString());
session->setNetworkInterfaceName(m_comboBoxInterface.currentText());
}
@@ -336,21 +339,25 @@ void AdvancedSettings::updateInterfaceAddressCombo()
const auto populateCombo = [this](const QHostAddress &addr)
{
if (addr.protocol() == QAbstractSocket::IPv4Protocol) {
if (addr.protocol() == QAbstractSocket::IPv4Protocol)
{
const QString str = addr.toString();
m_comboBoxInterfaceAddress.addItem(str, str);
}
else if (addr.protocol() == QAbstractSocket::IPv6Protocol) {
else if (addr.protocol() == QAbstractSocket::IPv6Protocol)
{
const QString str = Utils::Net::canonicalIPv6Addr(addr).toString();
m_comboBoxInterfaceAddress.addItem(str, str);
}
};
if (ifaceName.isEmpty()) {
if (ifaceName.isEmpty())
{
for (const QHostAddress &addr : asConst(QNetworkInterface::allAddresses()))
populateCombo(addr);
}
else {
else
{
const QNetworkInterface iface = QNetworkInterface::interfaceFromName(ifaceName);
const QList<QNetworkAddressEntry> addresses = iface.addressEntries();
for (const QNetworkAddressEntry &entry : addresses)
@@ -386,7 +393,8 @@ void AdvancedSettings::loadAdvancedSettings()
#if defined(Q_OS_WIN)
m_comboBoxOSMemoryPriority.addItems({tr("Normal"), tr("Below normal"), tr("Medium"), tr("Low"), tr("Very low")});
int OSMemoryPriorityIndex = 0;
switch (session->getOSMemoryPriority()) {
switch (session->getOSMemoryPriority())
{
default:
case BitTorrent::OSMemoryPriority::Normal:
OSMemoryPriorityIndex = 0;
@@ -580,16 +588,19 @@ void AdvancedSettings::loadAdvancedSettings()
const QString currentInterface = session->networkInterface();
bool interfaceExists = currentInterface.isEmpty();
int i = 1;
for (const QNetworkInterface &iface : asConst(QNetworkInterface::allInterfaces())) {
for (const QNetworkInterface &iface : asConst(QNetworkInterface::allInterfaces()))
{
m_comboBoxInterface.addItem(iface.humanReadableName(), iface.name());
if (!currentInterface.isEmpty() && (iface.name() == currentInterface)) {
if (!currentInterface.isEmpty() && (iface.name() == currentInterface))
{
m_comboBoxInterface.setCurrentIndex(i);
interfaceExists = true;
}
++i;
}
// Saved interface does not exist, show it anyway
if (!interfaceExists) {
if (!interfaceExists)
{
m_comboBoxInterface.addItem(session->networkInterfaceName(), currentInterface);
m_comboBoxInterface.setCurrentIndex(i);
}

View File

@@ -55,7 +55,8 @@ QString AutoExpandableDialog::getText(QWidget *parent, const QString &title, con
d.m_ui->textEdit->setInputMethodHints(inputMethodHints);
d.m_ui->textEdit->selectAll();
if (excludeExtension) {
if (excludeExtension)
{
int lastDotIndex = text.lastIndexOf('.');
if ((lastDotIndex > 3) && (text.mid(lastDotIndex - 4, 4).toLower() == ".tar"))
lastDotIndex -= 4;
@@ -86,7 +87,8 @@ void AutoExpandableDialog::showEvent(QShowEvent *e)
int wd = m_ui->textEdit->fontMetrics().width(m_ui->textEdit->text()) + 4;
#endif
if (!windowTitle().isEmpty()) {
if (!windowTitle().isEmpty())
{
// not really the font metrics in window title, so we enlarge it a bit,
// including the small icon and close button width
#if (QT_VERSION >= QT_VERSION_CHECK(5, 11, 0))
@@ -97,7 +99,8 @@ void AutoExpandableDialog::showEvent(QShowEvent *e)
wd = std::max(wd, w);
}
if (!m_ui->textLabel->text().isEmpty()) {
if (!m_ui->textLabel->text().isEmpty())
{
#if (QT_VERSION >= QT_VERSION_CHECK(5, 11, 0))
int w = m_ui->textLabel->fontMetrics().horizontalAdvance(m_ui->textLabel->text());
#else
@@ -109,7 +112,8 @@ void AutoExpandableDialog::showEvent(QShowEvent *e)
// Now resize the dialog to fit the contents
// max width of text from either of: label, title, textedit
// If the value is less than dialog default size, default size is used
if (wd > width()) {
if (wd > width())
{
QSize size = {width() - m_ui->verticalLayout->sizeHint().width() + wd, height()};
Utils::Gui::resize(this, size);
}

View File

@@ -64,18 +64,21 @@ BanListOptionsDialog::~BanListOptionsDialog()
void BanListOptionsDialog::on_buttonBox_accepted()
{
if (m_modified) {
if (m_modified)
{
// save to session
QStringList IPList;
// Operate on the m_sortFilter to grab the strings in sorted order
for (int i = 0; i < m_sortFilter->rowCount(); ++i) {
for (int i = 0; i < m_sortFilter->rowCount(); ++i)
{
QModelIndex index = m_sortFilter->index(i, 0);
IPList << index.data().toString();
}
BitTorrent::Session::instance()->setBannedIPs(IPList);
QDialog::accept();
}
else {
else
{
QDialog::reject();
}
}
@@ -83,7 +86,8 @@ void BanListOptionsDialog::on_buttonBox_accepted()
void BanListOptionsDialog::on_buttonBanIP_clicked()
{
QString ip = m_ui->txtIP->text();
if (!Utils::Net::isValidIP(ip)) {
if (!Utils::Net::isValidIP(ip))
{
QMessageBox::warning(this, tr("Warning"), tr("The entered IP address is invalid."));
return;
}
@@ -91,9 +95,11 @@ void BanListOptionsDialog::on_buttonBanIP_clicked()
// QHostAddress::toString() result format follows RFC5952;
// thus we avoid duplicate entries pointing to the same address
ip = QHostAddress(ip).toString();
for (int i = 0; i < m_sortFilter->rowCount(); ++i) {
for (int i = 0; i < m_sortFilter->rowCount(); ++i)
{
QModelIndex index = m_sortFilter->index(i, 0);
if (ip == index.data().toString()) {
if (ip == index.data().toString())
{
QMessageBox::warning(this, tr("Warning"), tr("The entered IP is already banned."));
return;
}

View File

@@ -57,7 +57,8 @@ public:
~CategoryModelItem()
{
clear();
if (m_parent) {
if (m_parent)
{
m_parent->m_torrentsCount -= m_torrentsCount;
const QString uid = m_parent->m_children.key(this);
m_parent->m_children.remove(uid);
@@ -211,16 +212,19 @@ QVariant CategoryFilterModel::data(const QModelIndex &index, int role) const
auto item = static_cast<const CategoryModelItem *>(index.internalPointer());
if ((index.column() == 0) && (role == Qt::DecorationRole)) {
if ((index.column() == 0) && (role == Qt::DecorationRole))
{
return UIThemeManager::instance()->getIcon("inode-directory");
}
if ((index.column() == 0) && (role == Qt::DisplayRole)) {
if ((index.column() == 0) && (role == Qt::DisplayRole))
{
return QString(QStringLiteral("%1 (%2)"))
.arg(item->name()).arg(item->torrentsCount());
}
if ((index.column() == 0) && (role == Qt::UserRole)) {
if ((index.column() == 0) && (role == Qt::UserRole))
{
return item->torrentsCount();
}
@@ -306,7 +310,8 @@ void CategoryFilterModel::categoryAdded(const QString &categoryName)
{
CategoryModelItem *parent = m_rootItem;
if (m_isSubcategoriesEnabled) {
if (m_isSubcategoriesEnabled)
{
QStringList expanded = BitTorrent::Session::expandCategory(categoryName);
if (expanded.count() > 1)
parent = findItem(expanded[expanded.count() - 2]);
@@ -322,7 +327,8 @@ void CategoryFilterModel::categoryAdded(const QString &categoryName)
void CategoryFilterModel::categoryRemoved(const QString &categoryName)
{
auto item = findItem(categoryName);
if (item) {
if (item)
{
QModelIndex i = index(item);
beginRemoveRows(i.parent(), i.row(), i.row());
delete item;
@@ -357,7 +363,8 @@ void CategoryFilterModel::torrentCategoryChanged(BitTorrent::TorrentHandle *cons
item->decreaseTorrentsCount();
i = index(item);
while (i.isValid()) {
while (i.isValid())
{
emit dataChanged(i, i);
i = parent(i);
}
@@ -367,7 +374,8 @@ void CategoryFilterModel::torrentCategoryChanged(BitTorrent::TorrentHandle *cons
item->increaseTorrentsCount();
i = index(item);
while (i.isValid()) {
while (i.isValid())
{
emit dataChanged(i, i);
i = parent(i);
}
@@ -404,13 +412,17 @@ void CategoryFilterModel::populate()
, [](Torrent *torrent) { return torrent->category().isEmpty(); })));
using Torrent = BitTorrent::TorrentHandle;
for (auto i = session->categories().cbegin(); i != session->categories().cend(); ++i) {
for (auto i = session->categories().cbegin(); i != session->categories().cend(); ++i)
{
const QString &category = i.key();
if (m_isSubcategoriesEnabled) {
if (m_isSubcategoriesEnabled)
{
CategoryModelItem *parent = m_rootItem;
for (const QString &subcat : asConst(session->expandCategory(category))) {
for (const QString &subcat : asConst(session->expandCategory(category)))
{
const QString subcatName = shortName(subcat);
if (!parent->hasChild(subcatName)) {
if (!parent->hasChild(subcatName))
{
new CategoryModelItem(
parent, subcatName
, std::count_if(torrents.cbegin(), torrents.cend()
@@ -419,7 +431,8 @@ void CategoryFilterModel::populate()
parent = parent->child(subcatName);
}
}
else {
else
{
new CategoryModelItem(
m_rootItem, category
, std::count_if(torrents.begin(), torrents.end()
@@ -437,7 +450,8 @@ CategoryModelItem *CategoryFilterModel::findItem(const QString &fullName) const
return m_rootItem->child(fullName);
CategoryModelItem *item = m_rootItem;
for (const QString &subcat : asConst(BitTorrent::Session::expandCategory(fullName))) {
for (const QString &subcat : asConst(BitTorrent::Session::expandCategory(fullName)))
{
const QString subcatName = shortName(subcat);
if (!item->hasChild(subcatName)) return nullptr;
item = item->child(subcatName);

View File

@@ -44,7 +44,8 @@ namespace
QString getCategoryFilter(const CategoryFilterProxyModel *const model, const QModelIndex &index)
{
QString categoryFilter; // Defaults to All
if (index.isValid()) {
if (index.isValid())
{
if (!index.parent().isValid() && (index.row() == 1))
categoryFilter = ""; // Uncategorized
else if (index.parent().isValid() || (index.row() > 1))
@@ -115,8 +116,10 @@ void CategoryFilterWidget::showMenu(const QPoint &)
connect(addAct, &QAction::triggered, this, &CategoryFilterWidget::addCategory);
const auto selectedRows = selectionModel()->selectedRows();
if (!selectedRows.empty() && !CategoryFilterModel::isSpecialItem(selectedRows.first())) {
if (BitTorrent::Session::instance()->isSubcategoriesEnabled()) {
if (!selectedRows.empty() && !CategoryFilterModel::isSpecialItem(selectedRows.first()))
{
if (BitTorrent::Session::instance()->isSubcategoriesEnabled())
{
const QAction *addSubAct = menu->addAction(
UIThemeManager::instance()->getIcon("list-add")
, tr("Add subcategory..."));
@@ -175,7 +178,8 @@ QSize CategoryFilterWidget::sizeHint() const
// otherwise widget will not correctly adjust the
// size when subcategories are used.
const QSize viewportSize {viewportSizeHint()};
return {
return
{
viewportSize.width(),
viewportSize.height() + static_cast<int>(0.5 * sizeHintForRow(0))
};
@@ -194,7 +198,8 @@ void CategoryFilterWidget::rowsInserted(const QModelIndex &parent, int start, in
// Expand all parents if the parent(s) of the node are not expanded.
QModelIndex p = parent;
while (p.isValid()) {
while (p.isValid())
{
if (!isExpanded(p))
expand(p);
p = model()->parent(p);
@@ -221,7 +226,8 @@ void CategoryFilterWidget::editCategory()
void CategoryFilterWidget::removeCategory()
{
const auto selectedRows = selectionModel()->selectedRows();
if (!selectedRows.empty() && !CategoryFilterModel::isSpecialItem(selectedRows.first())) {
if (!selectedRows.empty() && !CategoryFilterModel::isSpecialItem(selectedRows.first()))
{
BitTorrent::Session::instance()->removeCategory(
static_cast<CategoryFilterProxyModel *>(model())->categoryName(selectedRows.first()));
updateGeometry();
@@ -231,7 +237,8 @@ void CategoryFilterWidget::removeCategory()
void CategoryFilterWidget::removeUnusedCategories()
{
auto session = BitTorrent::Session::instance();
for (const QString &category : asConst(session->categories().keys())) {
for (const QString &category : asConst(session->categories().keys()))
{
if (model()->data(static_cast<CategoryFilterProxyModel *>(model())->index(category), Qt::UserRole) == 0)
session->removeCategory(category);
}

View File

@@ -43,8 +43,10 @@ QList<QNetworkCookie> CookiesModel::cookies() const
QVariant CookiesModel::headerData(int section, Qt::Orientation orientation, int role) const
{
if ((role == Qt::DisplayRole) && (orientation == Qt::Horizontal)) {
switch (section) {
if ((role == Qt::DisplayRole) && (orientation == Qt::Horizontal))
{
switch (section)
{
case COL_DOMAIN:
return tr("Domain");
case COL_PATH:
@@ -96,7 +98,8 @@ QVariant CookiesModel::data(const QModelIndex &index, int role) const
|| ((role != Qt::DisplayRole) && (role != Qt::EditRole)))
return {};
switch (index.column()) {
switch (index.column())
{
case COL_DOMAIN:
return m_cookies[index.row()].domain();
case COL_PATH:
@@ -116,7 +119,8 @@ bool CookiesModel::setData(const QModelIndex &index, const QVariant &value, int
{
if (role != Qt::EditRole) return false;
switch (index.column()) {
switch (index.column())
{
case COL_DOMAIN:
m_cookies[index.row()].setDomain(value.toString());
break;

View File

@@ -71,7 +71,8 @@ DownloadFromURLDialog::DownloadFromURLDialog(QWidget *parent)
const QVector<QStringRef> clipboardList = clipboardText.splitRef('\n');
QSet<QString> uniqueURLs;
for (QStringRef strRef : clipboardList) {
for (QStringRef strRef : clipboardList)
{
strRef = strRef.trimmed();
if (strRef.isEmpty()) continue;
@@ -96,14 +97,16 @@ void DownloadFromURLDialog::downloadButtonClicked()
const QVector<QStringRef> urls = plainText.splitRef('\n');
QSet<QString> uniqueURLs;
for (QStringRef url : urls) {
for (QStringRef url : urls)
{
url = url.trimmed();
if (url.isEmpty()) continue;
uniqueURLs << url.toString();
}
if (uniqueURLs.isEmpty()) {
if (uniqueURLs.isEmpty())
{
QMessageBox::warning(this, tr("No URL entered"), tr("Please type at least one URL."));
return;
}

View File

@@ -89,7 +89,8 @@ void ExecutionLogWidget::displayContextMenu(const QPoint &pos, const LogListView
menu->setAttribute(Qt::WA_DeleteOnClose);
// only show copy action if any of the row is selected
if (view->currentIndex().isValid()) {
if (view->currentIndex().isValid())
{
const QAction *copyAct = menu->addAction(UIThemeManager::instance()->getIcon("edit-copy"), tr("Copy"));
connect(copyAct, &QAction::triggered, view, &LogListView::copySelection);
}

View File

@@ -115,7 +115,8 @@ void FileSystemPathEdit::FileSystemPathEditPrivate::browseActionTriggered()
QString directory = q->currentDirectory().isEmpty() ? QDir::homePath() : q->currentDirectory();
QString selectedPath;
switch (m_mode) {
switch (m_mode)
{
case FileSystemPathEdit::Mode::FileOpen:
selectedPath = QFileDialog::getOpenFileName(q, dialogCaptionOrDefault(), directory, filter);
break;
@@ -139,7 +140,8 @@ QString FileSystemPathEdit::FileSystemPathEditPrivate::dialogCaptionOrDefault()
if (!m_dialogCaption.isEmpty())
return m_dialogCaption;
switch (m_mode) {
switch (m_mode)
{
case FileSystemPathEdit::Mode::FileOpen:
case FileSystemPathEdit::Mode::FileSave:
return defaultDialogCaptionForFile.tr();
@@ -155,7 +157,8 @@ void FileSystemPathEdit::FileSystemPathEditPrivate::modeChanged()
{
QStyle::StandardPixmap pixmap = QStyle::SP_DialogOpenButton;
bool showDirsOnly = false;
switch (m_mode) {
switch (m_mode)
{
case FileSystemPathEdit::Mode::FileOpen:
case FileSystemPathEdit::Mode::FileSave:
#ifdef Q_OS_WIN
@@ -229,17 +232,21 @@ void FileSystemPathEdit::setFileNameFilter(const QString &val)
// extract file masks
const int openBracePos = val.indexOf(QLatin1Char('('), 0);
const int closeBracePos = val.indexOf(QLatin1Char(')'), openBracePos + 1);
if ((openBracePos > 0) && (closeBracePos > 0) && (closeBracePos > openBracePos + 2)) {
if ((openBracePos > 0) && (closeBracePos > 0) && (closeBracePos > openBracePos + 2))
{
QString filterString = val.mid(openBracePos + 1, closeBracePos - openBracePos - 1);
if (filterString == QLatin1String("*")) { // no filters
if (filterString == QLatin1String("*"))
{ // no filters
d->m_editor->setFilenameFilters({});
}
else {
else
{
QStringList filters = filterString.split(QLatin1Char(' '), QString::SkipEmptyParts);
d->m_editor->setFilenameFilters(filters);
}
}
else {
else
{
d->m_editor->setFilenameFilters({});
}
#endif
@@ -261,7 +268,8 @@ void FileSystemPathEdit::onPathEdited()
{
Q_D(FileSystemPathEdit);
QString newPath = selectedPath();
if (newPath != d->m_lastSignaledPath) {
if (newPath != d->m_lastSignaledPath)
{
emit selectedPathChanged(newPath);
d->m_lastSignaledPath = newPath;
d->m_editor->widget()->setToolTip(editWidgetText());

View File

@@ -115,7 +115,8 @@ QValidator::State Private::FileSystemPathValidator::validate(QString &input, int
// components.size() - 1 because when path ends with QDir::separator(), we will not see the last
// character in the components array, yet everything past the one before the last delimiter
// belongs to the last component
for (; (componentWithCursorIndex < components.size() - 1) && (pathLength < pos); ++componentWithCursorIndex) {
for (; (componentWithCursorIndex < components.size() - 1) && (pathLength < pos); ++componentWithCursorIndex)
{
pathLength = components[componentWithCursorIndex].position() + components[componentWithCursorIndex].size();
}
@@ -140,12 +141,14 @@ QValidator::State Private::FileSystemPathValidator::validate(const QString &path
if (pathComponents.empty())
return strict ? QValidator::Invalid : QValidator::Intermediate;
for (int i = firstComponentToTest; i < lastComponentToTest; ++i) {
for (int i = firstComponentToTest; i < lastComponentToTest; ++i)
{
if (pathComponents[i].isEmpty()) continue;
QStringRef componentPath(&path, 0, pathComponents[i].position() + pathComponents[i].size());
m_lastTestResult = testPath(componentPath, false);
if (m_lastTestResult != TestResult::OK) {
if (m_lastTestResult != TestResult::OK)
{
m_lastTestedPath = componentPath.toString();
return strict ? QValidator::Invalid : QValidator::Intermediate;
}
@@ -155,7 +158,8 @@ QValidator::State Private::FileSystemPathValidator::validate(const QString &path
QStringRef componentPath(&path, 0, pathComponents[lastComponentToTest].position()
+ pathComponents[lastComponentToTest].size());
m_lastTestResult = testPath(componentPath, finalPath);
if (m_lastTestResult != TestResult::OK) {
if (m_lastTestResult != TestResult::OK)
{
m_lastTestedPath = componentPath.toString();
return strict ? QValidator::Invalid : QValidator::Intermediate;
}
@@ -172,7 +176,8 @@ Private::FileSystemPathValidator::testPath(const QStringRef &path, bool pathIsCo
if ((!pathIsComplete || m_directoriesOnly) && !fi.isDir())
return TestResult::NotADir;
if (pathIsComplete) {
if (pathIsComplete)
{
if (!m_directoriesOnly && fi.isDir())
return TestResult::NotAFile;
@@ -249,27 +254,33 @@ QWidget *Private::FileLineEdit::widget()
void Private::FileLineEdit::keyPressEvent(QKeyEvent *e)
{
QLineEdit::keyPressEvent(e);
if ((e->key() == Qt::Key_Space) && (e->modifiers() == Qt::CTRL)) {
if ((e->key() == Qt::Key_Space) && (e->modifiers() == Qt::CTRL))
{
m_completerModel->setRootPath(QFileInfo(text()).absoluteDir().absolutePath());
showCompletionPopup();
}
auto *validator = qobject_cast<const FileSystemPathValidator *>(this->validator());
if (validator) {
if (validator)
{
FileSystemPathValidator::TestResult lastTestResult = validator->lastTestResult();
QValidator::State lastState = validator->lastValidationState();
if (lastTestResult == FileSystemPathValidator::TestResult::OK) {
if (lastTestResult == FileSystemPathValidator::TestResult::OK)
{
delete m_warningAction;
m_warningAction = nullptr;
}
else {
if (!m_warningAction) {
else
{
if (!m_warningAction)
{
m_warningAction = new QAction(this);
addAction(m_warningAction, QLineEdit::TrailingPosition);
}
}
if (m_warningAction) {
if (m_warningAction)
{
if (lastState == QValidator::Invalid)
m_warningAction->setIcon(style()->standardIcon(QStyle::SP_MessageBoxCritical));
else if (lastState == QValidator::Intermediate)
@@ -284,7 +295,8 @@ void Private::FileLineEdit::contextMenuEvent(QContextMenuEvent *event)
QMenu *menu = createStandardContextMenu();
menu->setAttribute(Qt::WA_DeleteOnClose);
if (m_browseAction) {
if (m_browseAction)
{
menu->addSeparator();
menu->addAction(m_browseAction);
}
@@ -301,7 +313,8 @@ void Private::FileLineEdit::showCompletionPopup()
QString Private::FileLineEdit::warningText(FileSystemPathValidator::TestResult r)
{
using TestResult = FileSystemPathValidator::TestResult;
switch (r) {
switch (r)
{
case TestResult::DoesNotExist:
return tr("'%1' does not exist");
case TestResult::NotADir:

View File

@@ -68,7 +68,8 @@ IPSubnetWhitelistOptionsDialog::~IPSubnetWhitelistOptionsDialog()
void IPSubnetWhitelistOptionsDialog::on_buttonBox_accepted()
{
if (m_modified) {
if (m_modified)
{
// save to session
QStringList subnets;
// Operate on the m_sortFilter to grab the strings in sorted order
@@ -77,7 +78,8 @@ void IPSubnetWhitelistOptionsDialog::on_buttonBox_accepted()
Preferences::instance()->setWebUiAuthSubnetWhitelist(subnets);
QDialog::accept();
}
else {
else
{
QDialog::reject();
}
}
@@ -86,7 +88,8 @@ void IPSubnetWhitelistOptionsDialog::on_buttonWhitelistIPSubnet_clicked()
{
bool ok = false;
const Utils::Net::Subnet subnet = Utils::Net::parseSubnet(m_ui->txtIPSubnet->text(), &ok);
if (!ok) {
if (!ok)
{
QMessageBox::critical(this, tr("Error"), tr("The entered subnet is invalid."));
return;
}

View File

@@ -47,7 +47,8 @@ void LineEdit::resizeEvent(QResizeEvent *e)
void LineEdit::keyPressEvent(QKeyEvent *event)
{
if ((event->modifiers() == Qt::NoModifier) && (event->key() == Qt::Key_Escape)) {
if ((event->modifiers() == Qt::NoModifier) && (event->key() == Qt::Key_Escape))
{
clear();
}
QLineEdit::keyPressEvent(event);

View File

@@ -97,7 +97,8 @@ QVariant BaseLogModel::data(const QModelIndex &index, const int role) const
return {};
const Message &message = m_messages[messageIndex];
switch (role) {
switch (role)
{
case TimeRole:
return message.time();
case MessageRole:
@@ -117,7 +118,8 @@ void BaseLogModel::addNewMessage(const BaseLogModel::Message &message)
{
// if row is inserted on filled up buffer, the size will not change
// but because of calling of beginInsertRows function we'll have ghost rows.
if (m_messages.size() == MAX_VISIBLE_MESSAGES) {
if (m_messages.size() == MAX_VISIBLE_MESSAGES)
{
const int lastMessage = m_messages.size() - 1;
beginRemoveRows(QModelIndex(), lastMessage, lastMessage);
m_messages.pop_back();
@@ -138,7 +140,8 @@ void BaseLogModel::reset()
LogMessageModel::LogMessageModel(QObject *parent)
: BaseLogModel(parent)
, m_foregroundForMessageTypes {
, m_foregroundForMessageTypes
{
{Log::NORMAL, UIThemeManager::instance()->getColor(QLatin1String("Log.Normal"), QApplication::palette().color(QPalette::WindowText))},
{Log::INFO, UIThemeManager::instance()->getColor(QLatin1String("Log.Info"), Qt::blue)},
{Log::WARNING, UIThemeManager::instance()->getColor(QLatin1String("Log.Warning"), QColor {255, 165, 0})}, // orange

View File

@@ -281,8 +281,10 @@ MainWindow::MainWindow(QWidget *parent)
m_queueSeparatorMenu = m_ui->menuEdit->insertSeparator(m_ui->actionTopQueuePos);
#ifdef Q_OS_MACOS
for (QAction *action : asConst(m_ui->toolBar->actions())) {
if (action->isSeparator()) {
for (QAction *action : asConst(m_ui->toolBar->actions()))
{
if (action->isSeparator())
{
QWidget *spacer = new QWidget(this);
spacer->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
spacer->setMinimumWidth(16);
@@ -406,30 +408,38 @@ MainWindow::MainWindow(QWidget *parent)
readSettings();
#ifndef Q_OS_MACOS
if (m_systrayIcon) {
if (!(pref->startMinimized() || m_uiLocked)) {
if (m_systrayIcon)
{
if (!(pref->startMinimized() || m_uiLocked))
{
show();
activateWindow();
raise();
}
else if (pref->startMinimized()) {
else if (pref->startMinimized())
{
showMinimized();
if (pref->minimizeToTray()) {
if (pref->minimizeToTray())
{
hide();
if (!pref->minimizeToTrayNotified()) {
if (!pref->minimizeToTrayNotified())
{
showNotificationBaloon(tr("qBittorrent is minimized to tray"), tr("This behavior can be changed in the settings. You won't be reminded again."));
pref->setMinimizeToTrayNotified(true);
}
}
}
}
else {
else
{
#endif
// Make sure the Window is visible if we don't have a tray icon
if (pref->startMinimized()) {
if (pref->startMinimized())
{
showMinimized();
}
else {
else
{
show();
activateWindow();
raise();
@@ -456,14 +466,17 @@ MainWindow::MainWindow(QWidget *parent)
qDebug("GUI Built");
#ifdef Q_OS_WIN
if (!pref->neverCheckFileAssoc() && (!Preferences::isTorrentFileAssocSet() || !Preferences::isMagnetLinkAssocSet())) {
if (!pref->neverCheckFileAssoc() && (!Preferences::isTorrentFileAssocSet() || !Preferences::isMagnetLinkAssocSet()))
{
if (QMessageBox::question(this, tr("Torrent file association"),
tr("qBittorrent is not the default application to open torrent files or Magnet links.\nDo you want to associate qBittorrent to torrent files and Magnet links?"),
QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes) == QMessageBox::Yes) {
QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes) == QMessageBox::Yes)
{
Preferences::setTorrentFileAssoc(true);
Preferences::setMagnetLinkAssoc(true);
}
else {
else
{
pref->setNeverCheckFileAssoc();
}
}
@@ -567,7 +580,8 @@ void MainWindow::addToolbarContextMenu()
const auto buttonStyle = static_cast<Qt::ToolButtonStyle>(pref->getToolbarTextPosition());
if ((buttonStyle >= Qt::ToolButtonIconOnly) && (buttonStyle <= Qt::ToolButtonFollowStyle))
m_ui->toolBar->setToolButtonStyle(buttonStyle);
switch (buttonStyle) {
switch (buttonStyle)
{
case Qt::ToolButtonIconOnly:
iconsOnly->setChecked(true);
break;
@@ -635,7 +649,8 @@ bool MainWindow::defineUILockPassword()
if (!ok)
return false;
if (newPassword.size() < 3) {
if (newPassword.size() < 3)
{
QMessageBox::warning(this, tr("Invalid password"), tr("The password should contain at least 3 characters"));
return false;
}
@@ -657,7 +672,8 @@ void MainWindow::on_actionLock_triggered()
Preferences *const pref = Preferences::instance();
// Check if there is a password
if (pref->getUILockPassword().isEmpty()) {
if (pref->getUILockPassword().isEmpty())
{
if (!defineUILockPassword())
return;
}
@@ -676,9 +692,11 @@ void MainWindow::handleRSSUnreadCountUpdated(int count)
void MainWindow::displayRSSTab(bool enable)
{
if (enable) {
if (enable)
{
// RSS tab
if (!m_rssWidget) {
if (!m_rssWidget)
{
m_rssWidget = new RSSWidget(m_tabs);
connect(m_rssWidget.data(), &RSSWidget::unreadCountUpdated, this, &MainWindow::handleRSSUnreadCountUpdated);
#ifdef Q_OS_MACOS
@@ -689,7 +707,8 @@ void MainWindow::displayRSSTab(bool enable)
#endif
}
}
else {
else
{
delete m_rssWidget;
}
}
@@ -714,9 +733,11 @@ void MainWindow::showFilterContextMenu(const QPoint &)
void MainWindow::displaySearchTab(bool enable)
{
Preferences::instance()->setSearchEnabled(enable);
if (enable) {
if (enable)
{
// RSS tab
if (!m_searchWidget) {
if (!m_searchWidget)
{
m_searchWidget = new SearchWidget(this);
m_tabs->insertTab(1, m_searchWidget,
#ifndef Q_OS_MACOS
@@ -725,7 +746,8 @@ void MainWindow::displaySearchTab(bool enable)
tr("Search"));
}
}
else {
else
{
delete m_searchWidget;
}
}
@@ -751,7 +773,8 @@ void MainWindow::tabChanged(int newTab)
Q_UNUSED(newTab);
// We cannot rely on the index newTab
// because the tab order is undetermined now
if (m_tabs->currentWidget() == m_splitter) {
if (m_tabs->currentWidget() == m_splitter)
{
qDebug("Changed tab to transfer list, refreshing the list");
m_propertiesWidget->loadDynamicData();
m_searchFilterAction->setVisible(true);
@@ -759,7 +782,8 @@ void MainWindow::tabChanged(int newTab)
}
m_searchFilterAction->setVisible(false);
if (m_tabs->currentWidget() == m_searchWidget) {
if (m_tabs->currentWidget() == m_searchWidget)
{
qDebug("Changed tab to search engine, giving focus to search input");
m_searchWidget->giveFocusToSearchInput();
}
@@ -815,8 +839,10 @@ void MainWindow::readSettings()
void MainWindow::balloonClicked()
{
if (isHidden()) {
if (m_uiLocked) {
if (isHidden())
{
if (m_uiLocked)
{
// Ask for UI lock password
if (!unlockUI())
return;
@@ -916,7 +942,8 @@ void MainWindow::displayTransferTab() const
void MainWindow::displaySearchTab()
{
if (!m_searchWidget) {
if (!m_searchWidget)
{
m_ui->actionSearchWidget->setChecked(true);
displaySearchTab(true);
}
@@ -926,7 +953,8 @@ void MainWindow::displaySearchTab()
void MainWindow::displayRSSTab()
{
if (!m_rssWidget) {
if (!m_rssWidget)
{
m_ui->actionRSSReader->setChecked(true);
displayRSSTab(true);
}
@@ -936,7 +964,8 @@ void MainWindow::displayRSSTab()
void MainWindow::displayExecutionLogTab()
{
if (!m_executionLog) {
if (!m_executionLog)
{
m_ui->actionExecutionLogs->setChecked(true);
on_actionExecutionLogs_triggered(true);
}
@@ -988,7 +1017,8 @@ void MainWindow::on_actionSetGlobalUploadLimit_triggered()
const long newLimit = SpeedLimitDialog::askSpeedLimit(
this, &ok, tr("Global Upload Speed Limit"), session->uploadSpeedLimit());
if (ok) {
if (ok)
{
qDebug("Setting global upload rate limit to %.1fKb/s", newLimit / 1024.);
session->setUploadSpeedLimit(newLimit);
}
@@ -1003,7 +1033,8 @@ void MainWindow::on_actionSetGlobalDownloadLimit_triggered()
const long newLimit = SpeedLimitDialog::askSpeedLimit(
this, &ok, tr("Global Download Speed Limit"), session->downloadSpeedLimit());
if (ok) {
if (ok)
{
qDebug("Setting global download rate limit to %.1fKb/s", newLimit / 1024.);
session->setDownloadSpeedLimit(newLimit);
}
@@ -1059,7 +1090,8 @@ bool MainWindow::unlockUI()
Preferences *const pref = Preferences::instance();
const QByteArray secret = pref->getUILockPassword();
if (!Utils::Password::PBKDF2::verify(secret, password)) {
if (!Utils::Password::PBKDF2::verify(secret, password))
{
QMessageBox::warning(this, tr("Invalid password"), tr("The password is invalid"));
return false;
}
@@ -1085,9 +1117,11 @@ void MainWindow::notifyOfUpdate(const QString &)
// Toggle Main window visibility
void MainWindow::toggleVisibility(const QSystemTrayIcon::ActivationReason reason)
{
switch (reason) {
switch (reason)
{
case QSystemTrayIcon::Trigger:
if (isHidden()) {
if (isHidden())
{
if (m_uiLocked && !unlockUI()) // Ask for UI lock password
return;
@@ -1099,7 +1133,8 @@ void MainWindow::toggleVisibility(const QSystemTrayIcon::ActivationReason reason
raise();
activateWindow();
}
else {
else
{
hide();
}
break;
@@ -1138,7 +1173,8 @@ void MainWindow::showEvent(QShowEvent *e)
e->accept();
// Make sure the window is initially centered
if (!m_posInitialized) {
if (!m_posInitialized)
{
move(Utils::Gui::screenCenter(this));
m_posInitialized = true;
}
@@ -1146,14 +1182,17 @@ void MainWindow::showEvent(QShowEvent *e)
void MainWindow::keyPressEvent(QKeyEvent *event)
{
if (event->matches(QKeySequence::Paste)) {
if (event->matches(QKeySequence::Paste))
{
const QMimeData *mimeData {QGuiApplication::clipboard()->mimeData()};
if (mimeData->hasText()) {
if (mimeData->hasText())
{
const bool useTorrentAdditionDialog {AddNewTorrentDialog::isEnabled()};
const QStringList lines {mimeData->text().split('\n', QString::SkipEmptyParts)};
for (QString line : lines) {
for (QString line : lines)
{
line = line.trimmed();
if (!isTorrentLink(line))
@@ -1177,17 +1216,20 @@ void MainWindow::closeEvent(QCloseEvent *e)
{
Preferences *const pref = Preferences::instance();
#ifdef Q_OS_MACOS
if (!m_forceExit) {
if (!m_forceExit)
{
hide();
e->accept();
return;
}
#else
const bool goToSystrayOnExit = pref->closeToTray();
if (!m_forceExit && m_systrayIcon && goToSystrayOnExit && !this->isHidden()) {
if (!m_forceExit && m_systrayIcon && goToSystrayOnExit && !this->isHidden())
{
e->ignore();
QTimer::singleShot(0, this, &QWidget::hide);
if (!pref->closeToTrayNotified()) {
if (!pref->closeToTrayNotified())
{
showNotificationBaloon(tr("qBittorrent is closed to tray"), tr("This behavior can be changed in the settings. You won't be reminded again."));
pref->setCloseToTrayNotified(true);
}
@@ -1195,8 +1237,10 @@ void MainWindow::closeEvent(QCloseEvent *e)
}
#endif // Q_OS_MACOS
if (pref->confirmOnExit() && BitTorrent::Session::instance()->hasActiveTorrents()) {
if (e->spontaneous() || m_forceExit) {
if (pref->confirmOnExit() && BitTorrent::Session::instance()->hasActiveTorrents())
{
if (e->spontaneous() || m_forceExit)
{
if (!isVisible())
show();
QMessageBox confirmBox(QMessageBox::Question, tr("Exiting qBittorrent"),
@@ -1208,7 +1252,8 @@ void MainWindow::closeEvent(QCloseEvent *e)
QPushButton *alwaysBtn = confirmBox.addButton(tr("&Always Yes"), QMessageBox::YesRole);
confirmBox.setDefaultButton(noBtn);
confirmBox.exec();
if (!confirmBox.clickedButton() || (confirmBox.clickedButton() == noBtn)) {
if (!confirmBox.clickedButton() || (confirmBox.clickedButton() == noBtn))
{
// Cancel exit
e->ignore();
m_forceExit = false;
@@ -1242,7 +1287,8 @@ void MainWindow::on_actionCreateTorrent_triggered()
void MainWindow::createTorrentTriggered(const QString &path)
{
if (m_createTorrentDlg) {
if (m_createTorrentDlg)
{
m_createTorrentDlg->updateInputPath(path);
m_createTorrentDlg->activateWindow();
}
@@ -1253,29 +1299,37 @@ void MainWindow::createTorrentTriggered(const QString &path)
bool MainWindow::event(QEvent *e)
{
#ifndef Q_OS_MACOS
switch (e->type()) {
case QEvent::WindowStateChange: {
switch (e->type())
{
case QEvent::WindowStateChange:
{
qDebug("Window change event");
// Now check to see if the window is minimised
if (isMinimized()) {
if (isMinimized())
{
qDebug("minimisation");
Preferences *const pref = Preferences::instance();
if (m_systrayIcon && pref->minimizeToTray()) {
if (m_systrayIcon && pref->minimizeToTray())
{
qDebug() << "Has active window:" << (qApp->activeWindow() != nullptr);
// Check if there is a modal window
bool hasModalWindow = false;
for (QWidget *widget : asConst(QApplication::allWidgets())) {
if (widget->isModal()) {
for (QWidget *widget : asConst(QApplication::allWidgets()))
{
if (widget->isModal())
{
hasModalWindow = true;
break;
}
}
// Iconify if there is no modal window
if (!hasModalWindow) {
if (!hasModalWindow)
{
qDebug("Minimize to Tray enabled, hiding!");
e->ignore();
QTimer::singleShot(0, this, &QWidget::hide);
if (!pref->minimizeToTrayNotified()) {
if (!pref->minimizeToTrayNotified())
{
showNotificationBaloon(tr("qBittorrent is minimized to tray"), tr("This behavior can be changed in the settings. You won't be reminded again."));
pref->setMinimizeToTrayNotified(true);
}
@@ -1285,7 +1339,8 @@ bool MainWindow::event(QEvent *e)
}
break;
}
case QEvent::ToolBarChange: {
case QEvent::ToolBarChange:
{
qDebug("MAC: Received a toolbar change event!");
bool ret = QMainWindow::event(e);
@@ -1309,8 +1364,10 @@ void MainWindow::dropEvent(QDropEvent *event)
// remove scheme
QStringList files;
if (event->mimeData()->hasUrls()) {
for (const QUrl &url : asConst(event->mimeData()->urls())) {
if (event->mimeData()->hasUrls())
{
for (const QUrl &url : asConst(event->mimeData()->urls()))
{
if (url.isEmpty())
continue;
@@ -1319,13 +1376,15 @@ void MainWindow::dropEvent(QDropEvent *event)
: url.toString());
}
}
else {
else
{
files = event->mimeData()->text().split('\n');
}
// differentiate ".torrent" files/links & magnet links from others
QStringList torrentFiles, otherFiles;
for (const QString &file : asConst(files)) {
for (const QString &file : asConst(files))
{
if (isTorrentLink(file))
torrentFiles << file;
else
@@ -1334,7 +1393,8 @@ void MainWindow::dropEvent(QDropEvent *event)
// Download torrents
const bool useTorrentAdditionDialog = AddNewTorrentDialog::isEnabled();
for (const QString &file : asConst(torrentFiles)) {
for (const QString &file : asConst(torrentFiles))
{
if (useTorrentAdditionDialog)
AddNewTorrentDialog::show(file, this);
else
@@ -1343,7 +1403,8 @@ void MainWindow::dropEvent(QDropEvent *event)
if (!torrentFiles.isEmpty()) return;
// Create torrent
for (const QString &file : asConst(otherFiles)) {
for (const QString &file : asConst(otherFiles))
{
createTorrentTriggered(file);
// currently only handle the first entry
@@ -1370,7 +1431,8 @@ static bool dockClickHandler(id self, SEL cmd, ...)
Q_UNUSED(self)
Q_UNUSED(cmd)
if (dockMainWindowHandle && !dockMainWindowHandle->isVisible()) {
if (dockMainWindowHandle && !dockMainWindowHandle->isVisible())
{
dockMainWindowHandle->activate();
}
@@ -1407,7 +1469,8 @@ void MainWindow::on_actionOpen_triggered()
const bool useTorrentAdditionDialog = AddNewTorrentDialog::isEnabled();
for (const QString &file : pathsList) {
for (const QString &file : pathsList)
{
if (useTorrentAdditionDialog)
AddNewTorrentDialog::show(file, this);
else
@@ -1422,7 +1485,8 @@ void MainWindow::on_actionOpen_triggered()
void MainWindow::activate()
{
if (!m_uiLocked || unlockUI()) {
if (!m_uiLocked || unlockUI())
{
show();
activateWindow();
raise();
@@ -1436,11 +1500,13 @@ void MainWindow::optionsSaved()
void MainWindow::showStatusBar(bool show)
{
if (!show) {
if (!show)
{
// Remove status bar
setStatusBar(nullptr);
}
else if (!m_statusBar) {
else if (!m_statusBar)
{
// Create status bar
m_statusBar = new StatusBar;
connect(m_statusBar.data(), &StatusBar::connectionButtonClicked, this, &MainWindow::showConnectionSettings);
@@ -1458,26 +1524,33 @@ void MainWindow::loadPreferences(const bool configureSession)
#else
const bool newSystrayIntegration = pref->systrayIntegration();
m_ui->actionLock->setVisible(newSystrayIntegration);
if (newSystrayIntegration != (m_systrayIcon != nullptr)) {
if (newSystrayIntegration) {
if (newSystrayIntegration != (m_systrayIcon != nullptr))
{
if (newSystrayIntegration)
{
// create the trayicon
if (!QSystemTrayIcon::isSystemTrayAvailable()) {
if (!configureSession) { // Program startup
if (!QSystemTrayIcon::isSystemTrayAvailable())
{
if (!configureSession)
{ // Program startup
m_systrayCreator = new QTimer(this);
connect(m_systrayCreator.data(), &QTimer::timeout, this, &MainWindow::createSystrayDelayed);
m_systrayCreator->setSingleShot(true);
m_systrayCreator->start(2000);
qDebug("Info: System tray is unavailable, trying again later.");
}
else {
else
{
qDebug("Warning: System tray is unavailable.");
}
}
else {
else
{
createTrayIcon();
}
}
else {
else
{
// Destroy trayicon
delete m_systrayIcon;
delete m_trayIconMenu;
@@ -1488,10 +1561,12 @@ void MainWindow::loadPreferences(const bool configureSession)
m_systrayIcon->setIcon(getSystrayIcon());
#endif
// General
if (pref->isToolbarDisplayed()) {
if (pref->isToolbarDisplayed())
{
m_ui->toolBar->setVisible(true);
}
else {
else
{
// Clear search filter before hiding the top toolbar
m_searchFilter->clear();
m_ui->toolBar->setVisible(false);
@@ -1499,13 +1574,16 @@ void MainWindow::loadPreferences(const bool configureSession)
showStatusBar(pref->isStatusbarDisplayed());
if (pref->preventFromSuspendWhenDownloading() || pref->preventFromSuspendWhenSeeding()) {
if (!m_preventTimer->isActive()) {
if (pref->preventFromSuspendWhenDownloading() || pref->preventFromSuspendWhenSeeding())
{
if (!m_preventTimer->isActive())
{
updatePowerManagementState();
m_preventTimer->start(PREVENT_SUSPEND_INTERVAL);
}
}
else {
else
{
m_preventTimer->stop();
m_pwr->setActivityState(false);
}
@@ -1516,8 +1594,10 @@ void MainWindow::loadPreferences(const bool configureSession)
m_propertiesWidget->getPeerList()->setAlternatingRowColors(pref->useAlternatingRowColors());
// Queueing System
if (BitTorrent::Session::instance()->isQueueingSystemEnabled()) {
if (!m_ui->actionDecreaseQueuePos->isVisible()) {
if (BitTorrent::Session::instance()->isQueueingSystemEnabled())
{
if (!m_ui->actionDecreaseQueuePos->isVisible())
{
m_transferListWidget->hideQueuePosColumn(false);
m_ui->actionDecreaseQueuePos->setVisible(true);
m_ui->actionIncreaseQueuePos->setVisible(true);
@@ -1529,8 +1609,10 @@ void MainWindow::loadPreferences(const bool configureSession)
m_queueSeparatorMenu->setVisible(true);
}
}
else {
if (m_ui->actionDecreaseQueuePos->isVisible()) {
else
{
if (m_ui->actionDecreaseQueuePos->isVisible())
{
m_transferListWidget->hideQueuePosColumn(true);
m_ui->actionDecreaseQueuePos->setVisible(false);
m_ui->actionIncreaseQueuePos->setVisible(false);
@@ -1547,11 +1629,13 @@ void MainWindow::loadPreferences(const bool configureSession)
m_propertiesWidget->reloadPreferences();
#if defined(Q_OS_WIN) || defined(Q_OS_MACOS)
if (pref->isUpdateCheckEnabled() && !m_wasUpdateCheckEnabled) {
if (pref->isUpdateCheckEnabled() && !m_wasUpdateCheckEnabled)
{
m_wasUpdateCheckEnabled = true;
checkProgramUpdate();
}
else if (!pref->isUpdateCheckEnabled() && m_wasUpdateCheckEnabled) {
else if (!pref->isUpdateCheckEnabled() && m_wasUpdateCheckEnabled)
{
m_wasUpdateCheckEnabled = false;
m_programUpdateTimer->stop();
}
@@ -1566,15 +1650,18 @@ void MainWindow::reloadSessionStats()
// update global information
#ifdef Q_OS_MACOS
if (status.payloadDownloadRate > 0) {
if (status.payloadDownloadRate > 0)
{
QtMac::setBadgeLabelText(tr("%1/s", "s is a shorthand for seconds")
.arg(Utils::Misc::friendlyUnit(status.payloadDownloadRate)));
}
else if (!QtMac::badgeLabelText().isEmpty()) {
else if (!QtMac::badgeLabelText().isEmpty())
{
QtMac::setBadgeLabelText("");
}
#else
if (m_systrayIcon) {
if (m_systrayIcon)
{
const QString toolTip = QString::fromLatin1("%1\n%2").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)));
@@ -1582,7 +1669,8 @@ void MainWindow::reloadSessionStats()
}
#endif // Q_OS_MACOS
if (m_displaySpeedInTitle) {
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)
@@ -1592,7 +1680,8 @@ void MainWindow::reloadSessionStats()
void MainWindow::reloadTorrentStats(const QVector<BitTorrent::TorrentHandle *> &torrents)
{
if (currentTabWidget() == m_transferListWidget) {
if (currentTabWidget() == m_transferListWidget)
{
if (torrents.contains(m_propertiesWidget->getCurrentTorrent()))
m_propertiesWidget->loadDynamicData();
}
@@ -1638,7 +1727,8 @@ void MainWindow::showNotificationBaloon(const QString &title, const QString &msg
void MainWindow::downloadFromURLList(const QStringList &urlList)
{
const bool useTorrentAdditionDialog = AddNewTorrentDialog::isEnabled();
for (const QString &url : urlList) {
for (const QString &url : urlList)
{
if (useTorrentAdditionDialog)
AddNewTorrentDialog::show(url, this);
else
@@ -1656,19 +1746,23 @@ void MainWindow::downloadFromURLList(const QStringList &urlList)
void MainWindow::createSystrayDelayed()
{
static int timeout = 20;
if (QSystemTrayIcon::isSystemTrayAvailable()) {
if (QSystemTrayIcon::isSystemTrayAvailable())
{
// Ok, systray integration is now supported
// Create systray icon
createTrayIcon();
delete m_systrayCreator;
}
else {
if (timeout) {
else
{
if (timeout)
{
// Retry a bit later
m_systrayCreator->start(2000);
--timeout;
}
else {
else
{
// Timed out, apparently system really does not
// support systray icon
delete m_systrayCreator;
@@ -1780,11 +1874,13 @@ void MainWindow::on_actionRSSReader_triggered()
void MainWindow::on_actionSearchWidget_triggered()
{
if (!m_hasPython && m_ui->actionSearchWidget->isChecked()) {
if (!m_hasPython && m_ui->actionSearchWidget->isChecked())
{
const Utils::ForeignApps::PythonInfo pyInfo = Utils::ForeignApps::pythonInfo();
// Not installed
if (!pyInfo.isValid()) {
if (!pyInfo.isValid())
{
m_ui->actionSearchWidget->setChecked(false);
Preferences::instance()->setSearchEnabled(false);
@@ -1802,7 +1898,8 @@ void MainWindow::on_actionSearchWidget_triggered()
}
// Check version requirement
if (!pyInfo.isSupportedVersion()) {
if (!pyInfo.isSupportedVersion())
{
m_ui->actionSearchWidget->setChecked(false);
Preferences::instance()->setSearchEnabled(false);
@@ -1839,7 +1936,8 @@ void MainWindow::on_actionSearchWidget_triggered()
// an url
void MainWindow::on_actionDownloadFromURL_triggered()
{
if (!m_downloadFromURLDialog) {
if (!m_downloadFromURLDialog)
{
m_downloadFromURLDialog = new DownloadFromURLDialog(this);
connect(m_downloadFromURLDialog.data(), &DownloadFromURLDialog::urlsReadyToBeDownloaded, this, &MainWindow::downloadFromURLList);
}
@@ -1849,19 +1947,22 @@ void MainWindow::on_actionDownloadFromURL_triggered()
void MainWindow::handleUpdateCheckFinished(bool updateAvailable, QString newVersion, bool invokedByUser)
{
QMessageBox::StandardButton answer = QMessageBox::Yes;
if (updateAvailable) {
if (updateAvailable)
{
answer = QMessageBox::question(this, tr("qBittorrent Update Available")
, tr("A new version is available.") + "<br/>"
+ tr("Do you want to download %1?").arg(newVersion) + "<br/><br/>"
+ QString::fromLatin1("<a href=\"https://www.qbittorrent.org/news.php\">%1</a>").arg(tr("Open changelog..."))
, QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes);
if (answer == QMessageBox::Yes) {
if (answer == QMessageBox::Yes)
{
// The user want to update, let's download the update
ProgramUpdater *updater = dynamic_cast<ProgramUpdater * >(sender());
updater->updateProgram();
}
}
else if (invokedByUser) {
else if (invokedByUser)
{
QMessageBox::information(this, tr("Already Using the Latest qBittorrent Version"),
tr("No updates available.\nYou are already using the latest version."));
}
@@ -1899,7 +2000,8 @@ void MainWindow::minimizeWindow()
void MainWindow::on_actionExecutionLogs_triggered(bool checked)
{
if (checked) {
if (checked)
{
Q_ASSERT(!m_executionLog);
m_executionLog = new ExecutionLogWidget(static_cast<Log::MsgType>(executionLogMsgTypes()), m_tabs);
#ifdef Q_OS_MACOS
@@ -1909,7 +2011,8 @@ void MainWindow::on_actionExecutionLogs_triggered(bool checked)
m_tabs->setTabIcon(indexTab, UIThemeManager::instance()->getIcon("view-calendar-journal"));
#endif
}
else {
else
{
delete m_executionLog;
}
@@ -1997,7 +2100,8 @@ QIcon MainWindow::getSystrayIcon() const
const TrayIcon::Style style = Preferences::instance()->trayIconStyle();
// on Linux we use theme icons, and icons from resources everywhere else
#if (defined(Q_OS_UNIX) && !defined(Q_OS_MACOS))
switch (style) {
switch (style)
{
case TrayIcon::NORMAL:
return QIcon::fromTheme(QLatin1String("qbittorrent-tray"));
case TrayIcon::MONO_DARK:
@@ -2008,7 +2112,8 @@ QIcon MainWindow::getSystrayIcon() const
break;
}
#else
switch (style) {
switch (style)
{
case TrayIcon::NORMAL:
return UIThemeManager::instance()->getIcon(QLatin1String("qbittorrent-tray"));
case TrayIcon::MONO_DARK:
@@ -2057,7 +2162,8 @@ void MainWindow::installPython()
void MainWindow::pythonDownloadFinished(const Net::DownloadResult &result)
{
if (result.status != Net::DownloadStatus::Success) {
if (result.status != Net::DownloadStatus::Success)
{
setCursor(QCursor(Qt::ArrowCursor));
QMessageBox::warning(
this, tr("Download error")
@@ -2084,7 +2190,8 @@ void MainWindow::pythonDownloadFinished(const Net::DownloadResult &result)
Utils::Fs::forceRemove(result.filePath + ".exe");
// Reload search engine
if (Utils::ForeignApps::pythonInfo().isSupportedVersion()) {
if (Utils::ForeignApps::pythonInfo().isSupportedVersion())
{
m_ui->actionSearchWidget->setChecked(true);
displaySearchTab(true);
}

View File

@@ -84,7 +84,8 @@ namespace
QString languageToLocalizedString(const QLocale &locale)
{
switch (locale.language()) {
switch (locale.language())
{
case QLocale::Arabic: return QString::fromUtf8(C_LOCALE_ARABIC);
case QLocale::Armenian: return QString::fromUtf8(C_LOCALE_ARMENIAN);
case QLocale::Basque: return QString::fromUtf8(C_LOCALE_BASQUE);
@@ -92,7 +93,8 @@ namespace
case QLocale::Byelorussian: return QString::fromUtf8(C_LOCALE_BYELORUSSIAN);
case QLocale::Catalan: return QString::fromUtf8(C_LOCALE_CATALAN);
case QLocale::Chinese:
switch (locale.country()) {
switch (locale.country())
{
case QLocale::China: return QString::fromUtf8(C_LOCALE_CHINESE_SIMPLIFIED);
case QLocale::HongKong: return QString::fromUtf8(C_LOCALE_CHINESE_TRADITIONAL_HK);
default: return QString::fromUtf8(C_LOCALE_CHINESE_TRADITIONAL_TW);
@@ -102,7 +104,8 @@ namespace
case QLocale::Danish: return QString::fromUtf8(C_LOCALE_DANISH);
case QLocale::Dutch: return QString::fromUtf8(C_LOCALE_DUTCH);
case QLocale::English:
switch (locale.country()) {
switch (locale.country())
{
case QLocale::Australia: return QString::fromUtf8(C_LOCALE_ENGLISH_AUSTRALIA);
case QLocale::UnitedKingdom: return QString::fromUtf8(C_LOCALE_ENGLISH_UNITEDKINGDOM);
default: return QString::fromUtf8(C_LOCALE_ENGLISH);
@@ -195,7 +198,8 @@ OptionsDialog::OptionsDialog(QWidget *parent)
int maxHeight = -1;
for (int i = 0; i < m_ui->tabSelection->count(); ++i)
maxHeight = std::max(maxHeight, m_ui->tabSelection->visualItemRect(m_ui->tabSelection->item(i)).size().height());
for (int i = 0; i < m_ui->tabSelection->count(); ++i) {
for (int i = 0; i < m_ui->tabSelection->count(); ++i)
{
const QSize size(std::numeric_limits<int>::max(), static_cast<int>(maxHeight * 1.2));
m_ui->tabSelection->item(i)->setSizeHint(size);
}
@@ -225,8 +229,10 @@ OptionsDialog::OptionsDialog(QWidget *parent)
m_ui->hsplitter->setCollapsible(1, false);
// Get apply button in button box
const QList<QAbstractButton *> buttons = m_ui->buttonBox->buttons();
for (QAbstractButton *button : buttons) {
if (m_ui->buttonBox->buttonRole(button) == QDialogButtonBox::ApplyRole) {
for (QAbstractButton *button : buttons)
{
if (m_ui->buttonBox->buttonRole(button) == QDialogButtonBox::ApplyRole)
{
m_applyButton = button;
break;
}
@@ -263,7 +269,8 @@ OptionsDialog::OptionsDialog(QWidget *parent)
m_ui->checkShowSystray->setVisible(false);
#else
// Disable systray integration if it is not supported by the system
if (!QSystemTrayIcon::isSystemTrayAvailable()) {
if (!QSystemTrayIcon::isSystemTrayAvailable())
{
m_ui->checkShowSystray->setChecked(false);
m_ui->checkShowSystray->setEnabled(false);
m_ui->labelTrayIconStyle->setVisible(false);
@@ -567,19 +574,23 @@ void OptionsDialog::initializeLanguageCombo()
// List language files
const QDir langDir(":/lang");
const QStringList langFiles = langDir.entryList(QStringList("qbittorrent_*.qm"), QDir::Files);
for (const QString &langFile : langFiles) {
for (const QString &langFile : langFiles)
{
QString localeStr = langFile.mid(12); // remove "qbittorrent_"
localeStr.chop(3); // Remove ".qm"
QString languageName;
if (localeStr.startsWith("eo", Qt::CaseInsensitive)) {
if (localeStr.startsWith("eo", Qt::CaseInsensitive))
{
// QLocale doesn't work with that locale. Esperanto isn't a "real" language.
languageName = QString::fromUtf8(C_LOCALE_ESPERANTO);
}
else if (localeStr.startsWith("ltg", Qt::CaseInsensitive)) {
else if (localeStr.startsWith("ltg", Qt::CaseInsensitive))
{
// QLocale doesn't work with that locale.
languageName = QString::fromUtf8(C_LOCALE_LATGALIAN);
}
else {
else
{
QLocale locale(localeStr);
languageName = languageToLocalizedString(locale);
}
@@ -634,7 +645,8 @@ void OptionsDialog::saveWindowState() const
pref->setPrefSize(size());
// Splitter size
const QStringList sizesStr = {
const QStringList sizesStr =
{
QString::number(m_ui->hsplitter->sizes().first()),
QString::number(m_ui->hsplitter->sizes().last())
};
@@ -647,7 +659,8 @@ void OptionsDialog::saveOptions()
Preferences *const pref = Preferences::instance();
// Load the translation
QString locale = getLocale();
if (pref->getLocale() != locale) {
if (pref->getLocale() != locale)
{
auto *translator = new QTranslator;
if (translator->load(QLatin1String(":/lang/qbittorrent_") + locale))
qDebug("%s locale recognized, using translation.", qUtf8Printable(locale));
@@ -689,12 +702,14 @@ void OptionsDialog::saveOptions()
Preferences::setMagnetLinkAssoc(m_ui->checkAssociateMagnetLinks->isChecked());
#endif
#ifdef Q_OS_MACOS
if (m_ui->checkAssociateTorrents->isChecked()) {
if (m_ui->checkAssociateTorrents->isChecked())
{
Preferences::setTorrentFileAssoc();
m_ui->checkAssociateTorrents->setChecked(Preferences::isTorrentFileAssocSet());
m_ui->checkAssociateTorrents->setEnabled(!m_ui->checkAssociateTorrents->isChecked());
}
if (m_ui->checkAssociateMagnetLinks->isChecked()) {
if (m_ui->checkAssociateMagnetLinks->isChecked())
{
Preferences::setMagnetLinkAssoc();
m_ui->checkAssociateMagnetLinks->setChecked(Preferences::isMagnetLinkAssocSet());
m_ui->checkAssociateMagnetLinks->setEnabled(!m_ui->checkAssociateMagnetLinks->isChecked());
@@ -810,7 +825,8 @@ void OptionsDialog::saveOptions()
session->setGlobalMaxRatio(getMaxRatio());
session->setGlobalMaxSeedingMinutes(getMaxSeedingMinutes());
const QVector<MaxRatioAction> actIndex = {
const QVector<MaxRatioAction> actIndex =
{
Pause,
Remove,
DeleteFiles,
@@ -837,7 +853,8 @@ void OptionsDialog::saveOptions()
// End Queueing system preferences
// Web UI
pref->setWebUiEnabled(isWebUiEnabled());
if (isWebUiEnabled()) {
if (isWebUiEnabled())
{
pref->setServerDomains(m_ui->textServerDomains->text());
pref->setWebUiAddress(m_ui->textWebUiAddress->text());
pref->setWebUiPort(m_ui->spinWebUiPort->value());
@@ -888,7 +905,8 @@ bool OptionsDialog::isIPFilteringEnabled() const
Net::ProxyType OptionsDialog::getProxyType() const
{
switch (m_ui->comboProxyType->currentIndex()) {
switch (m_ui->comboProxyType->currentIndex())
{
case 1:
return Net::ProxyType::SOCKS4;
case 2:
@@ -927,7 +945,8 @@ void OptionsDialog::loadOptions()
#ifndef Q_OS_MACOS
m_ui->checkShowSystray->setChecked(pref->systrayIntegration());
if (m_ui->checkShowSystray->isChecked()) {
if (m_ui->checkShowSystray->isChecked())
{
m_ui->checkMinimizeToSysTray->setChecked(pref->minimizeToTray());
m_ui->checkCloseToSystray->setChecked(pref->closeToTray());
m_ui->comboTrayIcon->setCurrentIndex(pref->trayIconStyle());
@@ -1001,12 +1020,14 @@ void OptionsDialog::loadOptions()
m_ui->checkRecursiveDownload->setChecked(!pref->recursiveDownloadDisabled());
strValue = session->torrentExportDirectory();
if (strValue.isEmpty()) {
if (strValue.isEmpty())
{
// Disable
m_ui->checkExportDir->setChecked(false);
m_ui->textExportDir->setEnabled(false);
}
else {
else
{
// Enable
m_ui->checkExportDir->setChecked(true);
m_ui->textExportDir->setEnabled(true);
@@ -1014,12 +1035,14 @@ void OptionsDialog::loadOptions()
}
strValue = session->finishedTorrentExportDirectory();
if (strValue.isEmpty()) {
if (strValue.isEmpty())
{
// Disable
m_ui->checkExportDirFin->setChecked(false);
m_ui->textExportDirFin->setEnabled(false);
}
else {
else
{
// Enable
m_ui->checkExportDirFin->setChecked(true);
m_ui->textExportDirFin->setEnabled(true);
@@ -1060,49 +1083,57 @@ void OptionsDialog::loadOptions()
m_ui->spinPort->setDisabled(m_ui->checkRandomPort->isChecked());
intValue = session->maxConnections();
if (intValue > 0) {
if (intValue > 0)
{
// enable
m_ui->checkMaxConnecs->setChecked(true);
m_ui->spinMaxConnec->setEnabled(true);
m_ui->spinMaxConnec->setValue(intValue);
}
else {
else
{
// disable
m_ui->checkMaxConnecs->setChecked(false);
m_ui->spinMaxConnec->setEnabled(false);
}
intValue = session->maxConnectionsPerTorrent();
if (intValue > 0) {
if (intValue > 0)
{
// enable
m_ui->checkMaxConnecsPerTorrent->setChecked(true);
m_ui->spinMaxConnecPerTorrent->setEnabled(true);
m_ui->spinMaxConnecPerTorrent->setValue(intValue);
}
else {
else
{
// disable
m_ui->checkMaxConnecsPerTorrent->setChecked(false);
m_ui->spinMaxConnecPerTorrent->setEnabled(false);
}
intValue = session->maxUploads();
if (intValue > 0) {
if (intValue > 0)
{
// enable
m_ui->checkMaxUploads->setChecked(true);
m_ui->spinMaxUploads->setEnabled(true);
m_ui->spinMaxUploads->setValue(intValue);
}
else {
else
{
// disable
m_ui->checkMaxUploads->setChecked(false);
m_ui->spinMaxUploads->setEnabled(false);
}
intValue = session->maxUploadsPerTorrent();
if (intValue > 0) {
if (intValue > 0)
{
// enable
m_ui->checkMaxUploadsPerTorrent->setChecked(true);
m_ui->spinMaxUploadsPerTorrent->setEnabled(true);
m_ui->spinMaxUploadsPerTorrent->setValue(intValue);
}
else {
else
{
// disable
m_ui->checkMaxUploadsPerTorrent->setChecked(false);
m_ui->spinMaxUploadsPerTorrent->setEnabled(false);
@@ -1112,7 +1143,8 @@ void OptionsDialog::loadOptions()
Net::ProxyConfiguration proxyConf = proxyConfigManager->proxyConfiguration();
using Net::ProxyType;
bool useProxyAuth = false;
switch (proxyConf.type) {
switch (proxyConf.type)
{
case ProxyType::SOCKS4:
m_ui->comboProxyType->setCurrentIndex(1);
break;
@@ -1185,32 +1217,37 @@ void OptionsDialog::loadOptions()
m_ui->spinUploadRateForSlowTorrents->setValue(session->uploadRateForSlowTorrents());
m_ui->spinSlowTorrentsInactivityTimer->setValue(session->slowTorrentsInactivityTimer());
if (session->globalMaxRatio() >= 0.) {
if (session->globalMaxRatio() >= 0.)
{
// Enable
m_ui->checkMaxRatio->setChecked(true);
m_ui->spinMaxRatio->setEnabled(true);
m_ui->comboRatioLimitAct->setEnabled(true);
m_ui->spinMaxRatio->setValue(session->globalMaxRatio());
}
else {
else
{
// Disable
m_ui->checkMaxRatio->setChecked(false);
m_ui->spinMaxRatio->setEnabled(false);
}
if (session->globalMaxSeedingMinutes() >= 0) {
if (session->globalMaxSeedingMinutes() >= 0)
{
// Enable
m_ui->checkMaxSeedingMinutes->setChecked(true);
m_ui->spinMaxSeedingMinutes->setEnabled(true);
m_ui->spinMaxSeedingMinutes->setValue(session->globalMaxSeedingMinutes());
}
else {
else
{
// Disable
m_ui->checkMaxSeedingMinutes->setChecked(false);
m_ui->spinMaxSeedingMinutes->setEnabled(false);
}
m_ui->comboRatioLimitAct->setEnabled((session->globalMaxSeedingMinutes() >= 0) || (session->globalMaxRatio() >= 0.));
const QHash<MaxRatioAction, int> actIndex = {
const QHash<MaxRatioAction, int> actIndex =
{
{Pause, 0},
{Remove, 1},
{DeleteFiles, 2},
@@ -1386,16 +1423,20 @@ int OptionsDialog::getMaxUploadsPerTorrent() const
void OptionsDialog::on_buttonBox_accepted()
{
if (m_applyButton->isEnabled()) {
if (!schedTimesOk()) {
if (m_applyButton->isEnabled())
{
if (!schedTimesOk())
{
m_ui->tabSelection->setCurrentRow(TAB_SPEED);
return;
}
if (!webUIAuthenticationOk()) {
if (!webUIAuthenticationOk())
{
m_ui->tabSelection->setCurrentRow(TAB_WEBUI);
return;
}
if (!isAlternativeWebUIPathValid()) {
if (!isAlternativeWebUIPathValid())
{
m_ui->tabSelection->setCurrentRow(TAB_WEBUI);
return;
}
@@ -1409,16 +1450,20 @@ void OptionsDialog::on_buttonBox_accepted()
void OptionsDialog::applySettings(QAbstractButton *button)
{
if (button == m_applyButton) {
if (!schedTimesOk()) {
if (button == m_applyButton)
{
if (!schedTimesOk())
{
m_ui->tabSelection->setCurrentRow(TAB_SPEED);
return;
}
if (!webUIAuthenticationOk()) {
if (!webUIAuthenticationOk())
{
m_ui->tabSelection->setCurrentRow(TAB_WEBUI);
return;
}
if (!isAlternativeWebUIPathValid()) {
if (!isAlternativeWebUIPathValid())
{
m_ui->tabSelection->setCurrentRow(TAB_WEBUI);
return;
}
@@ -1456,24 +1501,28 @@ void OptionsDialog::toggleComboRatioLimitAct()
void OptionsDialog::enableProxy(const int index)
{
if (index >= 1) { // Any proxy type is used
if (index >= 1)
{ // Any proxy type is used
//enable
m_ui->lblProxyIP->setEnabled(true);
m_ui->textProxyIP->setEnabled(true);
m_ui->lblProxyPort->setEnabled(true);
m_ui->spinProxyPort->setEnabled(true);
m_ui->checkProxyPeerConnecs->setEnabled(true);
if (index >= 2) { // SOCKS5 or HTTP
if (index >= 2)
{ // SOCKS5 or HTTP
m_ui->checkProxyAuth->setEnabled(true);
m_ui->isProxyOnlyForTorrents->setEnabled(true);
}
else {
else
{
m_ui->checkProxyAuth->setEnabled(false);
m_ui->isProxyOnlyForTorrents->setEnabled(false);
m_ui->isProxyOnlyForTorrents->setChecked(true);
}
}
else { // No proxy
else
{ // No proxy
// disable
m_ui->lblProxyIP->setEnabled(false);
m_ui->textProxyIP->setEnabled(false);
@@ -1550,13 +1599,16 @@ QString OptionsDialog::getLocale() const
void OptionsDialog::setLocale(const QString &localeStr)
{
QString name;
if (localeStr.startsWith("eo", Qt::CaseInsensitive)) {
if (localeStr.startsWith("eo", Qt::CaseInsensitive))
{
name = "eo";
}
else if (localeStr.startsWith("ltg", Qt::CaseInsensitive)) {
else if (localeStr.startsWith("ltg", Qt::CaseInsensitive))
{
name = "ltg";
}
else {
else
{
QLocale locale(localeStr);
if (locale.language() == QLocale::Uzbek)
name = "uz@Latn";
@@ -1565,15 +1617,18 @@ void OptionsDialog::setLocale(const QString &localeStr)
}
// Attempt to find exact match
int index = m_ui->comboI18n->findData(name, Qt::UserRole);
if (index < 0) {
if (index < 0)
{
//Attempt to find a language match without a country
int pos = name.indexOf('_');
if (pos > -1) {
if (pos > -1)
{
QString lang = name.left(pos);
index = m_ui->comboI18n->findData(lang, Qt::UserRole);
}
}
if (index < 0) {
if (index < 0)
{
// Unrecognized, use US English
index = m_ui->comboI18n->findData("en", Qt::UserRole);
Q_ASSERT(index >= 0);
@@ -1616,10 +1671,12 @@ void OptionsDialog::on_addScanFolderButton_clicked()
Preferences *const pref = Preferences::instance();
const QString dir = QFileDialog::getExistingDirectory(this, tr("Select folder to monitor"),
Utils::Fs::toNativePath(Utils::Fs::folderName(pref->getScanDirsLastPath())));
if (!dir.isEmpty()) {
if (!dir.isEmpty())
{
const ScanFoldersModel::PathStatus status = ScanFoldersModel::instance()->addPath(dir, ScanFoldersModel::DEFAULT_LOCATION, QString(), false);
QString error;
switch (status) {
switch (status)
{
case ScanFoldersModel::AlreadyInList:
error = tr("Folder is already being monitored:");
break;
@@ -1649,7 +1706,8 @@ void OptionsDialog::on_removeScanFolderButton_clicked()
if (selected.isEmpty())
return;
Q_ASSERT(selected.count() == ScanFoldersModel::instance()->columnCount());
for (const QModelIndex &index : selected) {
for (const QModelIndex &index : selected)
{
if (index.column() == ScanFoldersModel::WATCH)
m_removedScanDirs << index.data().toString();
}
@@ -1704,13 +1762,15 @@ void OptionsDialog::webUIHttpsCertChanged(const QString &path, const ShowError s
return;
QFile file(path);
if (!file.open(QIODevice::ReadOnly)) {
if (!file.open(QIODevice::ReadOnly))
{
if (showError == ShowError::Show)
QMessageBox::warning(this, tr("Invalid path"), file.errorString());
return;
}
if (!Utils::Net::isSSLCertificatesValid(file.read(Utils::Net::MAX_SSL_FILE_SIZE))) {
if (!Utils::Net::isSSLCertificatesValid(file.read(Utils::Net::MAX_SSL_FILE_SIZE)))
{
if (showError == ShowError::Show)
QMessageBox::warning(this, tr("Invalid certificate"), tr("This is not a valid SSL certificate."));
return;
@@ -1728,13 +1788,15 @@ void OptionsDialog::webUIHttpsKeyChanged(const QString &path, const ShowError sh
return;
QFile file(path);
if (!file.open(QIODevice::ReadOnly)) {
if (!file.open(QIODevice::ReadOnly))
{
if (showError == ShowError::Show)
QMessageBox::warning(this, tr("Invalid path"), file.errorString());
return;
}
if (!Utils::Net::isSSLKeyValid(file.read(Utils::Net::MAX_SSL_FILE_SIZE))) {
if (!Utils::Net::isSSLKeyValid(file.read(Utils::Net::MAX_SSL_FILE_SIZE)))
{
if (showError == ShowError::Show)
QMessageBox::warning(this, tr("Invalid key"), tr("This is not a valid SSL key."));
return;
@@ -1779,7 +1841,8 @@ void OptionsDialog::handleIPFilterParsed(bool error, int ruleCount)
bool OptionsDialog::schedTimesOk()
{
if (m_ui->timeEditScheduleFrom->time() == m_ui->timeEditScheduleTo->time()) {
if (m_ui->timeEditScheduleFrom->time() == m_ui->timeEditScheduleTo->time())
{
QMessageBox::warning(this, tr("Time Error"), tr("The start time and the end time can't be the same."));
return false;
}
@@ -1788,11 +1851,13 @@ bool OptionsDialog::schedTimesOk()
bool OptionsDialog::webUIAuthenticationOk()
{
if (webUiUsername().length() < 3) {
if (webUiUsername().length() < 3)
{
QMessageBox::warning(this, tr("Length Error"), tr("The Web UI username must be at least 3 characters long."));
return false;
}
if (!webUiPassword().isEmpty() && (webUiPassword().length() < 6)) {
if (!webUiPassword().isEmpty() && (webUiPassword().length() < 6))
{
QMessageBox::warning(this, tr("Length Error"), tr("The Web UI password must be at least 6 characters long."));
return false;
}
@@ -1801,7 +1866,8 @@ bool OptionsDialog::webUIAuthenticationOk()
bool OptionsDialog::isAlternativeWebUIPathValid()
{
if (m_ui->groupAltWebUI->isChecked() && m_ui->textWebUIRootFolder->selectedPath().trimmed().isEmpty()) {
if (m_ui->groupAltWebUI->isChecked() && m_ui->textWebUIRootFolder->selectedPath().trimmed().isEmpty())
{
QMessageBox::warning(this, tr("Location Error"), tr("The alternative Web UI files location cannot be blank."));
return false;
}

View File

@@ -54,12 +54,14 @@ void PreviewListDelegate::paint(QPainter *painter, const QStyleOptionViewItem &o
QStyleOptionViewItem opt = QItemDelegate::setOptions(index, option);
drawBackground(painter, opt, index);
switch (index.column()) {
switch (index.column())
{
case PreviewSelectDialog::SIZE:
QItemDelegate::drawDisplay(painter, opt, option.rect, Utils::Misc::friendlyUnit(index.data().toLongLong()));
break;
case PreviewSelectDialog::PROGRESS: {
case PreviewSelectDialog::PROGRESS:
{
const qreal progress = (index.data().toReal() * 100);
QStyleOptionProgressBar newopt;

View File

@@ -86,12 +86,14 @@ PreviewSelectDialog::PreviewSelectDialog(QWidget *parent, const BitTorrent::Torr
// Fill list in
const QVector<qreal> fp = torrent->filesProgress();
int nbFiles = torrent->filesCount();
for (int i = 0; i < nbFiles; ++i) {
for (int i = 0; i < nbFiles; ++i)
{
QString fileName = torrent->fileName(i);
if (fileName.endsWith(QB_EXT))
fileName.chop(4);
QString extension = Utils::Fs::fileExtension(fileName).toUpper();
if (Utils::Misc::isPreviewable(extension)) {
if (Utils::Misc::isPreviewable(extension))
{
int row = m_previewListModel->rowCount();
m_previewListModel->insertRow(row);
m_previewListModel->setData(m_previewListModel->index(row, NAME), fileName);
@@ -128,7 +130,8 @@ void PreviewSelectDialog::previewButtonClicked()
// Only one file should be selected
const QString path = absolutePaths.at(selectedIndexes.at(0).data().toInt());
// File
if (!QFile::exists(path)) {
if (!QFile::exists(path))
{
const bool isSingleFile = (m_previewListModel->rowCount() == 1);
QWidget *parent = isSingleFile ? this->parentWidget() : this;
QMessageBox::critical(parent, tr("Preview impossible")
@@ -156,7 +159,8 @@ void PreviewSelectDialog::loadWindowState()
Utils::Gui::resize(this, m_storeDialogSize);
// Restore TreeView Header state
if (!m_storeTreeHeaderState.value().isEmpty()) {
if (!m_storeTreeHeaderState.value().isEmpty())
{
m_headerStateInitialized = m_ui->previewList->header()->restoreState(m_storeTreeHeaderState);
}
}
@@ -164,14 +168,16 @@ void PreviewSelectDialog::loadWindowState()
void PreviewSelectDialog::showEvent(QShowEvent *event)
{
// event originated from system
if (event->spontaneous()) {
if (event->spontaneous())
{
QDialog::showEvent(event);
return;
}
// Default size, have to be called after show(), because width is needed
// Set Name column width to 60% of TreeView
if (!m_headerStateInitialized) {
if (!m_headerStateInitialized)
{
const int nameSize = (m_ui->previewList->size().width() * 0.6);
m_ui->previewList->header()->resizeSection(0, nameSize);
m_headerStateInitialized = true;

View File

@@ -70,7 +70,8 @@ void ProgramUpdater::checkForUpdates()
void ProgramUpdater::rssDownloadFinished(const Net::DownloadResult &result)
{
if (result.status != Net::DownloadStatus::Success) {
if (result.status != Net::DownloadStatus::Success)
{
qDebug() << "Downloading the new qBittorrent updates RSS failed:" << result.errorString;
emit updateCheckFinished(false, QString(), m_invokedByUser);
return;
@@ -81,7 +82,8 @@ void ProgramUpdater::rssDownloadFinished(const Net::DownloadResult &result)
#ifdef Q_OS_MACOS
const QString OS_TYPE {"Mac OS X"};
#elif defined(Q_OS_WIN)
const QString OS_TYPE {(::IsWindows7OrGreater()
const QString OS_TYPE
{(::IsWindows7OrGreater()
&& QSysInfo::currentCpuArchitecture().endsWith("64"))
? "Windows x64" : "Windows"};
#endif
@@ -92,10 +94,12 @@ void ProgramUpdater::rssDownloadFinished(const Net::DownloadResult &result)
QString updateLink;
QString type;
while (!xml.atEnd()) {
while (!xml.atEnd())
{
xml.readNext();
if (xml.isStartElement()) {
if (xml.isStartElement())
{
if (xml.name() == "item")
inItem = true;
else if (inItem && xml.name() == "link")
@@ -105,11 +109,15 @@ void ProgramUpdater::rssDownloadFinished(const Net::DownloadResult &result)
else if (inItem && xml.name() == "version")
version = getStringValue(xml);
}
else if (xml.isEndElement()) {
if (inItem && xml.name() == "item") {
if (type.compare(OS_TYPE, Qt::CaseInsensitive) == 0) {
else if (xml.isEndElement())
{
if (inItem && xml.name() == "item")
{
if (type.compare(OS_TYPE, Qt::CaseInsensitive) == 0)
{
qDebug("The last update available is %s", qUtf8Printable(version));
if (!version.isEmpty()) {
if (!version.isEmpty())
{
qDebug("Detected version is %s", qUtf8Printable(version));
if (isVersionMoreRecent(version))
m_updateUrl = updateLink;
@@ -138,12 +146,14 @@ void ProgramUpdater::updateProgram()
bool ProgramUpdater::isVersionMoreRecent(const QString &remoteVersion) const
{
const QRegularExpressionMatch regVerMatch = QRegularExpression("([0-9.]+)").match(QBT_VERSION);
if (regVerMatch.hasMatch()) {
if (regVerMatch.hasMatch())
{
const QString localVersion = regVerMatch.captured(1);
const QVector<QStringRef> remoteParts = remoteVersion.splitRef('.');
const QVector<QStringRef> localParts = localVersion.splitRef('.');
for (int i = 0; i < qMin(remoteParts.size(), localParts.size()); ++i) {
for (int i = 0; i < qMin(remoteParts.size(), localParts.size()); ++i)
{
if (remoteParts[i].toInt() > localParts[i].toInt())
return true;
if (remoteParts[i].toInt() < localParts[i].toInt())

View File

@@ -59,7 +59,8 @@ QVector<float> DownloadedPiecesBar::bitfieldToFloatVector(const QBitArray &vecin
// image.x(0) = pieces.x(0.0 >= x < 1.7)
// image.x(1) = pieces.x(1.7 >= x < 3.4)
for (int x = 0; x < reqSize; ++x) {
for (int x = 0; x < reqSize; ++x)
{
// R - real
const float fromR = x * ratio;
const float toR = (x + 1) * ratio;
@@ -80,15 +81,18 @@ QVector<float> DownloadedPiecesBar::bitfieldToFloatVector(const QBitArray &vecin
float value = 0;
// case when calculated range is (15.2 >= x < 15.7)
if (x2 == toCMinusOne) {
if (x2 == toCMinusOne)
{
if (vecin[x2])
value += ratio;
++x2;
}
// case when (15.2 >= x < 17.8)
else {
else
{
// subcase (15.2 >= x < 16)
if (x2 != fromR) {
if (x2 != fromR)
{
if (vecin[x2])
value += 1.0 - (fromR - fromC);
++x2;
@@ -100,7 +104,8 @@ QVector<float> DownloadedPiecesBar::bitfieldToFloatVector(const QBitArray &vecin
value += 1.0;
// subcase (17 >= x < 17.8)
if (x2 == toCMinusOne) {
if (x2 == toCMinusOne)
{
if (vecin[x2])
value += 1.0 - (toC - toR);
++x2;
@@ -123,12 +128,14 @@ bool DownloadedPiecesBar::updateImage(QImage &image)
{
// qDebug() << "updateImage";
QImage image2(width() - 2 * borderWidth, 1, QImage::Format_RGB888);
if (image2.isNull()) {
if (image2.isNull())
{
qDebug() << "QImage image2() allocation failed, width():" << width();
return false;
}
if (m_pieces.isEmpty()) {
if (m_pieces.isEmpty())
{
image2.fill(backgroundColor());
image = image2;
return true;
@@ -138,10 +145,12 @@ bool DownloadedPiecesBar::updateImage(QImage &image)
QVector<float> scaledPiecesDl = bitfieldToFloatVector(m_downloadedPieces, image2.width());
// filling image
for (int x = 0; x < scaledPieces.size(); ++x) {
for (int x = 0; x < scaledPieces.size(); ++x)
{
float piecesToValue = scaledPieces.at(x);
float piecesToValueDl = scaledPiecesDl.at(x);
if (piecesToValueDl != 0) {
if (piecesToValueDl != 0)
{
float fillRatio = piecesToValue + piecesToValueDl;
float ratio = piecesToValueDl / fillRatio;
@@ -150,7 +159,8 @@ bool DownloadedPiecesBar::updateImage(QImage &image)
image2.setPixel(x, 0, mixedColor);
}
else {
else
{
image2.setPixel(x, 0, pieceColors()[piecesToValue * 255]);
}
}

View File

@@ -39,9 +39,11 @@ PeerListSortModel::PeerListSortModel(QObject *parent)
bool PeerListSortModel::lessThan(const QModelIndex &left, const QModelIndex &right) const
{
switch (sortColumn()) {
switch (sortColumn())
{
case PeerListWidget::IP:
case PeerListWidget::CLIENT: {
case PeerListWidget::CLIENT:
{
const QString strL = left.data(UnderlyingDataRole).toString();
const QString strR = right.data(UnderlyingDataRole).toString();
const int result = Utils::String::naturalCompare(strL, strR, Qt::CaseInsensitive);

View File

@@ -126,8 +126,10 @@ PeerListWidget::PeerListWidget(PropertiesWidget *parent)
hideColumn(PeerListColumns::COUNTRY);
// Ensure that at least one column is visible at all times
bool atLeastOne = false;
for (int i = 0; i < PeerListColumns::IP_HIDDEN; ++i) {
if (!isColumnHidden(i)) {
for (int i = 0; i < PeerListColumns::IP_HIDDEN; ++i)
{
if (!isColumnHidden(i))
{
atLeastOne = true;
break;
}
@@ -137,7 +139,8 @@ PeerListWidget::PeerListWidget(PropertiesWidget *parent)
// To also mitigate the above issue, we have to resize each column when
// its size is 0, because explicitly 'showing' the column isn't enough
// in the above scenario.
for (int i = 0; i < PeerListColumns::IP_HIDDEN; ++i) {
for (int i = 0; i < PeerListColumns::IP_HIDDEN; ++i)
{
if ((columnWidth(i) <= 0) && !isColumnHidden(i))
resizeColumnToContents(i);
}
@@ -178,7 +181,8 @@ void PeerListWidget::displayToggleColumnsMenu(const QPoint &)
menu->setAttribute(Qt::WA_DeleteOnClose);
menu->setTitle(tr("Column visibility"));
for (int i = 0; i < PeerListColumns::IP_HIDDEN; ++i) {
for (int i = 0; i < PeerListColumns::IP_HIDDEN; ++i)
{
if ((i == PeerListColumns::COUNTRY) && !Preferences::instance()->resolvePeerCountries())
continue;
@@ -191,7 +195,8 @@ void PeerListWidget::displayToggleColumnsMenu(const QPoint &)
connect(menu, &QMenu::triggered, this, [this](const QAction *action)
{
int visibleCols = 0;
for (int i = 0; i < PeerListColumns::IP_HIDDEN; ++i) {
for (int i = 0; i < PeerListColumns::IP_HIDDEN; ++i)
{
if (!isColumnHidden(i))
++visibleCols;
@@ -217,14 +222,17 @@ void PeerListWidget::displayToggleColumnsMenu(const QPoint &)
void PeerListWidget::updatePeerHostNameResolutionState()
{
if (Preferences::instance()->resolvePeerHostNames()) {
if (!m_resolver) {
if (Preferences::instance()->resolvePeerHostNames())
{
if (!m_resolver)
{
m_resolver = new Net::ReverseResolution(this);
connect(m_resolver, &Net::ReverseResolution::ipResolved, this, &PeerListWidget::handleResolved);
loadPeers(m_properties->getCurrentTorrent());
}
}
else {
else
{
delete m_resolver;
m_resolver = nullptr;
}
@@ -237,13 +245,15 @@ void PeerListWidget::updatePeerCountryResolutionState()
return;
m_resolveCountries = resolveCountries;
if (m_resolveCountries) {
if (m_resolveCountries)
{
loadPeers(m_properties->getCurrentTorrent());
showColumn(PeerListColumns::COUNTRY);
if (columnWidth(PeerListColumns::COUNTRY) <= 0)
resizeColumnToContents(PeerListColumns::COUNTRY);
}
else {
else
{
hideColumn(PeerListColumns::COUNTRY);
}
}
@@ -258,7 +268,8 @@ void PeerListWidget::showPeerListMenu(const QPoint &)
// Add Peer Action
// Do not allow user to add peers in a private torrent
if (!torrent->isQueued() && !torrent->isChecking() && !torrent->isPrivate()) {
if (!torrent->isQueued() && !torrent->isChecking() && !torrent->isPrivate())
{
const QAction *addPeerAct = menu->addAction(UIThemeManager::instance()->getIcon("user-group-new"), tr("Add a new peer..."));
connect(addPeerAct, &QAction::triggered, this, [this, torrent]()
{
@@ -274,7 +285,8 @@ void PeerListWidget::showPeerListMenu(const QPoint &)
});
}
if (!selectionModel()->selectedRows().isEmpty()) {
if (!selectionModel()->selectedRows().isEmpty())
{
const QAction *copyPeerAct = menu->addAction(UIThemeManager::instance()->getIcon("edit-copy"), tr("Copy IP:port"));
connect(copyPeerAct, &QAction::triggered, this, &PeerListWidget::copySelectedPeers);
@@ -298,7 +310,8 @@ void PeerListWidget::banSelectedPeers()
QVector<QString> selectedIPs;
selectedIPs.reserve(selectedIndexes.size());
for (const QModelIndex &index : selectedIndexes) {
for (const QModelIndex &index : selectedIndexes)
{
const int row = m_proxyModel->mapToSource(index).row();
const QString ip = m_listModel->item(row, PeerListColumns::IP_HIDDEN)->text();
selectedIPs += ip;
@@ -309,7 +322,8 @@ void PeerListWidget::banSelectedPeers()
, tr("Are you sure you want to permanently ban the selected peers?"));
if (btn != QMessageBox::Yes) return;
for (const QString &ip : selectedIPs) {
for (const QString &ip : selectedIPs)
{
BitTorrent::Session::instance()->banIP(ip);
LogMsg(tr("Peer \"%1\" is manually banned").arg(ip));
}
@@ -322,7 +336,8 @@ void PeerListWidget::copySelectedPeers()
const QModelIndexList selectedIndexes = selectionModel()->selectedRows();
QStringList selectedPeers;
for (const QModelIndex &index : selectedIndexes) {
for (const QModelIndex &index : selectedIndexes)
{
const int row = m_proxyModel->mapToSource(index).row();
const QString ip = m_listModel->item(row, PeerListColumns::IP_HIDDEN)->text();
const QString port = m_listModel->item(row, PeerListColumns::PORT)->text();
@@ -364,19 +379,22 @@ void PeerListWidget::loadPeers(const BitTorrent::TorrentHandle *torrent)
for (auto i = m_peerItems.cbegin(); i != m_peerItems.cend(); ++i)
existingPeers << i.key();
for (const BitTorrent::PeerInfo &peer : peers) {
for (const BitTorrent::PeerInfo &peer : peers)
{
if (peer.address().ip.isNull()) continue;
bool isNewPeer = false;
updatePeer(torrent, peer, isNewPeer);
if (!isNewPeer) {
if (!isNewPeer)
{
const PeerEndpoint peerEndpoint {peer.address(), peer.connectionType()};
existingPeers.remove(peerEndpoint);
}
}
// Remove peers that are gone
for (const PeerEndpoint &peerEndpoint : asConst(existingPeers)) {
for (const PeerEndpoint &peerEndpoint : asConst(existingPeers))
{
QStandardItem *item = m_peerItems.take(peerEndpoint);
QSet<QStandardItem *> &items = m_itemsByIP[peerEndpoint.address.ip];
@@ -411,7 +429,8 @@ void PeerListWidget::updatePeer(const BitTorrent::TorrentHandle *torrent, const
auto itemIter = m_peerItems.find(peerEndpoint);
isNewPeer = (itemIter == m_peerItems.end());
if (isNewPeer) {
if (isNewPeer)
{
// new item
const int row = m_listModel->rowCount();
m_listModel->insertRow(row);
@@ -449,9 +468,11 @@ void PeerListWidget::updatePeer(const BitTorrent::TorrentHandle *torrent, const
if (m_resolver)
m_resolver->resolve(peerEndpoint.address.ip);
if (m_resolveCountries) {
if (m_resolveCountries)
{
const QIcon icon = UIThemeManager::instance()->getFlagIcon(peer.country());
if (!icon.isNull()) {
if (!icon.isNull())
{
m_listModel->setData(m_listModel->index(row, PeerListColumns::COUNTRY), icon, Qt::DecorationRole);
const QString countryName = Net::GeoIPManager::CountryName(peer.country());
m_listModel->setData(m_listModel->index(row, PeerListColumns::COUNTRY), countryName, Qt::ToolTipRole);
@@ -479,7 +500,8 @@ void PeerListWidget::handleSortColumnChanged(const int col)
void PeerListWidget::wheelEvent(QWheelEvent *event)
{
if (event->modifiers() & Qt::ShiftModifier) {
if (event->modifiers() & Qt::ShiftModifier)
{
// Shift + scroll = horizontal scroll
event->accept();

View File

@@ -57,18 +57,22 @@ QVector<BitTorrent::PeerAddress> PeersAdditionDialog::askForPeers(QWidget *paren
void PeersAdditionDialog::validateInput()
{
if (m_ui->textEditPeers->toPlainText().trimmed().isEmpty()) {
if (m_ui->textEditPeers->toPlainText().trimmed().isEmpty())
{
QMessageBox::warning(this, tr("No peer entered"),
tr("Please type at least one peer."),
QMessageBox::Ok);
return;
}
for (const QString &peer : asConst(m_ui->textEditPeers->toPlainText().trimmed().split('\n'))) {
for (const QString &peer : asConst(m_ui->textEditPeers->toPlainText().trimmed().split('\n')))
{
const BitTorrent::PeerAddress addr = BitTorrent::PeerAddress::parse(peer);
if (!addr.ip.isNull()) {
if (!addr.ip.isNull())
{
m_peersList.append(addr);
}
else {
else
{
QMessageBox::warning(this, tr("Invalid peer"),
tr("The peer '%1' is invalid.").arg(peer),
QMessageBox::Ok);

View File

@@ -58,7 +58,8 @@ QVector<float> PieceAvailabilityBar::intToFloatVector(const QVector<int> &vecin,
// image.x(0) = pieces.x(0.0 >= x < 1.7)
// image.x(1) = pieces.x(1.7 >= x < 3.4)
for (int x = 0; x < reqSize; ++x) {
for (int x = 0; x < reqSize; ++x)
{
// R - real
const float fromR = x * ratio;
const float toR = (x + 1) * ratio;
@@ -79,15 +80,18 @@ QVector<float> PieceAvailabilityBar::intToFloatVector(const QVector<int> &vecin,
float value = 0;
// case when calculated range is (15.2 >= x < 15.7)
if (x2 == toCMinusOne) {
if (x2 == toCMinusOne)
{
if (vecin[x2])
value += ratio * vecin[x2];
++x2;
}
// case when (15.2 >= x < 17.8)
else {
else
{
// subcase (15.2 >= x < 16)
if (x2 != fromR) {
if (x2 != fromR)
{
if (vecin[x2])
value += (1.0 - (fromR - fromC)) * vecin[x2];
++x2;
@@ -99,7 +103,8 @@ QVector<float> PieceAvailabilityBar::intToFloatVector(const QVector<int> &vecin,
value += vecin[x2];
// subcase (17 >= x < 17.8)
if (x2 == toCMinusOne) {
if (x2 == toCMinusOne)
{
if (vecin[x2])
value += (1.0 - (toC - toR)) * vecin[x2];
++x2;
@@ -121,12 +126,14 @@ QVector<float> PieceAvailabilityBar::intToFloatVector(const QVector<int> &vecin,
bool PieceAvailabilityBar::updateImage(QImage &image)
{
QImage image2(width() - 2 * borderWidth, 1, QImage::Format_RGB888);
if (image2.isNull()) {
if (image2.isNull())
{
qDebug() << "QImage image2() allocation failed, width():" << width();
return false;
}
if (m_pieces.empty()) {
if (m_pieces.empty())
{
image2.fill(backgroundColor());
image = image2;
return true;
@@ -135,7 +142,8 @@ bool PieceAvailabilityBar::updateImage(QImage &image)
QVector<float> scaledPieces = intToFloatVector(m_pieces, image2.width());
// filling image
for (int x = 0; x < scaledPieces.size(); ++x) {
for (int x = 0; x < scaledPieces.size(); ++x)
{
float piecesToValue = scaledPieces.at(x);
image2.setPixel(x, 0, pieceColors()[piecesToValue * 255]);
}

View File

@@ -53,7 +53,8 @@ namespace
{
public:
PieceIndexToImagePos(const BitTorrent::TorrentInfo &torrentInfo, const QImage &image)
: m_bytesPerPixel {((image.width() > 0) && (torrentInfo.totalSize() >= image.width()))
: m_bytesPerPixel
{((image.width() > 0) && (torrentInfo.totalSize() >= image.width()))
? torrentInfo.totalSize() / image.width() : -1}
, m_torrentInfo {torrentInfo}
{
@@ -133,7 +134,8 @@ void PiecesBar::clear()
bool PiecesBar::event(QEvent *e)
{
if (e->type() == QEvent::ToolTip) {
if (e->type() == QEvent::ToolTip)
{
showToolTip(static_cast<QHelpEvent *>(e));
return true;
}
@@ -167,17 +169,20 @@ void PiecesBar::paintEvent(QPaintEvent *)
{
QPainter painter(this);
QRect imageRect(borderWidth, borderWidth, width() - 2 * borderWidth, height() - 2 * borderWidth);
if (m_image.isNull()) {
if (m_image.isNull())
{
painter.setBrush(backgroundColor());
painter.drawRect(imageRect);
}
else {
else
{
if (m_image.width() != imageRect.width())
updateImage(m_image);
painter.drawImage(imageRect, m_image);
}
if (!m_highlitedRegion.isNull()) {
if (!m_highlitedRegion.isNull())
{
QColor highlightColor {this->palette().color(QPalette::Active, QPalette::Highlight)};
highlightColor.setAlphaF(0.35);
QRect targetHighlightRect {m_highlitedRegion.adjusted(borderWidth, borderWidth, borderWidth, height() - 2 * borderWidth)};
@@ -247,19 +252,23 @@ void PiecesBar::showToolTip(const QHelpEvent *e)
QString toolTipText;
QTextStream stream(&toolTipText, QIODevice::WriteOnly);
const bool showDetailedInformation = QApplication::keyboardModifiers().testFlag(Qt::ShiftModifier);
if (showDetailedInformation && m_torrent->hasMetadata()) {
if (showDetailedInformation && m_torrent->hasMetadata())
{
const int imagePos = e->pos().x() - borderWidth;
if ((imagePos >=0) && (imagePos < m_image.width())) {
if ((imagePos >=0) && (imagePos < m_image.width()))
{
stream << "<html><body>";
PieceIndexToImagePos transform {m_torrent->info(), m_image};
int pieceIndex = transform.pieceIndex(imagePos);
const QVector<int> files {m_torrent->info().fileIndicesForPiece(pieceIndex)};
QString tooltipTitle;
if (files.count() > 1) {
if (files.count() > 1)
{
tooltipTitle = tr("Files in this piece:");
}
else {
else
{
if (m_torrent->info().fileSize(files.front()) == m_torrent->info().pieceLength(pieceIndex))
tooltipTitle = tr("File in this piece");
else
@@ -268,14 +277,16 @@ void PiecesBar::showToolTip(const QHelpEvent *e)
DetailedTooltipRenderer renderer(stream, tooltipTitle);
for (int f : files) {
for (int f : files)
{
const QString filePath {m_torrent->info().filePath(f)};
renderer(Utils::Misc::friendlyUnit(m_torrent->info().fileSize(f)), filePath);
}
stream << "</body></html>";
}
}
else {
else
{
stream << simpleToolTipText();
if (showDetailedInformation) // metadata are not available at this point
stream << '\n' << tr("Wait until metadata become available to see detailed information");
@@ -297,17 +308,20 @@ void PiecesBar::highlightFile(int imagePos)
int pieceIndex = transform.pieceIndex(imagePos);
QVector<int> fileIndices {m_torrent->info().fileIndicesForPiece(pieceIndex)};
if (fileIndices.count() == 1) {
if (fileIndices.count() == 1)
{
BitTorrent::TorrentInfo::PieceRange filePieces = m_torrent->info().filePieces(fileIndices.first());
ImageRange imageRange = transform.imagePos(filePieces);
QRect newHighlitedRegion {imageRange.first(), 0, imageRange.size(), m_image.height()};
if (newHighlitedRegion != m_highlitedRegion) {
if (newHighlitedRegion != m_highlitedRegion)
{
m_highlitedRegion = newHighlitedRegion;
update();
}
}
else if (!m_highlitedRegion.isEmpty()) {
else if (!m_highlitedRegion.isEmpty())
{
m_highlitedRegion = QRect();
update();
}
@@ -316,7 +330,8 @@ void PiecesBar::highlightFile(int imagePos)
void PiecesBar::updatePieceColors()
{
m_pieceColors = QVector<QRgb>(256);
for (int i = 0; i < 256; ++i) {
for (int i = 0; i < 256; ++i)
{
float ratio = (i / 255.0);
m_pieceColors[i] = mixTwoColors(backgroundColor().rgb(), pieceColor().rgb(), ratio);
}

View File

@@ -194,7 +194,8 @@ void PropertiesWidget::showPiecesDownloaded(bool show)
void PropertiesWidget::setVisibility(const bool visible)
{
if (!visible && (m_state == VISIBLE)) {
if (!visible && (m_state == VISIBLE))
{
const int tabBarHeight = m_tabBar->geometry().height(); // take height before hiding
auto *hSplitter = static_cast<QSplitter *>(parentWidget());
m_ui->stackedProperties->setVisible(false);
@@ -210,7 +211,8 @@ void PropertiesWidget::setVisibility(const bool visible)
return;
}
if (visible && (m_state == REDUCED)) {
if (visible && (m_state == REDUCED))
{
m_ui->stackedProperties->setVisible(true);
auto *hSplitter = static_cast<QSplitter *>(parentWidget());
if (m_handleWidth != -1)
@@ -314,7 +316,8 @@ void PropertiesWidget::loadTorrentInfos(BitTorrent::TorrentHandle *const torrent
// Hash
m_ui->labelHashVal->setText(m_torrent->hash());
m_propListModel->model()->clear();
if (m_torrent->hasMetadata()) {
if (m_torrent->hasMetadata())
{
// Creation date
m_ui->labelCreatedOnVal->setText(m_torrent->creationDate().toString(Qt::DefaultLocaleShortDate));
@@ -333,7 +336,8 @@ void PropertiesWidget::loadTorrentInfos(BitTorrent::TorrentHandle *const torrent
// Expand single-item folders recursively
QModelIndex currentIndex;
while (m_propListModel->rowCount(currentIndex) == 1) {
while (m_propListModel->rowCount(currentIndex) == 1)
{
currentIndex = m_propListModel->index(0, 0, currentIndex);
m_ui->filesList->setExpanded(currentIndex, true);
}
@@ -350,7 +354,8 @@ void PropertiesWidget::readSettings()
const Preferences *const pref = Preferences::instance();
// Restore splitter sizes
QStringList sizesStr = pref->getPropSplitterSizes().split(',');
if (sizesStr.size() == 2) {
if (sizesStr.size() == 2)
{
m_slideSizes << sizesStr.first().toInt();
m_slideSizes << sizesStr.last().toInt();
auto *hSplitter = static_cast<QSplitter *>(parentWidget());
@@ -396,8 +401,10 @@ void PropertiesWidget::loadDynamicData()
if (!m_torrent || (m_state != VISIBLE)) return;
// Transfer infos
switch (m_ui->stackedProperties->currentIndex()) {
case PropTabBar::MainTab: {
switch (m_ui->stackedProperties->currentIndex())
{
case PropTabBar::MainTab:
{
m_ui->labelWastedVal->setText(Utils::Misc::friendlyUnit(m_torrent->wastedSize()));
m_ui->labelUpTotalVal->setText(tr("%1 (%2 this session)").arg(Utils::Misc::friendlyUnit(m_torrent->totalUpload())
@@ -456,16 +463,19 @@ void PropertiesWidget::loadDynamicData()
m_ui->labelAddedOnVal->setText(m_torrent->addedTime().toString(Qt::DefaultLocaleShortDate));
if (m_torrent->hasMetadata()) {
if (m_torrent->hasMetadata())
{
m_ui->labelTotalPiecesVal->setText(tr("%1 x %2 (have %3)", "(torrent pieces) eg 152 x 4MB (have 25)").arg(m_torrent->piecesCount()).arg(Utils::Misc::friendlyUnit(m_torrent->pieceLength())).arg(m_torrent->piecesHave()));
if (!m_torrent->isSeed() && !m_torrent->isPaused() && !m_torrent->isQueued() && !m_torrent->isChecking()) {
if (!m_torrent->isSeed() && !m_torrent->isPaused() && !m_torrent->isQueued() && !m_torrent->isChecking())
{
// Pieces availability
showPiecesAvailability(true);
m_piecesAvailability->setAvailability(m_torrent->pieceAvailability());
m_ui->labelAverageAvailabilityVal->setText(Utils::String::fromDouble(m_torrent->distributedCopies(), 3));
}
else {
else
{
showPiecesAvailability(false);
}
@@ -474,7 +484,8 @@ void PropertiesWidget::loadDynamicData()
m_ui->labelProgressVal->setText(Utils::String::fromDouble(progress, 1) + '%');
m_downloadedPieces->setProgress(m_torrent->pieces(), m_torrent->downloadingPieces());
}
else {
else
{
showPiecesAvailability(false);
}
}
@@ -489,7 +500,8 @@ void PropertiesWidget::loadDynamicData()
break;
case PropTabBar::FilesTab:
// Files progress
if (m_torrent->hasMetadata()) {
if (m_torrent->hasMetadata())
{
qDebug("Updating priorities in files tab");
m_ui->filesList->setUpdatesEnabled(false);
m_propListModel->model()->updateFilesProgress(m_torrent->filesProgress());
@@ -511,7 +523,8 @@ void PropertiesWidget::loadUrlSeeds()
qDebug("Loading URL seeds");
const QVector<QUrl> hcSeeds = m_torrent->urlSeeds();
// Add url seeds
for (const QUrl &hcSeed : hcSeeds) {
for (const QUrl &hcSeed : hcSeeds)
{
qDebug("Loading URL seed: %s", qUtf8Printable(hcSeed.toString()));
new QListWidgetItem(hcSeed.toString(), m_ui->listWebSeeds);
}
@@ -519,7 +532,8 @@ void PropertiesWidget::loadUrlSeeds()
QString PropertiesWidget::getFullPath(const QModelIndex &index) const
{
if (m_propListModel->itemType(index) == TorrentContentModelItem::FileType) {
if (m_propListModel->itemType(index) == TorrentContentModelItem::FileType)
{
const int fileIdx = m_propListModel->getFileIndex(index);
const QString filename {m_torrent->filePath(fileIdx)};
const QDir saveDir {m_torrent->savePath(true)};
@@ -568,7 +582,8 @@ void PropertiesWidget::displayFilesListMenu(const QPoint &)
QMenu *menu = new QMenu(this);
menu->setAttribute(Qt::WA_DeleteOnClose);
if (selectedRows.size() == 1) {
if (selectedRows.size() == 1)
{
const QModelIndex index = selectedRows[0];
const QAction *actOpen = menu->addAction(UIThemeManager::instance()->getIcon("folder-documents"), tr("Open"));
@@ -583,12 +598,14 @@ void PropertiesWidget::displayFilesListMenu(const QPoint &)
menu->addSeparator();
}
if (!m_torrent->isSeed()) {
if (!m_torrent->isSeed())
{
QMenu *subMenu = menu->addMenu(tr("Priority"));
const auto applyPriorities = [this, selectedRows](const BitTorrent::DownloadPriority prio)
{
for (const QModelIndex &index : selectedRows) {
for (const QModelIndex &index : selectedRows)
{
m_propListModel->setData(
m_propListModel->index(index.row(), PRIORITY, index.parent()), static_cast<int>(prio));
}
@@ -646,7 +663,8 @@ void PropertiesWidget::displayWebSeedListMenu(const QPoint &)
const QAction *actAdd = menu->addAction(UIThemeManager::instance()->getIcon("list-add"), tr("New Web seed"));
connect(actAdd, &QAction::triggered, this, &PropertiesWidget::askWebSeed);
if (!rows.isEmpty()) {
if (!rows.isEmpty())
{
const QAction *actDel = menu->addAction(UIThemeManager::instance()->getIcon("list-remove"), tr("Remove Web seed"));
connect(actDel, &QAction::triggered, this, &PropertiesWidget::deleteSelectedUrlSeeds);
@@ -673,16 +691,20 @@ void PropertiesWidget::openSelectedFile()
void PropertiesWidget::configure()
{
// Speed widget
if (Preferences::instance()->isSpeedWidgetEnabled()) {
if (!m_speedWidget || !qobject_cast<SpeedWidget *>(m_speedWidget)) {
if (Preferences::instance()->isSpeedWidgetEnabled())
{
if (!m_speedWidget || !qobject_cast<SpeedWidget *>(m_speedWidget))
{
m_ui->speedLayout->removeWidget(m_speedWidget);
delete m_speedWidget;
m_speedWidget = new SpeedWidget {this};
m_ui->speedLayout->addWidget(m_speedWidget);
}
}
else {
if (!m_speedWidget || !qobject_cast<QLabel *>(m_speedWidget)) {
else
{
if (!m_speedWidget || !qobject_cast<QLabel *>(m_speedWidget))
{
m_ui->speedLayout->removeWidget(m_speedWidget);
delete m_speedWidget;
auto *label = new QLabel(tr("<center><b>Speed graphs are disabled</b><p>You may change this setting in Advanced Options </center>"), this);
@@ -702,7 +724,8 @@ void PropertiesWidget::askWebSeed()
QLatin1String("http://www."), &ok);
if (!ok) return;
qDebug("Adding %s web seed", qUtf8Printable(urlSeed));
if (!m_ui->listWebSeeds->findItems(urlSeed, Qt::MatchFixedString).empty()) {
if (!m_ui->listWebSeeds->findItems(urlSeed, Qt::MatchFixedString).empty())
{
QMessageBox::warning(this, "qBittorrent",
tr("This URL seed is already in the list."),
QMessageBox::Ok);
@@ -755,7 +778,8 @@ void PropertiesWidget::editWebSeed()
oldSeed, &result);
if (!result) return;
if (!m_ui->listWebSeeds->findItems(newSeed, Qt::MatchFixedString).empty()) {
if (!m_ui->listWebSeeds->findItems(newSeed, Qt::MatchFixedString).empty())
{
QMessageBox::warning(this, tr("qBittorrent"),
tr("This URL seed is already in the list."),
QMessageBox::Ok);
@@ -781,11 +805,13 @@ void PropertiesWidget::filteredFilesChanged()
void PropertiesWidget::filterText(const QString &filter)
{
m_propListModel->setFilterRegExp(QRegExp(filter, Qt::CaseInsensitive, QRegExp::WildcardUnix));
if (filter.isEmpty()) {
if (filter.isEmpty())
{
m_ui->filesList->collapseAll();
m_ui->filesList->expand(m_propListModel->index(0, 0));
}
else {
else
{
m_ui->filesList->expandAll();
}
}

View File

@@ -72,11 +72,13 @@ void PropListDelegate::initProgressStyleOption(QStyleOptionProgressBar &option,
ProgressBarDelegate::initProgressStyleOption(option, index);
const int priority
= index.sibling(index.row(), PRIORITY).data(TorrentContentModel::UnderlyingDataRole).toInt();
if (static_cast<BitTorrent::DownloadPriority>(priority) == BitTorrent::DownloadPriority::Ignored) {
if (static_cast<BitTorrent::DownloadPriority>(priority) == BitTorrent::DownloadPriority::Ignored)
{
option.state &= ~QStyle::State_Enabled;
option.palette = progressBarDisabledPalette();
}
else {
else
{
option.state |= QStyle::State_Enabled;
}
}
@@ -86,7 +88,8 @@ void PropListDelegate::setEditorData(QWidget *editor, const QModelIndex &index)
auto *combobox = static_cast<QComboBox *>(editor);
// Set combobox index
const int priority = index.data(TorrentContentModel::UnderlyingDataRole).toInt();
switch (static_cast<BitTorrent::DownloadPriority>(priority)) {
switch (static_cast<BitTorrent::DownloadPriority>(priority))
{
case BitTorrent::DownloadPriority::Ignored:
combobox->setCurrentIndex(0);
break;
@@ -106,7 +109,8 @@ QWidget *PropListDelegate::createEditor(QWidget *parent, const QStyleOptionViewI
{
if (index.column() != PRIORITY) return nullptr;
if (m_properties) {
if (m_properties)
{
const BitTorrent::TorrentHandle *torrent = m_properties->getCurrentTorrent();
if (!torrent || !torrent->hasMetadata() || torrent->isSeed())
return nullptr;
@@ -131,7 +135,8 @@ void PropListDelegate::setModelData(QWidget *editor, QAbstractItemModel *model,
const int value = combobox->currentIndex();
BitTorrent::DownloadPriority prio = BitTorrent::DownloadPriority::Normal; // NORMAL
switch (value) {
switch (value)
{
case 0:
prio = BitTorrent::DownloadPriority::Ignored; // IGNORED
break;

View File

@@ -122,8 +122,10 @@ void PropTabBar::setCurrentIndex(int index)
if (index >= m_btnGroup->buttons().size())
index = 0;
// If asked to hide or if the currently selected tab is clicked
if ((index < 0) || (m_currentIndex == index)) {
if (m_currentIndex >= 0) {
if ((index < 0) || (m_currentIndex == index))
{
if (m_currentIndex >= 0)
{
m_btnGroup->button(m_currentIndex)->setDown(false);
m_currentIndex = -1;
emit visibilityToggled(false);
@@ -131,10 +133,12 @@ void PropTabBar::setCurrentIndex(int index)
return;
}
// Unselect previous tab
if (m_currentIndex >= 0) {
if (m_currentIndex >= 0)
{
m_btnGroup->button(m_currentIndex)->setDown(false);
}
else {
else
{
// Nothing was selected, show!
emit visibilityToggled(true);
}

View File

@@ -79,26 +79,30 @@ namespace
if (value <= 12.0) return {12, SizeUnit::Byte};
SizeUnit calculatedUnit = SizeUnit::Byte;
while (value > 1024) {
while (value > 1024)
{
value /= 1024;
calculatedUnit = static_cast<SizeUnit>(static_cast<int>(calculatedUnit) + 1);
}
if (value > 100.0) {
if (value > 100.0)
{
int roundedValue = static_cast<int>(value / 40) * 40;
while (roundedValue < value)
roundedValue += 40;
return {static_cast<double>(roundedValue), calculatedUnit};
}
if (value > 10.0) {
if (value > 10.0)
{
int roundedValue = static_cast<int>(value / 4) * 4;
while (roundedValue < value)
roundedValue += 4;
return {static_cast<double>(roundedValue), calculatedUnit};
}
for (const auto &roundedValue : roundingTable) {
for (const auto &roundedValue : roundingTable)
{
if (value <= roundedValue)
return {roundedValue, calculatedUnit};
}
@@ -215,7 +219,8 @@ void SpeedPlotView::setPeriod(const TimePeriod period)
{
m_period = period;
switch (period) {
switch (period)
{
case SpeedPlotView::MIN1:
m_viewablePointsCount = MIN1_SEC;
m_currentData = &m_data5Min;
@@ -266,7 +271,8 @@ quint64 SpeedPlotView::maxYValue()
boost::circular_buffer<PointData> &queue = getCurrentData();
quint64 maxYValue = 0;
for (int id = UP; id < NB_GRAPHS; ++id) {
for (int id = UP; id < NB_GRAPHS; ++id)
{
if (!m_properties[static_cast<GraphID>(id)].enable)
continue;
@@ -292,7 +298,8 @@ void SpeedPlotView::paintEvent(QPaintEvent *)
rect.adjust(0, fontMetrics.height(), 0, 0); // Add top padding for top speed text
// draw Y axis speed labels
const QVector<QString> speedLabels = {
const QVector<QString> speedLabels =
{
formatLabel(niceScale.arg, niceScale.unit),
formatLabel((0.75 * niceScale.arg), niceScale.unit),
formatLabel((0.50 * niceScale.arg), niceScale.unit),
@@ -311,7 +318,8 @@ void SpeedPlotView::paintEvent(QPaintEvent *)
#endif
int i = 0;
for (const QString &label : speedLabels) {
for (const QString &label : speedLabels)
{
QRectF labelRect(rect.topLeft() + QPointF(-yAxisWidth, (i++) * 0.25 * rect.height() - fontMetrics.height()),
QSizeF(2 * yAxisWidth, fontMetrics.height()));
painter.drawText(labelRect, label, Qt::AlignRight | Qt::AlignTop);
@@ -333,7 +341,8 @@ void SpeedPlotView::paintEvent(QPaintEvent *)
painter.drawLine(fullRect.left(), rect.bottom(), rect.right(), rect.bottom());
const int TIME_AXIS_DIVISIONS = 6;
for (int i = 0; i < TIME_AXIS_DIVISIONS; ++i) {
for (int i = 0; i < TIME_AXIS_DIVISIONS; ++i)
{
const int x = rect.left() + (i * rect.width()) / TIME_AXIS_DIVISIONS;
painter.drawLine(x, fullRect.top(), x, fullRect.bottom());
}
@@ -349,12 +358,14 @@ void SpeedPlotView::paintEvent(QPaintEvent *)
boost::circular_buffer<PointData> &queue = getCurrentData();
for (int id = UP; id < NB_GRAPHS; ++id) {
for (int id = UP; id < NB_GRAPHS; ++id)
{
if (!m_properties[static_cast<GraphID>(id)].enable)
continue;
QVector<QPoint> points;
for (int i = static_cast<int>(queue.size()) - 1, j = 0; (i >= 0) && (j < m_viewablePointsCount); --i, ++j) {
for (int i = static_cast<int>(queue.size()) - 1, j = 0; (i >= 0) && (j < m_viewablePointsCount); --i, ++j)
{
int newX = rect.right() - j * xTickSize;
int newY = rect.bottom() - queue[i].y[id] * yMultiplier;
@@ -371,7 +382,8 @@ void SpeedPlotView::paintEvent(QPaintEvent *)
double legendHeight = 0;
int legendWidth = 0;
for (const auto &property : asConst(m_properties)) {
for (const auto &property : asConst(m_properties))
{
if (!property.enable)
continue;
@@ -391,7 +403,8 @@ void SpeedPlotView::paintEvent(QPaintEvent *)
painter.fillRect(legendBackgroundRect, legendBackgroundColor);
i = 0;
for (const auto &property : asConst(m_properties)) {
for (const auto &property : asConst(m_properties))
{
if (!property.enable)
continue;

View File

@@ -92,7 +92,8 @@ SpeedWidget::SpeedWidget(PropertiesWidget *parent)
m_graphsMenuActions = m_graphsMenu->actions();
for (int id = SpeedPlotView::UP; id < SpeedPlotView::NB_GRAPHS; ++id) {
for (int id = SpeedPlotView::UP; id < SpeedPlotView::NB_GRAPHS; ++id)
{
QAction *action = m_graphsMenuActions.at(id);
action->setCheckable(true);
action->setChecked(true);
@@ -168,7 +169,8 @@ void SpeedWidget::loadSettings()
m_periodCombobox->setCurrentIndex(periodIndex);
onPeriodChange(static_cast<SpeedPlotView::TimePeriod>(periodIndex));
for (int id = SpeedPlotView::UP; id < SpeedPlotView::NB_GRAPHS; ++id) {
for (int id = SpeedPlotView::UP; id < SpeedPlotView::NB_GRAPHS; ++id)
{
QAction *action = m_graphsMenuActions.at(id);
bool enable = preferences->getSpeedWidgetGraphEnable(id);
@@ -183,7 +185,8 @@ void SpeedWidget::saveSettings() const
preferences->setSpeedWidgetPeriod(m_periodCombobox->currentIndex());
for (int id = SpeedPlotView::UP; id < SpeedPlotView::NB_GRAPHS; ++id) {
for (int id = SpeedPlotView::UP; id < SpeedPlotView::NB_GRAPHS; ++id)
{
QAction *action = m_graphsMenuActions.at(id);
preferences->setSpeedWidgetGraphEnable(id, action->isChecked());
}

View File

@@ -152,7 +152,8 @@ QVector<QTreeWidgetItem *> TrackerListWidget::getSelectedTrackerItems() const
QVector<QTreeWidgetItem *> selectedTrackers;
selectedTrackers.reserve(selectedTrackerItems.size());
for (QTreeWidgetItem *item : selectedTrackerItems) {
for (QTreeWidgetItem *item : selectedTrackerItems)
{
if (indexOfTopLevelItem(item) >= NB_STICKY_ITEM) // Ignore STICKY ITEMS
selectedTrackers << item;
}
@@ -171,7 +172,8 @@ void TrackerListWidget::setRowColor(const int row, const QColor &color)
void TrackerListWidget::moveSelectionUp()
{
BitTorrent::TorrentHandle *const torrent = m_properties->getCurrentTorrent();
if (!torrent) {
if (!torrent)
{
clear();
return;
}
@@ -179,9 +181,11 @@ void TrackerListWidget::moveSelectionUp()
if (selectedTrackerItems.isEmpty()) return;
bool change = false;
for (QTreeWidgetItem *item : selectedTrackerItems) {
for (QTreeWidgetItem *item : selectedTrackerItems)
{
int index = indexOfTopLevelItem(item);
if (index > NB_STICKY_ITEM) {
if (index > NB_STICKY_ITEM)
{
insertTopLevelItem(index - 1, takeTopLevelItem(index));
change = true;
}
@@ -197,7 +201,8 @@ void TrackerListWidget::moveSelectionUp()
// Update torrent trackers
QVector<BitTorrent::TrackerEntry> trackers;
trackers.reserve(topLevelItemCount());
for (int i = NB_STICKY_ITEM; i < topLevelItemCount(); ++i) {
for (int i = NB_STICKY_ITEM; i < topLevelItemCount(); ++i)
{
const QString trackerURL = topLevelItem(i)->data(COL_URL, Qt::DisplayRole).toString();
BitTorrent::TrackerEntry e(trackerURL);
e.setTier(i - NB_STICKY_ITEM);
@@ -213,7 +218,8 @@ void TrackerListWidget::moveSelectionUp()
void TrackerListWidget::moveSelectionDown()
{
BitTorrent::TorrentHandle *const torrent = m_properties->getCurrentTorrent();
if (!torrent) {
if (!torrent)
{
clear();
return;
}
@@ -221,9 +227,11 @@ void TrackerListWidget::moveSelectionDown()
if (selectedTrackerItems.isEmpty()) return;
bool change = false;
for (int i = selectedItems().size() - 1; i >= 0; --i) {
for (int i = selectedItems().size() - 1; i >= 0; --i)
{
int index = indexOfTopLevelItem(selectedTrackerItems.at(i));
if (index < (topLevelItemCount() - 1)) {
if (index < (topLevelItemCount() - 1))
{
insertTopLevelItem(index + 1, takeTopLevelItem(index));
change = true;
}
@@ -239,7 +247,8 @@ void TrackerListWidget::moveSelectionDown()
// Update torrent trackers
QVector<BitTorrent::TrackerEntry> trackers;
trackers.reserve(topLevelItemCount());
for (int i = NB_STICKY_ITEM; i < topLevelItemCount(); ++i) {
for (int i = NB_STICKY_ITEM; i < topLevelItemCount(); ++i)
{
const QString trackerURL = topLevelItem(i)->data(COL_URL, Qt::DisplayRole).toString();
BitTorrent::TrackerEntry e(trackerURL);
e.setTier(i - NB_STICKY_ITEM);
@@ -294,7 +303,8 @@ void TrackerListWidget::loadStickyItems(const BitTorrent::TorrentHandle *torrent
else
m_LSDItem->setText(COL_STATUS, disabled);
if (torrent->isPrivate()) {
if (torrent->isPrivate())
{
QString privateMsg = tr("This torrent is private");
m_DHTItem->setText(COL_MSG, privateMsg);
m_PEXItem->setText(COL_MSG, privateMsg);
@@ -304,22 +314,26 @@ void TrackerListWidget::loadStickyItems(const BitTorrent::TorrentHandle *torrent
// XXX: libtorrent should provide this info...
// Count peers from DHT, PeX, LSD
uint seedsDHT = 0, seedsPeX = 0, seedsLSD = 0, peersDHT = 0, peersPeX = 0, peersLSD = 0;
for (const BitTorrent::PeerInfo &peer : asConst(torrent->peers())) {
for (const BitTorrent::PeerInfo &peer : asConst(torrent->peers()))
{
if (peer.isConnecting()) continue;
if (peer.fromDHT()) {
if (peer.fromDHT())
{
if (peer.isSeed())
++seedsDHT;
else
++peersDHT;
}
if (peer.fromPeX()) {
if (peer.fromPeX())
{
if (peer.isSeed())
++seedsPeX;
else
++peersPeX;
}
if (peer.fromLSD()) {
if (peer.fromLSD())
{
if (peer.isSeed())
++seedsLSD;
else
@@ -347,17 +361,20 @@ void TrackerListWidget::loadTrackers()
const QHash<QString, BitTorrent::TrackerInfo> trackerData = torrent->trackerInfos();
QStringList oldTrackerURLs = m_trackerItems.keys();
for (const BitTorrent::TrackerEntry &entry : asConst(torrent->trackers())) {
for (const BitTorrent::TrackerEntry &entry : asConst(torrent->trackers()))
{
const QString trackerURL = entry.url();
QTreeWidgetItem *item = m_trackerItems.value(trackerURL, nullptr);
if (!item) {
if (!item)
{
item = new QTreeWidgetItem();
item->setText(COL_URL, trackerURL);
addTopLevelItem(item);
m_trackerItems[trackerURL] = item;
}
else {
else
{
oldTrackerURLs.removeOne(trackerURL);
}
@@ -365,7 +382,8 @@ void TrackerListWidget::loadTrackers()
const BitTorrent::TrackerInfo data = trackerData.value(trackerURL);
switch (entry.status()) {
switch (entry.status())
{
case BitTorrent::TrackerEntry::Working:
item->setText(COL_STATUS, tr("Working"));
item->setText(COL_MSG, "");
@@ -427,7 +445,8 @@ void TrackerListWidget::copyTrackerUrl()
if (selectedTrackerItems.isEmpty()) return;
QStringList urlsToCopy;
for (const QTreeWidgetItem *item : selectedTrackerItems) {
for (const QTreeWidgetItem *item : selectedTrackerItems)
{
QString trackerURL = item->data(COL_URL, Qt::DisplayRole).toString();
qDebug() << QString("Copy: ") + trackerURL;
urlsToCopy << trackerURL;
@@ -439,7 +458,8 @@ void TrackerListWidget::copyTrackerUrl()
void TrackerListWidget::deleteSelectedTrackers()
{
BitTorrent::TorrentHandle *const torrent = m_properties->getCurrentTorrent();
if (!torrent) {
if (!torrent)
{
clear();
return;
}
@@ -448,7 +468,8 @@ void TrackerListWidget::deleteSelectedTrackers()
if (selectedTrackerItems.isEmpty()) return;
QStringList urlsToRemove;
for (const QTreeWidgetItem *item : selectedTrackerItems) {
for (const QTreeWidgetItem *item : selectedTrackerItems)
{
QString trackerURL = item->data(COL_URL, Qt::DisplayRole).toString();
urlsToRemove << trackerURL;
m_trackerItems.remove(trackerURL);
@@ -460,7 +481,8 @@ void TrackerListWidget::deleteSelectedTrackers()
QVector<BitTorrent::TrackerEntry> remainingTrackers;
remainingTrackers.reserve(trackers.size());
for (const BitTorrent::TrackerEntry &entry : trackers) {
for (const BitTorrent::TrackerEntry &entry : trackers)
{
if (!urlsToRemove.contains(entry.url()))
remainingTrackers.push_back(entry);
}
@@ -487,7 +509,8 @@ void TrackerListWidget::editSelectedTracker()
QLineEdit::Normal, trackerURL.toString(), &ok).trimmed();
if (!ok) return;
if (!newTrackerURL.isValid()) {
if (!newTrackerURL.isValid())
{
QMessageBox::warning(this, tr("Tracker editing failed"), tr("The tracker URL entered is invalid."));
return;
}
@@ -495,13 +518,16 @@ void TrackerListWidget::editSelectedTracker()
QVector<BitTorrent::TrackerEntry> trackers = torrent->trackers();
bool match = false;
for (BitTorrent::TrackerEntry &entry : trackers) {
if (newTrackerURL == QUrl(entry.url())) {
for (BitTorrent::TrackerEntry &entry : trackers)
{
if (newTrackerURL == QUrl(entry.url()))
{
QMessageBox::warning(this, tr("Tracker editing failed"), tr("The tracker URL already exists."));
return;
}
if (!match && (trackerURL == QUrl(entry.url()))) {
if (!match && (trackerURL == QUrl(entry.url())))
{
match = true;
BitTorrent::TrackerEntry newEntry(newTrackerURL.toString());
newEntry.setTier(entry.tier());
@@ -525,16 +551,20 @@ void TrackerListWidget::reannounceSelected()
const QVector<BitTorrent::TrackerEntry> trackers = torrent->trackers();
for (const QTreeWidgetItem *item : selItems) {
for (const QTreeWidgetItem *item : selItems)
{
// DHT case
if (item == m_DHTItem) {
if (item == m_DHTItem)
{
torrent->forceDHTAnnounce();
continue;
}
// Trackers case
for (int i = 0; i < trackers.size(); ++i) {
if (item->text(COL_URL) == trackers[i].url()) {
for (int i = 0; i < trackers.size(); ++i)
{
if (item->text(COL_URL) == trackers[i].url())
{
torrent->forceReannounce(i);
break;
}
@@ -556,7 +586,8 @@ void TrackerListWidget::showTrackerListMenu(const QPoint &)
const QAction *addAct = menu->addAction(UIThemeManager::instance()->getIcon("list-add"), tr("Add a new tracker..."));
connect(addAct, &QAction::triggered, this, &TrackerListWidget::askForTrackers);
if (!getSelectedTrackerItems().isEmpty()) {
if (!getSelectedTrackerItems().isEmpty())
{
const QAction *editAct = menu->addAction(UIThemeManager::instance()->getIcon("edit-rename"),tr("Edit tracker URL..."));
connect(editAct, &QAction::triggered, this, &TrackerListWidget::editSelectedTracker);
@@ -567,7 +598,8 @@ void TrackerListWidget::showTrackerListMenu(const QPoint &)
connect(copyAct, &QAction::triggered, this, &TrackerListWidget::copyTrackerUrl);
}
if (!torrent->isPaused()) {
if (!torrent->isPaused())
{
const QAction *reannounceSelAct = menu->addAction(UIThemeManager::instance()->getIcon("view-refresh"), tr("Force reannounce to selected trackers"));
connect(reannounceSelAct, &QAction::triggered, this, &TrackerListWidget::reannounceSelected);
@@ -597,7 +629,8 @@ void TrackerListWidget::saveSettings() const
QStringList TrackerListWidget::headerLabels()
{
return {
return
{
tr("Tier")
, tr("URL")
, tr("Status")
@@ -612,7 +645,8 @@ QStringList TrackerListWidget::headerLabels()
int TrackerListWidget::visibleColumnsCount() const
{
int visibleCols = 0;
for (int i = 0; i < COL_COUNT; ++i) {
for (int i = 0; i < COL_COUNT; ++i)
{
if (!isColumnHidden(i))
++visibleCols;
}
@@ -626,7 +660,8 @@ void TrackerListWidget::displayToggleColumnsMenu(const QPoint &)
menu->setAttribute(Qt::WA_DeleteOnClose);
menu->setTitle(tr("Column visibility"));
for (int i = 0; i < COL_COUNT; ++i) {
for (int i = 0; i < COL_COUNT; ++i)
{
QAction *myAct = menu->addAction(headerLabels().at(i));
myAct->setCheckable(true);
myAct->setChecked(!isColumnHidden(i));

View File

@@ -59,7 +59,8 @@ QStringList TrackersAdditionDialog::newTrackers() const
const QString plainText = m_ui->textEditTrackersList->toPlainText();
QStringList cleanTrackers;
for (QStringRef url : asConst(plainText.splitRef('\n'))) {
for (QStringRef url : asConst(plainText.splitRef('\n')))
{
url = url.trimmed();
if (!url.isEmpty())
cleanTrackers << url.toString();
@@ -78,7 +79,8 @@ void TrackersAdditionDialog::on_uTorrentListButton_clicked()
void TrackersAdditionDialog::torrentListDownloadFinished(const Net::DownloadResult &result)
{
if (result.status != Net::DownloadStatus::Success) {
if (result.status != Net::DownloadStatus::Success)
{
// To restore the cursor ...
setCursor(Qt::ArrowCursor);
m_ui->uTorrentListButton->setEnabled(true);
@@ -92,7 +94,8 @@ void TrackersAdditionDialog::torrentListDownloadFinished(const Net::DownloadResu
const QStringList trackersFromUser = m_ui->textEditTrackersList->toPlainText().split('\n');
QVector<BitTorrent::TrackerEntry> existingTrackers = m_torrent->trackers();
existingTrackers.reserve(trackersFromUser.size());
for (const QString &userURL : trackersFromUser) {
for (const QString &userURL : trackersFromUser)
{
const BitTorrent::TrackerEntry userTracker(userURL);
if (!existingTrackers.contains(userTracker))
existingTrackers << userTracker;
@@ -105,12 +108,14 @@ void TrackersAdditionDialog::torrentListDownloadFinished(const Net::DownloadResu
QBuffer buffer;
buffer.setData(result.data);
buffer.open(QBuffer::ReadOnly);
while (!buffer.atEnd()) {
while (!buffer.atEnd())
{
const QString line = buffer.readLine().trimmed();
if (line.isEmpty()) continue;
BitTorrent::TrackerEntry newTracker(line);
if (!existingTrackers.contains(newTracker)) {
if (!existingTrackers.contains(newTracker))
{
m_ui->textEditTrackersList->insertPlainText(line + '\n');
++nb;
}

View File

@@ -65,13 +65,16 @@ void ArticleListWidget::setRSSItem(RSS::Item *rssItem, bool unreadOnly)
m_unreadOnly = unreadOnly;
m_rssItem = rssItem;
if (m_rssItem) {
if (m_rssItem)
{
connect(m_rssItem, &RSS::Item::newArticle, this, &ArticleListWidget::handleArticleAdded);
connect(m_rssItem, &RSS::Item::articleRead, this, &ArticleListWidget::handleArticleRead);
connect(m_rssItem, &RSS::Item::articleAboutToBeRemoved, this, &ArticleListWidget::handleArticleAboutToBeRemoved);
for (const auto article : asConst(rssItem->articles())) {
if (!(m_unreadOnly && article->isRead())) {
for (const auto article : asConst(rssItem->articles()))
{
if (!(m_unreadOnly && article->isRead()))
{
auto item = createItem(article);
addItem(item);
m_rssArticleToListItemMapping.insert(article, item);
@@ -84,7 +87,8 @@ void ArticleListWidget::setRSSItem(RSS::Item *rssItem, bool unreadOnly)
void ArticleListWidget::handleArticleAdded(RSS::Article *rssArticle)
{
if (!(m_unreadOnly && rssArticle->isRead())) {
if (!(m_unreadOnly && rssArticle->isRead()))
{
auto item = createItem(rssArticle);
insertItem(0, item);
m_rssArticleToListItemMapping.insert(rssArticle, item);
@@ -124,13 +128,15 @@ QListWidgetItem *ArticleListWidget::createItem(RSS::Article *article) const
item->setData(Qt::DisplayRole, article->title());
item->setData(Qt::UserRole, reinterpret_cast<quintptr>(article));
if (article->isRead()) {
if (article->isRead())
{
const QColor defaultColor {palette().color(QPalette::Inactive, QPalette::WindowText)};
const QBrush foregroundBrush {UIThemeManager::instance()->getColor("RSS.ReadArticle", defaultColor)};
item->setData(Qt::ForegroundRole, foregroundBrush);
item->setData(Qt::DecorationRole, UIThemeManager::instance()->getIcon(QLatin1String("sphere")));
}
else {
else
{
const QColor defaultColor {palette().color(QPalette::Active, QPalette::Link)};
const QBrush foregroundBrush {UIThemeManager::instance()->getColor("RSS.UnreadArticle", defaultColor)};
item->setData(Qt::ForegroundRole, foregroundBrush);

View File

@@ -181,7 +181,8 @@ void AutomatedRssDownloader::loadFeedList()
{
const QSignalBlocker feedListSignalBlocker(m_ui->listFeeds);
for (const auto feed : asConst(RSS::Session::instance()->feeds())) {
for (const auto feed : asConst(RSS::Session::instance()->feeds()))
{
QListWidgetItem *item = new QListWidgetItem(feed->name(), m_ui->listFeeds);
item->setData(Qt::UserRole, feed->url());
item->setFlags(item->flags() | Qt::ItemIsUserCheckable | Qt::ItemIsTristate);
@@ -203,7 +204,8 @@ void AutomatedRssDownloader::updateFeedList()
bool enable = !selection.isEmpty();
for (int i = 0; i < m_ui->listFeeds->count(); ++i) {
for (int i = 0; i < m_ui->listFeeds->count(); ++i)
{
QListWidgetItem *item = m_ui->listFeeds->item(i);
const QString feedURL = item->data(Qt::UserRole).toString();
item->setHidden(!enable);
@@ -211,7 +213,8 @@ void AutomatedRssDownloader::updateFeedList()
bool allEnabled = true;
bool anyEnabled = false;
for (const QListWidgetItem *ruleItem : asConst(selection)) {
for (const QListWidgetItem *ruleItem : asConst(selection))
{
const auto rule = RSS::AutoDownloader::instance()->ruleByName(ruleItem->text());
if (rule.feedURLs().contains(feedURL))
anyEnabled = true;
@@ -236,14 +239,16 @@ void AutomatedRssDownloader::updateRuleDefinitionBox()
{
const QList<QListWidgetItem *> selection = m_ui->listRules->selectedItems();
QListWidgetItem *currentRuleItem = ((selection.count() == 1) ? selection.first() : nullptr);
if (m_currentRuleItem != currentRuleItem) {
if (m_currentRuleItem != currentRuleItem)
{
saveEditedRule(); // Save previous rule first
m_currentRuleItem = currentRuleItem;
//m_ui->listRules->setCurrentItem(m_currentRuleItem);
}
// Update rule definition box
if (m_currentRuleItem) {
if (m_currentRuleItem)
{
m_currentRule = RSS::AutoDownloader::instance()->ruleByName(m_currentRuleItem->text());
m_ui->lineContains->setText(m_currentRule.mustContain());
@@ -290,7 +295,8 @@ void AutomatedRssDownloader::updateRuleDefinitionBox()
updateFieldsToolTips(m_ui->checkRegex->isChecked());
m_ui->ruleDefBox->setEnabled(true);
}
else {
else
{
m_currentRule = RSS::AutoDownloadRule();
clearRuleDefinitionBox();
m_ui->ruleDefBox->setEnabled(false);
@@ -376,7 +382,8 @@ void AutomatedRssDownloader::on_addRuleBtn_clicked()
if (ruleName.isEmpty()) return;
// Check if this rule name already exists
if (RSS::AutoDownloader::instance()->hasRule(ruleName)) {
if (RSS::AutoDownloader::instance()->hasRule(ruleName))
{
QMessageBox::warning(this, tr("Rule name conflict")
, tr("A rule with this name already exists, please choose another name."));
return;
@@ -404,7 +411,8 @@ void AutomatedRssDownloader::on_removeRuleBtn_clicked()
void AutomatedRssDownloader::on_exportBtn_clicked()
{
if (RSS::AutoDownloader::instance()->rules().isEmpty()) {
if (RSS::AutoDownloader::instance()->rules().isEmpty())
{
QMessageBox::warning(this, tr("Invalid action")
, tr("The list is empty, there is nothing to export."));
return;
@@ -416,24 +424,28 @@ void AutomatedRssDownloader::on_exportBtn_clicked()
, QString::fromLatin1("%1;;%2").arg(m_formatFilterJSON, m_formatFilterLegacy), &selectedFilter);
if (path.isEmpty()) return;
const RSS::AutoDownloader::RulesFileFormat format {
const RSS::AutoDownloader::RulesFileFormat format
{
(selectedFilter == m_formatFilterJSON)
? RSS::AutoDownloader::RulesFileFormat::JSON
: RSS::AutoDownloader::RulesFileFormat::Legacy
};
if (format == RSS::AutoDownloader::RulesFileFormat::JSON) {
if (format == RSS::AutoDownloader::RulesFileFormat::JSON)
{
if (!path.endsWith(EXT_JSON, Qt::CaseInsensitive))
path += EXT_JSON;
}
else {
else
{
if (!path.endsWith(EXT_LEGACY, Qt::CaseInsensitive))
path += EXT_LEGACY;
}
QFile file {path};
if (!file.open(QFile::WriteOnly)
|| (file.write(RSS::AutoDownloader::instance()->exportRules(format)) == -1)) {
|| (file.write(RSS::AutoDownloader::instance()->exportRules(format)) == -1))
{
QMessageBox::critical(
this, tr("I/O Error")
, tr("Failed to create the destination file. Reason: %1").arg(file.errorString()));
@@ -450,23 +462,27 @@ void AutomatedRssDownloader::on_importBtn_clicked()
return;
QFile file {path};
if (!file.open(QIODevice::ReadOnly)) {
if (!file.open(QIODevice::ReadOnly))
{
QMessageBox::critical(
this, tr("I/O Error")
, tr("Failed to open the file. Reason: %1").arg(file.errorString()));
return;
}
const RSS::AutoDownloader::RulesFileFormat format {
const RSS::AutoDownloader::RulesFileFormat format
{
(selectedFilter == m_formatFilterJSON)
? RSS::AutoDownloader::RulesFileFormat::JSON
: RSS::AutoDownloader::RulesFileFormat::Legacy
};
try {
try
{
RSS::AutoDownloader::instance()->importRules(file.readAll(),format);
}
catch (const RSS::ParsingError &error) {
catch (const RSS::ParsingError &error)
{
QMessageBox::critical(
this, tr("Import Error")
, tr("Failed to import the selected rules file. Reason: %1").arg(error.message()));
@@ -483,8 +499,10 @@ void AutomatedRssDownloader::displayRulesListMenu()
const QList<QListWidgetItem *> selection = m_ui->listRules->selectedItems();
if (!selection.isEmpty()) {
if (selection.count() == 1) {
if (!selection.isEmpty())
{
if (selection.count() == 1)
{
const QAction *delAct = menu->addAction(UIThemeManager::instance()->getIcon("list-remove"), tr("Delete rule"));
connect(delAct, &QAction::triggered, this, &AutomatedRssDownloader::on_removeRuleBtn_clicked);
@@ -493,7 +511,8 @@ void AutomatedRssDownloader::displayRulesListMenu()
const QAction *renameAct = menu->addAction(UIThemeManager::instance()->getIcon("edit-rename"), tr("Rename rule..."));
connect(renameAct, &QAction::triggered, this, &AutomatedRssDownloader::renameSelectedRule);
}
else {
else
{
const QAction *delAct = menu->addAction(UIThemeManager::instance()->getIcon("list-remove"), tr("Delete selected rules"));
connect(delAct, &QAction::triggered, this, &AutomatedRssDownloader::on_removeRuleBtn_clicked);
}
@@ -513,18 +532,21 @@ void AutomatedRssDownloader::renameSelectedRule()
if (selection.isEmpty()) return;
QListWidgetItem *item = selection.first();
forever {
forever
{
QString newName = AutoExpandableDialog::getText(
this, tr("Rule renaming"), tr("Please type the new rule name")
, QLineEdit::Normal, item->text());
newName = newName.trimmed();
if (newName.isEmpty()) return;
if (RSS::AutoDownloader::instance()->hasRule(newName)) {
if (RSS::AutoDownloader::instance()->hasRule(newName))
{
QMessageBox::warning(this, tr("Rule name conflict")
, tr("A rule with this name already exists, please choose another name."));
}
else {
else
{
// Rename the rule
RSS::AutoDownloader::instance()->renameRule(item->text(), newName);
return;
@@ -545,7 +567,8 @@ void AutomatedRssDownloader::clearSelectedRuleDownloadedEpisodeList()
tr("Are you sure you want to clear the list of downloaded episodes for the selected rule?"),
QMessageBox::Yes | QMessageBox::No);
if (reply == QMessageBox::Yes) {
if (reply == QMessageBox::Yes)
{
m_currentRule.setPreviouslyMatchedEpisodes(QStringList());
handleRuleDefinitionChanged();
}
@@ -554,7 +577,8 @@ void AutomatedRssDownloader::clearSelectedRuleDownloadedEpisodeList()
void AutomatedRssDownloader::handleFeedCheckStateChange(QListWidgetItem *feedItem)
{
const QString feedURL = feedItem->data(Qt::UserRole).toString();
for (QListWidgetItem *ruleItem : asConst(m_ui->listRules->selectedItems())) {
for (QListWidgetItem *ruleItem : asConst(m_ui->listRules->selectedItems()))
{
RSS::AutoDownloadRule rule = (ruleItem == m_currentRuleItem
? m_currentRule
: RSS::AutoDownloader::instance()->ruleByName(ruleItem->text()));
@@ -578,11 +602,13 @@ void AutomatedRssDownloader::updateMatchingArticles()
{
m_ui->treeMatchingArticles->clear();
for (const QListWidgetItem *ruleItem : asConst(m_ui->listRules->selectedItems())) {
for (const QListWidgetItem *ruleItem : asConst(m_ui->listRules->selectedItems()))
{
RSS::AutoDownloadRule rule = (ruleItem == m_currentRuleItem
? m_currentRule
: RSS::AutoDownloader::instance()->ruleByName(ruleItem->text()));
for (const QString &feedURL : asConst(rule.feedURLs())) {
for (const QString &feedURL : asConst(rule.feedURLs()))
{
auto feed = RSS::Session::instance()->feedByURL(feedURL);
if (!feed) continue; // feed doesn't exist
@@ -605,16 +631,19 @@ void AutomatedRssDownloader::addFeedArticlesToTree(RSS::Feed *feed, const QStrin
// Check if this feed is already in the tree
QTreeWidgetItem *treeFeedItem = nullptr;
for (int i = 0; i < m_ui->treeMatchingArticles->topLevelItemCount(); ++i) {
for (int i = 0; i < m_ui->treeMatchingArticles->topLevelItemCount(); ++i)
{
QTreeWidgetItem *item = m_ui->treeMatchingArticles->topLevelItem(i);
if (item->data(0, Qt::UserRole).toString() == feed->url()) {
if (item->data(0, Qt::UserRole).toString() == feed->url())
{
treeFeedItem = item;
break;
}
}
// If there is none, create it
if (!treeFeedItem) {
if (!treeFeedItem)
{
treeFeedItem = new QTreeWidgetItem(QStringList() << feed->name());
treeFeedItem->setToolTip(0, feed->name());
QFont f = treeFeedItem->font(0);
@@ -626,10 +655,12 @@ void AutomatedRssDownloader::addFeedArticlesToTree(RSS::Feed *feed, const QStrin
}
// Insert the articles
for (const QString &article : articles) {
for (const QString &article : articles)
{
QPair<QString, QString> key(feed->name(), article);
if (!m_treeListEntries.contains(key)) {
if (!m_treeListEntries.contains(key))
{
m_treeListEntries << key;
QTreeWidgetItem *item = new QTreeWidgetItem(QStringList() << article);
item->setToolTip(0, article);
@@ -645,10 +676,12 @@ void AutomatedRssDownloader::addFeedArticlesToTree(RSS::Feed *feed, const QStrin
void AutomatedRssDownloader::updateFieldsToolTips(bool regex)
{
QString tip;
if (regex) {
if (regex)
{
tip = "<p>" + tr("Regex mode: use Perl-compatible regular expressions") + "</p>";
}
else {
else
{
tip = "<p>" + tr("Wildcard mode: you can use") + "<ul>"
+ "<li>" + tr("? to match any single character") + "</li>"
+ "<li>" + tr("* to match zero or more of any characters") + "</li>"
@@ -676,7 +709,8 @@ void AutomatedRssDownloader::updateMustLineValidity()
bool valid = true;
QString error;
if (!text.isEmpty()) {
if (!text.isEmpty())
{
QStringList tokens;
if (isRegex)
tokens << text;
@@ -684,9 +718,11 @@ void AutomatedRssDownloader::updateMustLineValidity()
for (const QString &token : asConst(text.split('|')))
tokens << Utils::String::wildcardToRegex(token);
for (const QString &token : asConst(tokens)) {
for (const QString &token : asConst(tokens))
{
QRegularExpression reg(token, QRegularExpression::CaseInsensitiveOption);
if (!reg.isValid()) {
if (!reg.isValid())
{
if (isRegex)
error = tr("Position %1: %2").arg(reg.patternErrorOffset()).arg(reg.errorString());
valid = false;
@@ -695,12 +731,14 @@ void AutomatedRssDownloader::updateMustLineValidity()
}
}
if (valid) {
if (valid)
{
m_ui->lineContains->setStyleSheet("");
m_ui->labelMustStat->setPixmap(QPixmap());
m_ui->labelMustStat->setToolTip("");
}
else {
else
{
m_ui->lineContains->setStyleSheet("QLineEdit { color: #ff0000; }");
m_ui->labelMustStat->setPixmap(UIThemeManager::instance()->getIcon("task-attention").pixmap(16, 16));
m_ui->labelMustStat->setToolTip(error);
@@ -714,7 +752,8 @@ void AutomatedRssDownloader::updateMustNotLineValidity()
bool valid = true;
QString error;
if (!text.isEmpty()) {
if (!text.isEmpty())
{
QStringList tokens;
if (isRegex)
tokens << text;
@@ -722,9 +761,11 @@ void AutomatedRssDownloader::updateMustNotLineValidity()
for (const QString &token : asConst(text.split('|')))
tokens << Utils::String::wildcardToRegex(token);
for (const QString &token : asConst(tokens)) {
for (const QString &token : asConst(tokens))
{
QRegularExpression reg(token, QRegularExpression::CaseInsensitiveOption);
if (!reg.isValid()) {
if (!reg.isValid())
{
if (isRegex)
error = tr("Position %1: %2").arg(reg.patternErrorOffset()).arg(reg.errorString());
valid = false;
@@ -733,12 +774,14 @@ void AutomatedRssDownloader::updateMustNotLineValidity()
}
}
if (valid) {
if (valid)
{
m_ui->lineNotContains->setStyleSheet("");
m_ui->labelMustNotStat->setPixmap(QPixmap());
m_ui->labelMustNotStat->setToolTip("");
}
else {
else
{
m_ui->lineNotContains->setStyleSheet("QLineEdit { color: #ff0000; }");
m_ui->labelMustNotStat->setPixmap(UIThemeManager::instance()->getIcon("task-attention").pixmap(16, 16));
m_ui->labelMustNotStat->setToolTip(error);
@@ -750,11 +793,13 @@ void AutomatedRssDownloader::updateEpisodeFilterValidity()
const QString text = m_ui->lineEFilter->text();
bool valid = text.isEmpty() || m_episodeRegex->match(text).hasMatch();
if (valid) {
if (valid)
{
m_ui->lineEFilter->setStyleSheet("");
m_ui->labelEpFilterStat->setPixmap(QPixmap());
}
else {
else
{
m_ui->lineEFilter->setStyleSheet("QLineEdit { color: #ff0000; }");
m_ui->labelEpFilterStat->setPixmap(UIThemeManager::instance()->getIcon("task-attention").pixmap(16, 16));
}

View File

@@ -97,7 +97,8 @@ void FeedListWidget::handleFeedStateChanged(RSS::Feed *feed)
void FeedListWidget::handleFeedIconLoaded(RSS::Feed *feed)
{
if (!feed->isLoading() && !feed->hasError()) {
if (!feed->isLoading() && !feed->hasError())
{
QTreeWidgetItem *item = m_rssToTreeItemMapping.value(feed);
Q_ASSERT(item);
@@ -107,10 +108,12 @@ void FeedListWidget::handleFeedIconLoaded(RSS::Feed *feed)
void FeedListWidget::handleItemUnreadCountChanged(RSS::Item *rssItem)
{
if (rssItem == RSS::Session::instance()->rootFolder()) {
if (rssItem == RSS::Session::instance()->rootFolder())
{
m_unreadStickyItem->setText(0, tr("Unread (%1)").arg(RSS::Session::instance()->rootFolder()->unreadCount()));
}
else {
else
{
QTreeWidgetItem *item = mapRSSItem(rssItem);
Q_ASSERT(item);
item->setData(0, Qt::DisplayRole, QString::fromLatin1("%1 (%2)").arg(rssItem->name(), QString::number(rssItem->unreadCount())));
@@ -151,9 +154,11 @@ QList<QTreeWidgetItem *> FeedListWidget::getAllOpenedFolders(QTreeWidgetItem *pa
{
QList<QTreeWidgetItem *> openedFolders;
int nbChildren = (parent ? parent->childCount() : topLevelItemCount());
for (int i = 0; i < nbChildren; ++i) {
for (int i = 0; i < nbChildren; ++i)
{
QTreeWidgetItem *item (parent ? parent->child(i) : topLevelItem(i));
if (isFolder(item) && item->isExpanded()) {
if (isFolder(item) && item->isExpanded())
{
QList<QTreeWidgetItem *> openedSubfolders = getAllOpenedFolders(item);
if (!openedSubfolders.empty())
openedFolders << openedSubfolders;
@@ -215,7 +220,8 @@ void FeedListWidget::dropEvent(QDropEvent *event)
: RSS::Session::instance()->rootFolder());
// move as much items as possible
for (QTreeWidgetItem *srcItem : asConst(selectedItems())) {
for (QTreeWidgetItem *srcItem : asConst(selectedItems()))
{
auto rssItem = getRSSItem(srcItem);
RSS::Session::instance()->moveItem(rssItem, RSS::Item::joinPath(destFolder->path(), rssItem->name()));
}
@@ -233,7 +239,8 @@ QTreeWidgetItem *FeedListWidget::createItem(RSS::Item *rssItem, QTreeWidgetItem
m_rssToTreeItemMapping[rssItem] = item;
QIcon icon;
if (auto feed = qobject_cast<RSS::Feed *>(rssItem)) {
if (auto feed = qobject_cast<RSS::Feed *>(rssItem))
{
if (feed->isLoading())
icon = UIThemeManager::instance()->getIcon(QLatin1String("loading"));
else if (feed->hasError())
@@ -243,7 +250,8 @@ QTreeWidgetItem *FeedListWidget::createItem(RSS::Item *rssItem, QTreeWidgetItem
else
icon = UIThemeManager::instance()->getIcon(QLatin1String("application-rss+xml"));
}
else {
else
{
icon = UIThemeManager::instance()->getIcon(QLatin1String("inode-directory"));
}
item->setData(0, Qt::DecorationRole, icon);
@@ -260,7 +268,8 @@ QTreeWidgetItem *FeedListWidget::createItem(RSS::Item *rssItem, QTreeWidgetItem
void FeedListWidget::fill(QTreeWidgetItem *parent, RSS::Folder *rssParent)
{
for (const auto rssItem : asConst(rssParent->items())) {
for (const auto rssItem : asConst(rssParent->items()))
{
QTreeWidgetItem *item = createItem(rssItem, parent);
// Recursive call if this is a folder.
if (auto folder = qobject_cast<RSS::Folder *>(rssItem))

View File

@@ -59,20 +59,23 @@ HtmlBrowser::~HtmlBrowser()
QVariant HtmlBrowser::loadResource(int type, const QUrl &name)
{
if (type == QTextDocument::ImageResource) {
if (type == QTextDocument::ImageResource)
{
QUrl url(name);
if (url.scheme().isEmpty())
url.setScheme("http");
QIODevice *dev = m_diskCache->data(url);
if (dev) {
if (dev)
{
qDebug() << "HtmlBrowser::loadResource() cache " << url.toString();
QByteArray res = dev->readAll();
delete dev;
return res;
}
if (!m_activeRequests.contains(url)) {
if (!m_activeRequests.contains(url))
{
m_activeRequests.insert(url, true);
qDebug() << "HtmlBrowser::loadResource() get " << url.toString();
QNetworkRequest req(url);
@@ -90,10 +93,12 @@ void HtmlBrowser::resourceLoaded(QNetworkReply *reply)
{
m_activeRequests.remove(reply->request().url());
if ((reply->error() == QNetworkReply::NoError) && (reply->size() > 0)) {
if ((reply->error() == QNetworkReply::NoError) && (reply->size() > 0))
{
qDebug() << "HtmlBrowser::resourceLoaded() save " << reply->request().url().toString();
}
else {
else
{
// If resource failed to load, replace it with warning icon and store it in cache for 1 day.
// Otherwise HTMLBrowser will keep trying to download it every time article is displayed,
// since it's not possible to cache error responses.

View File

@@ -150,13 +150,16 @@ void RSSWidget::displayRSSListMenu(const QPoint &pos)
menu->setAttribute(Qt::WA_DeleteOnClose);
const QList<QTreeWidgetItem *> selectedItems = m_feedListWidget->selectedItems();
if (!selectedItems.isEmpty()) {
if (!selectedItems.isEmpty())
{
menu->addAction(m_ui->actionUpdate);
menu->addAction(m_ui->actionMarkItemsRead);
menu->addSeparator();
if (selectedItems.size() == 1) {
if (selectedItems.first() != m_feedListWidget->stickyUnreadItem()) {
if (selectedItems.size() == 1)
{
if (selectedItems.first() != m_feedListWidget->stickyUnreadItem())
{
menu->addAction(m_ui->actionRename);
menu->addAction(m_ui->actionDelete);
menu->addSeparator();
@@ -164,19 +167,22 @@ void RSSWidget::displayRSSListMenu(const QPoint &pos)
menu->addAction(m_ui->actionNewFolder);
}
}
else {
else
{
menu->addAction(m_ui->actionDelete);
menu->addSeparator();
}
menu->addAction(m_ui->actionNewSubscription);
if (m_feedListWidget->isFeed(selectedItems.first())) {
if (m_feedListWidget->isFeed(selectedItems.first()))
{
menu->addSeparator();
menu->addAction(m_ui->actionCopyFeedURL);
}
}
else {
else
{
menu->addAction(m_ui->actionNewSubscription);
menu->addAction(m_ui->actionNewFolder);
menu->addSeparator();
@@ -190,7 +196,8 @@ void RSSWidget::displayItemsListMenu(const QPoint &)
{
bool hasTorrent = false;
bool hasLink = false;
for (const QListWidgetItem *item : asConst(m_articleListWidget->selectedItems())) {
for (const QListWidgetItem *item : asConst(m_articleListWidget->selectedItems()))
{
auto article = reinterpret_cast<RSS::Article *>(item->data(Qt::UserRole).value<quintptr>());
Q_ASSERT(article);
@@ -228,7 +235,8 @@ void RSSWidget::askNewFolder()
// Determine destination folder for new item
QTreeWidgetItem *destItem = nullptr;
QList<QTreeWidgetItem *> selectedItems = m_feedListWidget->selectedItems();
if (!selectedItems.empty()) {
if (!selectedItems.empty())
{
destItem = selectedItems.first();
if (!m_feedListWidget->isFolder(destItem))
destItem = destItem->parent();
@@ -268,7 +276,8 @@ void RSSWidget::on_newFeedButton_clicked()
// Determine destination folder for new item
QTreeWidgetItem *destItem = nullptr;
QList<QTreeWidgetItem *> selectedItems = m_feedListWidget->selectedItems();
if (!selectedItems.empty()) {
if (!selectedItems.empty())
{
destItem = selectedItems.first();
if (!m_feedListWidget->isFolder(destItem))
destItem = destItem->parent();
@@ -313,13 +322,17 @@ void RSSWidget::deleteSelectedItems()
void RSSWidget::loadFoldersOpenState()
{
const QStringList openedFolders = Preferences::instance()->getRssOpenFolders();
for (const QString &varPath : openedFolders) {
for (const QString &varPath : openedFolders)
{
QTreeWidgetItem *parent = nullptr;
for (const QString &name : asConst(varPath.split('\\'))) {
for (const QString &name : asConst(varPath.split('\\')))
{
int nbChildren = (parent ? parent->childCount() : m_feedListWidget->topLevelItemCount());
for (int i = 0; i < nbChildren; ++i) {
for (int i = 0; i < nbChildren; ++i)
{
QTreeWidgetItem *child = (parent ? parent->child(i) : m_feedListWidget->topLevelItem(i));
if (m_feedListWidget->getRSSItem(child)->name() == name) {
if (m_feedListWidget->getRSSItem(child)->name() == name)
{
parent = child;
parent->setExpanded(true);
break;
@@ -344,14 +357,16 @@ void RSSWidget::refreshAllFeeds()
void RSSWidget::downloadSelectedTorrents()
{
for (QListWidgetItem *item : asConst(m_articleListWidget->selectedItems())) {
for (QListWidgetItem *item : asConst(m_articleListWidget->selectedItems()))
{
auto article = reinterpret_cast<RSS::Article *>(item->data(Qt::UserRole).value<quintptr>());
Q_ASSERT(article);
// Mark as read
article->markAsRead();
if (!article->torrentUrl().isEmpty()) {
if (!article->torrentUrl().isEmpty())
{
if (AddNewTorrentDialog::isEnabled())
AddNewTorrentDialog::show(article->torrentUrl(), window());
else
@@ -363,7 +378,8 @@ void RSSWidget::downloadSelectedTorrents()
// open the url of the selected RSS articles in the Web browser
void RSSWidget::openSelectedArticlesUrls()
{
for (QListWidgetItem *item : asConst(m_articleListWidget->selectedItems())) {
for (QListWidgetItem *item : asConst(m_articleListWidget->selectedItems()))
{
auto article = reinterpret_cast<RSS::Article *>(item->data(Qt::UserRole).value<quintptr>());
Q_ASSERT(article);
@@ -387,7 +403,8 @@ void RSSWidget::renameSelectedRSSItem()
RSS::Item *rssItem = m_feedListWidget->getRSSItem(item);
const QString parentPath = RSS::Item::parentPath(rssItem->path());
bool ok = false;
do {
do
{
QString newName = AutoExpandableDialog::getText(
this, tr("Please choose a new name for this RSS feed"), tr("New feed name:")
, QLineEdit::Normal, rssItem->name(), &ok);
@@ -395,7 +412,8 @@ void RSSWidget::renameSelectedRSSItem()
if (!ok) return;
QString error;
if (!RSS::Session::instance()->moveItem(rssItem, RSS::Item::joinPath(parentPath, newName), &error)) {
if (!RSS::Session::instance()->moveItem(rssItem, RSS::Item::joinPath(parentPath, newName), &error))
{
QMessageBox::warning(nullptr, tr("Rename failed"), error);
ok = false;
}
@@ -404,8 +422,10 @@ void RSSWidget::renameSelectedRSSItem()
void RSSWidget::refreshSelectedItems()
{
for (QTreeWidgetItem *item : asConst(m_feedListWidget->selectedItems())) {
if (item == m_feedListWidget->stickyUnreadItem()) {
for (QTreeWidgetItem *item : asConst(m_feedListWidget->selectedItems()))
{
if (item == m_feedListWidget->stickyUnreadItem())
{
refreshAllFeeds();
return;
}
@@ -417,7 +437,8 @@ void RSSWidget::refreshSelectedItems()
void RSSWidget::copySelectedFeedsURL()
{
QStringList URLs;
for (QTreeWidgetItem *item : asConst(m_feedListWidget->selectedItems())) {
for (QTreeWidgetItem *item : asConst(m_feedListWidget->selectedItems()))
{
if (auto feed = qobject_cast<RSS::Feed *>(m_feedListWidget->getRSSItem(item)))
URLs << feed->url();
}
@@ -432,7 +453,8 @@ void RSSWidget::handleCurrentFeedItemChanged(QTreeWidgetItem *currentItem)
void RSSWidget::on_markReadButton_clicked()
{
for (QTreeWidgetItem *item : asConst(m_feedListWidget->selectedItems())) {
for (QTreeWidgetItem *item : asConst(m_feedListWidget->selectedItems()))
{
m_feedListWidget->getRSSItem(item)->markAsRead();
if (item == m_feedListWidget->stickyUnreadItem())
break; // all items was read
@@ -444,7 +466,8 @@ void RSSWidget::handleCurrentArticleItemChanged(QListWidgetItem *currentItem, QL
{
m_ui->textBrowser->clear();
if (previousItem) {
if (previousItem)
{
auto article = m_articleListWidget->getRSSArticle(previousItem);
Q_ASSERT(article);
article->markAsRead();
@@ -468,10 +491,12 @@ void RSSWidget::handleCurrentArticleItemChanged(QListWidgetItem *currentItem, QL
html += QString::fromLatin1("<div style='background-color: \"%1\";'><b>%2</b>%3</div>").arg(alternateBaseColor, tr("Author: "), article->author());
html += "</div>"
"<div style='margin-left: 5px; margin-right: 5px;'>";
if (Qt::mightBeRichText(article->description())) {
if (Qt::mightBeRichText(article->description()))
{
html += article->description();
}
else {
else
{
QString description = article->description();
QRegularExpression rx;
// If description is plain text, replace BBCode tags with HTML and wrap everything in <pre></pre> so it looks nice

View File

@@ -62,7 +62,8 @@ QWidget *ScanFoldersDelegate::createEditor(QWidget *parent, const QStyleOptionVi
editor->addItem(ScanFoldersModel::pathTypeDisplayName(ScanFoldersModel::DOWNLOAD_IN_WATCH_FOLDER));
editor->addItem(ScanFoldersModel::pathTypeDisplayName(ScanFoldersModel::DEFAULT_LOCATION));
editor->addItem(ScanFoldersModel::pathTypeDisplayName(ScanFoldersModel::CUSTOM_LOCATION));
if (index.data(Qt::UserRole).toInt() == ScanFoldersModel::CUSTOM_LOCATION) {
if (index.data(Qt::UserRole).toInt() == ScanFoldersModel::CUSTOM_LOCATION)
{
editor->insertSeparator(3);
editor->addItem(index.data().toString());
}
@@ -74,7 +75,8 @@ QWidget *ScanFoldersDelegate::createEditor(QWidget *parent, const QStyleOptionVi
void ScanFoldersDelegate::comboboxIndexChanged(int index)
{
if (index == ScanFoldersModel::CUSTOM_LOCATION) {
if (index == ScanFoldersModel::CUSTOM_LOCATION)
{
auto *w = static_cast<QWidget *>(sender());
if (w && w->parentWidget())
w->parentWidget()->setFocus();
@@ -86,7 +88,8 @@ void ScanFoldersDelegate::setModelData(QWidget *editor, QAbstractItemModel *mode
auto *combobox = static_cast<QComboBox*>(editor);
int value = combobox->currentIndex();
switch (value) {
switch (value)
{
case ScanFoldersModel::DOWNLOAD_IN_WATCH_FOLDER:
case ScanFoldersModel::DEFAULT_LOCATION:
model->setData(index, value, Qt::UserRole);

View File

@@ -108,9 +108,12 @@ void PluginSelectDialog::dropEvent(QDropEvent *event)
event->acceptProposedAction();
QStringList files;
if (event->mimeData()->hasUrls()) {
for (const QUrl &url : asConst(event->mimeData()->urls())) {
if (!url.isEmpty()) {
if (event->mimeData()->hasUrls())
{
for (const QUrl &url : asConst(event->mimeData()->urls()))
{
if (!url.isEmpty())
{
if (url.scheme().compare("file", Qt::CaseInsensitive) == 0)
files << url.toLocalFile();
else
@@ -118,13 +121,15 @@ void PluginSelectDialog::dropEvent(QDropEvent *event)
}
}
}
else {
else
{
files = event->mimeData()->text().split('\n');
}
if (files.isEmpty()) return;
for (const QString &file : asConst(files)) {
for (const QString &file : asConst(files))
{
qDebug("dropped %s", qUtf8Printable(file));
startAsyncOp();
m_pluginManager->installPlugin(file);
@@ -134,11 +139,13 @@ void PluginSelectDialog::dropEvent(QDropEvent *event)
// Decode if we accept drag 'n drop or not
void PluginSelectDialog::dragEnterEvent(QDragEnterEvent *event)
{
for (const QString &mime : asConst(event->mimeData()->formats())) {
for (const QString &mime : asConst(event->mimeData()->formats()))
{
qDebug("mimeData: %s", qUtf8Printable(mime));
}
if (event->mimeData()->hasFormat(QLatin1String("text/plain")) || event->mimeData()->hasFormat(QLatin1String("text/uri-list"))) {
if (event->mimeData()->hasFormat(QLatin1String("text/plain")) || event->mimeData()->hasFormat(QLatin1String("text/uri-list")))
{
event->acceptProposedAction();
}
}
@@ -153,11 +160,13 @@ void PluginSelectDialog::togglePluginState(QTreeWidgetItem *item, int)
{
PluginInfo *plugin = m_pluginManager->pluginInfo(item->text(PLUGIN_ID));
m_pluginManager->enablePlugin(plugin->name, !plugin->enabled);
if (plugin->enabled) {
if (plugin->enabled)
{
item->setText(PLUGIN_STATE, tr("Yes"));
setRowColor(m_ui->pluginsTree->indexOfTopLevelItem(item), "green");
}
else {
else
{
item->setText(PLUGIN_STATE, tr("No"));
setRowColor(m_ui->pluginsTree->indexOfTopLevelItem(item), "red");
}
@@ -189,14 +198,17 @@ void PluginSelectDialog::on_closeButton_clicked()
void PluginSelectDialog::on_actionUninstall_triggered()
{
bool error = false;
for (QTreeWidgetItem *item : asConst(m_ui->pluginsTree->selectedItems())) {
for (QTreeWidgetItem *item : asConst(m_ui->pluginsTree->selectedItems()))
{
int index = m_ui->pluginsTree->indexOfTopLevelItem(item);
Q_ASSERT(index != -1);
QString id = item->text(PLUGIN_ID);
if (m_pluginManager->uninstallPlugin(id)) {
if (m_pluginManager->uninstallPlugin(id))
{
delete item;
}
else {
else
{
error = true;
// Disable it instead
m_pluginManager->enablePlugin(id, false);
@@ -213,16 +225,19 @@ void PluginSelectDialog::on_actionUninstall_triggered()
void PluginSelectDialog::enableSelection(bool enable)
{
for (QTreeWidgetItem *item : asConst(m_ui->pluginsTree->selectedItems())) {
for (QTreeWidgetItem *item : asConst(m_ui->pluginsTree->selectedItems()))
{
int index = m_ui->pluginsTree->indexOfTopLevelItem(item);
Q_ASSERT(index != -1);
QString id = item->text(PLUGIN_ID);
m_pluginManager->enablePlugin(id, enable);
if (enable) {
if (enable)
{
item->setText(PLUGIN_STATE, tr("Yes"));
setRowColor(index, "green");
}
else {
else
{
item->setText(PLUGIN_STATE, tr("No"));
setRowColor(index, "red");
}
@@ -233,7 +248,8 @@ void PluginSelectDialog::enableSelection(bool enable)
void PluginSelectDialog::setRowColor(const int row, const QString &color)
{
QTreeWidgetItem *item = m_ui->pluginsTree->topLevelItem(row);
for (int i = 0; i < m_ui->pluginsTree->columnCount(); ++i) {
for (int i = 0; i < m_ui->pluginsTree->columnCount(); ++i)
{
item->setData(i, Qt::ForegroundRole, QColor(color));
}
}
@@ -243,7 +259,8 @@ QVector<QTreeWidgetItem*> PluginSelectDialog::findItemsWithUrl(const QString &ur
QVector<QTreeWidgetItem*> res;
res.reserve(m_ui->pluginsTree->topLevelItemCount());
for (int i = 0; i < m_ui->pluginsTree->topLevelItemCount(); ++i) {
for (int i = 0; i < m_ui->pluginsTree->topLevelItemCount(); ++i)
{
QTreeWidgetItem *item = m_ui->pluginsTree->topLevelItem(i);
if (url.startsWith(item->text(PLUGIN_URL), Qt::CaseInsensitive))
res << item;
@@ -254,7 +271,8 @@ QVector<QTreeWidgetItem*> PluginSelectDialog::findItemsWithUrl(const QString &ur
QTreeWidgetItem *PluginSelectDialog::findItemWithID(const QString &id)
{
for (int i = 0; i < m_ui->pluginsTree->topLevelItemCount(); ++i) {
for (int i = 0; i < m_ui->pluginsTree->topLevelItemCount(); ++i)
{
QTreeWidgetItem *item = m_ui->pluginsTree->topLevelItem(i);
if (id == item->text(PLUGIN_ID))
return item;
@@ -278,20 +296,24 @@ void PluginSelectDialog::addNewPlugin(const QString &pluginName)
item->setText(PLUGIN_NAME, plugin->fullName);
item->setText(PLUGIN_URL, plugin->url);
item->setText(PLUGIN_ID, plugin->name);
if (plugin->enabled) {
if (plugin->enabled)
{
item->setText(PLUGIN_STATE, tr("Yes"));
setRowColor(m_ui->pluginsTree->indexOfTopLevelItem(item), "green");
}
else {
else
{
item->setText(PLUGIN_STATE, tr("No"));
setRowColor(m_ui->pluginsTree->indexOfTopLevelItem(item), "red");
}
// Handle icon
if (QFile::exists(plugin->iconPath)) {
if (QFile::exists(plugin->iconPath))
{
// Good, we already have the icon
item->setData(PLUGIN_NAME, Qt::DecorationRole, QIcon(plugin->iconPath));
}
else {
else
{
// Icon is missing, we must download it
using namespace Net;
DownloadManager::instance()->download(
@@ -318,7 +340,8 @@ void PluginSelectDialog::finishAsyncOp()
void PluginSelectDialog::finishPluginUpdate()
{
--m_pendingUpdates;
if ((m_pendingUpdates == 0) && !m_updatedPlugins.isEmpty()) {
if ((m_pendingUpdates == 0) && !m_updatedPlugins.isEmpty())
{
m_updatedPlugins.sort(Qt::CaseInsensitive);
QMessageBox::information(this, tr("Search plugin update"), tr("Plugins installed or updated: %1").arg(m_updatedPlugins.join(", ")));
m_updatedPlugins.clear();
@@ -344,7 +367,8 @@ void PluginSelectDialog::askForPluginUrl()
tr("URL:"), QLineEdit::Normal, defaultUrl, &ok
);
while (ok && !url.isEmpty() && !url.endsWith(".py")) {
while (ok && !url.isEmpty() && !url.endsWith(".py"))
{
QMessageBox::warning(this, tr("Invalid link"), tr("The link doesn't seem to point to a search engine plugin."));
url = AutoExpandableDialog::getText(
this, tr("New search engine plugin URL"),
@@ -352,7 +376,8 @@ void PluginSelectDialog::askForPluginUrl()
);
}
if (ok && !url.isEmpty()) {
if (ok && !url.isEmpty())
{
startAsyncOp();
m_pluginManager->installPlugin(url);
}
@@ -364,7 +389,8 @@ void PluginSelectDialog::askForLocalPlugin()
nullptr, tr("Select search plugins"), QDir::homePath(),
tr("qBittorrent search plugin") + QLatin1String(" (*.py)")
);
for (const QString &path : pathsList) {
for (const QString &path : pathsList)
{
startAsyncOp();
m_pluginManager->installPlugin(path);
}
@@ -372,7 +398,8 @@ void PluginSelectDialog::askForLocalPlugin()
void PluginSelectDialog::iconDownloadFinished(const Net::DownloadResult &result)
{
if (result.status != Net::DownloadStatus::Success) {
if (result.status != Net::DownloadStatus::Success)
{
qDebug("Could not download favicon: %s, reason: %s", qUtf8Printable(result.url), qUtf8Printable(result.errorString));
return;
}
@@ -384,8 +411,10 @@ void PluginSelectDialog::iconDownloadFinished(const Net::DownloadResult &result)
// Detect a non-decodable icon
QList<QSize> sizes = icon.availableSizes();
bool invalid = (sizes.isEmpty() || icon.pixmap(sizes.first()).isNull());
if (!invalid) {
for (QTreeWidgetItem *item : asConst(findItemsWithUrl(result.url))) {
if (!invalid)
{
for (QTreeWidgetItem *item : asConst(findItemsWithUrl(result.url)))
{
QString id = item->text(PLUGIN_ID);
PluginInfo *plugin = m_pluginManager->pluginInfo(id);
if (!plugin) continue;
@@ -394,14 +423,16 @@ void PluginSelectDialog::iconDownloadFinished(const Net::DownloadResult &result)
.arg(SearchPluginManager::pluginsLocation()
, id
, result.url.endsWith(".ico", Qt::CaseInsensitive) ? "ico" : "png");
if (QFile::copy(filePath, iconPath)) {
if (QFile::copy(filePath, iconPath))
{
// This 2nd check is necessary. Some favicons (eg from piratebay)
// decode fine without an ext, but fail to do so when appending the ext
// from the url. Probably a Qt bug.
QIcon iconWithExt(iconPath);
QList<QSize> sizesExt = iconWithExt.availableSizes();
bool invalidExt = (sizesExt.isEmpty() || iconWithExt.pixmap(sizesExt.first()).isNull());
if (invalidExt) {
if (invalidExt)
{
Utils::Fs::forceRemove(iconPath);
continue;
}
@@ -418,12 +449,14 @@ void PluginSelectDialog::iconDownloadFinished(const Net::DownloadResult &result)
void PluginSelectDialog::checkForUpdatesFinished(const QHash<QString, PluginVersion> &updateInfo)
{
finishAsyncOp();
if (updateInfo.isEmpty()) {
if (updateInfo.isEmpty())
{
QMessageBox::information(this, tr("Search plugin update"), tr("All your plugins are already up to date."));
return;
}
for (auto i = updateInfo.cbegin(); i != updateInfo.cend(); ++i) {
for (auto i = updateInfo.cbegin(); i != updateInfo.cend(); ++i)
{
startAsyncOp();
++m_pendingUpdates;
m_pluginManager->updatePlugin(i.key());

View File

@@ -101,8 +101,10 @@ SearchJobWidget::SearchJobWidget(SearchHandler *searchHandler, QWidget *parent)
// Ensure that at least one column is visible at all times
bool atLeastOne = false;
for (int i = 0; i < SearchSortModel::DL_LINK; ++i) {
if (!m_ui->resultsBrowser->isColumnHidden(i)) {
for (int i = 0; i < SearchSortModel::DL_LINK; ++i)
{
if (!m_ui->resultsBrowser->isColumnHidden(i))
{
atLeastOne = true;
break;
}
@@ -218,7 +220,8 @@ void SearchJobWidget::downloadTorrents()
void SearchJobWidget::openTorrentPages() const
{
const QModelIndexList rows {m_ui->resultsBrowser->selectionModel()->selectedRows()};
for (const QModelIndex &rowIndex : rows) {
for (const QModelIndex &rowIndex : rows)
{
const QString descrLink = m_proxyModel->data(
m_proxyModel->index(rowIndex.row(), SearchSortModel::DESC_LINK)).toString();
if (!descrLink.isEmpty())
@@ -246,7 +249,8 @@ void SearchJobWidget::copyField(const int column) const
const QModelIndexList rows {m_ui->resultsBrowser->selectionModel()->selectedRows()};
QStringList list;
for (const QModelIndex &rowIndex : rows) {
for (const QModelIndex &rowIndex : rows)
{
const QString field = m_proxyModel->data(
m_proxyModel->index(rowIndex.row(), column)).toString();
if (!field.isEmpty())
@@ -273,10 +277,12 @@ void SearchJobWidget::downloadTorrent(const QModelIndex &rowIndex)
const QString siteUrl = m_proxyModel->data(
m_proxyModel->index(rowIndex.row(), SearchSortModel::ENGINE_URL)).toString();
if (torrentUrl.startsWith("magnet:", Qt::CaseInsensitive)) {
if (torrentUrl.startsWith("magnet:", Qt::CaseInsensitive))
{
addTorrentToSession(torrentUrl);
}
else {
else
{
SearchDownloadHandler *downloadHandler = m_searchHandler->manager()->downloadTorrent(siteUrl, torrentUrl);
connect(downloadHandler, &SearchDownloadHandler::downloadFinished, this, &SearchJobWidget::addTorrentToSession);
connect(downloadHandler, &SearchDownloadHandler::downloadFinished, downloadHandler, &SearchDownloadHandler::deleteLater);
@@ -418,7 +424,8 @@ void SearchJobWidget::contextMenuEvent(QContextMenuEvent *event)
QString SearchJobWidget::statusText(SearchJobWidget::Status st)
{
switch (st) {
switch (st)
{
case Status::Ongoing:
return tr("Searching...");
case Status::Finished:
@@ -455,7 +462,8 @@ void SearchJobWidget::displayToggleColumnsMenu(const QPoint &)
menu->setAttribute(Qt::WA_DeleteOnClose);
menu->setTitle(tr("Column visibility"));
for (int i = 0; i < SearchSortModel::DL_LINK; ++i) {
for (int i = 0; i < SearchSortModel::DL_LINK; ++i)
{
QAction *myAct = menu->addAction(m_searchListModel->headerData(i, Qt::Horizontal, Qt::DisplayRole).toString());
myAct->setCheckable(true);
myAct->setChecked(!m_ui->resultsBrowser->isColumnHidden(i));
@@ -465,7 +473,8 @@ void SearchJobWidget::displayToggleColumnsMenu(const QPoint &)
connect(menu, &QMenu::triggered, this, [this](const QAction *action)
{
int visibleCols = 0;
for (int i = 0; i < SearchSortModel::DL_LINK; ++i) {
for (int i = 0; i < SearchSortModel::DL_LINK; ++i)
{
if (!m_ui->resultsBrowser->isColumnHidden(i))
++visibleCols;
@@ -506,7 +515,8 @@ void SearchJobWidget::searchFailed()
void SearchJobWidget::appendSearchResults(const QVector<SearchResult> &results)
{
for (const SearchResult &result : results) {
for (const SearchResult &result : results)
{
// Add item to search result list
int row = m_searchListModel->rowCount();
m_searchListModel->insertRow(row);
@@ -543,7 +553,8 @@ CachedSettingValue<SearchJobWidget::NameFilteringMode> &SearchJobWidget::nameFil
void SearchJobWidget::keyPressEvent(QKeyEvent *event)
{
switch (event->key()) {
switch (event->key())
{
case Qt::Key_Enter:
case Qt::Key_Return:
downloadTorrents();

View File

@@ -54,10 +54,12 @@ void SearchSortModel::setNameFilter(const QString &searchTerm)
{
m_searchTerm = searchTerm;
if ((searchTerm.length() > 2)
&& searchTerm.startsWith(QLatin1Char('"')) && searchTerm.endsWith(QLatin1Char('"'))) {
&& searchTerm.startsWith(QLatin1Char('"')) && searchTerm.endsWith(QLatin1Char('"')))
{
m_searchTermWords = QStringList(m_searchTerm.mid(1, m_searchTerm.length() - 2));
}
else {
else
{
m_searchTermWords = searchTerm.split(QLatin1Char(' '), QString::SkipEmptyParts);
}
}
@@ -112,9 +114,11 @@ qint64 SearchSortModel::maxSize() const
bool SearchSortModel::lessThan(const QModelIndex &left, const QModelIndex &right) const
{
switch (sortColumn()) {
switch (sortColumn())
{
case NAME:
case ENGINE_URL: {
case ENGINE_URL:
{
const QString strL = left.data().toString();
const QString strR = right.data().toString();
const int result = Utils::String::naturalCompare(strL, strR, Qt::CaseInsensitive);
@@ -130,29 +134,34 @@ bool SearchSortModel::filterAcceptsRow(const int sourceRow, const QModelIndex &s
{
const QAbstractItemModel *const sourceModel = this->sourceModel();
if (m_isNameFilterEnabled && !m_searchTerm.isEmpty()) {
if (m_isNameFilterEnabled && !m_searchTerm.isEmpty())
{
const QString name = sourceModel->data(sourceModel->index(sourceRow, NAME, sourceParent), UnderlyingDataRole).toString();
for (const QString &word : asConst(m_searchTermWords)) {
for (const QString &word : asConst(m_searchTermWords))
{
if (!name.contains(word, Qt::CaseInsensitive))
return false;
}
}
if ((m_minSize > 0) || (m_maxSize >= 0)) {
if ((m_minSize > 0) || (m_maxSize >= 0))
{
const qlonglong size = sourceModel->data(sourceModel->index(sourceRow, SIZE, sourceParent), UnderlyingDataRole).toLongLong();
if (((m_minSize > 0) && (size < m_minSize))
|| ((m_maxSize > 0) && (size > m_maxSize)))
return false;
}
if ((m_minSeeds > 0) || (m_maxSeeds >= 0)) {
if ((m_minSeeds > 0) || (m_maxSeeds >= 0))
{
const int seeds = sourceModel->data(sourceModel->index(sourceRow, SEEDS, sourceParent), UnderlyingDataRole).toInt();
if (((m_minSeeds > 0) && (seeds < m_minSeeds))
|| ((m_maxSeeds > 0) && (seeds > m_maxSeeds)))
return false;
}
if ((m_minLeeches > 0) || (m_maxLeeches >= 0)) {
if ((m_minLeeches > 0) || (m_maxLeeches >= 0))
{
const int leeches = sourceModel->data(sourceModel->index(sourceRow, LEECHES, sourceParent), UnderlyingDataRole).toInt();
if (((m_minLeeches > 0) && (leeches < m_minLeeches))
|| ((m_maxLeeches > 0) && (leeches > m_maxLeeches)))

View File

@@ -63,7 +63,8 @@ namespace
{
QString statusIconName(SearchJobWidget::Status st)
{
switch (st) {
switch (st)
{
case SearchJobWidget::Status::Ongoing:
return QLatin1String("task-ongoing");
case SearchJobWidget::Status::Finished:
@@ -148,14 +149,16 @@ SearchWidget::SearchWidget(MainWindow *mainWindow)
bool SearchWidget::eventFilter(QObject *object, QEvent *event)
{
if (object == m_ui->tabWidget->tabBar()) {
if (object == m_ui->tabWidget->tabBar())
{
// Close tabs when middle-clicked
if (event->type() != QEvent::MouseButtonRelease)
return false;
const auto mouseEvent = static_cast<QMouseEvent *>(event);
const int tabIndex = m_ui->tabWidget->tabBar()->tabAt(mouseEvent->pos());
if ((mouseEvent->button() == Qt::MiddleButton) && (tabIndex >= 0)) {
if ((mouseEvent->button() == Qt::MiddleButton) && (tabIndex >= 0))
{
closeTab(tabIndex);
return true;
}
@@ -175,7 +178,8 @@ void SearchWidget::fillCatCombobox()
tmpList << qMakePair(SearchPluginManager::categoryFullName(cat), cat);
std::sort(tmpList.begin(), tmpList.end(), [](const QStrPair &l, const QStrPair &r) { return (QString::localeAwareCompare(l.first, r.first) < 0); });
for (const QStrPair &p : asConst(tmpList)) {
for (const QStrPair &p : asConst(tmpList))
{
qDebug("Supported category: %s", qUtf8Printable(p.second));
m_ui->comboCategory->addItem(p.first, p.second);
}
@@ -216,14 +220,16 @@ QString SearchWidget::selectedPlugin() const
void SearchWidget::selectActivePage()
{
if (SearchPluginManager::instance()->allPlugins().isEmpty()) {
if (SearchPluginManager::instance()->allPlugins().isEmpty())
{
m_ui->stackedPages->setCurrentWidget(m_ui->emptyPage);
m_ui->lineEditSearchPattern->setEnabled(false);
m_ui->comboCategory->setEnabled(false);
m_ui->selectPlugin->setEnabled(false);
m_ui->searchButton->setEnabled(false);
}
else {
else
{
m_ui->stackedPages->setCurrentWidget(m_ui->searchPage);
m_ui->lineEditSearchPattern->setEnabled(true);
m_ui->comboCategory->setEnabled(true);
@@ -254,11 +260,13 @@ void SearchWidget::selectMultipleBox(int index)
void SearchWidget::toggleFocusBetweenLineEdits()
{
if (m_ui->lineEditSearchPattern->hasFocus() && m_currentSearchTab) {
if (m_ui->lineEditSearchPattern->hasFocus() && m_currentSearchTab)
{
m_currentSearchTab->lineEditSearchResultsFilter()->setFocus();
m_currentSearchTab->lineEditSearchResultsFilter()->selectAll();
}
else {
else
{
m_ui->lineEditSearchPattern->setFocus();
m_ui->lineEditSearchPattern->selectAll();
}
@@ -284,14 +292,17 @@ void SearchWidget::giveFocusToSearchInput()
// Function called when we click on search button
void SearchWidget::on_searchButton_clicked()
{
if (!Utils::ForeignApps::pythonInfo().isValid()) {
if (!Utils::ForeignApps::pythonInfo().isValid())
{
m_mainWindow->showNotificationBaloon(tr("Search Engine"), tr("Please install Python to use the Search Engine."));
return;
}
if (m_activeSearchTab) {
if (m_activeSearchTab)
{
m_activeSearchTab->cancelSearch();
if (!m_isNewQueryString) {
if (!m_isNewQueryString)
{
m_ui->searchButton->setText(tr("Search"));
return;
}
@@ -301,7 +312,8 @@ void SearchWidget::on_searchButton_clicked()
const QString pattern = m_ui->lineEditSearchPattern->text().trimmed();
// No search pattern entered
if (pattern.isEmpty()) {
if (pattern.isEmpty())
{
QMessageBox::critical(this, tr("Empty search pattern"), tr("Please type a search pattern first"));
return;
}
@@ -344,10 +356,12 @@ void SearchWidget::tabStatusChanged(QWidget *tab)
m_ui->tabWidget->setTabIcon(tabIndex, UIThemeManager::instance()->getIcon(
statusIconName(static_cast<SearchJobWidget *>(tab)->status())));
if ((tab == m_activeSearchTab) && (m_activeSearchTab->status() != SearchJobWidget::Status::Ongoing)) {
if ((tab == m_activeSearchTab) && (m_activeSearchTab->status() != SearchJobWidget::Status::Ongoing))
{
Q_ASSERT(m_activeSearchTab->status() != SearchJobWidget::Status::Ongoing);
if (m_mainWindow->isNotificationsEnabled() && (m_mainWindow->currentTabWidget() != this)) {
if (m_mainWindow->isNotificationsEnabled() && (m_mainWindow->currentTabWidget() != this))
{
if (m_activeSearchTab->status() == SearchJobWidget::Status::Error)
m_mainWindow->showNotificationBaloon(tr("Search Engine"), tr("Search has failed"));
else

View File

@@ -91,7 +91,8 @@ void ShutdownConfirmDialog::updateSeconds()
{
--m_timeout;
updateText();
if (m_timeout == 0) {
if (m_timeout == 0)
{
m_timer.stop();
accept();
}
@@ -107,7 +108,8 @@ void ShutdownConfirmDialog::initText()
{
QPushButton *okButton = m_ui->buttonBox->button(QDialogButtonBox::Ok);
switch (m_action) {
switch (m_action)
{
case ShutdownDialogAction::Exit:
m_msg = tr("qBittorrent will now exit.");
okButton->setText(tr("E&xit Now"));

View File

@@ -59,7 +59,8 @@ long SpeedLimitDialog::askSpeedLimit(QWidget *parent, bool *ok, const QString &t
dlg.setWindowTitle(title);
dlg.setupDialog((maxVal / 1024.), (defaultVal / 1024.));
if (dlg.exec() == QDialog::Accepted) {
if (dlg.exec() == QDialog::Accepted)
{
if (ok) *ok = true;
const int val = dlg.getSpeedLimit();

View File

@@ -173,17 +173,21 @@ void StatusBar::updateConnectionStatus()
{
const BitTorrent::SessionStatus &sessionStatus = BitTorrent::Session::instance()->status();
if (!BitTorrent::Session::instance()->isListening()) {
if (!BitTorrent::Session::instance()->isListening())
{
m_connecStatusLblIcon->setIcon(UIThemeManager::instance()->getIcon(QLatin1String("disconnected")));
m_connecStatusLblIcon->setToolTip(QLatin1String("<b>") + tr("Connection Status:") + QLatin1String("</b><br>") + tr("Offline. This usually means that qBittorrent failed to listen on the selected port for incoming connections."));
}
else {
if (sessionStatus.hasIncomingConnections) {
else
{
if (sessionStatus.hasIncomingConnections)
{
// Connection OK
m_connecStatusLblIcon->setIcon(UIThemeManager::instance()->getIcon(QLatin1String("connected")));
m_connecStatusLblIcon->setToolTip(QLatin1String("<b>") + tr("Connection Status:") + QLatin1String("</b><br>") + tr("Online"));
}
else {
else
{
m_connecStatusLblIcon->setIcon(UIThemeManager::instance()->getIcon(QLatin1String("firewalled")));
m_connecStatusLblIcon->setToolTip(QLatin1String("<b>") + tr("Connection status:") + QLatin1String("</b><br>") + QLatin1String("<i>") + tr("No direct connections. This may indicate network configuration problems.") + QLatin1String("</i>"));
}
@@ -192,12 +196,14 @@ void StatusBar::updateConnectionStatus()
void StatusBar::updateDHTNodesNumber()
{
if (BitTorrent::Session::instance()->isDHTEnabled()) {
if (BitTorrent::Session::instance()->isDHTEnabled())
{
m_DHTLbl->setVisible(true);
m_DHTLbl->setText(tr("DHT: %1 nodes")
.arg(BitTorrent::Session::instance()->status().dhtNodes));
}
else {
else
{
m_DHTLbl->setVisible(false);
}
}
@@ -230,12 +236,14 @@ void StatusBar::refresh()
void StatusBar::updateAltSpeedsBtn(bool alternative)
{
if (alternative) {
if (alternative)
{
m_altSpeedsBtn->setIcon(UIThemeManager::instance()->getIcon(QLatin1String("slow")));
m_altSpeedsBtn->setToolTip(tr("Click to switch to regular speed limits"));
m_altSpeedsBtn->setDown(true);
}
else {
else
{
m_altSpeedsBtn->setIcon(UIThemeManager::instance()->getIcon(QLatin1String("slow_off")));
m_altSpeedsBtn->setToolTip(tr("Click to switch to alternative speed limits"));
m_altSpeedsBtn->setDown(false);
@@ -250,7 +258,8 @@ void StatusBar::capDownloadSpeed()
bool ok = false;
const long newLimit = SpeedLimitDialog::askSpeedLimit(
parentWidget(), &ok, tr("Global Download Speed Limit"), session->downloadSpeedLimit());
if (ok) {
if (ok)
{
qDebug("Setting global download rate limit to %.1fKb/s", newLimit / 1024.);
session->setDownloadSpeedLimit(newLimit);
refresh();
@@ -264,7 +273,8 @@ void StatusBar::capUploadSpeed()
bool ok = false;
const long newLimit = SpeedLimitDialog::askSpeedLimit(
parentWidget(), &ok, tr("Global Upload Speed Limit"), session->uploadSpeedLimit());
if (ok) {
if (ok)
{
qDebug("Setting global upload rate limit to %.1fKb/s", newLimit / 1024.);
session->setUploadSpeedLimit(newLimit);
refresh();

View File

@@ -120,7 +120,8 @@ QVariant TagFilterModel::data(const QModelIndex &index, int role) const
Q_ASSERT(isValidRow(row));
const TagModelItem &item = m_tagItems[row];
switch (role) {
switch (role)
{
case Qt::DecorationRole:
return UIThemeManager::instance()->getIcon("inode-directory");
case Qt::DisplayRole:
@@ -275,7 +276,8 @@ void TagFilterModel::populate()
[](Torrent *torrent) { return torrent->tags().isEmpty(); });
addToModel(getSpecialUntaggedTag(), untaggedCount);
for (const QString &tag : asConst(session->tags())) {
for (const QString &tag : asConst(session->tags()))
{
const int count = std::count_if(torrents.cbegin(), torrents.cend(),
[tag](Torrent *torrent) { return torrent->hasTag(tag); });
addToModel(tag, count);
@@ -295,7 +297,8 @@ void TagFilterModel::removeFromModel(int row)
int TagFilterModel::findRow(const QString &tag) const
{
for (int i = 0; i < m_tagItems.size(); ++i) {
for (int i = 0; i < m_tagItems.size(); ++i)
{
if (m_tagItems[i].tag() == tag)
return i;
}
@@ -314,7 +317,8 @@ QVector<TagModelItem *> TagFilterModel::findItems(const QSet<QString> &tags)
{
QVector<TagModelItem *> items;
items.reserve(tags.size());
for (const QString &tag : tags) {
for (const QString &tag : tags)
{
TagModelItem *item = findItem(tag);
if (item)
items.push_back(item);

View File

@@ -45,7 +45,8 @@ namespace
QString getTagFilter(const TagFilterProxyModel *const model, const QModelIndex &index)
{
QString tagFilter; // Defaults to All
if (index.isValid()) {
if (index.isValid())
{
if (index.row() == 1)
tagFilter = ""; // Untagged
else if (index.row() > 1)
@@ -113,7 +114,8 @@ void TagFilterWidget::showMenu(QPoint)
connect(addAct, &QAction::triggered, this, &TagFilterWidget::addTag);
const auto selectedRows = selectionModel()->selectedRows();
if (!selectedRows.empty() && !TagFilterModel::isSpecialItem(selectedRows.first())) {
if (!selectedRows.empty() && !TagFilterModel::isSpecialItem(selectedRows.first()))
{
const QAction *removeAct = menu->addAction(
UIThemeManager::instance()->getIcon("list-remove")
, tr("Remove tag"));
@@ -155,7 +157,8 @@ void TagFilterWidget::callUpdateGeometry()
QSize TagFilterWidget::sizeHint() const
{
return {
return
{
// Width should be exactly the width of the content
sizeHintForColumn(0),
// Height should be exactly the height of the content
@@ -181,12 +184,15 @@ QString TagFilterWidget::askTagName()
bool ok = false;
QString tag = "";
bool invalid = true;
while (invalid) {
while (invalid)
{
invalid = false;
tag = AutoExpandableDialog::getText(
this, tr("New Tag"), tr("Tag:"), QLineEdit::Normal, tag, &ok).trimmed();
if (ok && !tag.isEmpty()) {
if (!BitTorrent::Session::isValidTag(tag)) {
if (ok && !tag.isEmpty())
{
if (!BitTorrent::Session::isValidTag(tag))
{
QMessageBox::warning(
this, tr("Invalid tag name")
, tr("Tag name '%1' is invalid").arg(tag));
@@ -212,7 +218,8 @@ void TagFilterWidget::addTag()
void TagFilterWidget::removeTag()
{
const auto selectedRows = selectionModel()->selectedRows();
if (!selectedRows.empty() && !TagFilterModel::isSpecialItem(selectedRows.first())) {
if (!selectedRows.empty() && !TagFilterModel::isSpecialItem(selectedRows.first()))
{
BitTorrent::Session::instance()->removeTag(
static_cast<TagFilterProxyModel *>(model())->tag(selectedRows.first()));
updateGeometry();

View File

@@ -58,23 +58,27 @@ QString TorrentCategoryDialog::createCategory(QWidget *parent, const QString &pa
TorrentCategoryDialog dialog(parent);
dialog.setCategoryName(newCategoryName);
while (dialog.exec() == TorrentCategoryDialog::Accepted) {
while (dialog.exec() == TorrentCategoryDialog::Accepted)
{
newCategoryName = dialog.categoryName();
if (!BitTorrent::Session::isValidCategoryName(newCategoryName)) {
if (!BitTorrent::Session::isValidCategoryName(newCategoryName))
{
QMessageBox::critical(
parent, tr("Invalid category name")
, tr("Category name cannot contain '\\'.\n"
"Category name cannot start/end with '/'.\n"
"Category name cannot contain '//' sequence."));
}
else if (BitTorrent::Session::instance()->categories().contains(newCategoryName)) {
else if (BitTorrent::Session::instance()->categories().contains(newCategoryName))
{
QMessageBox::critical(
parent, tr("Category creation error")
, tr("Category with the given name already exists.\n"
"Please choose a different name and try again."));
}
else {
else
{
Session::instance()->addCategory(newCategoryName, dialog.savePath());
return newCategoryName;
}

View File

@@ -71,7 +71,8 @@ QModelIndex TorrentContentFilterModel::parent(const QModelIndex &child) const
bool TorrentContentFilterModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const
{
if (m_model->itemType(m_model->index(sourceRow, 0, sourceParent)) == TorrentContentModelItem::FolderType) {
if (m_model->itemType(m_model->index(sourceRow, 0, sourceParent)) == TorrentContentModelItem::FolderType)
{
// accept folders if they have at least one filtered item
return hasFiltered(m_model->index(sourceRow, 0, sourceParent));
}
@@ -81,17 +82,21 @@ bool TorrentContentFilterModel::filterAcceptsRow(int sourceRow, const QModelInde
bool TorrentContentFilterModel::lessThan(const QModelIndex &left, const QModelIndex &right) const
{
switch (sortColumn()) {
case TorrentContentModelItem::COL_NAME: {
switch (sortColumn())
{
case TorrentContentModelItem::COL_NAME:
{
const TorrentContentModelItem::ItemType leftType = m_model->itemType(m_model->index(left.row(), 0, left.parent()));
const TorrentContentModelItem::ItemType rightType = m_model->itemType(m_model->index(right.row(), 0, right.parent()));
if (leftType == rightType) {
if (leftType == rightType)
{
const QString strL = left.data().toString();
const QString strR = right.data().toString();
return Utils::String::naturalLessThan<Qt::CaseInsensitive>(strL, strR);
}
if ((leftType == TorrentContentModelItem::FolderType) && (sortOrder() == Qt::AscendingOrder)) {
if ((leftType == TorrentContentModelItem::FolderType) && (sortOrder() == Qt::AscendingOrder))
{
return true;
}
@@ -125,9 +130,11 @@ bool TorrentContentFilterModel::hasFiltered(const QModelIndex &folder) const
QString name = folder.data().toString();
if (name.contains(filterRegExp()))
return true;
for (int child = 0; child < m_model->rowCount(folder); ++child) {
for (int child = 0; child < m_model->rowCount(folder); ++child)
{
QModelIndex childIndex = m_model->index(child, 0, folder);
if (m_model->hasChildren(childIndex)) {
if (m_model->hasChildren(childIndex))
{
if (hasFiltered(childIndex))
return true;
continue;

View File

@@ -85,12 +85,14 @@ namespace
QIcon icon(const QFileInfo &info) const final
{
const QString ext = info.suffix();
if (!ext.isEmpty()) {
if (!ext.isEmpty())
{
QPixmap cached;
if (QPixmapCache::find(ext, &cached)) return {cached};
const QPixmap pixmap = pixmapForExtension(ext);
if (!pixmap.isNull()) {
if (!pixmap.isNull())
{
QPixmapCache::insert(ext, pixmap);
return {pixmap};
}
@@ -160,12 +162,14 @@ namespace
{
const QMimeType mimeType = m_db.mimeTypeForFile(info, QMimeDatabase::MatchExtension);
QIcon res = QIcon::fromTheme(mimeType.iconName());
if (!res.isNull()) {
if (!res.isNull())
{
return res;
}
res = QIcon::fromTheme(mimeType.genericIconName());
if (!res.isNull()) {
if (!res.isNull())
{
return res;
}
@@ -270,10 +274,12 @@ bool TorrentContentModel::setData(const QModelIndex &index, const QVariant &valu
if (!index.isValid())
return false;
if ((index.column() == TorrentContentModelItem::COL_NAME) && (role == Qt::CheckStateRole)) {
if ((index.column() == TorrentContentModelItem::COL_NAME) && (role == Qt::CheckStateRole))
{
auto *item = static_cast<TorrentContentModelItem*>(index.internalPointer());
qDebug("setData(%s, %d", qUtf8Printable(item->name()), value.toInt());
if (static_cast<int>(item->priority()) != value.toInt()) {
if (static_cast<int>(item->priority()) != value.toInt())
{
BitTorrent::DownloadPriority prio = BitTorrent::DownloadPriority::Normal;
if (value.toInt() == Qt::PartiallyChecked)
prio = BitTorrent::DownloadPriority::Mixed;
@@ -290,10 +296,12 @@ bool TorrentContentModel::setData(const QModelIndex &index, const QVariant &valu
return true;
}
if (role == Qt::EditRole) {
if (role == Qt::EditRole)
{
Q_ASSERT(index.isValid());
auto *item = static_cast<TorrentContentModelItem*>(index.internalPointer());
switch (index.column()) {
switch (index.column())
{
case TorrentContentModelItem::COL_NAME:
item->setName(value.toString());
break;
@@ -332,8 +340,10 @@ QVariant TorrentContentModel::data(const QModelIndex &index, int role) const
auto *item = static_cast<TorrentContentModelItem*>(index.internalPointer());
switch (role) {
case Qt::DecorationRole: {
switch (role)
{
case Qt::DecorationRole:
{
if (index.column() != TorrentContentModelItem::COL_NAME)
return {};
@@ -341,7 +351,8 @@ QVariant TorrentContentModel::data(const QModelIndex &index, int role) const
return m_fileIconProvider->icon(QFileIconProvider::Folder);
return m_fileIconProvider->icon(QFileInfo(item->name()));
}
case Qt::CheckStateRole: {
case Qt::CheckStateRole:
{
if (index.column() != TorrentContentModelItem::COL_NAME)
return {};
@@ -384,7 +395,8 @@ QVariant TorrentContentModel::headerData(int section, Qt::Orientation orientatio
if (orientation != Qt::Horizontal)
return {};
switch (role) {
switch (role)
{
case Qt::DisplayRole:
return m_rootItem->displayData(section);
@@ -476,7 +488,8 @@ void TorrentContentModel::setupModelData(const BitTorrent::TorrentInfo &info)
TorrentContentModelFolder *currentParent;
// Iterate over files
for (int i = 0; i < filesCount; ++i) {
for (int i = 0; i < filesCount; ++i)
{
currentParent = m_rootItem;
const QString path = Utils::Fs::toUniformPath(info.filePath(i));
@@ -484,10 +497,12 @@ void TorrentContentModel::setupModelData(const BitTorrent::TorrentInfo &info)
QVector<QStringRef> pathFolders = path.splitRef('/', QString::SkipEmptyParts);
pathFolders.removeLast();
for (const QStringRef &pathPartRef : asConst(pathFolders)) {
for (const QStringRef &pathPartRef : asConst(pathFolders))
{
const QString pathPart = pathPartRef.toString();
TorrentContentModelFolder *newParent = currentParent->childFolderWithName(pathPart);
if (!newParent) {
if (!newParent)
{
newParent = new TorrentContentModelFolder(pathPart, currentParent);
currentParent->appendChild(newParent);
}
@@ -503,7 +518,8 @@ void TorrentContentModel::setupModelData(const BitTorrent::TorrentInfo &info)
void TorrentContentModel::selectAll()
{
for (int i = 0; i < m_rootItem->childCount(); ++i) {
for (int i = 0; i < m_rootItem->childCount(); ++i)
{
TorrentContentModelItem* child = m_rootItem->child(i);
if (child->priority() == BitTorrent::DownloadPriority::Ignored)
child->setPriority(BitTorrent::DownloadPriority::Normal);

View File

@@ -88,7 +88,8 @@ TorrentContentModelItem *TorrentContentModelFolder::child(int row) const
TorrentContentModelFolder *TorrentContentModelFolder::childFolderWithName(const QString &name) const
{
for (TorrentContentModelItem *child : asConst(m_childItems)) {
for (TorrentContentModelItem *child : asConst(m_childItems))
{
if ((child->itemType() == FolderType) && (child->name() == name))
return static_cast<TorrentContentModelFolder *>(child);
}
@@ -112,8 +113,10 @@ void TorrentContentModelFolder::updatePriority()
// then the folder should have the same
// priority
const BitTorrent::DownloadPriority prio = m_childItems.first()->priority();
for (int i = 1; i < m_childItems.size(); ++i) {
if (m_childItems.at(i)->priority() != prio) {
for (int i = 1; i < m_childItems.size(); ++i)
{
if (m_childItems.at(i)->priority() != prio)
{
setPriority(BitTorrent::DownloadPriority::Mixed);
return;
}
@@ -145,7 +148,8 @@ void TorrentContentModelFolder::recalculateProgress()
qreal tProgress = 0;
qulonglong tSize = 0;
qulonglong tRemaining = 0;
for (TorrentContentModelItem *child : asConst(m_childItems)) {
for (TorrentContentModelItem *child : asConst(m_childItems))
{
if (child->priority() == BitTorrent::DownloadPriority::Ignored)
continue;
@@ -156,7 +160,8 @@ void TorrentContentModelFolder::recalculateProgress()
tRemaining += child->remaining();
}
if (!isRootItem() && (tSize > 0)) {
if (!isRootItem() && (tSize > 0))
{
m_progress = tProgress / tSize;
m_remaining = tRemaining;
Q_ASSERT(m_progress <= 1.);
@@ -168,25 +173,29 @@ void TorrentContentModelFolder::recalculateAvailability()
qreal tAvailability = 0;
qulonglong tSize = 0;
bool foundAnyData = false;
for (TorrentContentModelItem *child : asConst(m_childItems)) {
for (TorrentContentModelItem *child : asConst(m_childItems))
{
if (child->priority() == BitTorrent::DownloadPriority::Ignored)
continue;
if (child->itemType() == FolderType)
static_cast<TorrentContentModelFolder*>(child)->recalculateAvailability();
const qreal childAvailability = child->availability();
if (childAvailability >= 0) { // -1 means "no data"
if (childAvailability >= 0)
{ // -1 means "no data"
tAvailability += childAvailability * child->size();
foundAnyData = true;
}
tSize += child->size();
}
if (!isRootItem() && (tSize > 0) && foundAnyData) {
if (!isRootItem() && (tSize > 0) && foundAnyData)
{
m_availability = tAvailability / tSize;
Q_ASSERT(m_availability <= 1.);
}
else {
else
{
m_availability = -1.;
}
}

View File

@@ -107,11 +107,14 @@ QString TorrentContentModelItem::displayData(const int column) const
if (isRootItem())
return m_itemData.value(column);
switch (column) {
switch (column)
{
case COL_NAME:
return m_name;
case COL_PRIO: {
switch (m_priority) {
case COL_PRIO:
{
switch (m_priority)
{
case BitTorrent::DownloadPriority::Mixed:
return tr("Mixed", "Mixed (priorities");
case BitTorrent::DownloadPriority::Ignored:
@@ -124,7 +127,8 @@ QString TorrentContentModelItem::displayData(const int column) const
return tr("Normal", "Normal (priority)");
}
}
case COL_PROGRESS: {
case COL_PROGRESS:
{
const qreal progress = m_progress * 100;
return (static_cast<int>(progress) == 100)
? QString::fromLatin1("100%")
@@ -134,7 +138,8 @@ QString TorrentContentModelItem::displayData(const int column) const
return Utils::Misc::friendlyUnit(m_size);
case COL_REMAINING:
return Utils::Misc::friendlyUnit(remaining());
case COL_AVAILABILITY: {
case COL_AVAILABILITY:
{
const int avail = availability();
if (avail < 0)
return tr("N/A");
@@ -155,7 +160,8 @@ QVariant TorrentContentModelItem::underlyingData(const int column) const
if (isRootItem())
return m_itemData.value(column);
switch (column) {
switch (column)
{
case COL_NAME:
return m_name;
case COL_PRIO:

View File

@@ -62,7 +62,8 @@ TorrentContentTreeView::TorrentContentTreeView(QWidget *parent)
void TorrentContentTreeView::keyPressEvent(QKeyEvent *event)
{
if ((event->key() != Qt::Key_Space) && (event->key() != Qt::Key_Select)) {
if ((event->key() != Qt::Key_Space) && (event->key() != Qt::Key_Select))
{
QTreeView::keyPressEvent(event);
return;
}
@@ -72,7 +73,8 @@ void TorrentContentTreeView::keyPressEvent(QKeyEvent *event)
QModelIndex current = currentNameCell();
QVariant value = current.data(Qt::CheckStateRole);
if (!value.isValid()) {
if (!value.isValid())
{
Q_ASSERT(false);
return;
}
@@ -82,7 +84,8 @@ void TorrentContentTreeView::keyPressEvent(QKeyEvent *event)
const QModelIndexList selection = selectionModel()->selectedRows(TorrentContentModelItem::COL_NAME);
for (const QModelIndex &index : selection) {
for (const QModelIndex &index : selection)
{
Q_ASSERT(index.column() == TorrentContentModelItem::COL_NAME);
model()->setData(index, state, Qt::CheckStateRole);
}
@@ -109,14 +112,16 @@ void TorrentContentTreeView::renameSelectedFile(BitTorrent::TorrentHandle *torre
, modelIndex.data().toString(), &ok, isFile).trimmed();
if (!ok || !modelIndex.isValid()) return;
if (!Utils::Fs::isValidFileSystemName(newName)) {
if (!Utils::Fs::isValidFileSystemName(newName))
{
RaisedMessageBox::warning(this, tr("Rename error"),
tr("The name is empty or contains forbidden characters, please choose a different one."),
QMessageBox::Ok);
return;
}
if (isFile) {
if (isFile)
{
const int fileIndex = model->getFileIndex(modelIndex);
if (newName.endsWith(QB_EXT))
@@ -129,15 +134,18 @@ void TorrentContentTreeView::renameSelectedFile(BitTorrent::TorrentHandle *torre
const QString newFileName = newName + (useFilenameExt ? QB_EXT : QString());
const QString newFilePath = oldFilePath.leftRef(oldFilePath.size() - oldFileName.size()) + newFileName;
if (oldFileName == newFileName) {
if (oldFileName == newFileName)
{
qDebug("Name did not change: %s", qUtf8Printable(oldFileName));
return;
}
// check if that name is already used
for (int i = 0; i < torrent->filesCount(); ++i) {
for (int i = 0; i < torrent->filesCount(); ++i)
{
if (i == fileIndex) continue;
if (Utils::Fs::sameFileNames(torrent->filePath(i), newFilePath)) {
if (Utils::Fs::sameFileNames(torrent->filePath(i), newFilePath))
{
RaisedMessageBox::warning(this, tr("Rename error"),
tr("This name is already in use in this folder. Please use a different name."),
QMessageBox::Ok);
@@ -150,7 +158,8 @@ void TorrentContentTreeView::renameSelectedFile(BitTorrent::TorrentHandle *torre
model->setData(modelIndex, newName);
}
else {
else
{
// renaming a folder
const QString oldName = modelIndex.data().toString();
@@ -171,13 +180,15 @@ void TorrentContentTreeView::renameSelectedFile(BitTorrent::TorrentHandle *torre
const Qt::CaseSensitivity caseSensitivity = Qt::CaseSensitive;
#endif
for (int i = 0; i < torrent->filesCount(); ++i) {
for (int i = 0; i < torrent->filesCount(); ++i)
{
const QString currentPath = torrent->filePath(i);
if (currentPath.startsWith(oldPath))
continue;
if (currentPath.startsWith(newPath, caseSensitivity)) {
if (currentPath.startsWith(newPath, caseSensitivity))
{
RaisedMessageBox::warning(this, tr("The folder could not be renamed"),
tr("This name is already in use. Please use a different name."),
QMessageBox::Ok);
@@ -188,10 +199,12 @@ void TorrentContentTreeView::renameSelectedFile(BitTorrent::TorrentHandle *torre
// Replace path in all files
bool needForceRecheck = false;
for (int i = 0; i < torrent->filesCount(); ++i) {
for (int i = 0; i < torrent->filesCount(); ++i)
{
const QString currentPath = torrent->filePath(i);
if (currentPath.startsWith(oldPath)) {
if (currentPath.startsWith(oldPath))
{
const QString path {newPath + currentPath.mid(oldPath.length())};
if (!needForceRecheck && QFile::exists(path))
@@ -228,14 +241,16 @@ void TorrentContentTreeView::renameSelectedFile(BitTorrent::TorrentInfo &torrent
, modelIndex.data().toString(), &ok, isFile).trimmed();
if (!ok || !modelIndex.isValid()) return;
if (!Utils::Fs::isValidFileSystemName(newName)) {
if (!Utils::Fs::isValidFileSystemName(newName))
{
RaisedMessageBox::warning(this, tr("Rename error"),
tr("The name is empty or contains forbidden characters, please choose a different one."),
QMessageBox::Ok);
return;
}
if (isFile) {
if (isFile)
{
const int fileIndex = model->getFileIndex(modelIndex);
if (newName.endsWith(QB_EXT))
@@ -244,15 +259,18 @@ void TorrentContentTreeView::renameSelectedFile(BitTorrent::TorrentInfo &torrent
const QString oldFilePath = torrent.filePath(fileIndex);
const QString newFilePath = oldFilePath.leftRef(oldFilePath.size() - oldFileName.size()) + newName;
if (oldFileName == newName) {
if (oldFileName == newName)
{
qDebug("Name did not change: %s", qUtf8Printable(oldFileName));
return;
}
// check if that name is already used
for (int i = 0; i < torrent.filesCount(); ++i) {
for (int i = 0; i < torrent.filesCount(); ++i)
{
if (i == fileIndex) continue;
if (Utils::Fs::sameFileNames(torrent.filePath(i), newFilePath)) {
if (Utils::Fs::sameFileNames(torrent.filePath(i), newFilePath))
{
RaisedMessageBox::warning(this, tr("Rename error"),
tr("This name is already in use in this folder. Please use a different name."),
QMessageBox::Ok);
@@ -265,7 +283,8 @@ void TorrentContentTreeView::renameSelectedFile(BitTorrent::TorrentInfo &torrent
model->setData(modelIndex, newName);
}
else {
else
{
// renaming a folder
const QString oldName = modelIndex.data().toString();
@@ -286,13 +305,15 @@ void TorrentContentTreeView::renameSelectedFile(BitTorrent::TorrentInfo &torrent
const Qt::CaseSensitivity caseSensitivity = Qt::CaseSensitive;
#endif
for (int i = 0; i < torrent.filesCount(); ++i) {
for (int i = 0; i < torrent.filesCount(); ++i)
{
const QString currentPath = torrent.filePath(i);
if (currentPath.startsWith(oldPath))
continue;
if (currentPath.startsWith(newPath, caseSensitivity)) {
if (currentPath.startsWith(newPath, caseSensitivity))
{
RaisedMessageBox::warning(this, tr("The folder could not be renamed"),
tr("This name is already in use. Please use a different name."),
QMessageBox::Ok);
@@ -301,10 +322,12 @@ void TorrentContentTreeView::renameSelectedFile(BitTorrent::TorrentInfo &torrent
}
// Replace path in all files
for (int i = 0; i < torrent.filesCount(); ++i) {
for (int i = 0; i < torrent.filesCount(); ++i)
{
const QString currentPath = torrent.filePath(i);
if (currentPath.startsWith(oldPath)) {
if (currentPath.startsWith(oldPath))
{
const QString path {newPath + currentPath.mid(oldPath.length())};
torrent.renameFile(i, path);
}
@@ -317,7 +340,8 @@ void TorrentContentTreeView::renameSelectedFile(BitTorrent::TorrentInfo &torrent
QModelIndex TorrentContentTreeView::currentNameCell()
{
QModelIndex current = currentIndex();
if (!current.isValid()) {
if (!current.isValid())
{
Q_ASSERT(false);
return {};
}

View File

@@ -130,7 +130,8 @@ int TorrentCreatorDialog::getPieceSize() const
#if (LIBTORRENT_VERSION_NUM >= 20000)
BitTorrent::TorrentFormat TorrentCreatorDialog::getTorrentFormat() const
{
switch (m_ui->comboTorrentFormat->currentIndex()) {
switch (m_ui->comboTorrentFormat->currentIndex())
{
case 0:
return BitTorrent::TorrentFormat::V2;
case 1:
@@ -152,7 +153,8 @@ void TorrentCreatorDialog::dropEvent(QDropEvent *event)
{
event->acceptProposedAction();
if (event->mimeData()->hasUrls()) {
if (event->mimeData()->hasUrls())
{
// only take the first one
QUrl firstItem = event->mimeData()->urls().first();
QString path = (firstItem.scheme().compare("file", Qt::CaseInsensitive) == 0)
@@ -174,7 +176,8 @@ void TorrentCreatorDialog::onCreateButtonClicked()
// test if readable
const QFileInfo fi(input);
if (!fi.isReadable()) {
if (!fi.isReadable())
{
QMessageBox::critical(this, tr("Torrent creation failed"), tr("Reason: Path to file/folder is not readable."));
return;
}
@@ -195,7 +198,8 @@ void TorrentCreatorDialog::onCreateButtonClicked()
const QStringList trackers = m_ui->trackersList->toPlainText().trimmed()
.replace(QRegularExpression("\n\n[\n]+"), "\n\n").split('\n');
const BitTorrent::TorrentCreatorParams params {
const BitTorrent::TorrentCreatorParams params
{
m_ui->checkPrivate->isChecked()
#if (LIBTORRENT_VERSION_NUM >= 20000)
, getTorrentFormat()
@@ -227,10 +231,12 @@ void TorrentCreatorDialog::handleCreationSuccess(const QString &path, const QStr
{
// Remove busy cursor
setCursor(QCursor(Qt::ArrowCursor));
if (m_ui->checkStartSeeding->isChecked()) {
if (m_ui->checkStartSeeding->isChecked())
{
// Create save path temp data
const BitTorrent::TorrentInfo info = BitTorrent::TorrentInfo::loadFromFile(Utils::Fs::toNativePath(path));
if (!info.isValid()) {
if (!info.isValid())
{
QMessageBox::critical(this, tr("Torrent creation failed"), tr("Reason: Created torrent is invalid. It won't be added to download list."));
return;
}
@@ -238,7 +244,8 @@ void TorrentCreatorDialog::handleCreationSuccess(const QString &path, const QStr
BitTorrent::AddTorrentParams params;
params.savePath = branchPath;
params.skipChecking = true;
if (m_ui->checkIgnoreShareLimits->isChecked()) {
if (m_ui->checkIgnoreShareLimits->isChecked())
{
params.ratioLimit = BitTorrent::TorrentHandle::NO_RATIO_LIMIT;
params.seedingTimeLimit = BitTorrent::TorrentHandle::NO_SEEDING_TIME_LIMIT;
}

View File

@@ -63,7 +63,8 @@ void TrackerEntriesDialog::setTrackers(const QVector<BitTorrent::TrackerEntry> &
int maxTier = -1;
QHash<int, QString> tiers; // <tier, tracker URLs>
for (const BitTorrent::TrackerEntry &entry : trackers) {
for (const BitTorrent::TrackerEntry &entry : trackers)
{
tiers[entry.tier()] += (entry.url() + '\n');
maxTier = std::max(maxTier, entry.tier());
}
@@ -85,10 +86,12 @@ QVector<BitTorrent::TrackerEntry> TrackerEntriesDialog::trackers() const
entries.reserve(lines.size());
int tier = 0;
for (QStringRef line : lines) {
for (QStringRef line : lines)
{
line = line.trimmed();
if (line.isEmpty()) {
if (line.isEmpty())
{
++tier;
continue;
}

View File

@@ -51,7 +51,8 @@ QSize TransferListDelegate::sizeHint(const QStyleOptionViewItem &option, const Q
// This happens because icon from the 'name' column is no longer drawn.
static int nameColHeight = -1;
if (nameColHeight == -1) {
if (nameColHeight == -1)
{
const QModelIndex nameColumn = index.sibling(index.row(), TransferListModel::TR_NAME);
nameColHeight = QStyledItemDelegate::sizeHint(option, nameColumn).height();
}

View File

@@ -128,7 +128,8 @@ BaseFilterWidget::BaseFilterWidget(QWidget *parent, TransferListWidget *transfer
QSize BaseFilterWidget::sizeHint() const
{
return {
return
{
// Width should be exactly the width of the content
sizeHintForColumn(0),
// Height should be exactly the height of the content
@@ -225,7 +226,8 @@ void StatusFilterWidget::updateTorrentNumbers()
int nbErrored = 0;
const QVector<BitTorrent::TorrentHandle *> torrents = BitTorrent::Session::instance()->torrents();
for (const BitTorrent::TorrentHandle *torrent : torrents) {
for (const BitTorrent::TorrentHandle *torrent : torrents)
{
if (torrent->isDownloading())
++nbDownloading;
if (torrent->isUploading())
@@ -311,19 +313,23 @@ void TrackerFiltersList::addItem(const QString &tracker, const QString &hash)
QString host = getHost(tracker);
bool exists = m_trackers.contains(host);
if (exists) {
if (exists)
{
tmp = m_trackers.value(host);
if (tmp.contains(hash))
return;
if (host != "") {
if (host != "")
{
trackerItem = item(rowFromTracker(host));
}
else {
else
{
trackerItem = item(TRACKERLESS_ROW);
}
}
else {
else
{
trackerItem = new QListWidgetItem();
trackerItem->setData(Qt::DecorationRole, UIThemeManager::instance()->getIcon("network-server"));
@@ -334,7 +340,8 @@ void TrackerFiltersList::addItem(const QString &tracker, const QString &hash)
tmp.append(hash);
m_trackers.insert(host, tmp);
if (host == "") {
if (host == "")
{
trackerItem->setText(tr("Trackerless (%1)").arg(tmp.size()));
if (currentRow() == TRACKERLESS_ROW)
applyFilter(TRACKERLESS_ROW);
@@ -342,7 +349,8 @@ void TrackerFiltersList::addItem(const QString &tracker, const QString &hash)
}
trackerItem->setText(QString::fromLatin1("%1 (%2)").arg(host, QString::number(tmp.size())));
if (exists) {
if (exists)
{
if (currentRow() == rowFromTracker(host))
applyFilter(currentRow());
return;
@@ -350,8 +358,10 @@ void TrackerFiltersList::addItem(const QString &tracker, const QString &hash)
Q_ASSERT(count() >= 4);
int insPos = count();
for (int i = 4; i < count(); ++i) {
if (Utils::String::naturalLessThan<Qt::CaseSensitive>(host, item(i)->text())) {
for (int i = 4; i < count(); ++i)
{
if (Utils::String::naturalLessThan<Qt::CaseSensitive>(host, item(i)->text()))
{
insPos = i;
break;
}
@@ -371,12 +381,14 @@ void TrackerFiltersList::removeItem(const QString &tracker, const QString &hash)
return;
tmp.removeAll(hash);
if (!host.isEmpty()) {
if (!host.isEmpty())
{
// Remove from 'Error' and 'Warning' view
trackerSuccess(hash, tracker);
row = rowFromTracker(host);
trackerItem = item(row);
if (tmp.empty()) {
if (tmp.empty())
{
if (currentRow() == row)
setCurrentRow(0, QItemSelectionModel::SelectCurrent);
delete trackerItem;
@@ -387,7 +399,8 @@ void TrackerFiltersList::removeItem(const QString &tracker, const QString &hash)
if (trackerItem)
trackerItem->setText(QString::fromLatin1("%1 (%2)").arg(host, QString::number(tmp.size())));
}
else {
else
{
row = 1;
trackerItem = item(TRACKERLESS_ROW);
trackerItem->setText(tr("Trackerless (%1)").arg(tmp.size()));
@@ -411,10 +424,13 @@ void TrackerFiltersList::setDownloadTrackerFavicon(bool value)
if (value == m_downloadTrackerFavicon) return;
m_downloadTrackerFavicon = value;
if (m_downloadTrackerFavicon) {
for (auto i = m_trackers.cbegin(); i != m_trackers.cend(); ++i) {
if (m_downloadTrackerFavicon)
{
for (auto i = m_trackers.cbegin(); i != m_trackers.cend(); ++i)
{
const QString &tracker = i.key();
if (!tracker.isEmpty()) {
if (!tracker.isEmpty())
{
const QString scheme = getScheme(tracker);
downloadFavicon(QString("%1://%2/favicon.ico")
.arg((scheme.startsWith("http") ? scheme : "http"), getHost(tracker)));
@@ -428,28 +444,34 @@ void TrackerFiltersList::trackerSuccess(const QString &hash, const QString &trac
QStringList errored = m_errors.value(hash);
QStringList warned = m_warnings.value(hash);
if (errored.contains(tracker)) {
if (errored.contains(tracker))
{
errored.removeAll(tracker);
if (errored.empty()) {
if (errored.empty())
{
m_errors.remove(hash);
item(ERROR_ROW)->setText(tr("Error (%1)").arg(m_errors.size()));
if (currentRow() == ERROR_ROW)
applyFilter(ERROR_ROW);
}
else {
else
{
m_errors.insert(hash, errored);
}
}
if (warned.contains(tracker)) {
if (warned.contains(tracker))
{
warned.removeAll(tracker);
if (warned.empty()) {
if (warned.empty())
{
m_warnings.remove(hash);
item(WARNING_ROW)->setText(tr("Warning (%1)").arg(m_warnings.size()));
if (currentRow() == WARNING_ROW)
applyFilter(WARNING_ROW);
}
else {
else
{
m_warnings.insert(hash, warned);
}
}
@@ -495,7 +517,8 @@ void TrackerFiltersList::downloadFavicon(const QString &url)
void TrackerFiltersList::handleFavicoDownloadFinished(const Net::DownloadResult &result)
{
if (result.status != Net::DownloadStatus::Success) {
if (result.status != Net::DownloadStatus::Success)
{
if (result.url.endsWith(".ico", Qt::CaseInsensitive))
downloadFavicon(result.url.left(result.url.size() - 4) + ".png");
return;
@@ -503,7 +526,8 @@ void TrackerFiltersList::handleFavicoDownloadFinished(const Net::DownloadResult
const QString host = getHost(result.url);
if (!m_trackers.contains(host)) {
if (!m_trackers.contains(host))
{
Utils::Fs::forceRemove(result.filePath);
return;
}
@@ -515,12 +539,14 @@ void TrackerFiltersList::handleFavicoDownloadFinished(const Net::DownloadResult
//Detect a non-decodable icon
QList<QSize> sizes = icon.availableSizes();
bool invalid = (sizes.isEmpty() || icon.pixmap(sizes.first()).isNull());
if (invalid) {
if (invalid)
{
if (result.url.endsWith(".ico", Qt::CaseInsensitive))
downloadFavicon(result.url.left(result.url.size() - 4) + ".png");
Utils::Fs::forceRemove(result.filePath);
}
else {
else
{
trackerItem->setData(Qt::DecorationRole, QIcon(result.filePath));
m_iconPaths.append(result.filePath);
}
@@ -612,7 +638,8 @@ QString TrackerFiltersList::getHost(const QString &tracker) const
QStringList TrackerFiltersList::getHashes(const int row) const
{
switch (row) {
switch (row)
{
case TRACKERLESS_ROW:
return m_trackers.value("");
case ERROR_ROW:

View File

@@ -92,7 +92,8 @@ namespace
};
QHash<BitTorrent::TorrentState, QColor> colors;
for (const TorrentStateColorDescriptor &colorDescriptor : colorDescriptors) {
for (const TorrentStateColorDescriptor &colorDescriptor : colorDescriptors)
{
const QColor themeColor = UIThemeManager::instance()->getColor(colorDescriptor.id, QColor());
if (themeColor.isValid())
colors.insert(colorDescriptor.state, themeColor);
@@ -105,7 +106,8 @@ namespace
TransferListModel::TransferListModel(QObject *parent)
: QAbstractListModel {parent}
, m_statusStrings {
, m_statusStrings
{
{BitTorrent::TorrentState::Downloading, tr("Downloading")},
{BitTorrent::TorrentState::StalledDownloading, tr("Stalled", "Torrent is waiting for download to begin")},
{BitTorrent::TorrentState::DownloadingMetadata, tr("Downloading metadata", "Used when loading a magnet link")},
@@ -158,9 +160,12 @@ int TransferListModel::columnCount(const QModelIndex &) const
QVariant TransferListModel::headerData(int section, Qt::Orientation orientation, int role) const
{
if (orientation == Qt::Horizontal) {
if (role == Qt::DisplayRole) {
switch (section) {
if (orientation == Qt::Horizontal)
{
if (role == Qt::DisplayRole)
{
switch (section)
{
case TR_QUEUE_POSITION: return QChar('#');
case TR_NAME: return tr("Name", "i.e: torrent name");
case TR_SIZE: return tr("Size", "i.e: torrent size");
@@ -195,8 +200,10 @@ QVariant TransferListModel::headerData(int section, Qt::Orientation orientation,
default: return {};
}
}
else if (role == Qt::TextAlignmentRole) {
switch (section) {
else if (role == Qt::TextAlignmentRole)
{
switch (section)
{
case TR_AMOUNT_DOWNLOADED:
case TR_AMOUNT_UPLOADED:
case TR_AMOUNT_DOWNLOADED_SESSION:
@@ -324,7 +331,8 @@ QString TransferListModel::displayValue(const BitTorrent::TorrentHandle *torrent
: m_statusStrings[state];
};
switch (column) {
switch (column)
{
case TR_NAME:
return torrent->name();
case TR_QUEUE_POSITION:
@@ -394,7 +402,8 @@ QString TransferListModel::displayValue(const BitTorrent::TorrentHandle *torrent
QVariant TransferListModel::internalValue(const BitTorrent::TorrentHandle *torrent, const int column, const bool alt) const
{
switch (column) {
switch (column)
{
case TR_NAME:
return torrent->name();
case TR_QUEUE_POSITION:
@@ -469,7 +478,8 @@ QVariant TransferListModel::data(const QModelIndex &index, const int role) const
const BitTorrent::TorrentHandle *torrent = m_torrentList.value(index.row());
if (!torrent) return {};
switch (role) {
switch (role)
{
case Qt::ForegroundRole:
return m_stateThemeColors.value(torrent->state(), getDefaultColorByState(torrent->state()));
case Qt::DisplayRole:
@@ -483,7 +493,8 @@ QVariant TransferListModel::data(const QModelIndex &index, const int role) const
return getIconByState(torrent->state());
break;
case Qt::ToolTipRole:
switch (index.column()) {
switch (index.column())
{
case TR_NAME:
case TR_STATUS:
case TR_CATEGORY:
@@ -494,7 +505,8 @@ QVariant TransferListModel::data(const QModelIndex &index, const int role) const
}
break;
case Qt::TextAlignmentRole:
switch (index.column()) {
switch (index.column())
{
case TR_AMOUNT_DOWNLOADED:
case TR_AMOUNT_UPLOADED:
case TR_AMOUNT_DOWNLOADED_SESSION:
@@ -530,7 +542,8 @@ bool TransferListModel::setData(const QModelIndex &index, const QVariant &value,
if (!torrent) return false;
// Category and Name columns can be edited
switch (index.column()) {
switch (index.column())
{
case TR_NAME:
torrent->setName(value.toString());
break;
@@ -579,7 +592,8 @@ void TransferListModel::handleTorrentAboutToBeRemoved(BitTorrent::TorrentHandle
beginRemoveRows({}, row, row);
m_torrentList.removeAt(row);
m_torrentMap.remove(torrent);
for (int &value : m_torrentMap) {
for (int &value : m_torrentMap)
{
if (value > row)
--value;
}
@@ -598,15 +612,18 @@ void TransferListModel::handleTorrentsUpdated(const QVector<BitTorrent::TorrentH
{
const int columns = (columnCount() - 1);
if (torrents.size() <= (m_torrentList.size() * 0.5)) {
for (BitTorrent::TorrentHandle *const torrent : torrents) {
if (torrents.size() <= (m_torrentList.size() * 0.5))
{
for (BitTorrent::TorrentHandle *const torrent : torrents)
{
const int row = m_torrentMap.value(torrent, -1);
Q_ASSERT(row >= 0);
emit dataChanged(index(row, 0), index(row, columns));
}
}
else {
else
{
// save the overhead when more than half of the torrent list needs update
emit dataChanged(index(0, 0), index((rowCount() - 1), columns));
}
@@ -617,14 +634,16 @@ void TransferListModel::configure()
const Preferences *pref = Preferences::instance();
HideZeroValuesMode hideZeroValuesMode = HideZeroValuesMode::Never;
if (pref->getHideZeroValues()) {
if (pref->getHideZeroValues())
{
if (pref->getHideZeroComboValues() == 1)
hideZeroValuesMode = HideZeroValuesMode::Paused;
else
hideZeroValuesMode = HideZeroValuesMode::Always;
}
if (m_hideZeroValuesMode != hideZeroValuesMode) {
if (m_hideZeroValuesMode != hideZeroValuesMode)
{
m_hideZeroValuesMode = hideZeroValuesMode;
emit dataChanged(index(0, 0), index((rowCount() - 1), (columnCount() - 1)));
}
@@ -634,7 +653,8 @@ void TransferListModel::configure()
QIcon getIconByState(const BitTorrent::TorrentState state)
{
switch (state) {
switch (state)
{
case BitTorrent::TorrentState::Downloading:
case BitTorrent::TorrentState::ForcedDownloading:
case BitTorrent::TorrentState::DownloadingMetadata:
@@ -673,7 +693,8 @@ QColor getDefaultColorByState(const BitTorrent::TorrentState state)
// Color names taken from http://cloford.com/resources/colours/500col.htm
bool dark = isDarkTheme();
switch (state) {
switch (state)
{
case BitTorrent::TorrentState::Downloading:
case BitTorrent::TorrentState::ForcedDownloading:
case BitTorrent::TorrentState::DownloadingMetadata:

View File

@@ -112,7 +112,8 @@ bool TransferListSortModel::lessThan_impl(const QModelIndex &left, const QModelI
const QVariant leftValue = left.data(TransferListModel::UnderlyingDataRole);
const QVariant rightValue = right.data(TransferListModel::UnderlyingDataRole);
switch (sortColumn) {
switch (sortColumn)
{
case TransferListModel::TR_CATEGORY:
case TransferListModel::TR_TAGS:
case TransferListModel::TR_NAME:
@@ -132,27 +133,33 @@ bool TransferListSortModel::lessThan_impl(const QModelIndex &left, const QModelI
case TransferListModel::TR_ADD_DATE:
case TransferListModel::TR_SEED_DATE:
case TransferListModel::TR_SEEN_COMPLETE_DATE: {
case TransferListModel::TR_SEEN_COMPLETE_DATE:
{
const QDateTime dateL = leftValue.toDateTime();
const QDateTime dateR = rightValue.toDateTime();
if (dateL.isValid() && dateR.isValid()) {
if (dateL.isValid() && dateR.isValid())
{
if (dateL != dateR)
return dateL < dateR;
}
else if (dateL.isValid()) {
else if (dateL.isValid())
{
return true;
}
else if (dateR.isValid()) {
else if (dateR.isValid())
{
return false;
}
return hashLessThan();
}
case TransferListModel::TR_QUEUE_POSITION: {
case TransferListModel::TR_QUEUE_POSITION:
{
// QVariant has comparators for all basic types
if ((leftValue > 0) || (rightValue > 0)) {
if ((leftValue > 0) || (rightValue > 0))
{
if ((leftValue > 0) && (rightValue > 0))
return leftValue < rightValue;
@@ -165,14 +172,17 @@ bool TransferListSortModel::lessThan_impl(const QModelIndex &left, const QModelI
const QDateTime dateR = right.sibling(right.row(), TransferListModel::TR_SEED_DATE)
.data(TransferListModel::UnderlyingDataRole).toDateTime();
if (dateL.isValid() && dateR.isValid()) {
if (dateL.isValid() && dateR.isValid())
{
if (dateL != dateR)
return dateL < dateR;
}
else if (dateL.isValid()) {
else if (dateL.isValid())
{
return false;
}
else if (dateR.isValid()) {
else if (dateR.isValid())
{
return true;
}
@@ -180,7 +190,8 @@ bool TransferListSortModel::lessThan_impl(const QModelIndex &left, const QModelI
}
case TransferListModel::TR_SEEDS:
case TransferListModel::TR_PEERS: {
case TransferListModel::TR_PEERS:
{
// QVariant has comparators for all basic types
// Active peers/seeds take precedence over total peers/seeds.
if (leftValue != rightValue)
@@ -194,7 +205,8 @@ bool TransferListSortModel::lessThan_impl(const QModelIndex &left, const QModelI
return invokeLessThanForColumn(TransferListModel::TR_QUEUE_POSITION);
}
case TransferListModel::TR_ETA: {
case TransferListModel::TR_ETA:
{
// Sorting rules prioritized.
// 1. Active torrents at the top
// 2. Seeding torrents at the bottom
@@ -215,7 +227,8 @@ bool TransferListSortModel::lessThan_impl(const QModelIndex &left, const QModelI
.data(TransferListModel::UnderlyingDataRole).toInt();
const bool isSeedingL = (queuePosL < 0);
const bool isSeedingR = (queuePosR < 0);
if (isSeedingL != isSeedingR) {
if (isSeedingL != isSeedingR)
{
const bool isAscendingOrder = (sortOrder() == Qt::AscendingOrder);
if (isSeedingL)
return !isAscendingOrder;
@@ -227,7 +240,8 @@ bool TransferListSortModel::lessThan_impl(const QModelIndex &left, const QModelI
const qlonglong etaR = rightValue.toLongLong();
const bool isInvalidL = ((etaL < 0) || (etaL >= MAX_ETA));
const bool isInvalidR = ((etaR < 0) || (etaR >= MAX_ETA));
if (isInvalidL && isInvalidR) {
if (isInvalidL && isInvalidR)
{
if (isSeedingL) // Both seeding
return invokeLessThanForColumn(TransferListModel::TR_SEED_DATE);

View File

@@ -90,7 +90,8 @@ namespace
if (!torrent->hasMetadata())
return false;
for (int i = 0; i < torrent->filesCount(); ++i) {
for (int i = 0; i < torrent->filesCount(); ++i)
{
if (Utils::Misc::isPreviewable(Utils::Fs::fileExtension(torrent->fileName(i))))
return true;
}
@@ -159,7 +160,8 @@ TransferListWidget::TransferListWidget(QWidget *parent, MainWindow *mainWindow)
header()->setStretchLastSection(false);
// Default hidden columns
if (!columnLoaded) {
if (!columnLoaded)
{
setColumnHidden(TransferListModel::TR_ADD_DATE, true);
setColumnHidden(TransferListModel::TR_SEED_DATE, true);
setColumnHidden(TransferListModel::TR_UPLIMIT, true);
@@ -181,8 +183,10 @@ TransferListWidget::TransferListWidget(QWidget *parent, MainWindow *mainWindow)
//Ensure that at least one column is visible at all times
bool atLeastOne = false;
for (int i = 0; i < TransferListModel::NB_COLUMNS; ++i) {
if (!isColumnHidden(i)) {
for (int i = 0; i < TransferListModel::NB_COLUMNS; ++i)
{
if (!isColumnHidden(i))
{
atLeastOne = true;
break;
}
@@ -275,7 +279,8 @@ void TransferListWidget::torrentDoubleClicked()
else
action = Preferences::instance()->getActionOnDblClOnTorrentDl();
switch (action) {
switch (action)
{
case TOGGLE_PAUSE:
if (torrent->isPaused())
torrent->resume();
@@ -283,13 +288,15 @@ void TransferListWidget::torrentDoubleClicked()
torrent->pause();
break;
case PREVIEW_FILE:
if (torrentContainsPreviewableFiles(torrent)) {
if (torrentContainsPreviewableFiles(torrent))
{
auto *dialog = new PreviewSelectDialog(this, torrent);
dialog->setAttribute(Qt::WA_DeleteOnClose);
connect(dialog, &PreviewSelectDialog::readyToPreviewFile, this, &TransferListWidget::previewFile);
dialog->show();
}
else {
else
{
openDestinationFolder(torrent);
}
break;
@@ -395,7 +402,8 @@ void TransferListWidget::deleteSelectedTorrents(const bool deleteLocalFiles)
const QVector<BitTorrent::TorrentHandle *> torrents = getSelectedTorrents();
if (torrents.empty()) return;
if (Preferences::instance()->confirmTorrentDeletion()) {
if (Preferences::instance()->confirmTorrentDeletion())
{
auto *dialog = new DeletionConfirmationDialog(this, torrents.size(), torrents[0]->name(), deleteLocalFiles);
dialog->setAttribute(Qt::WA_DeleteOnClose);
connect(dialog, &DeletionConfirmationDialog::accepted, this, [this, dialog]()
@@ -406,7 +414,8 @@ void TransferListWidget::deleteSelectedTorrents(const bool deleteLocalFiles)
});
dialog->open();
}
else {
else
{
removeTorrents(torrents, deleteLocalFiles);
}
}
@@ -416,7 +425,8 @@ void TransferListWidget::deleteVisibleTorrents()
const QVector<BitTorrent::TorrentHandle *> torrents = getVisibleTorrents();
if (torrents.empty()) return;
if (Preferences::instance()->confirmTorrentDeletion()) {
if (Preferences::instance()->confirmTorrentDeletion())
{
auto *dialog = new DeletionConfirmationDialog(this, torrents.size(), torrents[0]->name(), false);
dialog->setAttribute(Qt::WA_DeleteOnClose);
connect(dialog, &DeletionConfirmationDialog::accepted, this, [this, dialog]()
@@ -427,7 +437,8 @@ void TransferListWidget::deleteVisibleTorrents()
});
dialog->open();
}
else {
else
{
removeTorrents(torrents, false);
}
}
@@ -498,15 +509,18 @@ void TransferListWidget::openSelectedTorrentsFolder() const
#ifdef Q_OS_MACOS
// On macOS you expect both the files and folders to be opened in their parent
// folders prehilighted for opening, so we use a custom method.
for (BitTorrent::TorrentHandle *const torrent : asConst(getSelectedTorrents())) {
for (BitTorrent::TorrentHandle *const torrent : asConst(getSelectedTorrents()))
{
QString path = torrent->contentPath(true);
pathsList.insert(path);
}
MacUtils::openFiles(pathsList);
#else
for (BitTorrent::TorrentHandle *const torrent : asConst(getSelectedTorrents())) {
for (BitTorrent::TorrentHandle *const torrent : asConst(getSelectedTorrents()))
{
QString path = torrent->contentPath(true);
if (!pathsList.contains(path)) {
if (!pathsList.contains(path))
{
if (torrent->filesCount() == 1)
Utils::Gui::openFolderSelect(path);
else
@@ -519,14 +533,17 @@ void TransferListWidget::openSelectedTorrentsFolder() const
void TransferListWidget::previewSelectedTorrents()
{
for (const BitTorrent::TorrentHandle *torrent : asConst(getSelectedTorrents())) {
if (torrentContainsPreviewableFiles(torrent)) {
for (const BitTorrent::TorrentHandle *torrent : asConst(getSelectedTorrents()))
{
if (torrentContainsPreviewableFiles(torrent))
{
auto *dialog = new PreviewSelectDialog(this, torrent);
dialog->setAttribute(Qt::WA_DeleteOnClose);
connect(dialog, &PreviewSelectDialog::readyToPreviewFile, this, &TransferListWidget::previewFile);
dialog->show();
}
else {
else
{
QMessageBox::critical(this, tr("Unable to preview"), tr("The selected torrent \"%1\" does not contain previewable files")
.arg(torrent->name()));
}
@@ -536,7 +553,8 @@ void TransferListWidget::previewSelectedTorrents()
void TransferListWidget::setDlLimitSelectedTorrents()
{
QVector<BitTorrent::TorrentHandle *> torrentsList;
for (BitTorrent::TorrentHandle *const torrent : asConst(getSelectedTorrents())) {
for (BitTorrent::TorrentHandle *const torrent : asConst(getSelectedTorrents()))
{
if (torrent->isSeed())
continue;
torrentsList += torrent;
@@ -544,8 +562,10 @@ void TransferListWidget::setDlLimitSelectedTorrents()
if (torrentsList.empty()) return;
int oldLimit = torrentsList.first()->downloadLimit();
for (BitTorrent::TorrentHandle *const torrent : asConst(torrentsList)) {
if (torrent->downloadLimit() != oldLimit) {
for (BitTorrent::TorrentHandle *const torrent : asConst(torrentsList))
{
if (torrent->downloadLimit() != oldLimit)
{
oldLimit = -1;
break;
}
@@ -557,7 +577,8 @@ void TransferListWidget::setDlLimitSelectedTorrents()
, BitTorrent::Session::instance()->globalDownloadSpeedLimit());
if (!ok) return;
for (BitTorrent::TorrentHandle *const torrent : asConst(torrentsList)) {
for (BitTorrent::TorrentHandle *const torrent : asConst(torrentsList))
{
qDebug("Applying download speed limit of %ld Kb/s to torrent %s", (newLimit / 1024l), qUtf8Printable(torrent->hash()));
torrent->setDownloadLimit(newLimit);
}
@@ -569,8 +590,10 @@ void TransferListWidget::setUpLimitSelectedTorrents()
if (torrentsList.empty()) return;
int oldLimit = torrentsList.first()->uploadLimit();
for (BitTorrent::TorrentHandle *const torrent : asConst(torrentsList)) {
if (torrent->uploadLimit() != oldLimit) {
for (BitTorrent::TorrentHandle *const torrent : asConst(torrentsList))
{
if (torrent->uploadLimit() != oldLimit)
{
oldLimit = -1;
break;
}
@@ -582,7 +605,8 @@ void TransferListWidget::setUpLimitSelectedTorrents()
, BitTorrent::Session::instance()->globalUploadSpeedLimit());
if (!ok) return;
for (BitTorrent::TorrentHandle *const torrent : asConst(torrentsList)) {
for (BitTorrent::TorrentHandle *const torrent : asConst(torrentsList))
{
qDebug("Applying upload speed limit of %ld Kb/s to torrent %s", (newLimit / 1024l), qUtf8Printable(torrent->hash()));
torrent->setUploadLimit(newLimit);
}
@@ -611,7 +635,8 @@ void TransferListWidget::setMaxRatioSelectedTorrents()
dialog->setAttribute(Qt::WA_DeleteOnClose);
connect(dialog, &QDialog::accepted, this, [dialog, torrents]()
{
for (BitTorrent::TorrentHandle *const torrent : torrents) {
for (BitTorrent::TorrentHandle *const torrent : torrents)
{
const qreal ratio = (dialog->useDefault()
? BitTorrent::TorrentHandle::USE_GLOBAL_RATIO : dialog->ratio());
torrent->setRatioLimit(ratio);
@@ -626,7 +651,8 @@ void TransferListWidget::setMaxRatioSelectedTorrents()
void TransferListWidget::recheckSelectedTorrents()
{
if (Preferences::instance()->confirmTorrentRecheck()) {
if (Preferences::instance()->confirmTorrentRecheck())
{
QMessageBox::StandardButton ret = QMessageBox::question(this, tr("Recheck confirmation"), tr("Are you sure you want to recheck the selected torrent(s)?"), QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes);
if (ret != QMessageBox::Yes) return;
}
@@ -648,7 +674,8 @@ void TransferListWidget::displayDLHoSMenu(const QPoint&)
menu->setAttribute(Qt::WA_DeleteOnClose);
menu->setTitle(tr("Column visibility"));
for (int i = 0; i < m_listModel->columnCount(); ++i) {
for (int i = 0; i < m_listModel->columnCount(); ++i)
{
if (!BitTorrent::Session::instance()->isQueueingSystemEnabled() && (i == TransferListModel::TR_QUEUE_POSITION))
continue;
@@ -661,7 +688,8 @@ void TransferListWidget::displayDLHoSMenu(const QPoint&)
connect(menu, &QMenu::triggered, this, [this](const QAction *action)
{
int visibleCols = 0;
for (int i = 0; i < TransferListModel::NB_COLUMNS; ++i) {
for (int i = 0; i < TransferListModel::NB_COLUMNS; ++i)
{
if (!isColumnHidden(i))
++visibleCols;
@@ -687,7 +715,8 @@ void TransferListWidget::displayDLHoSMenu(const QPoint&)
void TransferListWidget::setSelectedTorrentsSuperSeeding(const bool enabled) const
{
for (BitTorrent::TorrentHandle *const torrent : asConst(getSelectedTorrents())) {
for (BitTorrent::TorrentHandle *const torrent : asConst(getSelectedTorrents()))
{
if (torrent->hasMetadata())
torrent->setSuperSeeding(enabled);
}
@@ -730,10 +759,12 @@ void TransferListWidget::editTorrentTrackers()
const QVector<BitTorrent::TorrentHandle *> torrents = getSelectedTorrents();
QVector<BitTorrent::TrackerEntry> commonTrackers;
if (!torrents.empty()) {
if (!torrents.empty())
{
commonTrackers = torrents[0]->trackers();
for (const BitTorrent::TorrentHandle *torrent : torrents) {
for (const BitTorrent::TorrentHandle *torrent : torrents)
{
QSet<BitTorrent::TrackerEntry> trackerSet;
for (const BitTorrent::TrackerEntry &entry : asConst(torrent->trackers()))
@@ -771,7 +802,8 @@ QStringList TransferListWidget::askTagsForSelection(const QString &dialogTitle)
{
QStringList tags;
bool invalid = true;
while (invalid) {
while (invalid)
{
bool ok = false;
invalid = false;
const QString tagsInput = AutoExpandableDialog::getText(
@@ -779,9 +811,11 @@ QStringList TransferListWidget::askTagsForSelection(const QString &dialogTitle)
if (!ok || tagsInput.isEmpty())
return {};
tags = tagsInput.split(',', QString::SkipEmptyParts);
for (QString &tag : tags) {
for (QString &tag : tags)
{
tag = tag.trimmed();
if (!BitTorrent::Session::isValidTag(tag)) {
if (!BitTorrent::Session::isValidTag(tag))
{
QMessageBox::warning(this, tr("Invalid tag")
, tr("Tag name: '%1' is invalid").arg(tag));
invalid = true;
@@ -793,7 +827,8 @@ QStringList TransferListWidget::askTagsForSelection(const QString &dialogTitle)
void TransferListWidget::applyToSelectedTorrents(const std::function<void (BitTorrent::TorrentHandle *const)> &fn)
{
for (const QModelIndex &index : asConst(selectionModel()->selectedRows())) {
for (const QModelIndex &index : asConst(selectionModel()->selectedRows()))
{
BitTorrent::TorrentHandle *const torrent = m_listModel->torrentHandle(mapToSource(index));
Q_ASSERT(torrent);
fn(torrent);
@@ -812,7 +847,8 @@ void TransferListWidget::renameSelectedTorrent()
// Ask for a new Name
bool ok = false;
QString name = AutoExpandableDialog::getText(this, tr("Rename"), tr("New name:"), QLineEdit::Normal, torrent->name(), &ok);
if (ok && !name.isEmpty()) {
if (ok && !name.isEmpty())
{
name.replace(QRegularExpression("\r?\n|\r"), " ");
// Rename the torrent
m_listModel->setData(mi, name, Qt::DisplayRole);
@@ -918,7 +954,8 @@ void TransferListWidget::displayListMenu(const QPoint &)
QSet<QString> tagsInAny;
QSet<QString> tagsInAll;
for (const QModelIndex &index : selectedIndexes) {
for (const QModelIndex &index : selectedIndexes)
{
// Get the file name
// Get handle and pause the torrent
const BitTorrent::TorrentHandle *torrent = m_listModel->torrentHandle(mapToSource(index));
@@ -931,11 +968,13 @@ void TransferListWidget::displayListMenu(const QPoint &)
tagsInAny.unite(torrent->tags());
if (first) {
if (first)
{
firstAutoTMM = torrent->isAutoTMMEnabled();
tagsInAll = torrent->tags();
}
else {
else
{
tagsInAll.intersect(torrent->tags());
}
@@ -944,21 +983,26 @@ void TransferListWidget::displayListMenu(const QPoint &)
if (torrent->hasMetadata())
oneHasMetadata = true;
if (!torrent->isSeed()) {
if (!torrent->isSeed())
{
oneNotSeed = true;
if (first) {
if (first)
{
sequentialDownloadMode = torrent->isSequentialDownload();
prioritizeFirstLast = torrent->hasFirstLastPiecePriority();
}
else {
else
{
if (sequentialDownloadMode != torrent->isSequentialDownload())
allSameSequentialDownloadMode = false;
if (prioritizeFirstLast != torrent->hasFirstLastPiecePriority())
allSamePrioFirstlast = false;
}
}
else {
if (!oneNotSeed && allSameSuperSeeding && torrent->hasMetadata()) {
else
{
if (!oneNotSeed && allSameSuperSeeding && torrent->hasMetadata())
{
if (first)
superSeedingMode = torrent->superSeeding();
else if (superSeedingMode != torrent->superSeeding())
@@ -976,7 +1020,8 @@ void TransferListWidget::displayListMenu(const QPoint &)
else
needsPause = true;
if (torrent->isErrored() || torrent->hasMissingFiles()) {
if (torrent->isErrored() || torrent->hasMissingFiles())
{
// If torrent is in "errored" or "missing files" state
// it cannot keep further processing until you restart it.
needsStart = true;
@@ -990,7 +1035,8 @@ void TransferListWidget::displayListMenu(const QPoint &)
if (oneHasMetadata && oneNotSeed && !allSameSequentialDownloadMode
&& !allSamePrioFirstlast && !allSameSuperSeeding && !allSameCategory
&& needsStart && needsForce && needsPause && needsPreview && !allSameAutoTMM) {
&& needsStart && needsForce && needsPause && needsPreview && !allSameAutoTMM)
{
break;
}
}
@@ -1023,11 +1069,13 @@ void TransferListWidget::displayListMenu(const QPoint &)
categoryMenu->addSeparator();
for (const QString &category : asConst(categories)) {
for (const QString &category : asConst(categories))
{
const QString escapedCategory = QString(category).replace('&', "&&"); // avoid '&' becomes accelerator key
QAction *cat = new QAction(UIThemeManager::instance()->getIcon("inode-directory"), escapedCategory, categoryMenu);
if (allSameCategory && (category == firstCategory)) {
if (allSameCategory && (category == firstCategory))
{
cat->setCheckable(true);
cat->setChecked(true);
}
@@ -1056,7 +1104,8 @@ void TransferListWidget::displayListMenu(const QPoint &)
tagsMenu->addSeparator();
for (const QString &tag : asConst(tags)) {
for (const QString &tag : asConst(tags))
{
auto *action = new TriStateAction(tag, tagsMenu);
action->setCloseOnTriggered(false);
@@ -1086,7 +1135,8 @@ void TransferListWidget::displayListMenu(const QPoint &)
listMenu->addAction(actionSetDownloadLimit);
listMenu->addAction(actionSetUploadLimit);
listMenu->addAction(actionSetMaxRatio);
if (!oneNotSeed && oneHasMetadata) {
if (!oneNotSeed && oneHasMetadata)
{
actionSuperSeedingMode->setCheckState(allSameSuperSeeding
? (superSeedingMode ? Qt::Checked : Qt::Unchecked)
: Qt::PartiallyChecked);
@@ -1094,11 +1144,13 @@ void TransferListWidget::displayListMenu(const QPoint &)
}
listMenu->addSeparator();
bool addedPreviewAction = false;
if (needsPreview) {
if (needsPreview)
{
listMenu->addAction(actionPreviewFile);
addedPreviewAction = true;
}
if (oneNotSeed) {
if (oneNotSeed)
{
actionSequentialDownload->setCheckState(allSameSequentialDownloadMode
? (sequentialDownloadMode ? Qt::Checked : Qt::Unchecked)
: Qt::PartiallyChecked);
@@ -1114,13 +1166,15 @@ void TransferListWidget::displayListMenu(const QPoint &)
if (addedPreviewAction)
listMenu->addSeparator();
if (oneHasMetadata) {
if (oneHasMetadata)
{
listMenu->addAction(actionForceRecheck);
listMenu->addAction(actionForceReannounce);
listMenu->addSeparator();
}
listMenu->addAction(actionOpenDestinationFolder);
if (BitTorrent::Session::instance()->isQueueingSystemEnabled() && oneNotSeed) {
if (BitTorrent::Session::instance()->isQueueingSystemEnabled() && oneNotSeed)
{
listMenu->addSeparator();
QMenu *queueMenu = listMenu->addMenu(tr("Queue"));
queueMenu->addAction(actionTopQueuePos);
@@ -1142,7 +1196,8 @@ void TransferListWidget::currentChanged(const QModelIndex &current, const QModel
{
qDebug("CURRENT CHANGED");
BitTorrent::TorrentHandle *torrent = nullptr;
if (current.isValid()) {
if (current.isValid())
{
torrent = m_listModel->torrentHandle(mapToSource(current));
// Scroll Fix
scrollTo(current);
@@ -1187,7 +1242,8 @@ void TransferListWidget::applyStatusFilter(int f)
{
m_sortFilterModel->setStatusFilter(static_cast<TorrentFilter::Type>(f));
// Select first item if nothing is selected
if (selectionModel()->selectedRows(0).empty() && (m_sortFilterModel->rowCount() > 0)) {
if (selectionModel()->selectedRows(0).empty() && (m_sortFilterModel->rowCount() > 0))
{
qDebug("Nothing is selected, selecting first row: %s", qUtf8Printable(m_sortFilterModel->index(0, TransferListModel::TR_NAME).data().toString()));
selectionModel()->setCurrentIndex(m_sortFilterModel->index(0, TransferListModel::TR_NAME), QItemSelectionModel::SelectCurrent | QItemSelectionModel::Rows);
}
@@ -1205,7 +1261,8 @@ bool TransferListWidget::loadSettings()
void TransferListWidget::wheelEvent(QWheelEvent *event)
{
if (event->modifiers() & Qt::ShiftModifier) {
if (event->modifiers() & Qt::ShiftModifier)
{
// Shift + scroll = horizontal scroll
event->accept();

View File

@@ -74,7 +74,8 @@ void TriStateWidget::paintEvent(QPaintEvent *)
opt.menuHasCheckableItems = true;
opt.text = m_text;
switch (m_checkState) {
switch (m_checkState)
{
case Qt::PartiallyChecked:
opt.state |= QStyle::State_NoChange;
break;
@@ -87,7 +88,8 @@ void TriStateWidget::paintEvent(QPaintEvent *)
};
if ((opt.state & QStyle::State_HasFocus)
|| rect().contains(mapFromGlobal(QCursor::pos()))) {
|| rect().contains(mapFromGlobal(QCursor::pos())))
{
opt.state |= QStyle::State_Selected;
if (QApplication::mouseButtons() != Qt::NoButton)
@@ -102,11 +104,13 @@ void TriStateWidget::mouseReleaseEvent(QMouseEvent *event)
{
toggleCheckState();
if (m_closeOnTriggered) {
if (m_closeOnTriggered)
{
// parent `triggered` signal will be emitted
QWidget::mouseReleaseEvent(event);
}
else {
else
{
update();
// need to emit parent `triggered` signal manually
emit triggered(m_checkState == Qt::Checked);
@@ -116,10 +120,12 @@ void TriStateWidget::mouseReleaseEvent(QMouseEvent *event)
void TriStateWidget::keyPressEvent(QKeyEvent *event)
{
if ((event->key() == Qt::Key_Return)
|| (event->key() == Qt::Key_Enter)) {
|| (event->key() == Qt::Key_Enter))
{
toggleCheckState();
if (!m_closeOnTriggered) {
if (!m_closeOnTriggered)
{
update();
// need to emit parent `triggered` signal manually
emit triggered(m_checkState == Qt::Checked);
@@ -132,7 +138,8 @@ void TriStateWidget::keyPressEvent(QKeyEvent *event)
void TriStateWidget::toggleCheckState()
{
switch (m_checkState) {
switch (m_checkState)
{
case Qt::Unchecked:
case Qt::PartiallyChecked:
m_checkState = Qt::Checked;

View File

@@ -81,11 +81,14 @@ UIThemeManager::UIThemeManager()
#endif
{
const Preferences *const pref = Preferences::instance();
if (m_useCustomTheme) {
if (!QResource::registerResource(pref->customUIThemePath(), "/uitheme")) {
if (m_useCustomTheme)
{
if (!QResource::registerResource(pref->customUIThemePath(), "/uitheme"))
{
LogMsg(tr("Failed to load UI theme from file: \"%1\"").arg(pref->customUIThemePath()), Log::WARNING);
}
else {
else
{
loadColorsFromJSONConfig();
applyPalette();
applyStyleSheet();
@@ -101,7 +104,8 @@ UIThemeManager *UIThemeManager::instance()
void UIThemeManager::applyStyleSheet() const
{
QFile qssFile(":uitheme/stylesheet.qss");
if (!qssFile.open(QIODevice::ReadOnly | QIODevice::Text)) {
if (!qssFile.open(QIODevice::ReadOnly | QIODevice::Text))
{
qApp->setStyleSheet({});
LogMsg(tr("Couldn't apply theme stylesheet. stylesheet.qss couldn't be opened. Reason: %1").arg(qssFile.errorString())
, Log::WARNING);
@@ -114,7 +118,8 @@ void UIThemeManager::applyStyleSheet() const
QIcon UIThemeManager::getIcon(const QString &iconId, const QString &fallback) const
{
#if (defined(Q_OS_UNIX) && !defined(Q_OS_MACOS))
if (m_useSystemTheme) {
if (m_useSystemTheme)
{
QIcon icon = QIcon::fromTheme(iconId);
if (icon.name() != iconId)
icon = QIcon::fromTheme(fallback, QIcon(getIconPathFromResources(iconId, fallback)));
@@ -155,9 +160,11 @@ QColor UIThemeManager::getColor(const QString &id, const QColor &defaultColor) c
QString UIThemeManager::getIconPath(const QString &iconId) const
{
#if (defined(Q_OS_UNIX) && !defined(Q_OS_MACOS))
if (m_useSystemTheme) {
if (m_useSystemTheme)
{
QString path = Utils::Fs::tempPath() + iconId + QLatin1String(".png");
if (!QFile::exists(path)) {
if (!QFile::exists(path))
{
const QIcon icon = QIcon::fromTheme(iconId);
if (!icon.isNull())
icon.pixmap(32).save(path);
@@ -173,12 +180,14 @@ QString UIThemeManager::getIconPath(const QString &iconId) const
QString UIThemeManager::getIconPathFromResources(const QString &iconId, const QString &fallback) const
{
if (m_useCustomTheme) {
if (m_useCustomTheme)
{
const QString customIcon = findIcon(iconId, THEME_ICONS_DIR);
if (!customIcon.isEmpty())
return customIcon;
if (!fallback.isEmpty()) {
if (!fallback.isEmpty())
{
const QString fallbackIcon = findIcon(fallback, THEME_ICONS_DIR);
if (!fallbackIcon.isEmpty())
return fallbackIcon;
@@ -191,26 +200,31 @@ QString UIThemeManager::getIconPathFromResources(const QString &iconId, const QS
void UIThemeManager::loadColorsFromJSONConfig()
{
QFile configFile(CONFIG_FILE_NAME);
if (!configFile.open(QIODevice::ReadOnly)) {
if (!configFile.open(QIODevice::ReadOnly))
{
LogMsg(tr("Failed to open \"%1\". Reason: %2").arg(CONFIG_FILE_NAME, configFile.errorString()), Log::WARNING);
return;
}
QJsonParseError jsonError;
const QJsonDocument configJsonDoc = QJsonDocument::fromJson(configFile.readAll(), &jsonError);
if (jsonError.error != QJsonParseError::NoError) {
if (jsonError.error != QJsonParseError::NoError)
{
LogMsg(tr("\"%1\" has invalid format. Reason: %2").arg(CONFIG_FILE_NAME, jsonError.errorString()), Log::WARNING);
return;
}
if (!configJsonDoc.isObject()) {
if (!configJsonDoc.isObject())
{
LogMsg(tr("\"%1\" has invalid format. Reason: %2").arg(CONFIG_FILE_NAME, tr("Root JSON value is not an object")), Log::WARNING);
return;
}
const QJsonObject colors = configJsonDoc.object().value("colors").toObject();
for (auto color = colors.constBegin(); color != colors.constEnd(); ++color) {
for (auto color = colors.constBegin(); color != colors.constEnd(); ++color)
{
const QColor providedColor(color.value().toString());
if (!providedColor.isValid()) {
if (!providedColor.isValid())
{
LogMsg(tr("Invalid color for ID \"%1\" is provided by theme").arg(color.key()), Log::WARNING);
continue;
}
@@ -257,7 +271,8 @@ void UIThemeManager::applyPalette() const
};
QPalette palette = qApp->palette();
for (const ColorDescriptor &colorDescriptor : paletteColorDescriptors) {
for (const ColorDescriptor &colorDescriptor : paletteColorDescriptors)
{
const QColor defaultColor = palette.color(colorDescriptor.colorGroup, colorDescriptor.colorRole);
const QColor newColor = getColor(colorDescriptor.id, defaultColor);
palette.setColor(colorDescriptor.colorGroup, colorDescriptor.colorRole, newColor);

View File

@@ -43,15 +43,18 @@ UpDownRatioDialog::UpDownRatioDialog(bool useDefault, qreal initialRatioValue,
{
m_ui->setupUi(this);
if (useDefault) {
if (useDefault)
{
m_ui->useDefaultButton->setChecked(true);
}
else if ((initialRatioValue == -1.) && (initialTimeValue == -1)) {
else if ((initialRatioValue == -1.) && (initialTimeValue == -1))
{
m_ui->noLimitButton->setChecked(true);
initialRatioValue = BitTorrent::Session::instance()->globalMaxRatio();
initialTimeValue = BitTorrent::Session::instance()->globalMaxSeedingMinutes();
}
else {
else
{
m_ui->torrentLimitButton->setChecked(true);
if (initialRatioValue >= 0)

View File

@@ -105,7 +105,8 @@ QPixmap Utils::Gui::scaledPixmapSvg(const QString &path, const QWidget *widget,
QPixmap pm;
QPixmapCache cache;
if (!cache.find(normalizedKey, &pm)) {
if (!cache.find(normalizedKey, &pm))
{
pm = QIcon(path).pixmap(scaledHeight);
cache.insert(normalizedKey, pm);
}
@@ -178,7 +179,8 @@ void Utils::Gui::openFolderSelect(const QString &absolutePath)
QString path {Utils::Fs::toUniformPath(absolutePath)};
const QFileInfo pathInfo {path};
// If the item to select doesn't exist, try to open its parent
if (!pathInfo.exists(path)) {
if (!pathInfo.exists(path))
{
openPath(path.left(path.lastIndexOf('/')));
return;
}
@@ -186,7 +188,8 @@ void Utils::Gui::openFolderSelect(const QString &absolutePath)
#ifdef Q_OS_WIN
HRESULT hresult = ::CoInitializeEx(nullptr, COINIT_MULTITHREADED);
PIDLIST_ABSOLUTE pidl = ::ILCreateFromPathW(reinterpret_cast<PCTSTR>(Utils::Fs::toNativePath(path).utf16()));
if (pidl) {
if (pidl)
{
::SHOpenFolderAndSelectItems(pidl, 0, nullptr, 0);
::ILFree(pidl);
}
@@ -197,11 +200,13 @@ void Utils::Gui::openFolderSelect(const QString &absolutePath)
proc.start("xdg-mime", {"query", "default", "inode/directory"});
proc.waitForFinished();
const QString output = proc.readLine().simplified();
if ((output == "dolphin.desktop") || (output == "org.kde.dolphin.desktop")) {
if ((output == "dolphin.desktop") || (output == "org.kde.dolphin.desktop"))
{
proc.startDetached("dolphin", {"--select", Utils::Fs::toNativePath(path)});
}
else if ((output == "nautilus.desktop") || (output == "org.gnome.Nautilus.desktop")
|| (output == "nautilus-folder-handler.desktop")) {
|| (output == "nautilus-folder-handler.desktop"))
{
if (pathInfo.isDir())
path = path.left(path.lastIndexOf('/'));
proc.start("nautilus", {"--version"});
@@ -213,15 +218,18 @@ void Utils::Gui::openFolderSelect(const QString &absolutePath)
else
proc.startDetached("nautilus", {"--no-desktop", Utils::Fs::toNativePath(path)});
}
else if (output == "nemo.desktop") {
else if (output == "nemo.desktop")
{
if (pathInfo.isDir())
path = path.left(path.lastIndexOf('/'));
proc.startDetached("nemo", {"--no-desktop", Utils::Fs::toNativePath(path)});
}
else if ((output == "konqueror.desktop") || (output == "kfmclient_dir.desktop")) {
else if ((output == "konqueror.desktop") || (output == "kfmclient_dir.desktop"))
{
proc.startDetached("konqueror", {"--select", Utils::Fs::toNativePath(path)});
}
else {
else
{
// "caja" manager can't pinpoint the file, see: https://github.com/qbittorrent/qBittorrent/issues/5003
openPath(path.left(path.lastIndexOf('/')));
}