mirror of
https://github.com/qbittorrent/qBittorrent.git
synced 2024-11-28 21:38:51 +03:00
commit
f9a2b02a8d
7 changed files with 102 additions and 10 deletions
|
@ -2711,8 +2711,39 @@ bool SessionImpl::addTorrent_impl(const TorrentDescriptor &source, const AddTorr
|
|||
if (m_loadingTorrents.contains(id) || (infoHash.isHybrid() && m_loadingTorrents.contains(altID)))
|
||||
return false;
|
||||
|
||||
if (findTorrent(infoHash))
|
||||
if (Torrent *torrent = findTorrent(infoHash))
|
||||
{
|
||||
// a duplicate torrent is being added
|
||||
|
||||
if (hasMetadata)
|
||||
{
|
||||
// Trying to set metadata to existing torrent in case if it has none
|
||||
torrent->setMetadata(*source.info());
|
||||
}
|
||||
|
||||
if (!isMergeTrackersEnabled())
|
||||
{
|
||||
LogMsg(tr("Detected an attempt to add a duplicate torrent. Existing torrent: %1. Result: %2")
|
||||
.arg(torrent->name(), tr("Merging of trackers is disabled")));
|
||||
return false;
|
||||
}
|
||||
|
||||
const bool isPrivate = torrent->isPrivate() || (hasMetadata && source.info()->isPrivate());
|
||||
if (isPrivate)
|
||||
{
|
||||
LogMsg(tr("Detected an attempt to add a duplicate torrent. Existing torrent: %1. Result: %2")
|
||||
.arg(torrent->name(), tr("Trackers cannot be merged because it is a private torrent")));
|
||||
return false;
|
||||
}
|
||||
|
||||
// merge trackers and web seeds
|
||||
torrent->addTrackers(source.trackers());
|
||||
torrent->addUrlSeeds(source.urlSeeds());
|
||||
|
||||
LogMsg(tr("Detected an attempt to add a duplicate torrent. Existing torrent: %1. Result: %2")
|
||||
.arg(torrent->name(), tr("Trackers are merged from new source")));
|
||||
return false;
|
||||
}
|
||||
|
||||
// It looks illogical that we don't just use an existing handle,
|
||||
// but as previous experience has shown, it actually creates unnecessary
|
||||
|
|
|
@ -43,7 +43,6 @@ class QSslSocket;
|
|||
#else
|
||||
class QTcpSocket;
|
||||
#endif
|
||||
class QTextCodec;
|
||||
|
||||
namespace Net
|
||||
{
|
||||
|
|
|
@ -195,10 +195,8 @@ void PiecesBar::paintEvent(QPaintEvent *)
|
|||
|
||||
if (!m_highlightedRegion.isNull())
|
||||
{
|
||||
QColor highlightColor {this->palette().color(QPalette::Active, QPalette::Highlight)};
|
||||
highlightColor.setAlphaF(0.35f);
|
||||
QRect targetHighlightRect {m_highlightedRegion.adjusted(borderWidth, borderWidth, borderWidth, height() - 2 * borderWidth)};
|
||||
painter.fillRect(targetHighlightRect, highlightColor);
|
||||
painter.fillRect(targetHighlightRect, highlightedPieceColor());
|
||||
}
|
||||
|
||||
QPainterPath border;
|
||||
|
@ -231,6 +229,13 @@ QColor PiecesBar::pieceColor() const
|
|||
return palette().color(QPalette::Active, QPalette::Highlight);
|
||||
}
|
||||
|
||||
QColor PiecesBar::highlightedPieceColor() const
|
||||
{
|
||||
QColor col = palette().color(QPalette::Highlight).darker();
|
||||
col.setAlphaF(0.35);
|
||||
return col;
|
||||
}
|
||||
|
||||
QColor PiecesBar::colorBoxBorderColor() const
|
||||
{
|
||||
return palette().color(QPalette::Active, QPalette::ToolTipText);
|
||||
|
|
|
@ -68,7 +68,9 @@ protected:
|
|||
QColor backgroundColor() const;
|
||||
QColor borderColor() const;
|
||||
QColor pieceColor() const;
|
||||
QColor highlightedPieceColor() const;
|
||||
QColor colorBoxBorderColor() const;
|
||||
|
||||
const QVector<QRgb> &pieceColors() const;
|
||||
|
||||
// mix two colors by light model, ratio <0, 1>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Bittorrent Client using Qt and libtorrent.
|
||||
* Copyright (C) 2018 Vladimir Golovnev <glassez@yandex.ru>
|
||||
* Copyright (C) 2018-2024 Vladimir Golovnev <glassez@yandex.ru>
|
||||
* Copyright (C) 2006 Christophe Dumez <chris@qbittorrent.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
|
@ -50,6 +50,19 @@
|
|||
#include "searchsortmodel.h"
|
||||
#include "ui_searchjobwidget.h"
|
||||
|
||||
namespace
|
||||
{
|
||||
enum DataRole
|
||||
{
|
||||
LinkVisitedRole = Qt::UserRole + 100
|
||||
};
|
||||
|
||||
QColor visitedRowColor()
|
||||
{
|
||||
return QApplication::palette().color(QPalette::Disabled, QPalette::WindowText);
|
||||
}
|
||||
}
|
||||
|
||||
SearchJobWidget::SearchJobWidget(SearchHandler *searchHandler, IGUIApplication *app, QWidget *parent)
|
||||
: GUIApplicationComponent(app, parent)
|
||||
, m_ui {new Ui::SearchJobWidget}
|
||||
|
@ -158,6 +171,8 @@ SearchJobWidget::SearchJobWidget(SearchHandler *searchHandler, IGUIApplication *
|
|||
connect(this, &QObject::destroyed, searchHandler, &QObject::deleteLater);
|
||||
|
||||
setStatusTip(statusText(m_status));
|
||||
|
||||
connect(UIThemeManager::instance(), &UIThemeManager::themeChanged, this, &SearchJobWidget::onUIThemeChanged);
|
||||
}
|
||||
|
||||
SearchJobWidget::~SearchJobWidget()
|
||||
|
@ -179,9 +194,31 @@ QHeaderView *SearchJobWidget::header() const
|
|||
// Set the color of a row in data model
|
||||
void SearchJobWidget::setRowColor(int row, const QColor &color)
|
||||
{
|
||||
m_proxyModel->setDynamicSortFilter(false);
|
||||
for (int i = 0; i < m_proxyModel->columnCount(); ++i)
|
||||
m_proxyModel->setData(m_proxyModel->index(row, i), color, Qt::ForegroundRole);
|
||||
}
|
||||
|
||||
void SearchJobWidget::setRowVisited(const int row)
|
||||
{
|
||||
m_proxyModel->setDynamicSortFilter(false);
|
||||
|
||||
m_proxyModel->setData(m_proxyModel->index(row, 0), true, LinkVisitedRole);
|
||||
setRowColor(row, visitedRowColor());
|
||||
|
||||
m_proxyModel->setDynamicSortFilter(true);
|
||||
}
|
||||
|
||||
void SearchJobWidget::onUIThemeChanged()
|
||||
{
|
||||
m_proxyModel->setDynamicSortFilter(false);
|
||||
|
||||
for (int row = 0; row < m_proxyModel->rowCount(); ++row)
|
||||
{
|
||||
const QVariant userData = m_proxyModel->data(m_proxyModel->index(row, 0), LinkVisitedRole);
|
||||
const bool isVisited = userData.toBool();
|
||||
if (isVisited)
|
||||
setRowColor(row, visitedRowColor());
|
||||
}
|
||||
|
||||
m_proxyModel->setDynamicSortFilter(true);
|
||||
}
|
||||
|
@ -284,7 +321,8 @@ void SearchJobWidget::downloadTorrent(const QModelIndex &rowIndex, const AddTorr
|
|||
, this, [this, option](const QString &source) { addTorrentToSession(source, option); });
|
||||
connect(downloadHandler, &SearchDownloadHandler::downloadFinished, downloadHandler, &SearchDownloadHandler::deleteLater);
|
||||
}
|
||||
setRowColor(rowIndex.row(), QApplication::palette().color(QPalette::LinkVisited));
|
||||
|
||||
setRowVisited(rowIndex.row());
|
||||
}
|
||||
|
||||
void SearchJobWidget::addTorrentToSession(const QString &source, const AddTorrentOption option)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Bittorrent Client using Qt and libtorrent.
|
||||
* Copyright (C) 2018 Vladimir Golovnev <glassez@yandex.ru>
|
||||
* Copyright (C) 2018-2024 Vladimir Golovnev <glassez@yandex.ru>
|
||||
* Copyright (C) 2006 Christophe Dumez <chris@qbittorrent.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
|
@ -113,8 +113,10 @@ private:
|
|||
void fillFilterComboBoxes();
|
||||
NameFilteringMode filteringMode() const;
|
||||
QHeaderView *header() const;
|
||||
void setRowColor(int row, const QColor &color);
|
||||
int visibleColumnsCount() const;
|
||||
void setRowColor(int row, const QColor &color);
|
||||
void setRowVisited(int row);
|
||||
void onUIThemeChanged();
|
||||
|
||||
void downloadTorrents(AddTorrentOption option = AddTorrentOption::Default);
|
||||
void openTorrentPages() const;
|
||||
|
|
|
@ -70,6 +70,13 @@
|
|||
<option value="FilesChecked">QBT_TR(Files checked)QBT_TR[CONTEXT=OptionsDialog]</option>
|
||||
</select>
|
||||
</div>
|
||||
<fieldset class="settings">
|
||||
<legend>QBT_TR(When duplicate torrent is being added)QBT_TR[CONTEXT=OptionsDialog]</legend>
|
||||
<div class="formRow">
|
||||
<input type="checkbox" id="mergeTrackersInput">
|
||||
<label for="mergeTrackersInput">QBT_TR(Merge trackers to existing torrent)QBT_TR[CONTEXT=OptionsDialog]</label>
|
||||
</div>
|
||||
</fieldset>
|
||||
<div class="formRow">
|
||||
<input type="checkbox" id="deletetorrentfileafter_checkbox" />
|
||||
<label for="deletetorrentfileafter_checkbox">QBT_TR(Delete .torrent files afterwards)QBT_TR[CONTEXT=OptionsDialog]</label>
|
||||
|
@ -145,6 +152,10 @@
|
|||
<input type="checkbox" id="use_subcategories_checkbox" />
|
||||
<label for="use_subcategories_checkbox">QBT_TR(Use Subcategories)QBT_TR[CONTEXT=OptionsDialog]</label>
|
||||
</div>
|
||||
<div class="formRow">
|
||||
<input type="checkbox" id="categoryPathsManualModeCheckbox" title="QBT_TR(Resolve relative Save Path against appropriate Category path instead of Default one)QBT_TR[CONTEXT=OptionsDialog]">
|
||||
<label for="categoryPathsManualModeCheckbox">QBT_TR(Use Category paths in Manual Mode)QBT_TR[CONTEXT=OptionsDialog]</label>
|
||||
</div>
|
||||
<table>
|
||||
<tr>
|
||||
<td>
|
||||
|
@ -2033,6 +2044,7 @@ Use ';' to split multiple entries. Can use wildcard '*'.)QBT_TR[CONTEXT=OptionsD
|
|||
break;
|
||||
}
|
||||
$("stopConditionSelect").getChildren("option")[index].selected = true;
|
||||
$("mergeTrackersInput").setProperty("checked", pref.merge_trackers);
|
||||
$("deletetorrentfileafter_checkbox").setProperty("checked", pref.auto_delete_mode);
|
||||
|
||||
$("preallocateall_checkbox").setProperty("checked", pref.preallocate_all);
|
||||
|
@ -2045,6 +2057,7 @@ Use ';' to split multiple entries. Can use wildcard '*'.)QBT_TR[CONTEXT=OptionsD
|
|||
$("save_path_changed_tmm_combobox").setProperty("value", pref.save_path_changed_tmm_enabled);
|
||||
$("category_changed_tmm_combobox").setProperty("value", pref.category_changed_tmm_enabled);
|
||||
$("use_subcategories_checkbox").setProperty("checked", pref.use_subcategories);
|
||||
$("categoryPathsManualModeCheckbox").setProperty("checked", pref.use_category_paths_in_manual_mode);
|
||||
$("savepath_text").setProperty("value", pref.save_path);
|
||||
$("temppath_checkbox").setProperty("checked", pref.temp_path_enabled);
|
||||
$("temppath_text").setProperty("value", pref.temp_path);
|
||||
|
@ -2417,6 +2430,7 @@ Use ';' to split multiple entries. Can use wildcard '*'.)QBT_TR[CONTEXT=OptionsD
|
|||
settings["add_to_top_of_queue"] = $("addToTopOfQueueCheckbox").getProperty("checked");
|
||||
settings["add_stopped_enabled"] = $("dontstartdownloads_checkbox").getProperty("checked");
|
||||
settings["torrent_stop_condition"] = $("stopConditionSelect").getSelected()[0].getProperty("value");
|
||||
settings["merge_trackers"] = $("mergeTrackersInput").getProperty("checked");
|
||||
settings["auto_delete_mode"] = Number($("deletetorrentfileafter_checkbox").getProperty("checked"));
|
||||
|
||||
settings["preallocate_all"] = $("preallocateall_checkbox").getProperty("checked");
|
||||
|
@ -2429,6 +2443,7 @@ Use ';' to split multiple entries. Can use wildcard '*'.)QBT_TR[CONTEXT=OptionsD
|
|||
settings["save_path_changed_tmm_enabled"] = ($("save_path_changed_tmm_combobox").getProperty("value") === "true");
|
||||
settings["category_changed_tmm_enabled"] = ($("category_changed_tmm_combobox").getProperty("value") === "true");
|
||||
settings["use_subcategories"] = $("use_subcategories_checkbox").getProperty("checked");
|
||||
settings["use_category_paths_in_manual_mode"] = $("categoryPathsManualModeCheckbox").getProperty("checked");
|
||||
settings["save_path"] = $("savepath_text").getProperty("value");
|
||||
settings["temp_path_enabled"] = $("temppath_checkbox").getProperty("checked");
|
||||
settings["temp_path"] = $("temppath_text").getProperty("value");
|
||||
|
|
Loading…
Reference in a new issue