Support disk number in db query widget

This commit is contained in:
Martchus 2019-06-01 12:50:09 +02:00
parent de5bb26303
commit 89e3e4b657
6 changed files with 63 additions and 10 deletions

View File

@ -80,6 +80,8 @@ TagValue QueryResultsModel::fieldValue(int row, KnownField knownField) const
return TagValue(res.track); return TagValue(res.track);
case KnownField::TotalParts: case KnownField::TotalParts:
return TagValue(res.totalTracks); return TagValue(res.totalTracks);
case KnownField::DiskPosition:
return TagValue(PositionInSet(res.disk));
case KnownField::Cover: case KnownField::Cover:
if (!res.cover.isEmpty()) { if (!res.cover.isEmpty()) {
TagValue tagValue(res.cover.data(), static_cast<size_t>(res.cover.size()), TagDataType::Picture); TagValue tagValue(res.cover.data(), static_cast<size_t>(res.cover.size()), TagDataType::Picture);
@ -119,13 +121,19 @@ QVariant QueryResultsModel::data(const QModelIndex &index, int role) const
if (res.track) { if (res.track) {
return res.track; return res.track;
} else { } else {
return QString(); return QVariant();
} }
case TotalTracksCol: case TotalTracksCol:
if (res.totalTracks) { if (res.totalTracks) {
return res.totalTracks; return res.totalTracks;
} else { } else {
return QString(); return QVariant();
}
case DiskCol:
if (res.disk) {
return res.disk;
} else {
return QVariant();
} }
default:; default:;
} }
@ -157,14 +165,16 @@ QVariant QueryResultsModel::headerData(int section, Qt::Orientation orientation,
return tr("Album"); return tr("Album");
case ArtistCol: case ArtistCol:
return tr("Artist"); return tr("Artist");
case GenreCol:
return tr("Genre");
case YearCol: case YearCol:
return tr("Year"); return tr("Year");
case TrackCol: case TrackCol:
return tr("Track"); return tr("Track");
case TotalTracksCol: case TotalTracksCol:
return tr("Total tracks"); return tr("Total tracks");
case GenreCol: case DiskCol:
return tr("Genre"); return tr("Disk");
default:; default:;
} }
break; break;
@ -183,7 +193,7 @@ int QueryResultsModel::rowCount(const QModelIndex &parent) const
int QueryResultsModel::columnCount(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 const QByteArray *QueryResultsModel::cover(const QModelIndex &index) const

View File

@ -50,6 +50,8 @@ public:
YearCol, YearCol,
TrackCol, TrackCol,
TotalTracksCol, TotalTracksCol,
DiskCol,
EndCol,
}; };
const QList<SongDescription> &results() const; const QList<SongDescription> &results() const;

View File

@ -250,7 +250,12 @@ void MusicBrainzResultsModel::parseInitialResults(const QByteArray &data)
// -> sort recordings within each release by track number and add recordings to results // -> sort recordings within each release by track number and add recordings to results
for (auto &releaseAndRecordings : recordingsByRelease) { for (auto &releaseAndRecordings : recordingsByRelease) {
auto &recordings = releaseAndRecordings.second; 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) { for (auto &recording : recordings) {
m_results << move(recording); m_results << move(recording);
} }

View File

@ -289,6 +289,7 @@ void DbQueryWidget::applyMatchingResults(TagEdit *tagEdit)
const auto givenAlbum = tagEdit->value(KnownField::Album); const auto givenAlbum = tagEdit->value(KnownField::Album);
const auto givenArtist = tagEdit->value(KnownField::Artist); const auto givenArtist = tagEdit->value(KnownField::Artist);
const auto givenTrack = tagEdit->trackNumber(); const auto givenTrack = tagEdit->trackNumber();
const auto givenDisk = tagEdit->diskNumber();
if (givenTitle.isEmpty() && !givenTrack) { if (givenTitle.isEmpty() && !givenTrack) {
return; return;
@ -296,10 +297,19 @@ void DbQueryWidget::applyMatchingResults(TagEdit *tagEdit)
// find row matching already present data // find row matching already present data
for (int row = 0, rowCount = m_model->rowCount(); row != rowCount; ++row) { for (int row = 0, rowCount = m_model->rowCount(); row != rowCount; ++row) {
if ((!givenTitle.isEmpty() && givenTitle != m_model->fieldValue(row, KnownField::Title)) // skip row if title, track, album or artist do not match
|| (!givenAlbum.isEmpty() && givenAlbum != m_model->fieldValue(row, KnownField::Album)) // -> ignore fields which aren't specified, though
|| (!givenArtist.isEmpty() && givenArtist != m_model->fieldValue(row, KnownField::Artist)) // -> ignore track and disk mismatch if the title matches (likely the track/disk number has been taken over incorrectly)
|| (givenTrack && givenTrack != m_model->fieldValue(row, KnownField::PartNumber).toInteger())) { 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; continue;
} }

View File

@ -89,6 +89,31 @@ std::int32_t TagEdit::trackNumber() const
return trackNumber; 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. * \brief Assigns the specified \a tag to the edit.
* \param updateUi Specifies whether the UI of should be updated. * \param updateUi Specifies whether the UI of should be updated.

View File

@ -33,6 +33,7 @@ public:
const QList<TagParser::Tag *> &tags() const; const QList<TagParser::Tag *> &tags() const;
TagParser::TagValue value(TagParser::KnownField field, TagParser::TagTextEncoding encoding = TagParser::TagTextEncoding::Utf16LittleEndian) const; TagParser::TagValue value(TagParser::KnownField field, TagParser::TagTextEncoding encoding = TagParser::TagTextEncoding::Utf16LittleEndian) const;
std::int32_t trackNumber() const; std::int32_t trackNumber() const;
std::int32_t diskNumber() const;
void setTag(TagParser::Tag *tag, bool updateUi = true); void setTag(TagParser::Tag *tag, bool updateUi = true);
void setTags(const QList<TagParser::Tag *> &tags, bool updateUi = true); void setTags(const QList<TagParser::Tag *> &tags, bool updateUi = true);
bool setValue( bool setValue(