feat: add labels to DetailsDialog of Qt client

This commit is contained in:
Nick 2023-12-25 23:09:20 +01:00 committed by GitHub
parent b562983cbd
commit e80ec7b7a4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 115 additions and 5 deletions

View File

@ -25,6 +25,7 @@
#include <QResizeEvent>
#include <QRegularExpression>
#include <QStringList>
#include <QString>
#include <QStyle>
#include <QTreeWidgetItem>
@ -282,6 +283,9 @@ DetailsDialog::DetailsDialog(Session& session, Prefs& prefs, TorrentModel const&
// set up the debounce timer
connect(&ui_debounce_timer_, &QTimer::timeout, this, &DetailsDialog::refreshUI);
ui_debounce_timer_.setSingleShot(true);
// set labels
connect(ui_.dialogButtons, &QDialogButtonBox::clicked, this, &DetailsDialog::onButtonBoxClicked);
}
DetailsDialog::~DetailsDialog()
@ -300,6 +304,8 @@ void DetailsDialog::setIds(torrent_ids_t const& ids)
session_.refreshDetailInfo(ids_);
tracker_model_->refresh(model_, ids_);
labels_need_refresh_ = true;
refreshModel();
refreshUI();
}
@ -386,6 +392,40 @@ void DetailsDialog::onSessionCalled(Session::Tag tag)
}
}
void DetailsDialog::onButtonBoxClicked(QAbstractButton* button)
{
if (ui_.dialogButtons->standardButton(button) == QDialogButtonBox::Close)
{
if (ui_.labelsTextEdit->isReadOnly()) // no edits could have been made
{
return;
}
QString const labels_text = ui_.labelsTextEdit->toPlainText().trimmed();
if (labels_text == labels_baseline_) // no edits have been made
{
return;
}
QString const re = QStringLiteral("((,|;)\\s*)");
//see https://doc.qt.io/qt-5/qt.html#SplitBehaviorFlags-enum
#if QT_VERSION < QT_VERSION_CHECK(5, 14, 0)
QStringList const labels_list = labels_text.split(QRegularExpression(re), QString::SkipEmptyParts);
#else
QStringList const labels_list = labels_text.split(QRegularExpression(re), Qt::SkipEmptyParts);
#endif
torrentSet(TR_KEY_labels, labels_list);
if (!ids_.empty())
{
session_.refreshDetailInfo(ids_);
}
}
}
namespace
{
@ -849,6 +889,39 @@ void DetailsDialog::refreshUI()
ui_.privacyValueLabel->setText(string);
// myLabelsTextEdit
if (labels_need_refresh_)
{
labels_need_refresh_ = false;
if (torrents.empty())
{
labels_baseline_.clear();
ui_.labelsTextEdit->setText({});
ui_.labelsTextEdit->setPlaceholderText(none);
ui_.labelsTextEdit->setReadOnly(true);
ui_.labelsTextEdit->setEnabled(true);
}
else if (auto const& baseline = torrents[0]->labels(); std::all_of(
std::begin(torrents),
std::end(torrents),
[&baseline](auto const* tor) { return tor->labels() == baseline; }))
{
labels_baseline_ = baseline.join(QStringLiteral(", "));
ui_.labelsTextEdit->setText(labels_baseline_);
ui_.labelsTextEdit->setPlaceholderText(none);
ui_.labelsTextEdit->setReadOnly(false);
ui_.labelsTextEdit->setEnabled(true);
}
else // mixed
{
labels_baseline_.clear();
ui_.labelsTextEdit->setText({});
ui_.labelsTextEdit->setPlaceholderText(mixed);
ui_.labelsTextEdit->setEnabled(false);
}
}
// myCommentBrowser
string = none;
bool is_comment_mixed = false;
@ -1250,8 +1323,12 @@ void DetailsDialog::setEnabled(bool enabled)
void DetailsDialog::initInfoTab()
{
int const h = QFontMetrics{ ui_.commentBrowser->font() }.lineSpacing() * 4;
ui_.commentBrowser->setFixedHeight(h);
int const cbh = QFontMetrics{ ui_.commentBrowser->font() }.lineSpacing() * 4;
ui_.commentBrowser->setFixedHeight(cbh);
int const lteh = QFontMetrics{ ui_.labelsTextEdit->font() }.lineSpacing() * 2;
ui_.labelsTextEdit->setFixedHeight(lteh);
ui_.labelsTextEdit->setText(QStringLiteral("Initializing..."));
auto* cr = new ColumnResizer{ this };
cr->addLayout(ui_.activitySectionLayout);

View File

@ -66,6 +66,9 @@ private slots:
void onTorrentsChanged(torrent_ids_t const& ids, Torrent::fields_t const& fields);
void onSessionCalled(Session::Tag tag);
// Details tab
void onButtonBoxClicked(QAbstractButton* button);
// Tracker tab
void onTrackerSelectionChanged();
void onAddTrackerClicked();
@ -131,6 +134,8 @@ private:
torrent_ids_t ids_;
QTimer model_timer_;
QTimer ui_debounce_timer_;
bool labels_need_refresh_ = true;
QString labels_baseline_;
std::shared_ptr<TrackerModel> tracker_model_;
std::shared_ptr<TrackerModelFilter> tracker_filter_;

View File

@ -457,6 +457,23 @@
</widget>
</item>
<item row="6" column="0">
<widget class="QLabel" name="labelsLabel">
<property name="text">
<string>Labels:</string>
</property>
<property name="buddy">
<cstring>labelsTextEdit</cstring>
</property>
</widget>
</item>
<item row="6" column="1">
<widget class="QTextEdit" name="labelsTextEdit">
<property name="readOnly">
<bool>false</bool>
</property>
</widget>
</item>
<item row="7" column="0">
<widget class="QLabel" name="commentLabel">
<property name="text">
<string>Comment:</string>
@ -466,7 +483,7 @@
</property>
</widget>
</item>
<item row="6" column="1">
<item row="7" column="1">
<widget class="QTextBrowser" name="commentBrowser">
<property name="textInteractionFlags">
<set>Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>

View File

@ -524,11 +524,12 @@ std::vector<std::string_view> const& Session::getKeyNames(TorrentProperties prop
if (names.empty())
{
// unchanging fields needed by the main window
static auto constexpr MainInfoKeys = std::array<tr_quark, 8>{
static auto constexpr MainInfoKeys = std::array<tr_quark, 9>{
TR_KEY_addedDate, //
TR_KEY_downloadDir, //
TR_KEY_file_count, //
TR_KEY_hashString, //
TR_KEY_labels, //
TR_KEY_name, //
TR_KEY_primary_mime_type, //
TR_KEY_totalSize, //
@ -565,12 +566,13 @@ std::vector<std::string_view> const& Session::getKeyNames(TorrentProperties prop
};
// unchanging fields needed by the details dialog
static auto constexpr DetailInfoKeys = std::array<tr_quark, 9>{
static auto constexpr DetailInfoKeys = std::array<tr_quark, 10>{
TR_KEY_comment, //
TR_KEY_creator, //
TR_KEY_dateCreated, //
TR_KEY_files, //
TR_KEY_isPrivate, //
TR_KEY_labels, //
TR_KEY_pieceCount, //
TR_KEY_pieceSize, //
TR_KEY_trackerList, //

View File

@ -202,6 +202,7 @@ Torrent::fields_t Torrent::update(tr_quark const* keys, tr_variant const* const*
HANDLE_KEY(isFinished, is_finished, IS_FINISHED)
HANDLE_KEY(isPrivate, is_private, IS_PRIVATE)
HANDLE_KEY(isStalled, is_stalled, IS_STALLED)
HANDLE_KEY(labels, labels, LABELS)
HANDLE_KEY(leftUntilDone, left_until_done, LEFT_UNTIL_DONE)
HANDLE_KEY(manualAnnounceTime, manual_announce_time, MANUAL_ANNOUNCE_TIME)
HANDLE_KEY(metadataPercentComplete, metadata_percent_complete, METADATA_PERCENT_COMPLETE)

View File

@ -16,6 +16,7 @@
#include <QMetaType>
#include <QObject>
#include <QString>
#include <QStringList>
#include <libtransmission/transmission.h>
@ -415,6 +416,11 @@ public:
bool includesTracker(QString const& sitename) const;
[[nodiscard]] constexpr auto const& labels() const noexcept
{
return labels_;
}
[[nodiscard]] constexpr auto const& sitenames() const noexcept
{
return sitenames_;
@ -588,6 +594,7 @@ public:
IS_FINISHED,
IS_PRIVATE,
IS_STALLED,
LABELS,
LEFT_UNTIL_DONE,
MANUAL_ANNOUNCE_TIME,
METADATA_PERCENT_COMPLETE,
@ -690,6 +697,7 @@ private:
PeerList peers_;
FileList files_;
QStringList labels_;
std::vector<QString> sitenames_;
TrackerStatsList tracker_stats_;