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);
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<size_t>(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

View File

@ -50,6 +50,8 @@ public:
YearCol,
TrackCol,
TotalTracksCol,
DiskCol,
EndCol,
};
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
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);
}

View File

@ -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;
}

View File

@ -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.

View File

@ -33,6 +33,7 @@ public:
const QList<TagParser::Tag *> &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<TagParser::Tag *> &tags, bool updateUi = true);
bool setValue(