Add sort columns to playlists
Increment playlist state version from 1 to 2 to get sort columns next to their "original" column. Discard old stored playlist state in config file.
This commit is contained in:
@@ -219,11 +219,17 @@ bool Playlist::column_is_editable(const Playlist::Column column) {
|
||||
|
||||
switch (column) {
|
||||
case Column::Title:
|
||||
case Column::TitleSort:
|
||||
case Column::Artist:
|
||||
case Column::ArtistSort:
|
||||
case Column::Album:
|
||||
case Column::AlbumSort:
|
||||
case Column::AlbumArtist:
|
||||
case Column::AlbumArtistSort:
|
||||
case Column::Composer:
|
||||
case Column::ComposerSort:
|
||||
case Column::Performer:
|
||||
case Column::PerformerSort:
|
||||
case Column::Grouping:
|
||||
case Column::Track:
|
||||
case Column::Disc:
|
||||
@@ -247,21 +253,39 @@ bool Playlist::set_column_value(Song &song, const Playlist::Column column, const
|
||||
case Column::Title:
|
||||
song.set_title(value.toString());
|
||||
break;
|
||||
case Column::TitleSort:
|
||||
song.set_titlesort(value.toString());
|
||||
break;
|
||||
case Column::Artist:
|
||||
song.set_artist(value.toString());
|
||||
break;
|
||||
case Column::ArtistSort:
|
||||
song.set_artistsort(value.toString());
|
||||
break;
|
||||
case Column::Album:
|
||||
song.set_album(value.toString());
|
||||
break;
|
||||
case Column::AlbumSort:
|
||||
song.set_albumsort(value.toString());
|
||||
break;
|
||||
case Column::AlbumArtist:
|
||||
song.set_albumartist(value.toString());
|
||||
break;
|
||||
case Column::AlbumArtistSort:
|
||||
song.set_albumartistsort(value.toString());
|
||||
break;
|
||||
case Column::Composer:
|
||||
song.set_composer(value.toString());
|
||||
break;
|
||||
case Column::ComposerSort:
|
||||
song.set_composersort(value.toString());
|
||||
break;
|
||||
case Column::Performer:
|
||||
song.set_performer(value.toString());
|
||||
break;
|
||||
case Column::PerformerSort:
|
||||
song.set_performersort(value.toString());
|
||||
break;
|
||||
case Column::Grouping:
|
||||
song.set_grouping(value.toString());
|
||||
break;
|
||||
@@ -319,8 +343,11 @@ QVariant Playlist::data(const QModelIndex &idx, const int role) const {
|
||||
// Don't forget to change Playlist::CompareItems when adding new columns
|
||||
switch (static_cast<Column>(idx.column())) {
|
||||
case Column::Title: return song.PrettyTitle();
|
||||
case Column::TitleSort: return song.titlesort();
|
||||
case Column::Artist: return song.artist();
|
||||
case Column::ArtistSort: return song.artistsort();
|
||||
case Column::Album: return song.album();
|
||||
case Column::AlbumSort: return song.albumsort();
|
||||
case Column::Length: return song.length_nanosec();
|
||||
case Column::Track: return song.track();
|
||||
case Column::Disc: return song.disc();
|
||||
@@ -328,8 +355,11 @@ QVariant Playlist::data(const QModelIndex &idx, const int role) const {
|
||||
case Column::OriginalYear: return song.effective_originalyear();
|
||||
case Column::Genre: return song.genre();
|
||||
case Column::AlbumArtist: return song.playlist_albumartist();
|
||||
case Column::AlbumArtistSort: return song.albumartistsort();
|
||||
case Column::Composer: return song.composer();
|
||||
case Column::ComposerSort: return song.composersort();
|
||||
case Column::Performer: return song.performer();
|
||||
case Column::PerformerSort: return song.performersort();
|
||||
case Column::Grouping: return song.grouping();
|
||||
|
||||
case Column::PlayCount: return song.playcount();
|
||||
@@ -1326,8 +1356,11 @@ bool Playlist::CompareItems(const Column column, const Qt::SortOrder order, Play
|
||||
|
||||
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);
|
||||
@@ -1335,8 +1368,11 @@ bool Playlist::CompareItems(const Column column, const Qt::SortOrder order, Play
|
||||
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::PlayCount: cmp(playcount);
|
||||
@@ -1380,8 +1416,11 @@ 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");
|
||||
@@ -1389,8 +1428,11 @@ QString Playlist::column_name(const Column column) {
|
||||
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");
|
||||
@@ -2109,21 +2151,39 @@ Playlist::Columns Playlist::ChangedColumns(const Song &metadata1, const Song &me
|
||||
if (metadata1.title() != metadata2.title()) {
|
||||
columns << Column::Title;
|
||||
}
|
||||
if (metadata1.titlesort() != metadata2.titlesort()) {
|
||||
columns << Column::TitleSort;
|
||||
}
|
||||
if (metadata1.artist() != metadata2.artist()) {
|
||||
columns << Column::Artist;
|
||||
}
|
||||
if (metadata1.artistsort() != metadata2.artistsort()) {
|
||||
columns << Column::ArtistSort;
|
||||
}
|
||||
if (metadata1.album() != metadata2.album()) {
|
||||
columns << Column::Album;
|
||||
}
|
||||
if (metadata1.albumsort() != metadata2.albumsort()) {
|
||||
columns << Column::AlbumSort;
|
||||
}
|
||||
if (metadata1.effective_albumartist() != metadata2.effective_albumartist()) {
|
||||
columns << Column::AlbumArtist;
|
||||
}
|
||||
if (metadata1.albumartistsort() != metadata2.albumartistsort()) {
|
||||
columns << Column::AlbumArtistSort;
|
||||
}
|
||||
if (metadata1.performer() != metadata2.performer()) {
|
||||
columns << Column::Performer;
|
||||
}
|
||||
if (metadata1.performersort() != metadata2.performersort()) {
|
||||
columns << Column::PerformerSort;
|
||||
}
|
||||
if (metadata1.composer() != metadata2.composer()) {
|
||||
columns << Column::Composer;
|
||||
}
|
||||
if (metadata1.composersort() != metadata2.composersort()) {
|
||||
columns << Column::ComposerSort;
|
||||
}
|
||||
if (metadata1.year() != metadata2.year()) {
|
||||
columns << Column::Year;
|
||||
}
|
||||
|
||||
@@ -101,11 +101,17 @@ class Playlist : public QAbstractListModel {
|
||||
// Always add new columns to the end of this enum - the values are persisted
|
||||
enum class Column {
|
||||
Title = 0,
|
||||
TitleSort,
|
||||
Artist,
|
||||
ArtistSort,
|
||||
Album,
|
||||
AlbumSort,
|
||||
AlbumArtist,
|
||||
AlbumArtistSort,
|
||||
Performer,
|
||||
PerformerSort,
|
||||
Composer,
|
||||
ComposerSort,
|
||||
Year,
|
||||
OriginalYear,
|
||||
Track,
|
||||
|
||||
@@ -387,13 +387,19 @@ TagCompletionModel::TagCompletionModel(SharedPtr<CollectionBackend> backend, con
|
||||
QString TagCompletionModel::database_column(const Playlist::Column column) {
|
||||
|
||||
switch (column) {
|
||||
case Playlist::Column::Artist: return u"artist"_s;
|
||||
case Playlist::Column::Album: return u"album"_s;
|
||||
case Playlist::Column::AlbumArtist: return u"albumartist"_s;
|
||||
case Playlist::Column::Composer: return u"composer"_s;
|
||||
case Playlist::Column::Performer: return u"performer"_s;
|
||||
case Playlist::Column::Grouping: return u"grouping"_s;
|
||||
case Playlist::Column::Genre: return u"genre"_s;
|
||||
case Playlist::Column::Artist: return u"artist"_s;
|
||||
case Playlist::Column::ArtistSort: return u"artistsort"_s;
|
||||
case Playlist::Column::Album: return u"album"_s;
|
||||
case Playlist::Column::AlbumSort: return u"albumsort"_s;
|
||||
case Playlist::Column::AlbumArtist: return u"albumartist"_s;
|
||||
case Playlist::Column::AlbumArtistSort: return u"albumartistsort"_s;
|
||||
case Playlist::Column::Composer: return u"composer"_s;
|
||||
case Playlist::Column::ComposerSort: return u"composersort"_s;
|
||||
case Playlist::Column::Performer: return u"performer"_s;
|
||||
case Playlist::Column::PerformerSort: return u"performersort"_s;
|
||||
case Playlist::Column::Grouping: return u"grouping"_s;
|
||||
case Playlist::Column::Genre: return u"genre"_s;
|
||||
case Playlist::Column::TitleSort: return u"titlesort"_s;
|
||||
default:
|
||||
qLog(Warning) << "Unknown column" << static_cast<int>(column);
|
||||
return QString();
|
||||
|
||||
@@ -87,6 +87,7 @@ constexpr int kGlowIntensitySteps = 24;
|
||||
constexpr int kAutoscrollGraceTimeout = 30; // seconds
|
||||
constexpr int kDropIndicatorWidth = 2;
|
||||
constexpr int kDropIndicatorGradientWidth = 5;
|
||||
constexpr int kHeaderStateVersion = 2;
|
||||
} // namespace
|
||||
|
||||
PlaylistView::PlaylistView(QWidget *parent)
|
||||
@@ -131,7 +132,6 @@ PlaylistView::PlaylistView(QWidget *parent)
|
||||
cached_current_row_row_(-1),
|
||||
drop_indicator_row_(-1),
|
||||
drag_over_(false),
|
||||
header_state_version_(1),
|
||||
column_alignment_(DefaultColumnAlignment()),
|
||||
rating_locked_(false),
|
||||
dynamic_controls_(new DynamicPlaylistControls(this)),
|
||||
@@ -217,12 +217,18 @@ void PlaylistView::SetItemDelegates() {
|
||||
setItemDelegate(new PlaylistDelegateBase(this));
|
||||
|
||||
setItemDelegateForColumn(static_cast<int>(Playlist::Column::Title), new TextItemDelegate(this));
|
||||
setItemDelegateForColumn(static_cast<int>(Playlist::Column::TitleSort), new TagCompletionItemDelegate(this, collection_backend_, Playlist::Column::TitleSort));
|
||||
setItemDelegateForColumn(static_cast<int>(Playlist::Column::Album), new TagCompletionItemDelegate(this, collection_backend_, Playlist::Column::Album));
|
||||
setItemDelegateForColumn(static_cast<int>(Playlist::Column::AlbumSort), new TagCompletionItemDelegate(this, collection_backend_, Playlist::Column::AlbumSort));
|
||||
setItemDelegateForColumn(static_cast<int>(Playlist::Column::Artist), new TagCompletionItemDelegate(this, collection_backend_, Playlist::Column::Artist));
|
||||
setItemDelegateForColumn(static_cast<int>(Playlist::Column::ArtistSort), new TagCompletionItemDelegate(this, collection_backend_, Playlist::Column::ArtistSort));
|
||||
setItemDelegateForColumn(static_cast<int>(Playlist::Column::AlbumArtist), new TagCompletionItemDelegate(this, collection_backend_, Playlist::Column::AlbumArtist));
|
||||
setItemDelegateForColumn(static_cast<int>(Playlist::Column::AlbumArtistSort), new TagCompletionItemDelegate(this, collection_backend_, Playlist::Column::AlbumArtistSort));
|
||||
setItemDelegateForColumn(static_cast<int>(Playlist::Column::Genre), new TagCompletionItemDelegate(this, collection_backend_, Playlist::Column::Genre));
|
||||
setItemDelegateForColumn(static_cast<int>(Playlist::Column::Composer), new TagCompletionItemDelegate(this, collection_backend_, Playlist::Column::Composer));
|
||||
setItemDelegateForColumn(static_cast<int>(Playlist::Column::ComposerSort), new TagCompletionItemDelegate(this, collection_backend_, Playlist::Column::ComposerSort));
|
||||
setItemDelegateForColumn(static_cast<int>(Playlist::Column::Performer), new TagCompletionItemDelegate(this, collection_backend_, Playlist::Column::Performer));
|
||||
setItemDelegateForColumn(static_cast<int>(Playlist::Column::PerformerSort), new TagCompletionItemDelegate(this, collection_backend_, Playlist::Column::PerformerSort));
|
||||
setItemDelegateForColumn(static_cast<int>(Playlist::Column::Grouping), new TagCompletionItemDelegate(this, collection_backend_, Playlist::Column::Grouping));
|
||||
setItemDelegateForColumn(static_cast<int>(Playlist::Column::Length), new LengthItemDelegate(this));
|
||||
setItemDelegateForColumn(static_cast<int>(Playlist::Column::Filesize), new SizeItemDelegate(this));
|
||||
@@ -304,11 +310,26 @@ void PlaylistView::LoadHeaderState() {
|
||||
|
||||
Settings s;
|
||||
s.beginGroup(PlaylistSettings::kSettingsGroup);
|
||||
// Since we use serialized internal data structures, we cannot read anything but the current version
|
||||
const int header_state_version = s.value(PlaylistSettings::kStateVersion, 0).toInt();
|
||||
if (s.contains(PlaylistSettings::kState)) {
|
||||
header_state_version_ = s.value(PlaylistSettings::kStateVersion, 0).toInt();
|
||||
header_state_ = s.value(PlaylistSettings::kState).toByteArray();
|
||||
if (header_state_version == kHeaderStateVersion) {
|
||||
header_state_ = s.value(PlaylistSettings::kState).toByteArray();
|
||||
}
|
||||
else {
|
||||
// Force header state reset since column indices may have changed between versions
|
||||
header_state_.clear();
|
||||
}
|
||||
}
|
||||
if (s.contains(PlaylistSettings::kColumnAlignments)) {
|
||||
if (header_state_version == kHeaderStateVersion) {
|
||||
column_alignment_ = s.value(PlaylistSettings::kColumnAlignments).value<ColumnAlignmentMap>();
|
||||
}
|
||||
else {
|
||||
// Force column alignment reset since column indices may have changed between versions
|
||||
column_alignment_.clear();
|
||||
}
|
||||
}
|
||||
if (s.contains(PlaylistSettings::kColumnAlignments)) column_alignment_ = s.value(PlaylistSettings::kColumnAlignments).value<ColumnAlignmentMap>();
|
||||
s.endGroup();
|
||||
|
||||
if (column_alignment_.isEmpty()) {
|
||||
@@ -329,7 +350,6 @@ void PlaylistView::SetHeaderState() {
|
||||
void PlaylistView::ResetHeaderState() {
|
||||
|
||||
set_initial_header_layout_ = true;
|
||||
header_state_version_ = 1;
|
||||
header_state_ = header_->ResetState();
|
||||
RestoreHeaderState();
|
||||
|
||||
@@ -347,9 +367,15 @@ void PlaylistView::RestoreHeaderState() {
|
||||
|
||||
header_->SetStretchEnabled(true);
|
||||
|
||||
header_->HideSection(static_cast<int>(Playlist::Column::TitleSort));
|
||||
header_->HideSection(static_cast<int>(Playlist::Column::ArtistSort));
|
||||
header_->HideSection(static_cast<int>(Playlist::Column::AlbumSort));
|
||||
header_->HideSection(static_cast<int>(Playlist::Column::AlbumArtist));
|
||||
header_->HideSection(static_cast<int>(Playlist::Column::AlbumArtistSort));
|
||||
header_->HideSection(static_cast<int>(Playlist::Column::Performer));
|
||||
header_->HideSection(static_cast<int>(Playlist::Column::PerformerSort));
|
||||
header_->HideSection(static_cast<int>(Playlist::Column::Composer));
|
||||
header_->HideSection(static_cast<int>(Playlist::Column::ComposerSort));
|
||||
header_->HideSection(static_cast<int>(Playlist::Column::Year));
|
||||
header_->HideSection(static_cast<int>(Playlist::Column::OriginalYear));
|
||||
header_->HideSection(static_cast<int>(Playlist::Column::Disc));
|
||||
@@ -400,11 +426,6 @@ void PlaylistView::RestoreHeaderState() {
|
||||
|
||||
}
|
||||
|
||||
if (header_state_version_ < 1) {
|
||||
header_->HideSection(static_cast<int>(Playlist::Column::Rating));
|
||||
header_state_version_ = 1;
|
||||
}
|
||||
|
||||
// Make sure at least one column is visible
|
||||
bool all_hidden = true;
|
||||
for (int i = 0; i < header_->count(); ++i) {
|
||||
@@ -1305,7 +1326,7 @@ void PlaylistView::SaveSettings() {
|
||||
|
||||
Settings s;
|
||||
s.beginGroup(PlaylistSettings::kSettingsGroup);
|
||||
s.setValue(PlaylistSettings::kStateVersion, header_state_version_);
|
||||
s.setValue(PlaylistSettings::kStateVersion, kHeaderStateVersion);
|
||||
s.setValue(PlaylistSettings::kState, header_->SaveState());
|
||||
s.setValue(PlaylistSettings::kColumnAlignments, QVariant::fromValue<ColumnAlignmentMap>(column_alignment_));
|
||||
s.setValue(PlaylistSettings::kRatingLocked, rating_locked_);
|
||||
|
||||
@@ -284,7 +284,6 @@ class PlaylistView : public QTreeView {
|
||||
int drop_indicator_row_;
|
||||
bool drag_over_;
|
||||
|
||||
int header_state_version_;
|
||||
QByteArray header_state_;
|
||||
ColumnAlignmentMap column_alignment_;
|
||||
bool rating_locked_;
|
||||
|
||||
Reference in New Issue
Block a user