From 140935bd8c497f06cbf6a8e710051c5f167895c4 Mon Sep 17 00:00:00 2001 From: Jonas Kvinge Date: Mon, 5 Aug 2019 19:17:31 +0200 Subject: [PATCH] Add album - disc grouping --- src/collection/collectionfilterwidget.cpp | 16 +++- src/collection/collectionmodel.cpp | 96 ++++++++++++++++++++++- src/collection/collectionmodel.h | 8 +- src/collection/groupbydialog.cpp | 28 ++++--- src/collection/groupbydialog.ui | 72 ++++++++++++----- src/collection/savedgroupingmanager.cpp | 52 ++++++------ src/internet/internetsearchmodel.cpp | 38 ++++++--- 7 files changed, 236 insertions(+), 74 deletions(-) diff --git a/src/collection/collectionfilterwidget.cpp b/src/collection/collectionfilterwidget.cpp index efd151a72..880294658 100644 --- a/src/collection/collectionfilterwidget.cpp +++ b/src/collection/collectionfilterwidget.cpp @@ -153,11 +153,23 @@ void CollectionFilterWidget::UpdateGroupByActions() { QActionGroup *CollectionFilterWidget::CreateGroupByActions(QObject *parent) { QActionGroup *ret = new QActionGroup(parent); + ret->addAction(CreateGroupByAction(tr("Group by Album artist/Album"), parent, CollectionModel::Grouping(CollectionModel::GroupBy_AlbumArtist, CollectionModel::GroupBy_Album))); + ret->addAction(CreateGroupByAction(tr("Group by Album artist/Album - Disc"), parent, CollectionModel::Grouping(CollectionModel::GroupBy_AlbumArtist, CollectionModel::GroupBy_AlbumDisc))); + ret->addAction(CreateGroupByAction(tr("Group by Album artist/Year - Album"), parent, CollectionModel::Grouping(CollectionModel::GroupBy_AlbumArtist, CollectionModel::GroupBy_YearAlbum))); + ret->addAction(CreateGroupByAction(tr("Group by Album artist/Year - Album - Disc"), parent, CollectionModel::Grouping(CollectionModel::GroupBy_AlbumArtist, CollectionModel::GroupBy_YearAlbumDisc))); + ret->addAction(CreateGroupByAction(tr("Group by Artist/Album"), parent, CollectionModel::Grouping(CollectionModel::GroupBy_Artist, CollectionModel::GroupBy_Album))); - ret->addAction(CreateGroupByAction(tr("Group by Genre/Artist/Album"), parent, CollectionModel::Grouping(CollectionModel::GroupBy_Genre, CollectionModel::GroupBy_Artist, CollectionModel::GroupBy_Album))); - ret->addAction(CreateGroupByAction(tr("Group by Artist"), parent, CollectionModel::Grouping(CollectionModel::GroupBy_Artist))); + ret->addAction(CreateGroupByAction(tr("Group by Artist/Album - Disc"), parent, CollectionModel::Grouping(CollectionModel::GroupBy_Artist, CollectionModel::GroupBy_AlbumDisc))); ret->addAction(CreateGroupByAction(tr("Group by Artist/Year - Album"), parent, CollectionModel::Grouping(CollectionModel::GroupBy_Artist, CollectionModel::GroupBy_YearAlbum))); + ret->addAction(CreateGroupByAction(tr("Group by Artist/Year - Album - Disc"), parent, CollectionModel::Grouping(CollectionModel::GroupBy_Artist, CollectionModel::GroupBy_YearAlbumDisc))); + + ret->addAction(CreateGroupByAction(tr("Group by Genre/Album artist/Album"), parent, CollectionModel::Grouping(CollectionModel::GroupBy_Genre, CollectionModel::GroupBy_AlbumArtist, CollectionModel::GroupBy_Album))); + ret->addAction(CreateGroupByAction(tr("Group by Genre/Artist/Album"), parent, CollectionModel::Grouping(CollectionModel::GroupBy_Genre, CollectionModel::GroupBy_Artist, CollectionModel::GroupBy_Album))); + + ret->addAction(CreateGroupByAction(tr("Group by Album Artist"), parent, CollectionModel::Grouping(CollectionModel::GroupBy_AlbumArtist))); + ret->addAction(CreateGroupByAction(tr("Group by Artist"), parent, CollectionModel::Grouping(CollectionModel::GroupBy_Artist))); + ret->addAction(CreateGroupByAction(tr("Group by Album"), parent, CollectionModel::Grouping(CollectionModel::GroupBy_Album))); ret->addAction(CreateGroupByAction(tr("Group by Genre/Album"), parent, CollectionModel::Grouping(CollectionModel::GroupBy_Genre, CollectionModel::GroupBy_Album))); diff --git a/src/collection/collectionmodel.cpp b/src/collection/collectionmodel.cpp index 12f428db0..4b795e1ab 100644 --- a/src/collection/collectionmodel.cpp +++ b/src/collection/collectionmodel.cpp @@ -261,6 +261,12 @@ void CollectionModel::SongsDiscovered(const SongList &songs) { } } break; + case GroupBy_AlbumDisc: + key = PrettyAlbumDisc(song.album(), qMax(0, song.disc())); + break; + case GroupBy_YearAlbumDisc: + key = PrettyYearAlbumDisc(qMax(0, song.year()), song.album(), qMax(0, song.disc())); + break; case GroupBy_None: qLog(Error) << "GroupBy_None"; break; @@ -323,6 +329,7 @@ QString CollectionModel::DividerKey(GroupBy type, CollectionItem *item) const { case GroupBy_AlbumArtist: case GroupBy_Artist: case GroupBy_Album: + case GroupBy_AlbumDisc: case GroupBy_Composer: case GroupBy_Performer: case GroupBy_Grouping: @@ -343,6 +350,7 @@ QString CollectionModel::DividerKey(GroupBy type, CollectionItem *item) const { return SortTextForNumber(item->sort_text.toInt() / 10 * 10); case GroupBy_YearAlbum: + case GroupBy_YearAlbumDisc: return SortTextForNumber(item->metadata.year()); case GroupBy_OriginalYearAlbum: @@ -370,14 +378,15 @@ QString CollectionModel::DividerDisplayText(GroupBy type, const QString &key) co // Pretty display text for the dividers. switch (type) { - case GroupBy_Album: + case GroupBy_AlbumArtist: case GroupBy_Artist: + case GroupBy_Album: + case GroupBy_AlbumDisc: case GroupBy_Composer: case GroupBy_Performer: case GroupBy_Disc: case GroupBy_Grouping: case GroupBy_Genre: - case GroupBy_AlbumArtist: case GroupBy_FileType: case GroupBy_Format: if (key == "0") return "0-9"; @@ -385,6 +394,7 @@ QString CollectionModel::DividerDisplayText(GroupBy type, const QString &key) co case GroupBy_YearAlbum: case GroupBy_OriginalYearAlbum: + case GroupBy_YearAlbumDisc: if (key == "0000") return tr("Unknown"); return key.toUpper(); @@ -618,7 +628,11 @@ QVariant CollectionModel::data(const QModelIndex &idx, int role) const { bool is_album_node = false; if (role == Qt::DecorationRole && item->type == CollectionItem::Type_Container) { GroupBy container_type = group_by_[item->container_level]; - is_album_node = container_type == GroupBy_Album || container_type == GroupBy_YearAlbum || container_type == GroupBy_OriginalYearAlbum; + is_album_node = container_type == GroupBy_Album || + container_type == GroupBy_AlbumDisc || + container_type == GroupBy_YearAlbum || + container_type == GroupBy_YearAlbumDisc || + container_type == GroupBy_OriginalYearAlbum; } if (is_album_node) { // It has const behaviour some of the time - that's ok right? @@ -646,8 +660,10 @@ QVariant CollectionModel::data(const CollectionItem *item, int role) const { case CollectionItem::Type_Container: switch (container_type) { case GroupBy_Album: + case GroupBy_AlbumDisc: case GroupBy_YearAlbum: case GroupBy_OriginalYearAlbum: + case GroupBy_YearAlbumDisc: return album_icon_; case GroupBy_Artist: case GroupBy_AlbumArtist: @@ -916,6 +932,12 @@ void CollectionModel::InitQuery(GroupBy type, CollectionQuery *q) { case GroupBy_Format: q->SetColumnSpec("DISTINCT filetype, samplerate, bitdepth"); break; + case GroupBy_AlbumDisc: + q->SetColumnSpec("DISTINCT album, disc"); + break; + case GroupBy_YearAlbumDisc: + q->SetColumnSpec("DISTINCT year, album, disc"); + break; case GroupBy_None: q->SetColumnSpec("%songs_table.ROWID, " + Song::kColumnSpec); break; @@ -1000,6 +1022,15 @@ void CollectionModel::FilterQuery(GroupBy type, CollectionItem *item, Collection q->AddWhere("samplerate", item->metadata.samplerate()); q->AddWhere("bitdepth", item->metadata.bitdepth()); break; + case GroupBy_AlbumDisc: + q->AddWhere("album", item->metadata.album()); + q->AddWhere("disc", item->metadata.disc()); + break; + case GroupBy_YearAlbumDisc: + q->AddWhere("year", item->metadata.year()); + q->AddWhere("album", item->metadata.album()); + q->AddWhere("disc", item->metadata.disc()); + break; case GroupBy_None: qLog(Error) << "Unknown GroupBy type" << type << "used in filter"; break; @@ -1123,6 +1154,24 @@ CollectionItem *CollectionModel::ItemFromQuery(GroupBy type, bool signal, bool c item->sort_text = SortTextForNumber(bitrate) + " "; break; } + case GroupBy_AlbumDisc:{ + item->metadata.set_album(row.value(0).toString()); + item->metadata.set_disc(row.value(1).toInt()); + item->key = PrettyAlbumDisc(item->metadata.album(), item->metadata.disc()); + int disc = qMax(0, row.value(1).toInt()); + item->sort_text = item->metadata.album() + SortTextForNumber(disc); + break; + } + case GroupBy_YearAlbumDisc:{ + item->metadata.set_year(row.value(0).toInt()); + item->metadata.set_album(row.value(1).toString()); + item->metadata.set_disc(row.value(2).toInt()); + item->key = PrettyYearAlbumDisc(item->metadata.year(), item->metadata.album(), item->metadata.disc()); + int year = qMax(0, row.value(0).toInt()); + int disc = qMax(0, row.value(2).toInt()); + item->sort_text = SortTextForNumber(year) + item->metadata.album() + SortTextForNumber(disc); + break; + } case GroupBy_None: item->metadata.InitFromQuery(row, true); item->key = item->metadata.title(); @@ -1239,6 +1288,24 @@ CollectionItem *CollectionModel::ItemFromSong(GroupBy type, bool signal, bool cr } break; } + case GroupBy_AlbumDisc:{ + item->metadata.set_album(s.album()); + item->metadata.set_disc(s.disc()); + item->key = PrettyAlbumDisc(s.album(), s.disc()); + int disc = qMax(0, s.disc()); + item->sort_text = s.album() + SortTextForNumber(disc); + break; + } + case GroupBy_YearAlbumDisc:{ + item->metadata.set_year(s.year()); + item->metadata.set_album(s.album()); + item->metadata.set_disc(s.disc()); + item->key = PrettyYearAlbumDisc(s.year(), s.album(), s.disc()); + int year = qMax(0, s.year()); + int disc = qMax(0, s.disc()); + item->sort_text = SortTextForNumber(year) + s.album() + SortTextForNumber(disc); + break; + } case GroupBy_None: item->metadata = s; item->key = s.title(); @@ -1289,13 +1356,34 @@ QString CollectionModel::TextOrUnknown(const QString &text) { } -QString CollectionModel::PrettyYearAlbum(int year, const QString &album) { +QString CollectionModel::PrettyYearAlbum(const int year, const QString &album) { if (year <= 0) return TextOrUnknown(album); return QString::number(year) + " - " + TextOrUnknown(album); } +QString CollectionModel::PrettyAlbumDisc(const QString &album, const int disc) { + + if (disc <= 0) return TextOrUnknown(album); + else if (album.contains(QRegExp(Song::kAlbumRemoveDisc))) return TextOrUnknown(album); + else return TextOrUnknown(album) + " - (Disc " + QString::number(disc) + ")"; + +} + +QString CollectionModel::PrettyYearAlbumDisc(const int year, const QString &album, const int disc) { + + QString str; + + if (year <= 0) str = TextOrUnknown(album); + else str = QString::number(year) + " - " + TextOrUnknown(album); + + if (!album.contains(QRegExp(Song::kAlbumRemoveDisc)) && disc > 0) str += " - (Disc " + QString::number(disc) + ")"; + + return str; + +} + QString CollectionModel::SortText(QString text) { if (text.isEmpty()) { diff --git a/src/collection/collectionmodel.h b/src/collection/collectionmodel.h index 58bf47076..b1e0b13bc 100644 --- a/src/collection/collectionmodel.h +++ b/src/collection/collectionmodel.h @@ -100,7 +100,9 @@ class CollectionModel : public SimpleTreeModel { GroupBy_OriginalYear = 14, GroupBy_Samplerate = 15, GroupBy_Bitdepth = 16, - GroupBy_Format = 17 + GroupBy_Format = 17, + GroupBy_AlbumDisc = 18, + GroupBy_YearAlbumDisc = 19 }; struct Grouping { @@ -161,7 +163,9 @@ class CollectionModel : public SimpleTreeModel { // Utility functions for manipulating text static QString TextOrUnknown(const QString &text); - static QString PrettyYearAlbum(int year, const QString &album); + 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 SortText(QString text); static QString SortTextForNumber(int year); static QString SortTextForArtist(QString artist); diff --git a/src/collection/groupbydialog.cpp b/src/collection/groupbydialog.cpp index d5754de96..02424a519 100644 --- a/src/collection/groupbydialog.cpp +++ b/src/collection/groupbydialog.cpp @@ -85,20 +85,22 @@ GroupByDialog::GroupByDialog(QWidget *parent) : QDialog(parent), ui_(new Ui_Grou p_->mapping_.insert(Mapping(CollectionModel::GroupBy_Artist, 1)); p_->mapping_.insert(Mapping(CollectionModel::GroupBy_AlbumArtist, 2)); p_->mapping_.insert(Mapping(CollectionModel::GroupBy_Album, 3)); - p_->mapping_.insert(Mapping(CollectionModel::GroupBy_Disc, 4)); - p_->mapping_.insert(Mapping(CollectionModel::GroupBy_Format, 5)); - p_->mapping_.insert(Mapping(CollectionModel::GroupBy_Genre, 6)); - p_->mapping_.insert(Mapping(CollectionModel::GroupBy_OriginalYear, 7)); + p_->mapping_.insert(Mapping(CollectionModel::GroupBy_AlbumDisc, 4)); + p_->mapping_.insert(Mapping(CollectionModel::GroupBy_Disc, 5)); + p_->mapping_.insert(Mapping(CollectionModel::GroupBy_Format, 6)); + p_->mapping_.insert(Mapping(CollectionModel::GroupBy_Genre, 7)); p_->mapping_.insert(Mapping(CollectionModel::GroupBy_Year, 8)); - p_->mapping_.insert(Mapping(CollectionModel::GroupBy_OriginalYearAlbum, 9)); - p_->mapping_.insert(Mapping(CollectionModel::GroupBy_YearAlbum, 10)); - p_->mapping_.insert(Mapping(CollectionModel::GroupBy_Composer, 11)); - p_->mapping_.insert(Mapping(CollectionModel::GroupBy_Performer, 12)); - p_->mapping_.insert(Mapping(CollectionModel::GroupBy_Grouping, 13)); - p_->mapping_.insert(Mapping(CollectionModel::GroupBy_FileType, 14)); - p_->mapping_.insert(Mapping(CollectionModel::GroupBy_Samplerate, 15)); - p_->mapping_.insert(Mapping(CollectionModel::GroupBy_Bitdepth, 16)); - p_->mapping_.insert(Mapping(CollectionModel::GroupBy_Bitrate, 17)); + p_->mapping_.insert(Mapping(CollectionModel::GroupBy_YearAlbum, 9)); + p_->mapping_.insert(Mapping(CollectionModel::GroupBy_YearAlbumDisc, 10)); + p_->mapping_.insert(Mapping(CollectionModel::GroupBy_OriginalYear, 11)); + p_->mapping_.insert(Mapping(CollectionModel::GroupBy_OriginalYearAlbum, 12)); + p_->mapping_.insert(Mapping(CollectionModel::GroupBy_Composer, 13)); + p_->mapping_.insert(Mapping(CollectionModel::GroupBy_Performer, 14)); + p_->mapping_.insert(Mapping(CollectionModel::GroupBy_Grouping, 15)); + p_->mapping_.insert(Mapping(CollectionModel::GroupBy_FileType, 16)); + p_->mapping_.insert(Mapping(CollectionModel::GroupBy_Samplerate, 17)); + p_->mapping_.insert(Mapping(CollectionModel::GroupBy_Bitdepth, 18)); + p_->mapping_.insert(Mapping(CollectionModel::GroupBy_Bitrate, 19)); connect(ui_->buttonbox->button(QDialogButtonBox::Reset), SIGNAL(clicked()), SLOT(Reset())); diff --git a/src/collection/groupbydialog.ui b/src/collection/groupbydialog.ui index 04479218c..00e1941b7 100644 --- a/src/collection/groupbydialog.ui +++ b/src/collection/groupbydialog.ui @@ -63,6 +63,11 @@ Album + + + Album - Disc + + Disc @@ -78,11 +83,6 @@ Genre - - - Original year - - Year @@ -90,12 +90,22 @@ - Original year - Album + Year - Album - Year - Album + Year - Album - Disc + + + + + Original year + + + + + Original year - Album @@ -164,6 +174,11 @@ Album + + + Album - Disc + + Disc @@ -179,11 +194,6 @@ Genre - - - Original year - - Year @@ -191,12 +201,22 @@ - Original year - Album + Year - Album - Year - Album + Year - Album - Disc + + + + + Original year + + + + + Original year - Album @@ -265,6 +285,11 @@ Album + + + Album - Disc + + Disc @@ -280,11 +305,6 @@ Genre - - - Original year - - Year @@ -292,12 +312,22 @@ - Original year - Album + Year - Album - Year - Album + Year - Album - Disc + + + + + Original year + + + + + Original year - Album diff --git a/src/collection/savedgroupingmanager.cpp b/src/collection/savedgroupingmanager.cpp index 599490e79..1e2bd59fb 100644 --- a/src/collection/savedgroupingmanager.cpp +++ b/src/collection/savedgroupingmanager.cpp @@ -77,29 +77,44 @@ QString SavedGroupingManager::GroupByToString(const CollectionModel::GroupBy &g) case CollectionModel::GroupBy_None: { return tr("None"); } - case CollectionModel::GroupBy_AlbumArtist: { - return tr("Album artist"); - } case CollectionModel::GroupBy_Artist: { return tr("Artist"); } + case CollectionModel::GroupBy_AlbumArtist: { + return tr("Album artist"); + } case CollectionModel::GroupBy_Album: { return tr("Album"); } - case CollectionModel::GroupBy_YearAlbum: { - return tr("Year - Album"); + case CollectionModel::GroupBy_AlbumDisc: { + return tr("Album - Disc"); } - case CollectionModel::GroupBy_Year: { - return tr("Year"); + case CollectionModel::GroupBy_Disc: { + return tr("Disc"); } - case CollectionModel::GroupBy_Composer: { - return tr("Composer"); + case CollectionModel::GroupBy_Format: { + return tr("Format"); } case CollectionModel::GroupBy_Genre: { return tr("Genre"); } - case CollectionModel::GroupBy_FileType: { - return tr("File type"); + case CollectionModel::GroupBy_Year: { + return tr("Year"); + } + case CollectionModel::GroupBy_YearAlbum: { + return tr("Year - Album"); + } + case CollectionModel::GroupBy_YearAlbumDisc: { + return tr("Year - Album - Disc"); + } + case CollectionModel::GroupBy_OriginalYear: { + return tr("Original year"); + } + case CollectionModel::GroupBy_OriginalYearAlbum: { + return tr("Original year - Album"); + } + case CollectionModel::GroupBy_Composer: { + return tr("Composer"); } case CollectionModel::GroupBy_Performer: { return tr("Performer"); @@ -107,6 +122,9 @@ QString SavedGroupingManager::GroupByToString(const CollectionModel::GroupBy &g) case CollectionModel::GroupBy_Grouping: { return tr("Grouping"); } + case CollectionModel::GroupBy_FileType: { + return tr("File type"); + } case CollectionModel::GroupBy_Samplerate: { return tr("Sample rate"); } @@ -116,18 +134,6 @@ QString SavedGroupingManager::GroupByToString(const CollectionModel::GroupBy &g) case CollectionModel::GroupBy_Bitrate: { return tr("Bitrate"); } - case CollectionModel::GroupBy_Disc: { - return tr("Disc"); - } - case CollectionModel::GroupBy_OriginalYearAlbum: { - return tr("Original year - Album"); - } - case CollectionModel::GroupBy_OriginalYear: { - return tr("Original year"); - } - case CollectionModel::GroupBy_Format: { - return tr("Format"); - } default: { return tr("Unknown"); } } diff --git a/src/internet/internetsearchmodel.cpp b/src/internet/internetsearchmodel.cpp index 4fdd6f1ee..327623547 100644 --- a/src/internet/internetsearchmodel.cpp +++ b/src/internet/internetsearchmodel.cpp @@ -86,7 +86,6 @@ QStandardItem *InternetSearchModel::BuildContainers(const Song &s, QStandardItem QString display_text; QString sort_text; QString unique_tag; - int year = 0; switch (group_by_[level]) { @@ -114,33 +113,37 @@ QStandardItem *InternetSearchModel::BuildContainers(const Song &s, QStandardItem has_artist_icon = true; break; - case CollectionModel::GroupBy_YearAlbum: - year = qMax(0, s.year()); + case CollectionModel::GroupBy_YearAlbum:{ + int year = qMax(0, s.year()); display_text = CollectionModel::PrettyYearAlbum(year, s.album()); sort_text = CollectionModel::SortTextForNumber(year) + s.album(); unique_tag = s.album_id(); has_album_icon = true; break; + } - case CollectionModel::GroupBy_OriginalYearAlbum: - year = qMax(0, s.effective_originalyear()); + case CollectionModel::GroupBy_OriginalYearAlbum:{ + int year = qMax(0, s.effective_originalyear()); display_text = CollectionModel::PrettyYearAlbum(year, s.album()); sort_text = CollectionModel::SortTextForNumber(year) + s.album(); unique_tag = s.album_id(); has_album_icon = true; break; + } - case CollectionModel::GroupBy_Year: - year = qMax(0, s.year()); + case CollectionModel::GroupBy_Year:{ + int year = qMax(0, s.year()); display_text = QString::number(year); sort_text = CollectionModel::SortTextForNumber(year) + " "; break; + } - case CollectionModel::GroupBy_OriginalYear: - year = qMax(0, s.effective_originalyear()); + case CollectionModel::GroupBy_OriginalYear:{ + int year = qMax(0, s.effective_originalyear()); display_text = QString::number(year); sort_text = CollectionModel::SortTextForNumber(year) + " "; break; + } case CollectionModel::GroupBy_Composer: display_text = CollectionModel::TextOrUnknown(s.composer()); @@ -214,6 +217,23 @@ QStandardItem *InternetSearchModel::BuildContainers(const Song &s, QStandardItem sort_text = display_text; break; + case CollectionModel::GroupBy_AlbumDisc:{ + int disc = qMax(0, s.disc()); + display_text = CollectionModel::PrettyAlbumDisc(s.album(), disc); + sort_text = s.album() + CollectionModel::SortTextForNumber(disc); + 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()); + display_text = CollectionModel::PrettyYearAlbumDisc(year, s.album(), disc); + sort_text = CollectionModel::SortTextForNumber(year) + s.album() + CollectionModel::SortTextForNumber(disc); + unique_tag = s.album_id(); + has_album_icon = true; + break; + } case CollectionModel::GroupBy_None: return parent; }