Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1554,6 +1554,7 @@ add_library(
src/track/serato/markers.cpp
src/track/serato/markers2.cpp
src/track/serato/tags.cpp
src/track/taglib/fmpsrating.cpp
src/track/taglib/trackmetadata_ape.cpp
src/track/taglib/trackmetadata_common.cpp
src/track/taglib/trackmetadata_file.cpp
Expand Down Expand Up @@ -2764,6 +2765,7 @@ if(BUILD_TESTING)
src/test/portmidienumeratortest.cpp
src/test/queryutiltest.cpp
src/test/rangelist_test.cpp
src/test/ratingexportimport_test.cpp
src/test/readaheadmanager_test.cpp
src/test/replaygaintest.cpp
src/test/rescalertest.cpp
Expand Down
11 changes: 11 additions & 0 deletions src/library/library_prefs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,17 @@ const ConfigKey mixxx::library::prefs::kSyncSeratoMetadataConfigKey =
mixxx::library::prefs::kConfigGroup,
QStringLiteral("SeratoMetadataExport")};

// Rating import/export using FMPS_Rating standard
const ConfigKey mixxx::library::prefs::kExportRatingToFileTagsConfigKey =
ConfigKey{
mixxx::library::prefs::kConfigGroup,
QStringLiteral("export_rating_to_file_tags")};

const ConfigKey mixxx::library::prefs::kImportRatingFromFileTagsConfigKey =
ConfigKey{
mixxx::library::prefs::kConfigGroup,
QStringLiteral("import_rating_from_file_tags")};

