1
0
Fork 0
mirror of https://github.com/transmission/transmission synced 2025-01-30 19:03:04 +00:00

feat: nicer add-torrent workflow in the qt client. (#1410)

* If you accidentally try to add a lot of duplicates -- for example, by
  starting up with a lot of duplicate torrents in the watchdir -- then
  coalesce all of them into a single error dialog instead of spamming
  the desktop with a different dialog for every duplicate.

* Make the duplicate torrent dialog's error message slightly terser to
  make it accommodate a long list of torrents: omit the ".torrent" file
  suffixes and show an abbreviated form of the existing torrent's hash.

* Support searching by torrent hash in the filterbar's text entry.
  This is useful when copy/pasting the hash from the duplicate torrent
  error dialog and is also consistent with the GTK client behavior.

* Copy the GTK client's behavior of appending ".added" to the end of
  .torrent files after they've been added to the session.
This commit is contained in:
Charles Kerr 2020-08-26 20:42:41 -05:00 committed by GitHub
parent 1bb9e2eef2
commit cf9b81eb7d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 56 additions and 12 deletions

View file

@ -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();

View file

@ -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<QString>(dup, TR_KEY_hashString);
if (hash)
{
duplicates_.try_emplace(add_me.readableShortName(), *hash);
duplicates_timer_.start(1000);
}
}
auto const name = dictFind<QString>(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"(<p><b>Unable to add "%1".</b></p><p>It is a duplicate of "%2" which is already added.</p>)").
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;

View file

@ -15,6 +15,7 @@
#include <QObject>
#include <QString>
#include <QStringList>
#include <QTimer>
#include <libtransmission/transmission.h>
#include <libtransmission/quark.h>
@ -24,6 +25,7 @@
#include "RpcQueue.h"
#include "Torrent.h"
#include "Typedefs.h"
#include "Utils.h" // std::hash<QString>
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<QString, QString> duplicates_;
QTimer duplicates_timer_;
};

View file

@ -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;