mirror of
https://github.com/transmission/transmission
synced 2025-02-19 04:41:11 +00:00
feat: add labels to DetailsDialog of Qt client
This commit is contained in:
parent
b562983cbd
commit
e80ec7b7a4
6 changed files with 115 additions and 5 deletions
|
@ -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);
|
||||
|
|
|
@ -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_;
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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, //
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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_;
|
||||
|
||||
|
|
Loading…
Reference in a new issue