From 89e3e4b6574514c2cdb248e01ad4782036daca90 Mon Sep 17 00:00:00 2001 From: Martchus Date: Sat, 1 Jun 2019 12:50:09 +0200 Subject: [PATCH] Support disk number in db query widget --- dbquery/dbquery.cpp | 20 +++++++++++++++----- dbquery/dbquery.h | 2 ++ dbquery/musicbrainz.cpp | 7 ++++++- gui/dbquerywidget.cpp | 18 ++++++++++++++---- gui/tagedit.cpp | 25 +++++++++++++++++++++++++ gui/tagedit.h | 1 + 6 files changed, 63 insertions(+), 10 deletions(-) diff --git a/dbquery/dbquery.cpp b/dbquery/dbquery.cpp index f99e82a..1189b79 100644 --- a/dbquery/dbquery.cpp +++ b/dbquery/dbquery.cpp @@ -80,6 +80,8 @@ TagValue QueryResultsModel::fieldValue(int row, KnownField knownField) const return TagValue(res.track); case KnownField::TotalParts: return TagValue(res.totalTracks); + case KnownField::DiskPosition: + return TagValue(PositionInSet(res.disk)); case KnownField::Cover: if (!res.cover.isEmpty()) { TagValue tagValue(res.cover.data(), static_cast(res.cover.size()), TagDataType::Picture); @@ -119,13 +121,19 @@ QVariant QueryResultsModel::data(const QModelIndex &index, int role) const if (res.track) { return res.track; } else { - return QString(); + return QVariant(); } case TotalTracksCol: if (res.totalTracks) { return res.totalTracks; } else { - return QString(); + return QVariant(); + } + case DiskCol: + if (res.disk) { + return res.disk; + } else { + return QVariant(); } default:; } @@ -157,14 +165,16 @@ QVariant QueryResultsModel::headerData(int section, Qt::Orientation orientation, return tr("Album"); case ArtistCol: return tr("Artist"); + case GenreCol: + return tr("Genre"); case YearCol: return tr("Year"); case TrackCol: return tr("Track"); case TotalTracksCol: return tr("Total tracks"); - case GenreCol: - return tr("Genre"); + case DiskCol: + return tr("Disk"); default:; } break; @@ -183,7 +193,7 @@ int QueryResultsModel::rowCount(const QModelIndex &parent) const int QueryResultsModel::columnCount(const QModelIndex &parent) const { - return parent.isValid() ? 0 : (TotalTracksCol + 1); + return parent.isValid() ? 0 : EndCol; } const QByteArray *QueryResultsModel::cover(const QModelIndex &index) const diff --git a/dbquery/dbquery.h b/dbquery/dbquery.h index 9df9e27..1e999cf 100644 --- a/dbquery/dbquery.h +++ b/dbquery/dbquery.h @@ -50,6 +50,8 @@ public: YearCol, TrackCol, TotalTracksCol, + DiskCol, + EndCol, }; const QList &results() const; diff --git a/dbquery/musicbrainz.cpp b/dbquery/musicbrainz.cpp index abaf969..6e39a55 100644 --- a/dbquery/musicbrainz.cpp +++ b/dbquery/musicbrainz.cpp @@ -250,7 +250,12 @@ void MusicBrainzResultsModel::parseInitialResults(const QByteArray &data) // -> sort recordings within each release by track number and add recordings to results for (auto &releaseAndRecordings : recordingsByRelease) { auto &recordings = releaseAndRecordings.second; - std::sort(recordings.begin(), recordings.end(), [](const auto &lhs, const auto &rhs) { return lhs.track < rhs.track; }); + std::sort(recordings.begin(), recordings.end(), [](const auto &recording1, const auto &recording2) { + if (recording1.disk != recording2.disk) { + return recording1.disk < recording2.disk; + } + return recording1.track < recording2.track; + }); for (auto &recording : recordings) { m_results << move(recording); } diff --git a/gui/dbquerywidget.cpp b/gui/dbquerywidget.cpp index d08d7b2..bc32d09 100644 --- a/gui/dbquerywidget.cpp +++ b/gui/dbquerywidget.cpp @@ -289,6 +289,7 @@ void DbQueryWidget::applyMatchingResults(TagEdit *tagEdit) const auto givenAlbum = tagEdit->value(KnownField::Album); const auto givenArtist = tagEdit->value(KnownField::Artist); const auto givenTrack = tagEdit->trackNumber(); + const auto givenDisk = tagEdit->diskNumber(); if (givenTitle.isEmpty() && !givenTrack) { return; @@ -296,10 +297,19 @@ void DbQueryWidget::applyMatchingResults(TagEdit *tagEdit) // find row matching already present data for (int row = 0, rowCount = m_model->rowCount(); row != rowCount; ++row) { - if ((!givenTitle.isEmpty() && givenTitle != m_model->fieldValue(row, KnownField::Title)) - || (!givenAlbum.isEmpty() && givenAlbum != m_model->fieldValue(row, KnownField::Album)) - || (!givenArtist.isEmpty() && givenArtist != m_model->fieldValue(row, KnownField::Artist)) - || (givenTrack && givenTrack != m_model->fieldValue(row, KnownField::PartNumber).toInteger())) { + // skip row if title, track, album or artist do not match + // -> ignore fields which aren't specified, though + // -> ignore track and disk mismatch if the title matches (likely the track/disk number has been taken over incorrectly) + const auto rowTitle = m_model->fieldValue(row, KnownField::Title); + const auto rowAlbum = m_model->fieldValue(row, KnownField::Album); + const auto rowArtist = m_model->fieldValue(row, KnownField::Artist); + const auto rowTrack = m_model->fieldValue(row, KnownField::PartNumber).toInteger(); + const auto rowDisk = m_model->fieldValue(row, KnownField::DiskPosition).toInteger(); + const auto titleMismatch = givenTitle != rowTitle; + if ((!givenTitle.isEmpty() && titleMismatch) || (!givenAlbum.isEmpty() && givenAlbum != rowAlbum) + || (!givenArtist.isEmpty() && givenArtist != rowArtist) + || (givenTrack && (givenTitle.isEmpty() || titleMismatch) && givenTrack != rowTrack) + || (givenDisk && rowDisk && (givenTitle.isEmpty() || titleMismatch) && givenDisk != rowDisk)) { continue; } diff --git a/gui/tagedit.cpp b/gui/tagedit.cpp index 7457bb4..53e369f 100644 --- a/gui/tagedit.cpp +++ b/gui/tagedit.cpp @@ -89,6 +89,31 @@ std::int32_t TagEdit::trackNumber() const return trackNumber; } +int32_t TagEdit::diskNumber() const +{ + std::int32_t diskNumber = 0; + try { + diskNumber = value(KnownField::DiskPosition).toPositionInSet().position(); + } catch (const ConversionException &) { + } + if (diskNumber) { + return diskNumber; + } + for (const auto *const tag : tags()) { + if (!tag->supportsTarget() || tag->targetLevel() != TagTargetLevel::Part) { + continue; + } + try { + diskNumber = value(KnownField::PartNumber).toInteger(); + } catch (const ConversionException &) { + } + if (diskNumber) { + return diskNumber; + } + } + return diskNumber; +} + /*! * \brief Assigns the specified \a tag to the edit. * \param updateUi Specifies whether the UI of should be updated. diff --git a/gui/tagedit.h b/gui/tagedit.h index df78709..90f77d4 100644 --- a/gui/tagedit.h +++ b/gui/tagedit.h @@ -33,6 +33,7 @@ public: const QList &tags() const; TagParser::TagValue value(TagParser::KnownField field, TagParser::TagTextEncoding encoding = TagParser::TagTextEncoding::Utf16LittleEndian) const; std::int32_t trackNumber() const; + std::int32_t diskNumber() const; void setTag(TagParser::Tag *tag, bool updateUi = true); void setTags(const QList &tags, bool updateUi = true); bool setValue(