Refactor use of sort tags

This commit is contained in:
Jonas Kvinge
2025-08-09 19:08:51 +02:00
parent 65d9b6a9e9
commit c4646531b0
10 changed files with 244 additions and 352 deletions

View File

@@ -1,6 +1,6 @@
/*
* Strawberry Music Player
* Copyright 2018-2024, Jonas Kvinge <jonas@jkvinge.net>
* Copyright 2018-2025, Jonas Kvinge <jonas@jkvinge.net>
*
* Strawberry is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -54,6 +54,7 @@
#include "includes/scoped_ptr.h"
#include "includes/shared_ptr.h"
#include "constants/collectionsettings.h"
#include "core/logging.h"
#include "core/standardpaths.h"
#include "core/database.h"
@@ -76,6 +77,7 @@ using namespace std::chrono_literals;
using namespace Qt::Literals::StringLiterals;
const int CollectionModel::kPrettyCoverSize = 32;
namespace {
constexpr char kPixmapDiskCacheDir[] = "pixmapcache";
constexpr char kVariousArtists[] = QT_TR_NOOP("Various artists");
@@ -206,9 +208,10 @@ void CollectionModel::ReloadSettings() {
Settings settings;
settings.beginGroup(CollectionSettings::kSettingsGroup);
const bool show_pretty_covers = settings.value(CollectionSettings::kPrettyCovers, true).toBool();
const bool show_dividers= settings.value(CollectionSettings::kShowDividers, true).toBool();
const bool show_dividers = settings.value(CollectionSettings::kShowDividers, true).toBool();
const bool show_various_artists = settings.value(CollectionSettings::kVariousArtists, true).toBool();
const CollectionSettings::SortBehaviour sort_behaviour = static_cast<CollectionSettings::SortBehaviour>(settings.value(CollectionSettings::kSortBehaviour, static_cast<int>(CollectionSettings::SortBehaviour::AsIs)).toInt());
const bool sort_skip_articles_for_artists = settings.value(CollectionSettings::kSkipArticlesForArtists, true).toBool();
const bool sort_skip_articles_for_albums = settings.value(CollectionSettings::kSkipArticlesForAlbums, false).toBool();
use_disk_cache_ = settings.value(CollectionSettings::kSettingsDiskCacheEnable, false).toBool();
QPixmapCache::setCacheLimit(static_cast<int>(MaximumCacheSize(&settings, CollectionSettings::kSettingsCacheSize, CollectionSettings::kSettingsCacheSizeUnit, CollectionSettings::kSettingsCacheSizeDefault) / 1024));
@@ -223,11 +226,13 @@ void CollectionModel::ReloadSettings() {
if (show_pretty_covers != options_current_.show_pretty_covers ||
show_dividers != options_current_.show_dividers ||
show_various_artists != options_current_.show_various_artists ||
sort_behaviour != options_current_.sort_behaviour) {
sort_skip_articles_for_artists != options_current_.sort_skip_articles_for_artists ||
sort_skip_articles_for_albums != options_current_.sort_skip_articles_for_albums) {
options_current_.show_pretty_covers = show_pretty_covers;
options_current_.show_dividers = show_dividers;
options_current_.show_various_artists = show_various_artists;
options_current_.sort_behaviour = sort_behaviour;
options_current_.sort_skip_articles_for_artists = sort_skip_articles_for_artists;
options_current_.sort_skip_articles_for_albums = sort_skip_articles_for_albums;
ScheduleReset();
}
@@ -695,7 +700,7 @@ CollectionItem *CollectionModel::CreateContainerItem(const GroupBy group_by, con
QString divider_key;
if (options_active_.show_dividers && container_level == 0) {
divider_key = DividerKey(group_by, song, SortText(group_by, song, options_active_.sort_behaviour));
divider_key = DividerKey(group_by, song, SortText(group_by, song, options_active_.sort_skip_articles_for_artists, options_active_.sort_skip_articles_for_albums));
if (!divider_key.isEmpty()) {
if (!divider_nodes_.contains(divider_key)) {
CreateDividerItem(divider_key, DividerDisplayText(group_by, divider_key), parent);
@@ -708,8 +713,8 @@ CollectionItem *CollectionModel::CreateContainerItem(const GroupBy group_by, con
CollectionItem *item = new CollectionItem(CollectionItem::Type::Container, parent);
item->container_level = container_level;
item->container_key = container_key;
item->display_text = DisplayText(group_by, song, options_active_.sort_behaviour);
item->sort_text = SortText(group_by, song, options_active_.sort_behaviour);
item->display_text = DisplayText(group_by, song);
item->sort_text = SortText(group_by, song, options_active_.sort_skip_articles_for_artists, options_active_.sort_skip_articles_for_albums);
if (!divider_key.isEmpty()) {
item->sort_text.prepend(divider_key + QLatin1Char(' '));
}
@@ -958,15 +963,15 @@ void CollectionModel::AlbumCoverLoaded(const quint64 id, const AlbumCoverLoaderR
}
QString CollectionModel::DisplayText(const GroupBy group_by, const Song &song, const CollectionSettings::SortBehaviour sort_behaviour) {
QString CollectionModel::DisplayText(const GroupBy group_by, const Song &song) {
switch (group_by) {
case GroupBy::AlbumArtist:
return NameOrSortname(song.effective_albumartist(), song.albumartistsort(), sort_behaviour);
return TextOrUnknown(song.effective_albumartist());
case GroupBy::Artist:
return NameOrSortname(song.artist(), song.artistsort(), sort_behaviour);
return TextOrUnknown(song.artist());
case GroupBy::Album:
return NameOrSortname(song.album(), song.albumsort(), sort_behaviour);
return TextOrUnknown(song.album());
case GroupBy::AlbumDisc:
return PrettyAlbumDisc(song.album(), song.disc());
case GroupBy::YearAlbum:
@@ -986,9 +991,9 @@ QString CollectionModel::DisplayText(const GroupBy group_by, const Song &song, c
case GroupBy::Genre:
return TextOrUnknown(song.genre());
case GroupBy::Composer:
return NameOrSortname(song.composer(), song.composersort(), sort_behaviour);
return TextOrUnknown(song.composer());
case GroupBy::Performer:
return NameOrSortname(song.performer(), song.performersort(), sort_behaviour);
return TextOrUnknown(song.performer());
case GroupBy::Grouping:
return TextOrUnknown(song.grouping());
case GroupBy::FileType:
@@ -1010,26 +1015,6 @@ QString CollectionModel::DisplayText(const GroupBy group_by, const Song &song, c
}
QString CollectionModel::NameOrSortname(const QString &name, const QString &sort_name, const CollectionSettings::SortBehaviour sort_behaviour) {
QString str;
switch (sort_behaviour) {
using namespace CollectionSettings;
case SortBehaviour::AsIs:
case SortBehaviour::SkipArticles:
case SortBehaviour::UseSortTagForSort:
str = name;
break;
case SortBehaviour::UseSortTagForDisplayAndSort:
str = sort_name;
break;
}
return TextOrUnknown(str);
}
QString CollectionModel::TextOrUnknown(const QString &text) {
if (text.isEmpty()) return tr("Unknown");
@@ -1084,25 +1069,25 @@ QString CollectionModel::PrettyFormat(const Song &song) {
}
QString CollectionModel::SortText(const GroupBy group_by, const Song &song, const CollectionSettings::SortBehaviour sort_behaviour) {
QString CollectionModel::SortText(const GroupBy group_by, const Song &song, const bool sort_skip_articles_for_artists, const bool sort_skip_articles_for_albums) {
switch (group_by) {
case GroupBy::AlbumArtist:
return SortTextForName(song.effective_albumartist(), song.albumartistsort(), sort_behaviour);
return SortTextForName(song.effective_albumartist_with_sort(), sort_skip_articles_for_artists);
case GroupBy::Artist:
return SortTextForName(song.artist(), song.artistsort(), sort_behaviour);
return SortTextForName(song.effective_artistsort(), sort_skip_articles_for_artists);
case GroupBy::Album:
return SortTextForName(song.album(), song.albumsort(), sort_behaviour);
return SortTextForName(song.effective_albumsort(), sort_skip_articles_for_albums);
case GroupBy::AlbumDisc:
return song.album() + SortTextForNumber(std::max(0, song.disc()));
return SortTextForName(song.effective_albumsort(), sort_skip_articles_for_albums) + SortTextForNumber(std::max(0, song.disc()));
case GroupBy::YearAlbum:
return SortTextForNumber(std::max(0, song.year())) + song.grouping() + song.album();
return SortTextForNumber(std::max(0, song.year())) + song.grouping() + SortTextForName(song.effective_albumsort(), sort_skip_articles_for_albums);
case GroupBy::YearAlbumDisc:
return SortTextForNumber(std::max(0, song.year())) + song.album() + SortTextForNumber(std::max(0, song.disc()));
return SortTextForNumber(std::max(0, song.year())) + SortTextForName(song.effective_albumsort(), sort_skip_articles_for_albums) + SortTextForNumber(std::max(0, song.disc()));
case GroupBy::OriginalYearAlbum:
return SortTextForNumber(std::max(0, song.effective_originalyear())) + song.grouping() + song.album();
return SortTextForNumber(std::max(0, song.effective_originalyear())) + song.grouping() + SortTextForName(song.effective_albumsort(), sort_skip_articles_for_albums);
case GroupBy::OriginalYearAlbumDisc:
return SortTextForNumber(std::max(0, song.effective_originalyear())) + song.album() + SortTextForNumber(std::max(0, song.disc()));
return SortTextForNumber(std::max(0, song.effective_originalyear())) + SortTextForName(song.effective_albumsort(), sort_skip_articles_for_albums) + SortTextForNumber(std::max(0, song.disc()));
case GroupBy::Disc:
return SortTextForNumber(std::max(0, song.disc()));
case GroupBy::Year:
@@ -1110,13 +1095,13 @@ QString CollectionModel::SortText(const GroupBy group_by, const Song &song, cons
case GroupBy::OriginalYear:
return SortTextForNumber(std::max(0, song.effective_originalyear())) + QLatin1Char(' ');
case GroupBy::Genre:
return SortTextForName(song.genre(), song.genre(), sort_behaviour);
return SortText(song.genre());
case GroupBy::Composer:
return SortTextForName(song.composer(), song.composersort(), sort_behaviour);
return SortTextForName(song.effective_composersort(), sort_skip_articles_for_artists);
case GroupBy::Performer:
return SortTextForName(song.performer(), song.performersort(), sort_behaviour);
return SortTextForName(song.effective_performersort(), sort_skip_articles_for_artists);
case GroupBy::Grouping:
return SortTextForName(song.grouping(), song.grouping(), sort_behaviour);
return SortText(song.grouping());
case GroupBy::FileType:
return song.TextForFiletype();
case GroupBy::Format:
@@ -1151,43 +1136,9 @@ QString CollectionModel::SortText(QString text) {
}
QString CollectionModel::SortTextSkipArticles(QString name) {
QString CollectionModel::SortTextForName(const QString &name, const bool sort_skip_articles) {
name = SortText(name);
for (const auto &i : Song::kArticles) {
if (name.startsWith(i)) {
qint64 ilen = i.length();
name = name.right(name.length() - ilen) + ", "_L1 + i.left(ilen - 1);
break;
}
}
return name;
}
QString CollectionModel::SortTextForName(const QString &name, const QString &sort_name, const CollectionSettings::SortBehaviour sort_behaviour) {
QString str;
switch (sort_behaviour) {
using namespace CollectionSettings;
case SortBehaviour::AsIs:
str = SortText(name);
break;
case SortBehaviour::SkipArticles:
str = SortTextSkipArticles(name);
break;
case SortBehaviour::UseSortTagForSort:
str = SortText(sort_name);
break;
case SortBehaviour::UseSortTagForDisplayAndSort:
str = SortText(sort_name);
break;
}
return str;
return sort_skip_articles ? SkipArticles(SortText(name)) : SortText(name);
}
@@ -1218,6 +1169,20 @@ QString CollectionModel::SortTextForBitrate(const int bitrate) {
}
QString CollectionModel::SkipArticles(QString name) {
for (const auto &i : Song::kArticles) {
if (name.startsWith(i)) {
qint64 ilen = i.length();
name = name.right(name.length() - ilen) + ", "_L1 + i.left(ilen - 1);
break;
}
}
return name;
}
bool CollectionModel::IsSongTitleDataChanged(const Song &song1, const Song &song2) {
return song1.url() != song2.url() ||

View File

@@ -1,6 +1,6 @@
/*
* Strawberry Music Player
* Copyright 2018-2024, Jonas Kvinge <jonas@jkvinge.net>
* Copyright 2018-2025, Jonas Kvinge <jonas@jkvinge.net>
*
* Strawberry is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -52,7 +52,6 @@
#include "collectionmodelupdate.h"
#include "collectionfilteroptions.h"
#include "collectionitem.h"
#include "constants/collectionsettings.h"
class QTimer;
class Settings;
@@ -130,14 +129,16 @@ class CollectionModel : public SimpleTreeModel<CollectionItem> {
show_dividers(true),
show_pretty_covers(true),
show_various_artists(true),
sort_behaviour(CollectionSettings::SortBehaviour::SkipArticles),
sort_skip_articles_for_artists(false),
sort_skip_articles_for_albums(false),
separate_albums_by_grouping(false) {}
Grouping group_by;
bool show_dividers;
bool show_pretty_covers;
bool show_various_artists;
CollectionSettings::SortBehaviour sort_behaviour;
bool sort_skip_articles_for_artists;
bool sort_skip_articles_for_albums;
bool separate_albums_by_grouping;
CollectionFilterOptions filter_options;
};
@@ -177,22 +178,21 @@ class CollectionModel : public SimpleTreeModel<CollectionItem> {
QMimeData *mimeData(const QModelIndexList &indexes) const override;
// Utility functions for manipulating text
static QString DisplayText(const GroupBy group_by, const Song &song, const CollectionSettings::SortBehaviour sort_behaviour);
static QString NameOrSortname(const QString &name, const QString &sort_name, const CollectionSettings::SortBehaviour sort_behaviour);
QString DisplayText(const GroupBy group_by, const Song &song);
static QString TextOrUnknown(const QString &text);
static QString PrettyYearAlbum(const int year, const QString &album);
static QString PrettyAlbumDisc(const QString &album, const int disc);
static QString PrettyYearAlbumDisc(const int year, const QString &album, const int disc);
static QString PrettyDisc(const int disc);
static QString PrettyFormat(const Song &song);
QString SortText(const GroupBy group_by, const Song &song, const CollectionSettings::SortBehaviour sort_behaviour);
QString SortText(const GroupBy group_by, const Song &song, const bool sort_skip_articles_for_artists, const bool sort_skip_articles_for_albums);
static QString SortText(QString text);
static QString SortTextForName(const QString &name, const QString &sort_name, const CollectionSettings::SortBehaviour sort_behaviour);
static QString SortTextForName(const QString &name, const bool sort_skip_articles);
static QString SortTextForNumber(const int number);
static QString SortTextSkipArticles(QString name);
static QString SortTextForSong(const Song &song);
static QString SortTextForYear(const int year);
static QString SortTextForBitrate(const int bitrate);
static QString SkipArticles(QString name);
static bool IsSongTitleDataChanged(const Song &song1, const Song &song2);
QString ContainerKey(const GroupBy group_by, const Song &song, bool &has_unique_album_identifier) const;

View File

@@ -1,6 +1,6 @@
/*
* Strawberry Music Player
* Copyright 2024, Jonas Kvinge <jonas@jkvinge.net>
* Copyright 2024-2025, Jonas Kvinge <jonas@jkvinge.net>
*
* Strawberry is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -24,18 +24,20 @@ namespace CollectionSettings {
constexpr char kSettingsGroup[] = "Collection";
constexpr char kStartupScan[] = "startup_scan";
constexpr char kMonitor[] = "monitor";
constexpr char kSongTracking[] = "song_tracking";
constexpr char kMarkSongsUnavailable[] = "mark_songs_unavailable";
constexpr char kSongENUR128LoudnessAnalysis[] = "song_ebur128_loudness_analysis";
constexpr char kExpireUnavailableSongs[] = "expire_unavailable_songs";
constexpr char kCoverArtPatterns[] = "cover_art_patterns";
constexpr char kAutoOpen[] = "auto_open";
constexpr char kShowDividers[] = "show_dividers";
constexpr char kPrettyCovers[] = "pretty_covers";
constexpr char kVariousArtists[] = "various_artists";
constexpr char kSortBehaviour[] = "sort_behaviour";
constexpr char kStartupScan[] = "startup_scan";
constexpr char kMonitor[] = "monitor";
constexpr char kSongTracking[] = "song_tracking";
constexpr char kSongENUR128LoudnessAnalysis[] = "song_ebur128_loudness_analysis";
constexpr char kMarkSongsUnavailable[] = "mark_songs_unavailable";
constexpr char kExpireUnavailableSongs[] = "expire_unavailable_songs";
constexpr char kCoverArtPatterns[] = "cover_art_patterns";
constexpr char kSkipArticlesForArtists[] = "skip_articles_for_artists";
constexpr char kSkipArticlesForAlbums[] = "skip_articles_for_albums";
constexpr char kShowSortText[] = "show_sort_text";
constexpr char kSettingsCacheSize[] = "cache_size";
constexpr char kSettingsCacheSizeUnit[] = "cache_size_unit";
constexpr char kSettingsDiskCacheEnable[] = "disk_cache_enable";
@@ -50,13 +52,6 @@ constexpr char kOverwriteRating[] = "overwrite_rating";
constexpr char kDeleteFiles[] = "delete_files";
constexpr char kLastPath[] = "last_path";
enum class SortBehaviour {
AsIs = 1,
SkipArticles = 2,
UseSortTagForSort = 3,
UseSortTagForDisplayAndSort = 4
};
enum class CacheSizeUnit {
KB,
MB,

View File

@@ -2,7 +2,7 @@
* Strawberry Music Player
* This file was part of Clementine.
* Copyright 2010, David Sansome <me@davidsansome.com>
* Copyright 2018-2024, Jonas Kvinge <jonas@jkvinge.net>
* Copyright 2018-2025, Jonas Kvinge <jonas@jkvinge.net>
*
* Strawberry is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -349,11 +349,6 @@ struct Song::Private : public QSharedData {
bool init_from_file_; // Whether this song was loaded from a file using taglib.
bool suspicious_tags_; // Whether our encoding guesser thinks these tags might be incorrectly encoded.
QString title_sortable_;
QString album_sortable_;
QString artist_sortable_;
QString albumartist_sortable_;
QUrl stream_url_; // Temporary stream URL set by the URL handler.
};
@@ -529,23 +524,18 @@ QString *Song::mutable_musicbrainz_work_id() { return &d->musicbrainz_work_id_;
bool Song::init_from_file() const { return d->init_from_file_; }
const QString &Song::title_sortable() const { return d->title_sortable_; }
const QString &Song::album_sortable() const { return d->album_sortable_; }
const QString &Song::artist_sortable() const { return d->artist_sortable_; }
const QString &Song::albumartist_sortable() const { return d->albumartist_sortable_; }
const QUrl &Song::stream_url() const { return d->stream_url_; }
void Song::set_id(const int id) { d->id_ = id; }
void Song::set_valid(const bool v) { d->valid_ = v; }
void Song::set_title(const QString &v) { d->title_sortable_ = sortable(v); d->title_ = v; }
void Song::set_title(const QString &v) { d->title_ = v; }
void Song::set_titlesort(const QString &v) { d->titlesort_ = v; }
void Song::set_album(const QString &v) { d->album_sortable_ = sortable(v); d->album_ = v; }
void Song::set_album(const QString &v) { d->album_ = v; }
void Song::set_albumsort(const QString &v) { d->albumsort_ = v; }
void Song::set_artist(const QString &v) { d->artist_sortable_ = sortable(v); d->artist_ = v; }
void Song::set_artist(const QString &v) { d->artist_ = v; }
void Song::set_artistsort(const QString &v) { d->artistsort_ = v; }
void Song::set_albumartist(const QString &v) { d->albumartist_sortable_ = sortable(v); d->albumartist_ = v; }
void Song::set_albumartist(const QString &v) { d->albumartist_ = v; }
void Song::set_albumartistsort(const QString &v) { d->albumartistsort_ = v; }
void Song::set_track(const int v) { d->track_ = v; }
void Song::set_disc(const int v) { d->disc_ = v; }
@@ -624,44 +614,13 @@ void Song::set_init_from_file(const bool v) { d->init_from_file_ = v; }
void Song::set_stream_url(const QUrl &v) { d->stream_url_ = v; }
void Song::set_title(const TagLib::String &v) {
const QString title = TagLibStringToQString(v);
d->title_sortable_ = sortable(title);
d->title_ = title;
}
void Song::set_title(const TagLib::String &v) { d->title_ = TagLibStringToQString(v); }
void Song::set_titlesort(const TagLib::String &v) { d->titlesort_ = TagLibStringToQString(v); }
void Song::set_album(const TagLib::String &v) {
const QString album = TagLibStringToQString(v);
d->album_sortable_ = sortable(album);
d->album_ = album;
}
void Song::set_album(const TagLib::String &v) { d->album_ = TagLibStringToQString(v); }
void Song::set_albumsort(const TagLib::String &v) { d->albumsort_ = TagLibStringToQString(v); }
void Song::set_artist(const TagLib::String &v) {
const QString artist = TagLibStringToQString(v);
d->artist_sortable_ = sortable(artist);
d->artist_ = artist;
}
void Song::set_artist(const TagLib::String &v) { d->artist_ = TagLibStringToQString(v); }
void Song::set_artistsort(const TagLib::String &v) { d->artistsort_ = TagLibStringToQString(v); }
void Song::set_albumartist(const TagLib::String &v) {
const QString albumartist = TagLibStringToQString(v);
d->albumartist_sortable_ = sortable(albumartist);
d->albumartist_ = albumartist;
}
void Song::set_albumartist(const TagLib::String &v) { d->albumartist_ = TagLibStringToQString(v); }
void Song::set_albumartistsort(const TagLib::String &v) { d->albumartistsort_ = TagLibStringToQString(v); }
void Song::set_genre(const TagLib::String &v) { d->genre_ = TagLibStringToQString(v); }
void Song::set_composer(const TagLib::String &v) { d->composer_ = TagLibStringToQString(v); }
@@ -688,12 +647,17 @@ void Song::set_musicbrainz_release_group_id(const TagLib::String &v) { d->musicb
void Song::set_musicbrainz_work_id(const TagLib::String &v) { d->musicbrainz_work_id_ = TagLibStringToQString(v).remove(u' ').replace(u';', u'/'); }
const QUrl &Song::effective_url() const { return !d->stream_url_.isEmpty() && d->stream_url_.isValid() ? d->stream_url_ : d->url_; }
const QString &Song::effective_titlesort() const { return d->titlesort_.isEmpty() ? d->title_ : d->titlesort_; }
const QString &Song::effective_albumartist() const { return d->albumartist_.isEmpty() ? d->artist_ : d->albumartist_; }
const QString &Song::effective_albumartist_sortable() const { return d->albumartist_.isEmpty() ? d->artist_sortable_ : d->albumartist_sortable_; }
const QString &Song::effective_albumartistsort_only() const { return d->albumartistsort_.isEmpty() ? d->albumartist_ : d->albumartistsort_; }
const QString &Song::effective_albumartist_with_sort() const { return effective_albumartistsort_only().isEmpty() ? effective_artistsort() : effective_albumartistsort_only(); }
const QString &Song::effective_artistsort() const { return d->artistsort_.isEmpty() ? d->artist_ : d->artistsort_; }
const QString &Song::effective_album() const { return d->album_.isEmpty() ? d->title_ : d->album_; }
const QString &Song::effective_albumsort() const { return d->albumsort_.isEmpty() ? d->album_ : d->albumsort_; }
const QString &Song::effective_composersort() const { return d->composersort_.isEmpty() ? d->composer_ : d->composersort_; }
const QString &Song::effective_performersort() const { return d->performersort_.isEmpty() ? d->performer_ : d->performersort_; }
int Song::effective_originalyear() const { return d->originalyear_ < 0 ? d->year_ : d->originalyear_; }
const QString &Song::playlist_albumartist() const { return is_compilation() ? d->albumartist_ : effective_albumartist(); }
const QString &Song::playlist_albumartist_sortable() const { return is_compilation() ? d->albumartist_sortable_ : effective_albumartist_sortable(); }
const QString &Song::playlist_albumartist() const { return is_compilation() ? effective_albumartistsort_only() : effective_albumartist_with_sort(); }
bool Song::is_metadata_good() const { return !d->url_.isEmpty() && !d->artist_.isEmpty() && !d->title_.isEmpty(); }
bool Song::is_local_collection_song() const { return d->source_ == Source::Collection; }
@@ -853,21 +817,6 @@ bool Song::save_embedded_cover_supported(const FileType filetype) {
}
QString Song::sortable(const QString &v) {
QString copy = v.toLower();
for (const auto &i : kArticles) {
if (copy.startsWith(i)) {
qint64 ilen = i.length();
return copy.right(copy.length() - ilen) + u", "_s + copy.left(ilen - 1);
}
}
return copy;
}
int Song::ColumnIndex(const QString &field) {
return static_cast<int>(kRowIdColumns.indexOf(field));

View File

@@ -2,7 +2,7 @@
* Strawberry Music Player
* This file was part of Clementine.
* Copyright 2010, David Sansome <me@davidsansome.com>
* Copyright 2018-2024, Jonas Kvinge <jonas@jkvinge.net>
* Copyright 2018-2025, Jonas Kvinge <jonas@jkvinge.net>
*
* Strawberry is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -256,11 +256,6 @@ class Song {
bool init_from_file() const;
const QString &title_sortable() const;
const QString &album_sortable() const;
const QString &artist_sortable() const;
const QString &albumartist_sortable() const;
const QUrl &stream_url() const;
// Setters
@@ -385,12 +380,17 @@ class Song {
void set_musicbrainz_work_id(const TagLib::String &v);
const QUrl &effective_url() const;
const QString &effective_titlesort() const;
const QString &effective_albumartist() const;
const QString &effective_albumartist_sortable() const;
const QString &effective_albumartistsort_only() const;
const QString &effective_albumartist_with_sort() const;
const QString &effective_artistsort() const;
const QString &effective_album() const;
const QString &effective_albumsort() const;
const QString &effective_composersort() const;
const QString &effective_performersort() const;
int effective_originalyear() const;
const QString &playlist_albumartist() const;
const QString &playlist_albumartist_sortable() const;
bool is_metadata_good() const;
bool is_local_collection_song() const;
@@ -555,9 +555,6 @@ class Song {
private:
struct Private;
static QString sortable(const QString &v);
QSharedDataPointer<Private> d;
};

View File

@@ -378,12 +378,12 @@ QVariant Playlist::data(const QModelIndex &idx, const int role) const {
case Column::DateCreated: return song.ctime();
case Column::Comment:
if (role == Qt::DisplayRole) return song.comment().simplified();
if (role == Qt::DisplayRole) return song.comment().simplified();
return song.comment();
case Column::EBUR128IntegratedLoudness: return song.ebur128_integrated_loudness_lufs().has_value() ? song.ebur128_integrated_loudness_lufs().value() : QVariant();
case Column::EBUR128LoudnessRange: return song.ebur128_loudness_range_lu().has_value() ? song.ebur128_loudness_range_lu().value() : QVariant();
case Column::EBUR128LoudnessRange: return song.ebur128_loudness_range_lu().has_value() ? song.ebur128_loudness_range_lu().value() : QVariant();
case Column::Source: return QVariant::fromValue(song.source());
@@ -1346,118 +1346,126 @@ QMimeData *Playlist::mimeData(const QModelIndexList &indexes) const {
}
namespace {
inline bool CompareStr(const QString &a, const QString &b) {
return QString::localeAwareCompare(a.toLower(), b.toLower()) < 0;
}
template<typename T>
inline bool CompareVal(const T &a, const T &b) {
return a < b;
}
} // namespace
bool Playlist::CompareItems(const Column column, const Qt::SortOrder order, PlaylistItemPtr _a, PlaylistItemPtr _b) {
PlaylistItemPtr a = order == Qt::AscendingOrder ? _a : _b;
PlaylistItemPtr b = order == Qt::AscendingOrder ? _b : _a;
PlaylistItemPtr a = (order == Qt::AscendingOrder) ? _a : _b;
PlaylistItemPtr b = (order == Qt::AscendingOrder) ? _b : _a;
#define cmp(field) return a->EffectiveMetadata().field() < b->EffectiveMetadata().field()
#define strcmp(field) return QString::localeAwareCompare(a->EffectiveMetadata().field().toLower(), b->EffectiveMetadata().field().toLower()) < 0;
const auto &ma = a->EffectiveMetadata();
const auto &mb = b->EffectiveMetadata();
switch (column) {
case Column::Title: strcmp(title_sortable);
case Column::TitleSort: strcmp(titlesort);
case Column::Artist: strcmp(artist_sortable);
case Column::ArtistSort: strcmp(artistsort);
case Column::Album: strcmp(album_sortable);
case Column::AlbumSort: strcmp(albumsort);
case Column::Length: cmp(length_nanosec);
case Column::Track: cmp(track);
case Column::Disc: cmp(disc);
case Column::Year: cmp(year);
case Column::OriginalYear: cmp(effective_originalyear);
case Column::Genre: strcmp(genre);
case Column::AlbumArtist: strcmp(playlist_albumartist_sortable);
case Column::AlbumArtistSort: strcmp(albumartistsort);
case Column::Composer: strcmp(composer);
case Column::ComposerSort: strcmp(composersort);
case Column::Performer: strcmp(performer);
case Column::PerformerSort: strcmp(performersort);
case Column::Grouping: strcmp(grouping);
case Column::Title: return CompareStr(ma.effective_titlesort(), mb.effective_titlesort());
case Column::TitleSort: return CompareStr(ma.titlesort(), mb.titlesort());
case Column::Artist: return CompareStr(ma.effective_artistsort(), mb.effective_artistsort());
case Column::ArtistSort: return CompareStr(ma.artistsort(), mb.artistsort());
case Column::Album: return CompareStr(ma.effective_albumsort(), mb.effective_albumsort());
case Column::AlbumSort: return CompareStr(ma.albumsort(), mb.albumsort());
case Column::Length: return CompareVal(ma.length_nanosec(), mb.length_nanosec());
case Column::Track: return CompareVal(ma.track(), mb.track());
case Column::Disc: return CompareVal(ma.disc(), mb.disc());
case Column::Year: return CompareVal(ma.year(), mb.year());
case Column::OriginalYear: return CompareVal(ma.effective_originalyear(), mb.effective_originalyear());
case Column::Genre: return CompareStr(ma.genre(), mb.genre());
case Column::AlbumArtist: return CompareStr(ma.playlist_albumartist(), mb.playlist_albumartist());
case Column::AlbumArtistSort: return CompareStr(ma.albumartistsort(), mb.albumartistsort());
case Column::Composer: return CompareStr(ma.effective_composersort(), mb.effective_composersort());
case Column::ComposerSort: return CompareStr(ma.composersort(), mb.composersort());
case Column::Performer: return CompareStr(ma.effective_performersort(), mb.effective_performersort());
case Column::PerformerSort: return CompareStr(ma.performersort(), mb.performersort());
case Column::Grouping: return CompareStr(ma.grouping(), mb.grouping());
case Column::PlayCount: cmp(playcount);
case Column::SkipCount: cmp(skipcount);
case Column::LastPlayed: cmp(lastplayed);
case Column::PlayCount: return CompareVal(ma.playcount(), mb.playcount());
case Column::SkipCount: return CompareVal(ma.skipcount(), mb.skipcount());
case Column::LastPlayed: return CompareVal(ma.lastplayed(), mb.lastplayed());
case Column::Bitrate: cmp(bitrate);
case Column::Samplerate: cmp(samplerate);
case Column::Bitdepth: cmp(bitdepth);
case Column::URL:
return QString::localeAwareCompare(a->OriginalUrl().path(), b->OriginalUrl().path()) < 0;
case Column::BaseFilename: cmp(basefilename);
case Column::Filesize: cmp(filesize);
case Column::Filetype: cmp(filetype);
case Column::DateModified: cmp(mtime);
case Column::DateCreated: cmp(ctime);
case Column::Bitrate: return CompareVal(ma.bitrate(), mb.bitrate());
case Column::Samplerate: return CompareVal(ma.samplerate(), mb.samplerate());
case Column::Bitdepth: return CompareVal(ma.bitdepth(), mb.bitdepth());
case Column::URL: return CompareStr(a->OriginalUrl().path(), b->OriginalUrl().path());
case Column::BaseFilename: return CompareVal(ma.basefilename(), mb.basefilename());
case Column::Filesize: return CompareVal(ma.filesize(), mb.filesize());
case Column::Filetype: return CompareVal(ma.filetype(), mb.filetype());
case Column::DateModified: return CompareVal(ma.mtime(), mb.mtime());
case Column::DateCreated: return CompareVal(ma.ctime(), mb.ctime());
case Column::Comment: strcmp(comment);
case Column::Source: cmp(source);
case Column::Comment: return CompareStr(ma.comment(), mb.comment());
case Column::Source: return CompareVal(ma.source(), mb.source());
case Column::Rating: cmp(rating);
case Column::Rating: return CompareVal(ma.rating(), mb.rating());
case Column::HasCUE: cmp(has_cue);
case Column::HasCUE: return CompareVal(ma.has_cue(), mb.has_cue());
case Column::EBUR128IntegratedLoudness: cmp(ebur128_integrated_loudness_lufs);
case Column::EBUR128LoudnessRange: cmp(ebur128_loudness_range_lu);
case Column::EBUR128IntegratedLoudness: return CompareVal(ma.ebur128_integrated_loudness_lufs(), mb.ebur128_integrated_loudness_lufs());
case Column::EBUR128LoudnessRange: return CompareVal(ma.ebur128_loudness_range_lu(), mb.ebur128_loudness_range_lu());
case Column::Mood:
case Column::ColumnCount:
break;
}
#undef cmp
#undef strcmp
return false;
}
QString Playlist::column_name(const Column column) {
switch (column) {
case Column::Title: return tr("Title");
case Column::TitleSort: return tr("Title Sort");
case Column::Artist: return tr("Artist");
case Column::ArtistSort: return tr("Artist Sort");
case Column::Album: return tr("Album");
case Column::AlbumSort: return tr("Album Sort");
case Column::Track: return tr("Track");
case Column::Disc: return tr("Disc");
case Column::Length: return tr("Length");
case Column::Year: return tr("Year");
case Column::OriginalYear: return tr("Original Year");
case Column::Genre: return tr("Genre");
case Column::AlbumArtist: return tr("Album Artist");
case Column::AlbumArtistSort: return tr("Album Artist Sort");
case Column::Composer: return tr("Composer");
case Column::ComposerSort: return tr("Composer Sort");
case Column::Performer: return tr("Performer");
case Column::PerformerSort: return tr("Performer Sort");
case Column::Grouping: return tr("Grouping");
case Column::Title: return tr("Title");
case Column::TitleSort: return tr("Title Sort");
case Column::Artist: return tr("Artist");
case Column::ArtistSort: return tr("Artist Sort");
case Column::Album: return tr("Album");
case Column::AlbumSort: return tr("Album Sort");
case Column::Track: return tr("Track");
case Column::Disc: return tr("Disc");
case Column::Length: return tr("Length");
case Column::Year: return tr("Year");
case Column::OriginalYear: return tr("Original Year");
case Column::Genre: return tr("Genre");
case Column::AlbumArtist: return tr("Album Artist");
case Column::AlbumArtistSort: return tr("Album Artist Sort");
case Column::Composer: return tr("Composer");
case Column::ComposerSort: return tr("Composer Sort");
case Column::Performer: return tr("Performer");
case Column::PerformerSort: return tr("Performer Sort");
case Column::Grouping: return tr("Grouping");
case Column::PlayCount: return tr("Play Count");
case Column::SkipCount: return tr("Skip Count");
case Column::LastPlayed: return tr("Last Played");
case Column::PlayCount: return tr("Play Count");
case Column::SkipCount: return tr("Skip Count");
case Column::LastPlayed: return tr("Last Played");
case Column::Samplerate: return tr("Sample Rate");
case Column::Bitdepth: return tr("Bit Depth");
case Column::Bitrate: return tr("Bitrate");
case Column::Samplerate: return tr("Sample Rate");
case Column::Bitdepth: return tr("Bit Depth");
case Column::Bitrate: return tr("Bitrate");
case Column::URL: return tr("URL");
case Column::BaseFilename: return tr("File Name (without path)");
case Column::Filesize: return tr("File Size");
case Column::Filetype: return tr("File Type");
case Column::DateModified: return tr("Date Modified");
case Column::DateCreated: return tr("Date Created");
case Column::URL: return tr("URL");
case Column::BaseFilename: return tr("File Name (without path)");
case Column::Filesize: return tr("File Size");
case Column::Filetype: return tr("File Type");
case Column::DateModified: return tr("Date Modified");
case Column::DateCreated: return tr("Date Created");
case Column::Comment: return tr("Comment");
case Column::Source: return tr("Source");
case Column::Mood: return tr("Mood");
case Column::Rating: return tr("Rating");
case Column::HasCUE: return tr("CUE");
case Column::Comment: return tr("Comment");
case Column::Source: return tr("Source");
case Column::Mood: return tr("Mood");
case Column::Rating: return tr("Rating");
case Column::HasCUE: return tr("CUE");
case Column::EBUR128IntegratedLoudness: return tr("Integrated Loudness");
case Column::EBUR128LoudnessRange: return tr("Loudness Range");
case Column::EBUR128LoudnessRange: return tr("Loudness Range");
case Column::ColumnCount:
break;

View File

@@ -2,7 +2,7 @@
* Strawberry Music Player
* This file was part of Clementine.
* Copyright 2010, David Sansome <me@davidsansome.com>
* Copyright 2018-2024, Jonas Kvinge <jonas@jkvinge.net>
* Copyright 2018-2025, Jonas Kvinge <jonas@jkvinge.net>
*
* Strawberry is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -83,15 +83,9 @@ CollectionSettingsPage::CollectionSettingsPage(SettingsDialog *dialog,
ui_->setupUi(this);
ui_->list->setItemDelegate(new NativeSeparatorsDelegate(this));
// Icons
setWindowIcon(IconLoader::Load(u"library-music"_s, true, 0, 32));
ui_->add_directory->setIcon(IconLoader::Load(u"document-open-folder"_s));
ui_->combobox_sort->setItemData(0, static_cast<int>(SortBehaviour::AsIs));
ui_->combobox_sort->setItemData(1, static_cast<int>(SortBehaviour::SkipArticles));
ui_->combobox_sort->setItemData(2, static_cast<int>(SortBehaviour::UseSortTagForSort));
ui_->combobox_sort->setItemData(3, static_cast<int>(SortBehaviour::UseSortTagForDisplayAndSort));
ui_->combobox_cache_size->addItem(u"KB"_s, static_cast<int>(CacheSizeUnit::KB));
ui_->combobox_cache_size->addItem(u"MB"_s, static_cast<int>(CacheSizeUnit::MB));
@@ -153,21 +147,24 @@ void CollectionSettingsPage::Load() {
Settings s;
s.beginGroup(kSettingsGroup);
ui_->auto_open->setChecked(s.value(kAutoOpen, true).toBool());
ui_->show_dividers->setChecked(s.value(kShowDividers, true).toBool());
ui_->pretty_covers->setChecked(s.value(kPrettyCovers, true).toBool());
ui_->various_artists->setChecked(s.value(kVariousArtists, true).toBool());
ui_->combobox_sort->setCurrentIndex(ui_->combobox_sort->findData(s.value(kSortBehaviour, static_cast<int>(SortBehaviour::SkipArticles)).toInt()));
ui_->startup_scan->setChecked(s.value(kStartupScan, true).toBool());
ui_->monitor->setChecked(s.value(kMonitor, true).toBool());
ui_->song_tracking->setChecked(s.value(kSongTracking, false).toBool());
ui_->song_ebur128_loudness_analysis->setChecked(s.value(kSongENUR128LoudnessAnalysis, false).toBool());
ui_->mark_songs_unavailable->setChecked(ui_->song_tracking->isChecked() ? true : s.value(kMarkSongsUnavailable, true).toBool());
ui_->song_ebur128_loudness_analysis->setChecked(s.value(kSongENUR128LoudnessAnalysis, false).toBool());
ui_->expire_unavailable_songs_days->setValue(s.value(kExpireUnavailableSongs, 60).toInt());
QStringList filters = s.value(kCoverArtPatterns, QStringList() << u"front"_s << u"cover"_s).toStringList();
ui_->cover_art_patterns->setText(filters.join(u','));
ui_->auto_open->setChecked(s.value(kAutoOpen, true).toBool());
ui_->show_dividers->setChecked(s.value(kShowDividers, true).toBool());
ui_->pretty_covers->setChecked(s.value(kPrettyCovers, true).toBool());
ui_->various_artists->setChecked(s.value(kVariousArtists, true).toBool());
ui_->checkbox_skip_articles_for_artists->setChecked(s.value(kSkipArticlesForArtists, true).toBool());
ui_->checkbox_skip_articles_for_albums->setChecked(s.value(kSkipArticlesForAlbums, false).toBool());
ui_->spinbox_cache_size->setValue(s.value(kSettingsCacheSize, kSettingsCacheSizeDefault).toInt());
ui_->combobox_cache_size->setCurrentIndex(ui_->combobox_cache_size->findData(s.value(kSettingsCacheSizeUnit, static_cast<int>(CacheSizeUnit::MB)).toInt()));
ui_->checkbox_disk_cache->setChecked(s.value(kSettingsDiskCacheEnable, false).toBool());
@@ -197,24 +194,23 @@ void CollectionSettingsPage::Save() {
Settings s;
s.beginGroup(kSettingsGroup);
s.setValue(kStartupScan, ui_->startup_scan->isChecked());
s.setValue(kMonitor, ui_->monitor->isChecked());
s.setValue(kSongTracking, ui_->song_tracking->isChecked());
s.setValue(kMarkSongsUnavailable, ui_->song_tracking->isChecked() ? true : ui_->mark_songs_unavailable->isChecked());
s.setValue(kSongENUR128LoudnessAnalysis, ui_->song_ebur128_loudness_analysis->isChecked());
s.setValue(kExpireUnavailableSongs, ui_->expire_unavailable_songs_days->value());
const QString filter_text = ui_->cover_art_patterns->text();
s.setValue(kCoverArtPatterns, filter_text.split(u',', Qt::SkipEmptyParts));
s.setValue(kAutoOpen, ui_->auto_open->isChecked());
s.setValue(kShowDividers, ui_->show_dividers->isChecked());
s.setValue(kPrettyCovers, ui_->pretty_covers->isChecked());
s.setValue(kVariousArtists, ui_->various_artists->isChecked());
const SortBehaviour menu_sort = static_cast<SortBehaviour>(ui_->combobox_sort->currentData().toInt());
s.setValue(kSortBehaviour, static_cast<int>(menu_sort));
s.setValue(kStartupScan, ui_->startup_scan->isChecked());
s.setValue(kMonitor, ui_->monitor->isChecked());
s.setValue(kSongTracking, ui_->song_tracking->isChecked());
s.setValue(kSongENUR128LoudnessAnalysis, ui_->song_ebur128_loudness_analysis->isChecked());
s.setValue(kMarkSongsUnavailable, ui_->song_tracking->isChecked() ? true : ui_->mark_songs_unavailable->isChecked());
s.setValue(kExpireUnavailableSongs, ui_->expire_unavailable_songs_days->value());
QString filter_text = ui_->cover_art_patterns->text();
const QStringList filters = filter_text.split(u',', Qt::SkipEmptyParts);
s.setValue(kCoverArtPatterns, filters);
s.setValue(kSkipArticlesForArtists, ui_->checkbox_skip_articles_for_artists->isChecked());
s.setValue(kSkipArticlesForAlbums, ui_->checkbox_skip_articles_for_albums->isChecked());
s.setValue(kSettingsCacheSize, ui_->spinbox_cache_size->value());
s.setValue(kSettingsCacheSizeUnit, ui_->combobox_cache_size->currentData().toInt());

View File

@@ -2,7 +2,7 @@
* Strawberry Music Player
* This file was part of Clementine.
* Copyright 2010, David Sansome <me@davidsansome.com>
* Copyright 2018-2024, Jonas Kvinge <jonas@jkvinge.net>
* Copyright 2018-2025, Jonas Kvinge <jonas@jkvinge.net>
*
* Strawberry is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by

View File

@@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>604</width>
<height>1035</height>
<height>1112</height>
</rect>
</property>
<property name="windowTitle">
@@ -235,37 +235,18 @@ If there are no matches then it will use the largest image in the directory.</st
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupbox_sort">
<property name="title">
<string>When sorting names like &quot;The Beatles&quot;...</string>
</property>
<layout class="QVBoxLayout" name="layout_sort">
<item>
<widget class="QComboBox" name="combobox_sort">
<item>
<property name="text">
<string>Sort and show name as is</string>
</property>
</item>
<item>
<property name="text">
<string>Skip articles &quot;The, A, An&quot; for sorting but show name as is</string>
</property>
</item>
<item>
<property name="text">
<string>Use sort tag for sorting and show name as is</string>
</property>
</item>
<item>
<property name="text">
<string>Use sort tag for sorting and display</string>
</property>
</item>
<widget class="QCheckBox" name="checkbox_skip_articles_for_artists">
<property name="text">
<string>Skip leading articles (&quot;the&quot;, &quot;a&quot;, &quot;an&quot;) when sorting artists, composers and performers</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="checkbox_skip_articles_for_albums">
<property name="text">
<string>Skip leading articles (&quot;the&quot;, &quot;a&quot;, &quot;an&quot;) when sorting albums</string>
</property>
</widget>
</item>
</layout>
@@ -551,7 +532,8 @@ If there are no matches then it will use the largest image in the directory.</st
<tabstop>show_dividers</tabstop>
<tabstop>pretty_covers</tabstop>
<tabstop>various_artists</tabstop>
<tabstop>combobox_sort</tabstop>
<tabstop>checkbox_skip_articles_for_artists</tabstop>
<tabstop>checkbox_skip_articles_for_albums</tabstop>
<tabstop>spinbox_cache_size</tabstop>
<tabstop>combobox_cache_size</tabstop>
<tabstop>checkbox_disk_cache</tabstop>

View File

@@ -97,7 +97,7 @@ QStandardItem *StreamingSearchModel::BuildContainers(const Song &s, QStandardIte
}
else {
display_text = CollectionModel::TextOrUnknown(s.effective_albumartist());
sort_text = CollectionModel::SortTextSkipArticles(s.effective_albumartist());
sort_text = CollectionModel::SortTextForName(s.effective_albumartist_with_sort(), true);
}
has_artist_icon = true;
break;
@@ -109,60 +109,60 @@ QStandardItem *StreamingSearchModel::BuildContainers(const Song &s, QStandardIte
}
else {
display_text = CollectionModel::TextOrUnknown(s.artist());
sort_text = CollectionModel::SortTextSkipArticles(s.artist());
sort_text = CollectionModel::SortTextForName(s.effective_artistsort(), true);
}
has_artist_icon = true;
break;
case CollectionModel::GroupBy::Album:
display_text = CollectionModel::TextOrUnknown(s.album());
sort_text = CollectionModel::SortTextSkipArticles(s.album());
sort_text = CollectionModel::SortTextForName(s.effective_albumsort(), false);
unique_tag = s.album_id();
has_album_icon = true;
break;
case CollectionModel::GroupBy::AlbumDisc:{
int disc = qMax(0, s.disc());
const int disc = std::max(0, s.disc());
display_text = CollectionModel::PrettyAlbumDisc(s.album(), disc);
sort_text = s.album() + CollectionModel::SortTextForNumber(disc);
sort_text = CollectionModel::SortTextForName(s.effective_albumsort(), false) + CollectionModel::SortTextForNumber(disc);
unique_tag = s.album_id();
has_album_icon = true;
break;
}
case CollectionModel::GroupBy::YearAlbum:{
int year = qMax(0, s.year());
const int year = std::max(0, s.year());
display_text = CollectionModel::PrettyYearAlbum(year, s.album());
sort_text = CollectionModel::SortTextForNumber(year) + s.album();
sort_text = CollectionModel::SortTextForNumber(year) + CollectionModel::SortTextForName(s.effective_albumsort(), false);
unique_tag = s.album_id();
has_album_icon = true;
break;
}
case CollectionModel::GroupBy::YearAlbumDisc:{
int year = qMax(0, s.year());
int disc = qMax(0, s.disc());
const int year = std::max(0, s.year());
const int disc = std::max(0, s.disc());
display_text = CollectionModel::PrettyYearAlbumDisc(year, s.album(), disc);
sort_text = CollectionModel::SortTextForNumber(year) + s.album() + CollectionModel::SortTextForNumber(disc);
sort_text = CollectionModel::SortTextForNumber(year) + CollectionModel::SortTextForName(s.effective_albumsort(), false) + CollectionModel::SortTextForNumber(disc);
unique_tag = s.album_id();
has_album_icon = true;
break;
}
case CollectionModel::GroupBy::OriginalYearAlbum:{
int year = qMax(0, s.effective_originalyear());
const int year = std::max(0, s.effective_originalyear());
display_text = CollectionModel::PrettyYearAlbum(year, s.album());
sort_text = CollectionModel::SortTextForNumber(year) + s.album();
sort_text = CollectionModel::SortTextForNumber(year) + CollectionModel::SortTextForName(s.effective_albumsort(), false);
unique_tag = s.album_id();
has_album_icon = true;
break;
}
case CollectionModel::GroupBy::OriginalYearAlbumDisc:{
const int year = qMax(0, s.effective_originalyear());
const int disc = qMax(0, s.disc());
const int year = std::max(0, s.effective_originalyear());
const int disc = std::max(0, s.disc());
display_text = CollectionModel::PrettyYearAlbumDisc(year, s.album(), disc);
sort_text = CollectionModel::SortTextForNumber(year) + s.album() + CollectionModel::SortTextForNumber(disc);
sort_text = CollectionModel::SortTextForNumber(year) + CollectionModel::SortTextForName(s.effective_albumsort(), false) + CollectionModel::SortTextForNumber(disc);
unique_tag = s.album_id();
has_album_icon = true;
break;
@@ -170,7 +170,7 @@ QStandardItem *StreamingSearchModel::BuildContainers(const Song &s, QStandardIte
case CollectionModel::GroupBy::Disc:
display_text = CollectionModel::PrettyDisc(s.disc());
sort_text = CollectionModel::SortTextSkipArticles(display_text);
sort_text = CollectionModel::SortText(display_text);
has_album_icon = true;
break;
@@ -190,25 +190,25 @@ QStandardItem *StreamingSearchModel::BuildContainers(const Song &s, QStandardIte
case CollectionModel::GroupBy::Genre:
display_text = CollectionModel::TextOrUnknown(s.genre());
sort_text = CollectionModel::SortTextSkipArticles(s.genre());
sort_text = CollectionModel::SortText(s.genre());
has_album_icon = true;
break;
case CollectionModel::GroupBy::Composer:
display_text = CollectionModel::TextOrUnknown(s.composer());
sort_text = CollectionModel::SortTextSkipArticles(s.composer());
sort_text = CollectionModel::SortTextForName(s.composer(), true);
has_album_icon = true;
break;
case CollectionModel::GroupBy::Performer:
display_text = CollectionModel::TextOrUnknown(s.performer());
sort_text = CollectionModel::SortTextSkipArticles(s.performer());
sort_text = CollectionModel::SortTextForName(s.performer(), true);
has_album_icon = true;
break;
case CollectionModel::GroupBy::Grouping:
display_text = CollectionModel::TextOrUnknown(s.grouping());
sort_text = CollectionModel::SortTextSkipArticles(s.grouping());
sort_text = CollectionModel::SortText(s.grouping());
has_album_icon = true;
break;