Add support for saving playcounts and ratings to tags

This commit is contained in:
Jonas Kvinge
2021-10-24 16:08:17 +02:00
parent ce7926cfa4
commit 3ab86543ad
22 changed files with 1230 additions and 286 deletions

View File

@@ -166,6 +166,9 @@ EditTagDialog::EditTagDialog(Application *app, QWidget *parent)
QObject::connect(checkbox, &QCheckBox::stateChanged, this, &EditTagDialog::FieldValueEdited);
QObject::connect(checkbox, &CheckBox::Reset, this, &EditTagDialog::ResetField);
}
else if (RatingBox *ratingbox = qobject_cast<RatingBox*>(widget)) {
QObject::connect(ratingbox, &RatingWidget::RatingChanged, this, &EditTagDialog::FieldValueEdited);
}
}
}
@@ -184,6 +187,7 @@ EditTagDialog::EditTagDialog(Application *app, QWidget *parent)
QObject::connect(ui_->song_list->selectionModel(), &QItemSelectionModel::selectionChanged, this, &EditTagDialog::SelectionChanged);
QObject::connect(ui_->button_box, &QDialogButtonBox::clicked, this, &EditTagDialog::ButtonClicked);
QObject::connect(ui_->playcount_reset, &QPushButton::clicked, this, &EditTagDialog::ResetPlayCounts);
QObject::connect(ui_->rating, &RatingWidget::RatingChanged, this, &EditTagDialog::SongRated);
#ifdef HAVE_MUSICBRAINZ
QObject::connect(ui_->fetch_tag, &QPushButton::clicked, this, &EditTagDialog::FetchTag);
#endif
@@ -478,6 +482,7 @@ QVariant EditTagDialog::Data::value(const Song &song, const QString &id) {
if (id == "disc") return song.disc();
if (id == "year") return song.year();
if (id == "compilation") return song.compilation();
if (id == "rating") { return song.rating(); }
qLog(Warning) << "Unknown ID" << id;
return QVariant();
@@ -499,6 +504,7 @@ void EditTagDialog::Data::set_value(const QString &id, const QVariant &value) {
else if (id == "disc") current_.set_disc(value.toInt());
else if (id == "year") current_.set_year(value.toInt());
else if (id == "compilation") current_.set_compilation(value.toBool());
else if (id == "rating") { current_.set_rating(value.toDouble()); }
else qLog(Warning) << "Unknown ID" << id;
}
@@ -832,7 +838,6 @@ void EditTagDialog::UpdateStatisticsTab(const Song &song) {
ui_->playcount->setText(QString::number(qMax(0, song.playcount())));
ui_->skipcount->setText(QString::number(qMax(0, song.skipcount())));
ui_->lastplayed->setText(song.lastplayed() <= 0 ? tr("Never") : QDateTime::fromSecsSinceEpoch(song.lastplayed()).toString(QLocale::system().dateTimeFormat(QLocale::LongFormat)));
}
@@ -1094,6 +1099,10 @@ void EditTagDialog::SaveData() {
QObject::connect(reply, &TagReaderReply::Finished, this, [this, reply, ref]() { SongSaveTagsComplete(reply, ref.current_.url().toLocalFile(), ref.current_); }, Qt::QueuedConnection);
}
if (ref.current_.rating() != ref.original_.rating() && ref.current_.is_collection_song()) {
app_->collection_backend()->UpdateSongRatingAsync(ref.current_.id(), ref.current_.rating(), true);
}
QString embedded_cover_from_file;
// If embedded album cover is selected and it isn't saved to the tags, then save it even if no action was done.
if (ui_->checkbox_embedded_cover->isChecked() && ref.cover_action_ == UpdateCoverAction_None && !ref.original_.has_embedded_cover() && ref.original_.save_embedded_cover_supported()) {
@@ -1256,6 +1265,18 @@ void EditTagDialog::ResetPlayCounts() {
}
void EditTagDialog::SongRated(const float rating) {
const QModelIndexList indexes = ui_->song_list->selectionModel()->selectedIndexes();
if (indexes.isEmpty()) return;
for (const QModelIndex &idx : indexes) {
if (!data_[idx.row()].current_.is_valid() || data_[idx.row()].current_.id() == -1) return;
data_[idx.row()].current_.set_rating(rating);
}
}
void EditTagDialog::FetchTag() {
#ifdef HAVE_MUSICBRAINZ

View File

@@ -116,6 +116,7 @@ class EditTagDialog : public QDialog {
void ResetField();
void ButtonClicked(QAbstractButton *button);
void ResetPlayCounts();
void SongRated(const float rating);
void FetchTag();
void FetchTagSongChosen(const Song &original_song, const Song &new_metadata);

View File

@@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>800</width>
<height>843</height>
<height>889</height>
</rect>
</property>
<property name="windowTitle">
@@ -125,10 +125,10 @@
</property>
<property name="html">
<string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;meta charset=&quot;utf-8&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Verdana'; font-size:10pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Noto Sans';&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Noto Sans'; font-size:11pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:10pt;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="textInteractionFlags">
<set>Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
@@ -611,10 +611,10 @@ p, li { white-space: pre-wrap; }
</property>
<property name="html">
<string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;meta charset=&quot;utf-8&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Verdana'; font-size:10pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Noto Sans';&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Noto Sans'; font-size:11pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:10pt;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
</widget>
</item>
@@ -627,8 +627,24 @@ p, li { white-space: pre-wrap; }
<property name="sizeConstraint">
<enum>QLayout::SetMinimumSize</enum>
</property>
<item row="13" column="2">
<widget class="LineEdit" name="grouping">
<item row="4" column="3">
<widget class="SpinBox" name="year">
<property name="correctionMode">
<enum>QAbstractSpinBox::CorrectToNearestValue</enum>
</property>
<property name="maximum">
<number>9999</number>
</property>
<property name="has_clear_button" stdset="0">
<bool>false</bool>
</property>
<property name="has_reset_button" stdset="0">
<bool>true</bool>
</property>
</widget>
</item>
<item row="14" column="1">
<widget class="LineEdit" name="genre">
<property name="has_reset_button" stdset="0">
<bool>true</bool>
</property>
@@ -637,66 +653,8 @@ p, li { white-space: pre-wrap; }
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label_title">
<property name="minimumSize">
<size>
<width>80</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>Title</string>
</property>
<property name="buddy">
<cstring>title</cstring>
</property>
</widget>
</item>
<item row="15" column="2">
<widget class="CheckBox" name="compilation">
<property name="has_reset_button" stdset="0">
<bool>false</bool>
</property>
<property name="has_clear_button" stdset="0">
<bool>false</bool>
</property>
</widget>
</item>
<item row="14" column="0">
<widget class="QLabel" name="genre_label">
<property name="minimumSize">
<size>
<width>80</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>Genre</string>
</property>
<property name="buddy">
<cstring>genre</cstring>
</property>
</widget>
</item>
<item row="21" column="2">
<widget class="TextEdit" name="comment">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="has_reset_button" stdset="0">
<bool>true</bool>
</property>
<property name="has_clear_button" stdset="0">
<bool>false</bool>
</property>
</widget>
</item>
<item row="3" column="3">
<widget class="QLabel" name="disc_label">
<item row="3" column="2">
<widget class="QLabel" name="label_disc">
<property name="text">
<string>Disc</string>
</property>
@@ -705,157 +663,8 @@ p, li { white-space: pre-wrap; }
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QLabel" name="label_albumartist">
<property name="minimumSize">
<size>
<width>80</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>Album artist</string>
</property>
<property name="buddy">
<cstring>albumartist</cstring>
</property>
</widget>
</item>
<item row="15" column="0">
<widget class="QLabel" name="label_compilation">
<property name="minimumSize">
<size>
<width>80</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>Compilation</string>
</property>
<property name="buddy">
<cstring>compilation</cstring>
</property>
</widget>
</item>
<item row="4" column="2">
<widget class="LineEdit" name="album">
<property name="has_reset_button" stdset="0">
<bool>true</bool>
</property>
<property name="has_clear_button" stdset="0">
<bool>false</bool>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="label_album">
<property name="minimumSize">
<size>
<width>80</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>Album</string>
</property>
<property name="buddy">
<cstring>album</cstring>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_artist">
<property name="minimumSize">
<size>
<width>80</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>Artist</string>
</property>
<property name="buddy">
<cstring>artist</cstring>
</property>
</widget>
</item>
<item row="21" column="0">
<widget class="QLabel" name="label_comment">
<property name="minimumSize">
<size>
<width>80</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>Comment</string>
</property>
<property name="buddy">
<cstring>comment</cstring>
</property>
</widget>
</item>
<item row="8" column="0">
<widget class="QLabel" name="label_composer">
<property name="minimumSize">
<size>
<width>80</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>Composer</string>
</property>
<property name="buddy">
<cstring>composer</cstring>
</property>
</widget>
</item>
<item row="20" column="2">
<widget class="QPushButton" name="fetch_tag">
<property name="text">
<string>Complete tags automatically</string>
</property>
<property name="icon">
<iconset resource="../../data/data.qrc">
<normaloff>:/pictures/musicbrainz.png</normaloff>:/pictures/musicbrainz.png</iconset>
</property>
<property name="iconSize">
<size>
<width>38</width>
<height>22</height>
</size>
</property>
</widget>
</item>
<item row="9" column="0">
<widget class="QLabel" name="label_performer">
<property name="minimumSize">
<size>
<width>80</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>Performer</string>
</property>
<property name="buddy">
<cstring>performer</cstring>
</property>
</widget>
</item>
<item row="3" column="2">
<widget class="LineEdit" name="artist">
<property name="has_reset_button" stdset="0">
<bool>true</bool>
</property>
<property name="has_clear_button" stdset="0">
<bool>false</bool>
</property>
</widget>
</item>
<item row="14" column="2">
<widget class="LineEdit" name="genre">
<item row="8" column="1">
<widget class="LineEdit" name="composer">
<property name="has_reset_button" stdset="0">
<bool>true</bool>
</property>
@@ -880,24 +689,24 @@ p, li { white-space: pre-wrap; }
</property>
</widget>
</item>
<item row="3" column="4">
<widget class="SpinBox" name="disc">
<property name="correctionMode">
<enum>QAbstractSpinBox::CorrectToNearestValue</enum>
<item row="5" column="0">
<widget class="QLabel" name="label_albumartist">
<property name="minimumSize">
<size>
<width>80</width>
<height>0</height>
</size>
</property>
<property name="maximum">
<number>9999</number>
<property name="text">
<string>Album artist</string>
</property>
<property name="has_clear_button" stdset="0">
<bool>false</bool>
</property>
<property name="has_reset_button" stdset="0">
<bool>true</bool>
<property name="buddy">
<cstring>albumartist</cstring>
</property>
</widget>
</item>
<item row="8" column="2">
<widget class="LineEdit" name="composer">
<item row="13" column="1">
<widget class="LineEdit" name="grouping">
<property name="has_reset_button" stdset="0">
<bool>true</bool>
</property>
@@ -906,7 +715,27 @@ p, li { white-space: pre-wrap; }
</property>
</widget>
</item>
<item row="0" column="2">
<item row="9" column="1">
<widget class="LineEdit" name="performer">
<property name="has_reset_button" stdset="0">
<bool>true</bool>
</property>
<property name="has_clear_button" stdset="0">
<bool>false</bool>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="LineEdit" name="artist">
<property name="has_reset_button" stdset="0">
<bool>true</bool>
</property>
<property name="has_clear_button" stdset="0">
<bool>false</bool>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="LineEdit" name="title">
<property name="has_reset_button" stdset="0">
<bool>true</bool>
@@ -916,7 +745,7 @@ p, li { white-space: pre-wrap; }
</property>
</widget>
</item>
<item row="0" column="4">
<item row="0" column="3">
<widget class="SpinBox" name="track">
<property name="correctionMode">
<enum>QAbstractSpinBox::CorrectToNearestValue</enum>
@@ -932,28 +761,99 @@ p, li { white-space: pre-wrap; }
</property>
</widget>
</item>
<item row="5" column="2">
<widget class="LineEdit" name="albumartist">
<property name="has_reset_button" stdset="0">
<bool>true</bool>
<item row="4" column="0">
<widget class="QLabel" name="label_album">
<property name="minimumSize">
<size>
<width>80</width>
<height>0</height>
</size>
</property>
<property name="has_clear_button" stdset="0">
<bool>false</bool>
<property name="text">
<string>Album</string>
</property>
<property name="buddy">
<cstring>album</cstring>
</property>
</widget>
</item>
<item row="9" column="2">
<widget class="LineEdit" name="performer">
<property name="has_reset_button" stdset="0">
<bool>true</bool>
<item row="4" column="2">
<widget class="QLabel" name="label_year">
<property name="text">
<string>Year</string>
</property>
<property name="has_clear_button" stdset="0">
<bool>false</bool>
<property name="buddy">
<cstring>year</cstring>
</property>
</widget>
</item>
<item row="4" column="4">
<widget class="SpinBox" name="year">
<item row="0" column="0">
<widget class="QLabel" name="label_title">
<property name="minimumSize">
<size>
<width>80</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>Title</string>
</property>
<property name="buddy">
<cstring>title</cstring>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_artist">
<property name="minimumSize">
<size>
<width>80</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>Artist</string>
</property>
<property name="buddy">
<cstring>artist</cstring>
</property>
</widget>
</item>
<item row="8" column="0">
<widget class="QLabel" name="label_composer">
<property name="minimumSize">
<size>
<width>80</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>Composer</string>
</property>
<property name="buddy">
<cstring>composer</cstring>
</property>
</widget>
</item>
<item row="21" column="1">
<widget class="QPushButton" name="fetch_tag">
<property name="text">
<string>Complete tags automatically</string>
</property>
<property name="icon">
<iconset resource="../../data/data.qrc">
<normaloff>:/pictures/musicbrainz.png</normaloff>:/pictures/musicbrainz.png</iconset>
</property>
<property name="iconSize">
<size>
<width>38</width>
<height>22</height>
</size>
</property>
</widget>
</item>
<item row="3" column="3">
<widget class="SpinBox" name="disc">
<property name="correctionMode">
<enum>QAbstractSpinBox::CorrectToNearestValue</enum>
</property>
@@ -968,7 +868,117 @@ p, li { white-space: pre-wrap; }
</property>
</widget>
</item>
<item row="0" column="3">
<item row="15" column="1">
<widget class="CheckBox" name="compilation">
<property name="has_reset_button" stdset="0">
<bool>false</bool>
</property>
<property name="has_clear_button" stdset="0">
<bool>false</bool>
</property>
</widget>
</item>
<item row="14" column="0">
<widget class="QLabel" name="label_genre">
<property name="minimumSize">
<size>
<width>80</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>Genre</string>
</property>
<property name="buddy">
<cstring>genre</cstring>
</property>
</widget>
</item>
<item row="22" column="0">
<widget class="QLabel" name="label_comment">
<property name="minimumSize">
<size>
<width>80</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>Comment</string>
</property>
<property name="buddy">
<cstring>comment</cstring>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="LineEdit" name="album">
<property name="has_reset_button" stdset="0">
<bool>true</bool>
</property>
<property name="has_clear_button" stdset="0">
<bool>false</bool>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="LineEdit" name="albumartist">
<property name="has_reset_button" stdset="0">
<bool>true</bool>
</property>
<property name="has_clear_button" stdset="0">
<bool>false</bool>
</property>
</widget>
</item>
<item row="22" column="1">
<widget class="TextEdit" name="comment">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="has_reset_button" stdset="0">
<bool>true</bool>
</property>
<property name="has_clear_button" stdset="0">
<bool>false</bool>
</property>
</widget>
</item>
<item row="9" column="0">
<widget class="QLabel" name="label_performer">
<property name="minimumSize">
<size>
<width>80</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>Performer</string>
</property>
<property name="buddy">
<cstring>performer</cstring>
</property>
</widget>
</item>
<item row="15" column="0">
<widget class="QLabel" name="label_compilation">
<property name="minimumSize">
<size>
<width>80</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>Compilation</string>
</property>
<property name="buddy">
<cstring>compilation</cstring>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QLabel" name="label_track">
<property name="text">
<string>Track</string>
@@ -978,16 +988,19 @@ p, li { white-space: pre-wrap; }
</property>
</widget>
</item>
<item row="4" column="3">
<widget class="QLabel" name="label_year">
<item row="16" column="0">
<widget class="QLabel" name="label_rating">
<property name="text">
<string>Year</string>
<string>Rating</string>
</property>
<property name="buddy">
<cstring>year</cstring>
<cstring>rating</cstring>
</property>
</widget>
</item>
<item row="16" column="1">
<widget class="RatingBox" name="rating" native="true"/>
</item>
</layout>
</item>
<item>
@@ -1088,6 +1101,12 @@ p, li { white-space: pre-wrap; }
<extends>QCheckBox</extends>
<header>widgets/lineedit.h</header>
</customwidget>
<customwidget>
<class>RatingBox</class>
<extends>QWidget</extends>
<header>widgets/lineedit.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<tabstops>
<tabstop>song_list</tabstop>