const ConfigKey mixxx::library::prefs::kUseRelativePathOnExportConfigKey =
ConfigKey{
mixxx::library::prefs::kConfigGroup,
Expand Down
4 changes: 4 additions & 0 deletions src/library/library_prefs.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,10 @@ extern const ConfigKey kResetMissingTagMetadataOnImportConfigKey;

extern const ConfigKey kSyncSeratoMetadataConfigKey;

extern const ConfigKey kExportRatingToFileTagsConfigKey;

extern const ConfigKey kImportRatingFromFileTagsConfigKey;

extern const ConfigKey kUseRelativePathOnExportConfigKey;

extern const ConfigKey kCoverArtFetcherQualityConfigKey;
Expand Down
13 changes: 8 additions & 5 deletions src/library/trackcollectionmanager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -310,11 +310,14 @@ ExportTrackMetadataResult TrackCollectionManager::exportTrackMetadataBeforeSavin
// last synchronized. Exporting metadata will update this time
// stamp on the track object!
if (pTrack->isMarkedForMetadataExport() ||
(pTrack->isDirty() &&
m_pConfig &&
m_pConfig->getValueString(
mixxx::library::prefs::kSyncTrackMetadataConfigKey)
.toInt() == 1)) {
(pTrack->isDirty() && m_pConfig &&
(m_pConfig->getValue(
mixxx::library::prefs::kSyncTrackMetadataConfigKey,
false) ||
m_pConfig->getValue(
mixxx::library::prefs::
kExportRatingToFileTagsConfigKey,
false)))) {
switch (mode) {
case TrackMetadataExportMode::Immediate: {
// Export track metadata now by saving as file tags.
Expand Down
1 change: 1 addition & 0 deletions src/library/trackset/baseplaylistfeature.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ BasePlaylistFeature::BasePlaylistFeature(

initActions();
connectPlaylistDAO();

connect(m_pLibrary,
&Library::trackSelected,
this,
Expand Down
12 changes: 12 additions & 0 deletions src/preferences/dialog/dlgpreflibrary.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,8 @@ void DlgPrefLibrary::slotResetToDefaults() {
spinbox_history_min_tracks_to_keep->setValue(1);
checkBox_sync_track_metadata->setChecked(false);
checkBox_serato_metadata_export->setChecked(false);
checkBox_rating_export->setChecked(false);
checkBox_rating_import->setChecked(false);
checkBox_use_relative_path->setChecked(false);
checkBox_edit_metadata_selected_clicked->setChecked(kEditMetadataSelectedClickDefault);
radioButton_dbclick_deck->setChecked(true);
Expand Down Expand Up @@ -293,6 +295,10 @@ void DlgPrefLibrary::slotUpdate() {
checkBox_serato_metadata_export->setChecked(
m_pConfig->getValue(kSyncSeratoMetadataConfigKey, false));
setSeratoMetadataEnabled(checkBox_sync_track_metadata->isChecked());
checkBox_rating_export->setChecked(
m_pConfig->getValue(kExportRatingToFileTagsConfigKey, false));
checkBox_rating_import->setChecked(
m_pConfig->getValue(kImportRatingFromFileTagsConfigKey, false));
checkBox_use_relative_path->setChecked(m_pConfig->getValue(
kUseRelativePathOnExportConfigKey, false));

Expand Down Expand Up @@ -531,6 +537,12 @@ void DlgPrefLibrary::slotApply() {
m_pConfig->set(
kSyncSeratoMetadataConfigKey,
ConfigValue{checkBox_serato_metadata_export->isChecked()});
m_pConfig->set(
kExportRatingToFileTagsConfigKey,
ConfigValue{checkBox_rating_export->isChecked()});
m_pConfig->set(
kImportRatingFromFileTagsConfigKey,
ConfigValue{checkBox_rating_import->isChecked()});

m_pConfig->set(kUseRelativePathOnExportConfigKey,
ConfigValue((int)checkBox_use_relative_path->isChecked()));
Expand Down
24 changes: 24 additions & 0 deletions src/preferences/dialog/dlgpreflibrarydlg.ui
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,28 @@
</item>

<item row="2" column="0" colspan="2">
<widget class="QCheckBox" name="checkBox_rating_export">
<property name="toolTip">
<string>Write star ratings into file tags using the FMPS_Rating standard whenever the rating of a track has changed.&lt;br/&gt;Only the rating tag is written; other file tags are not touched unless metadata synchronization is also enabled.&lt;br/&gt;This allows ratings to be shared with other media players that support FMPS (e.g., Strawberry, Clementine).</string>
</property>
<property name="text">
<string>Export star ratings to file tags (FMPS_Rating)</string>
</property>
</widget>
</item>

<item row="3" column="0" colspan="2">
<widget class="QCheckBox" name="checkBox_rating_import">
<property name="toolTip">
<string>Import star ratings from file tags when tracks are loaded or scanned.&lt;br/&gt;Reads FMPS_Rating (and POPM for MP3 files) from file tags.&lt;br/&gt;If the file has changed since Mixxx last synchronized it, the rating from the file replaces the rating stored in Mixxx. Otherwise an existing rating in Mixxx is kept and only missing ratings are filled in.</string>
</property>
<property name="text">
<string>Import star ratings from file tags</string>
</property>
</widget>
</item>

<item row="4" column="0" colspan="2">
<widget class="QCheckBox" name="checkBox_use_relative_path">
<property name="text">
<string>Use relative paths for playlist export if possible</string>
Expand Down Expand Up @@ -685,6 +707,8 @@
<tabstop>checkBox_library_scan_summary</tabstop>
<tabstop>checkBox_sync_track_metadata</tabstop>
<tabstop>checkBox_serato_metadata_export</tabstop>
<tabstop>checkBox_rating_export</tabstop>
<tabstop>checkBox_rating_import</tabstop>
<tabstop>checkBox_use_relative_path</tabstop>
<tabstop>checkBox_edit_metadata_selected_clicked</tabstop>
<tabstop>radioButton_dbclick_deck</tabstop>
Expand Down
15 changes: 15 additions & 0 deletions src/sources/metadatasource.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include <QFile>
#include <QImage>
#include <memory>
#include <optional>
#include <utility>

#include "track/trackmetadata.h"
Expand Down Expand Up @@ -61,6 +62,20 @@ class MetadataSource {
const TrackMetadata& /*trackMetadata*/) const {
return std::make_pair(ExportResult::Unsupported, QDateTime());
}

/// Import rating from file tags using FMPS_Rating standard.
/// Returns the rating (0-5) if found, nullopt otherwise.
/// Default implementation returns nullopt (no rating support).
virtual std::optional<int> importRating() const {
return std::nullopt;
}

/// Export rating to file tags using FMPS_Rating standard.
/// Returns true if export succeeded, false otherwise.
/// Default implementation returns false (no rating support).
virtual bool exportRating(int /*rating*/) const {
return false;
}
};

typedef std::shared_ptr<MetadataSource> MetadataSourcePointer;
Expand Down
Loading