diff --git a/qt/AddData.cc b/qt/AddData.cc index ba154b3e2..e121bf206 100644 --- a/qt/AddData.cc +++ b/qt/AddData.cc @@ -121,7 +121,7 @@ QString AddData::readableShortName() const switch (type) { case FILENAME: - return QFileInfo(filename).fileName(); + return QFileInfo(filename).baseName(); case URL: return url.path().split(QLatin1Char('/')).last(); diff --git a/qt/Session.cc b/qt/Session.cc index 110f58ab2..1a90c32a6 100644 --- a/qt/Session.cc +++ b/qt/Session.cc @@ -311,6 +311,9 @@ Session::Session(QString config_dir, Prefs& prefs) : connect(&rpc_, SIGNAL(dataSendProgress()), this, SIGNAL(dataSendProgress())); connect(&rpc_, SIGNAL(networkResponse(QNetworkReply::NetworkError, QString)), this, SIGNAL(networkResponse(QNetworkReply::NetworkError, QString))); + + duplicates_timer_.setSingleShot(true); + connect(&duplicates_timer_, &QTimer::timeout, this, &Session::onDuplicatesTimer); } Session::~Session() @@ -1100,23 +1103,30 @@ void Session::addTorrent(AddData const& add_me, tr_variant* args, bool trash_ori d->show(); }); - q->add([add_me](RpcResponse const& r) + q->add([this, add_me](RpcResponse const& r) { tr_variant* dup; + bool session_has_torrent = false; - if (!tr_variantDictFindDict(r.args.get(), TR_KEY_torrent_duplicate, &dup)) + if (tr_variantDictFindDict(r.args.get(), TR_KEY_torrent_added, &dup)) { - return; + session_has_torrent = true; + } + else if (tr_variantDictFindDict(r.args.get(), TR_KEY_torrent_duplicate, &dup)) + { + session_has_torrent = true; + + auto const hash = dictFind(dup, TR_KEY_hashString); + if (hash) + { + duplicates_.try_emplace(add_me.readableShortName(), *hash); + duplicates_timer_.start(1000); + } } - auto const name = dictFind(dup, TR_KEY_name); - if (name) + if (session_has_torrent && !add_me.filename.isEmpty()) { - auto* d = new QMessageBox(QMessageBox::Warning, tr("Add Torrent"), - tr(R"(

Unable to add "%1".

It is a duplicate of "%2" which is already added.

)"). - arg(add_me.readableShortName()).arg(*name), QMessageBox::Close, qApp->activeWindow()); - QObject::connect(d, &QMessageBox::rejected, d, &QMessageBox::deleteLater); - d->show(); + QFile(add_me.filename).rename(QStringLiteral("%1.added").arg(add_me.filename)); } }); @@ -1133,6 +1143,32 @@ void Session::addTorrent(AddData const& add_me, tr_variant* args, bool trash_ori q->run(); } +void Session::onDuplicatesTimer() +{ + decltype(duplicates_) duplicates; + duplicates.swap(duplicates_); + + QStringList lines; + for (auto it : duplicates_) + { + lines.push_back(tr("%1 (copy of %2)") + .arg(it.first) + .arg(it.second.left(7))); + } + + if (!lines.empty()) + { + lines.sort(Qt::CaseInsensitive); + auto* d = new QMessageBox(QMessageBox::Warning, + tr("Unable to add Duplicate Torrent(s)", "", lines.size()), + lines.join(QStringLiteral("\n")), + QMessageBox::Close, + qApp->activeWindow()); + QObject::connect(d, &QMessageBox::rejected, d, &QMessageBox::deleteLater); + d->show(); + } +} + void Session::addTorrent(AddData const& add_me) { tr_variant args; diff --git a/qt/Session.h b/qt/Session.h index 44e102838..53fa45138 100644 --- a/qt/Session.h +++ b/qt/Session.h @@ -15,6 +15,7 @@ #include #include #include +#include #include #include @@ -24,6 +25,7 @@ #include "RpcQueue.h" #include "Torrent.h" #include "Typedefs.h" +#include "Utils.h" // std::hash class AddData; class Prefs; @@ -120,6 +122,7 @@ public: public slots: void addTorrent(AddData const& addme); void launchWebInterface(); + void onDuplicatesTimer(); void queueMoveBottom(torrent_ids_t const& torrentIds = {}); void queueMoveDown(torrent_ids_t const& torrentIds = {}); void queueMoveTop(torrent_ids_t const& torrentIds = {}); @@ -176,4 +179,7 @@ private: bool is_definitely_local_session_ = true; RpcClient rpc_; torrent_ids_t const RecentlyActiveIDs = { -1 }; + + std::map duplicates_; + QTimer duplicates_timer_; }; diff --git a/qt/TorrentFilter.cc b/qt/TorrentFilter.cc index 84f1b96b2..424255345 100644 --- a/qt/TorrentFilter.cc +++ b/qt/TorrentFilter.cc @@ -253,7 +253,9 @@ bool TorrentFilter::filterAcceptsRow(int source_row, QModelIndex const& source_p if (accepts) { auto const text = prefs_.getString(Prefs::FILTER_TEXT); - accepts = text.isEmpty() || tor.name().contains(text, Qt::CaseInsensitive); + accepts = text.isEmpty() || + tor.name().contains(text, Qt::CaseInsensitive) || + tor.hashString().contains(text, Qt::CaseInsensitive); } return accepts;