Refactor use of sort tags
This commit is contained in:
@@ -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() ||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 "The Beatles"...</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 "The, A, An" 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 ("the", "a", "an") 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 ("the", "a", "an") 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>
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user