Skip to content

Commit

Permalink
Merge pull request mixxxdj#14008 from m0dB/keystring-from-key-id-or-k…
Browse files Browse the repository at this point in the history
…ey-2.5

determine the key string from either key id or key in the basetrackcache
  • Loading branch information
ywwg authored Dec 16, 2024
2 parents a20384b + 082f84a commit 16a4873
Show file tree
Hide file tree
Showing 5 changed files with 174 additions and 113 deletions.
197 changes: 117 additions & 80 deletions src/library/basetrackcache.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ bool BaseTrackCache::updateTrackInIndex(
// preallocate memory for all columns at once
record.resize(numColumns);
for (int i = 0; i < numColumns; ++i) {
getTrackValueForColumn(pTrack, i, record[i]);
record[i] = getTrackValueForColumn(pTrack, i);
}
if (m_bIsCaching) {
replaceRecentTrack(std::move(trackId), pTrack);
Expand Down Expand Up @@ -324,11 +324,10 @@ void BaseTrackCache::updateTracksInIndex(const QSet<TrackId>& trackIds) {
emit tracksChanged(trackIds);
}

void BaseTrackCache::getTrackValueForColumn(TrackPointer pTrack,
int column,
QVariant& trackValue) const {
QVariant BaseTrackCache::getTrackValueForColumn(TrackPointer pTrack,
int column) const {
if (!pTrack || column < 0) {
return;
return QVariant{};
}

if (m_bIsCaching) {
Expand All @@ -338,85 +337,119 @@ void BaseTrackCache::getTrackValueForColumn(TrackPointer pTrack,
// TODO(XXX) Qt properties could really help here.
// TODO(rryan) this is all TrackDAO specific. What about iTunes/RB/etc.?
if (fieldIndex(ColumnCache::COLUMN_LIBRARYTABLE_ARTIST) == column) {
trackValue.setValue(pTrack->getArtist());
} else if (fieldIndex(ColumnCache::COLUMN_LIBRARYTABLE_TITLE) == column) {
trackValue.setValue(pTrack->getTitle());
} else if (fieldIndex(ColumnCache::COLUMN_LIBRARYTABLE_ALBUM) == column) {
trackValue.setValue(pTrack->getAlbum());
} else if (fieldIndex(ColumnCache::COLUMN_LIBRARYTABLE_ALBUMARTIST) == column) {
trackValue.setValue(pTrack->getAlbumArtist());
} else if (fieldIndex(ColumnCache::COLUMN_LIBRARYTABLE_YEAR) == column) {
trackValue.setValue(pTrack->getYear());
} else if (fieldIndex(ColumnCache::COLUMN_LIBRARYTABLE_DATETIMEADDED) == column) {
trackValue.setValue(pTrack->getDateAdded());
} else if (fieldIndex(ColumnCache::COLUMN_LIBRARYTABLE_LAST_PLAYED_AT) == column) {
trackValue.setValue(pTrack->getLastPlayedAt());
} else if (fieldIndex(ColumnCache::COLUMN_LIBRARYTABLE_GENRE) == column) {
trackValue.setValue(pTrack->getGenre());
} else if (fieldIndex(ColumnCache::COLUMN_LIBRARYTABLE_COMPOSER) == column) {
trackValue.setValue(pTrack->getComposer());
} else if (fieldIndex(ColumnCache::COLUMN_LIBRARYTABLE_GROUPING) == column) {
trackValue.setValue(pTrack->getGrouping());
} else if (fieldIndex(ColumnCache::COLUMN_LIBRARYTABLE_FILETYPE) == column) {
trackValue.setValue(pTrack->getType());
} else if (fieldIndex(ColumnCache::COLUMN_LIBRARYTABLE_TRACKNUMBER) == column) {
trackValue.setValue(pTrack->getTrackNumber());
} else if (fieldIndex(ColumnCache::COLUMN_TRACKLOCATIONSTABLE_LOCATION) == column) {
trackValue.setValue(QDir::toNativeSeparators(pTrack->getLocation()));
} else if (fieldIndex(ColumnCache::COLUMN_LIBRARYTABLE_COMMENT) == column) {
trackValue.setValue(pTrack->getComment());
} else if (fieldIndex(ColumnCache::COLUMN_LIBRARYTABLE_DURATION) == column) {
trackValue.setValue(pTrack->getDuration());
} else if (fieldIndex(ColumnCache::COLUMN_LIBRARYTABLE_BITRATE) == column) {
trackValue.setValue(pTrack->getBitrate());
} else if (fieldIndex(ColumnCache::COLUMN_LIBRARYTABLE_BPM) == column) {
trackValue.setValue(pTrack->getBpm());
} else if (fieldIndex(ColumnCache::COLUMN_LIBRARYTABLE_REPLAYGAIN) == column) {
trackValue.setValue(pTrack->getReplayGain().getRatio());
} else if (fieldIndex(ColumnCache::COLUMN_LIBRARYTABLE_PLAYED) == column) {
trackValue.setValue(pTrack->getPlayCounter().isPlayed());
} else if (fieldIndex(ColumnCache::COLUMN_LIBRARYTABLE_TIMESPLAYED) == column) {
trackValue.setValue(pTrack->getPlayCounter().getTimesPlayed());
} else if (fieldIndex(ColumnCache::COLUMN_LIBRARYTABLE_RATING) == column) {
trackValue.setValue(pTrack->getRating());
} else if (fieldIndex(ColumnCache::COLUMN_LIBRARYTABLE_KEY) == column) {
trackValue.setValue(pTrack->getKeyText());
} else if (fieldIndex(ColumnCache::COLUMN_LIBRARYTABLE_KEY_ID) == column) {
trackValue.setValue(static_cast<int>(pTrack->getKey()));
} else if (fieldIndex(ColumnCache::COLUMN_LIBRARYTABLE_BPM_LOCK) == column) {
trackValue.setValue(pTrack->isBpmLocked());
} else if (fieldIndex(ColumnCache::COLUMN_LIBRARYTABLE_COLOR) == column) {
trackValue.setValue(mixxx::RgbColor::toQVariant(pTrack->getColor()));
} else if (fieldIndex(ColumnCache::COLUMN_LIBRARYTABLE_COVERART_LOCATION) == column) {
trackValue.setValue(pTrack->getCoverInfo().coverLocation);
} else if (fieldIndex(ColumnCache::COLUMN_LIBRARYTABLE_COVERART_HASH) == column ||
return QVariant{pTrack->getArtist()};
}
if (fieldIndex(ColumnCache::COLUMN_LIBRARYTABLE_TITLE) == column) {
return QVariant{pTrack->getTitle()};
}
if (fieldIndex(ColumnCache::COLUMN_LIBRARYTABLE_ALBUM) == column) {
return QVariant{pTrack->getAlbum()};
}
if (fieldIndex(ColumnCache::COLUMN_LIBRARYTABLE_ALBUMARTIST) == column) {
return QVariant{pTrack->getAlbumArtist()};
}
if (fieldIndex(ColumnCache::COLUMN_LIBRARYTABLE_YEAR) == column) {
return QVariant{pTrack->getYear()};
}
if (fieldIndex(ColumnCache::COLUMN_LIBRARYTABLE_DATETIMEADDED) == column) {
return QVariant{pTrack->getDateAdded()};
}
if (fieldIndex(ColumnCache::COLUMN_LIBRARYTABLE_LAST_PLAYED_AT) == column) {
return QVariant{pTrack->getLastPlayedAt()};
}
if (fieldIndex(ColumnCache::COLUMN_LIBRARYTABLE_GENRE) == column) {
return QVariant{pTrack->getGenre()};
}
if (fieldIndex(ColumnCache::COLUMN_LIBRARYTABLE_COMPOSER) == column) {
return QVariant{pTrack->getComposer()};
}
if (fieldIndex(ColumnCache::COLUMN_LIBRARYTABLE_GROUPING) == column) {
return QVariant{pTrack->getGrouping()};
}
if (fieldIndex(ColumnCache::COLUMN_LIBRARYTABLE_FILETYPE) == column) {
return QVariant{pTrack->getType()};
}
if (fieldIndex(ColumnCache::COLUMN_LIBRARYTABLE_TRACKNUMBER) == column) {
return QVariant{pTrack->getTrackNumber()};
}
if (fieldIndex(ColumnCache::COLUMN_TRACKLOCATIONSTABLE_LOCATION) == column) {
return QVariant{QDir::toNativeSeparators(pTrack->getLocation())};
}
if (fieldIndex(ColumnCache::COLUMN_LIBRARYTABLE_COMMENT) == column) {
return QVariant{pTrack->getComment()};
}
if (fieldIndex(ColumnCache::COLUMN_LIBRARYTABLE_DURATION) == column) {
return QVariant{pTrack->getDuration()};
}
if (fieldIndex(ColumnCache::COLUMN_LIBRARYTABLE_BITRATE) == column) {
return QVariant{pTrack->getBitrate()};
}
if (fieldIndex(ColumnCache::COLUMN_LIBRARYTABLE_BPM) == column) {
return QVariant{pTrack->getBpm()};
}
if (fieldIndex(ColumnCache::COLUMN_LIBRARYTABLE_REPLAYGAIN) == column) {
return QVariant{pTrack->getReplayGain().getRatio()};
}
if (fieldIndex(ColumnCache::COLUMN_LIBRARYTABLE_PLAYED) == column) {
return QVariant{pTrack->getPlayCounter().isPlayed()};
}
if (fieldIndex(ColumnCache::COLUMN_LIBRARYTABLE_TIMESPLAYED) == column) {
return QVariant{pTrack->getPlayCounter().getTimesPlayed()};
}
if (fieldIndex(ColumnCache::COLUMN_LIBRARYTABLE_RATING) == column) {
return QVariant{pTrack->getRating()};
}
if (fieldIndex(ColumnCache::COLUMN_LIBRARYTABLE_KEY) == column) {
// The Key value is determined by either the KEY_ID or KEY column
return QVariant{KeyUtils::keyFromKeyTextAndIdValues(
pTrack->getKeyText(), pTrack->getKey())};
}
if (fieldIndex(ColumnCache::COLUMN_LIBRARYTABLE_KEY_ID) == column) {
return QVariant{static_cast<int>(pTrack->getKey())};
}
if (fieldIndex(ColumnCache::COLUMN_LIBRARYTABLE_BPM_LOCK) == column) {
return QVariant{pTrack->isBpmLocked()};
}
if (fieldIndex(ColumnCache::COLUMN_LIBRARYTABLE_COLOR) == column) {
return mixxx::RgbColor::toQVariant(pTrack->getColor());
}
if (fieldIndex(ColumnCache::COLUMN_LIBRARYTABLE_COVERART_LOCATION) == column) {
return QVariant{pTrack->getCoverInfo().coverLocation};
}
if (fieldIndex(ColumnCache::COLUMN_LIBRARYTABLE_COVERART_HASH) == column ||
fieldIndex(ColumnCache::COLUMN_LIBRARYTABLE_COVERART) == column) {
// For sorting, we give COLUMN_LIBRARYTABLE_COVERART the same value as
// the cover digest.
trackValue.setValue(pTrack->getCoverInfo().imageDigest());
} else if (fieldIndex(ColumnCache::COLUMN_LIBRARYTABLE_COVERART_COLOR) == column) {
trackValue.setValue(mixxx::RgbColor::toQVariant(pTrack->getCoverInfo().color));
} else if (fieldIndex(ColumnCache::COLUMN_LIBRARYTABLE_COVERART_DIGEST) == column) {
trackValue.setValue(pTrack->getCoverInfo().imageDigest());
} else if (fieldIndex(ColumnCache::COLUMN_LIBRARYTABLE_COVERART_SOURCE) == column) {
trackValue.setValue(static_cast<int>(pTrack->getCoverInfo().source));
} else if (fieldIndex(ColumnCache::COLUMN_LIBRARYTABLE_COVERART_TYPE) == column) {
trackValue.setValue(static_cast<int>(pTrack->getCoverInfo().type));
return QVariant{pTrack->getCoverInfo().imageDigest()};
}
if (fieldIndex(ColumnCache::COLUMN_LIBRARYTABLE_COVERART_COLOR) == column) {
return mixxx::RgbColor::toQVariant(pTrack->getCoverInfo().color);
}
if (fieldIndex(ColumnCache::COLUMN_LIBRARYTABLE_COVERART_DIGEST) == column) {
return QVariant{pTrack->getCoverInfo().imageDigest()};
}
if (fieldIndex(ColumnCache::COLUMN_LIBRARYTABLE_COVERART_SOURCE) == column) {
return QVariant{static_cast<int>(pTrack->getCoverInfo().source)};
}
if (fieldIndex(ColumnCache::COLUMN_LIBRARYTABLE_COVERART_TYPE) == column) {
return QVariant{static_cast<int>(pTrack->getCoverInfo().type)};
}
return QVariant{};
}

QVariant BaseTrackCache::data(TrackId trackId, int column) const {
QVariant result;

if (!m_bIndexBuilt) {
qDebug() << this << "ERROR index is not built for" << m_tableName;
return result;
return QVariant{};
}

if (m_bIsCaching) {
TrackPointer pTrack = getRecentTrack(trackId);
if (pTrack) {
getTrackValueForColumn(pTrack, column, result);
QVariant result = getTrackValueForColumn(pTrack, column);
if (result.isValid()) {
return result;
}
}
}

Expand All @@ -427,14 +460,20 @@ QVariant BaseTrackCache::data(TrackId trackId, int column) const {
// TODO(rryan) this code is flawed for columns that contains row-specific
// metadata. Currently the upper-levels will not delegate row-specific
// columns to this method, but there should still be a check here I think.
if (!result.isValid()) {
auto it = m_trackInfo.constFind(trackId);
if (it != m_trackInfo.constEnd()) {
const QVector<QVariant>& fields = it.value();
result = fields.value(column, result);
}
auto it = m_trackInfo.constFind(trackId);
if (it == m_trackInfo.constEnd()) {
return QVariant{};
}
return result;

const QVector<QVariant>& fields = it.value();
if (column == fieldIndex(ColumnCache::COLUMN_LIBRARYTABLE_KEY)) {
// The Key value is determined by either the KEY_ID or KEY column
const auto columnForKeyId = fieldIndex(ColumnCache::COLUMN_LIBRARYTABLE_KEY_ID);
return KeyUtils::keyFromKeyTextAndIdFields(
fields.value(column, QVariant{}),
fields.value(columnForKeyId, QVariant{}));
}
return fields.value(column, QVariant{});
}

void BaseTrackCache::filterAndSort(const QSet<TrackId>& trackIds,
Expand Down Expand Up @@ -604,9 +643,7 @@ int BaseTrackCache::findSortInsertionPoint(TrackPointer pTrack,
return 0;
}
for (const auto& sc: sortColumns) {
QVariant trackValue;
getTrackValueForColumn(pTrack, sc.m_column - columnOffset, trackValue);
trackValues.append(trackValue);
trackValues.append(getTrackValueForColumn(pTrack, sc.m_column - columnOffset));
}

int min = 0;
Expand Down
3 changes: 1 addition & 2 deletions src/library/basetrackcache.h
Original file line number Diff line number Diff line change
Expand Up @@ -96,8 +96,7 @@ class BaseTrackCache : public QObject {
void updateTrackInIndex(TrackId trackId);
bool updateTrackInIndex(const TrackPointer& pTrack);
void updateTracksInIndex(const QSet<TrackId>& trackIds);
void getTrackValueForColumn(TrackPointer pTrack, int column,
QVariant& trackValue) const;
QVariant getTrackValueForColumn(TrackPointer pTrack, int column) const;

int findSortInsertionPoint(TrackPointer pTrack,
const QList<SortColumn>& sortColumns,
Expand Down
34 changes: 6 additions & 28 deletions src/library/basetracktablemodel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -872,34 +872,12 @@ QVariant BaseTrackTableModel::roleValue(
}
}
}
case ColumnCache::COLUMN_LIBRARYTABLE_KEY: {
// If we know the semantic key via the LIBRARYTABLE_KEY_ID
// column (as opposed to the string representation of the key
// currently stored in the DB) then lookup the key and render it
// using the user's selected notation.
const QVariant keyCodeValue = rawSiblingValue(
index,
ColumnCache::COLUMN_LIBRARYTABLE_KEY_ID);
if (keyCodeValue.isNull()) {
// Otherwise, just use the column value as is
return std::move(rawValue);
}
// Convert or clear invalid values
VERIFY_OR_DEBUG_ASSERT(keyCodeValue.canConvert<int>()) {
return QVariant();
}
bool ok;
const auto keyCode = keyCodeValue.toInt(&ok);
VERIFY_OR_DEBUG_ASSERT(ok) {
return QVariant();
}
const auto key = KeyUtils::keyFromNumericValue(keyCode);
if (key == mixxx::track::io::key::INVALID) {
return QVariant();
}
// Render the key with the user-provided notation
return KeyUtils::keyToString(key);
}
case ColumnCache::COLUMN_LIBRARYTABLE_KEY:
// The Key value is determined by either the KEY_ID or KEY column
return KeyUtils::keyFromKeyTextAndIdFields(
rawValue,
rawSiblingValue(
index, ColumnCache::COLUMN_LIBRARYTABLE_KEY_ID));
case ColumnCache::COLUMN_LIBRARYTABLE_REPLAYGAIN: {
if (rawValue.isNull()) {
return QVariant();
Expand Down
47 changes: 44 additions & 3 deletions src/track/keyutils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -520,13 +520,17 @@ ChromaticKey KeyUtils::guessKeyFromText(const QString& text) {

// static
ChromaticKey KeyUtils::keyFromNumericValue(double value) {
int value_floored = int(value);
int value_floored = static_cast<int>(value);
return keyFromNumericValue(value_floored);
}

if (!ChromaticKey_IsValid(value_floored)) {
// static
ChromaticKey KeyUtils::keyFromNumericValue(int value) {
if (!ChromaticKey_IsValid(value)) {
return mixxx::track::io::key::INVALID;
}

return static_cast<ChromaticKey>(value_floored);
return static_cast<ChromaticKey>(value);
}

KeyUtils::KeyNotation KeyUtils::keyNotationFromNumericValue(double value) {
Expand Down Expand Up @@ -781,3 +785,40 @@ int KeyUtils::keyToCircleOfFifthsOrder(mixxx::track::io::key::ChromaticKey key,
return s_sortKeysCircleOfFifthsLancelot[static_cast<int>(key)];
}
}

// static
QVariant KeyUtils::keyFromKeyTextAndIdFields(
const QVariant& keyTextField, const QVariant& keyIdField) {
// Helper function used by basetrackcache.cpp and basetracktablemodel.cpp
// to determine the Key string from either the LIBRARYTABLE_KEY or the
// LIBRARYTABLE_KEY_ID field.
//
// If we know the semantic key via the LIBRARYTABLE_KEY_ID
// column (as opposed to the string representation of the key
// currently stored in the DB) then lookup the key and render it
// using the user's selected notation.
if (keyIdField.isNull()) {
// Otherwise, just use the KEY column value as is
return keyTextField;
}
// Convert or clear invalid values
VERIFY_OR_DEBUG_ASSERT(keyIdField.canConvert<int>()) {
return keyTextField;
}
bool ok;
const auto keyId = keyIdField.toInt(&ok);
VERIFY_OR_DEBUG_ASSERT(ok) {
return keyTextField;
}
const auto key = KeyUtils::keyFromNumericValue(keyId);
if (key == mixxx::track::io::key::INVALID) {
return keyTextField;
}
// Render the key with the user-provided notation
return QVariant{KeyUtils::keyToString(key)};
}

// static
QString KeyUtils::keyFromKeyTextAndIdValues(const QString& keyText, const ChromaticKey& keyId) {
return keyId == mixxx::track::io::key::INVALID ? keyText : KeyUtils::keyToString(keyId);
}
6 changes: 6 additions & 0 deletions src/track/keyutils.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ class KeyUtils {
KeyNotation notation = KeyNotation::Custom);

static mixxx::track::io::key::ChromaticKey keyFromNumericValue(double value);
static mixxx::track::io::key::ChromaticKey keyFromNumericValue(int value);
static KeyNotation keyNotationFromNumericValue(double value);
static KeyNotation keyNotationFromString(const QString& notationName);

Expand Down Expand Up @@ -132,6 +133,11 @@ class KeyUtils {
static int keyToCircleOfFifthsOrder(mixxx::track::io::key::ChromaticKey key,
KeyNotation notation);

static QVariant keyFromKeyTextAndIdFields(
const QVariant& keyTextField, const QVariant& keyIdField);
static QString keyFromKeyTextAndIdValues(const QString& keyText,
const mixxx::track::io::key::ChromaticKey& key);

private:
static QMutex s_notationMutex;
static QMap<mixxx::track::io::key::ChromaticKey, QString> s_notation;
Expand Down

0 comments on commit 16a4873

Please sign in to comment.