mirror of
https://github.com/strawberrymusicplayer/strawberry
synced 2025-01-31 09:44:50 +01:00
CollectionModel: Make separating albums by grouping optional
Fixes #1018
This commit is contained in:
parent
c219995218
commit
6562258db5
@ -2,6 +2,7 @@
|
||||
* Strawberry Music Player
|
||||
* This file was part of Clementine.
|
||||
* Copyright 2010, David Sansome <me@davidsansome.com>
|
||||
* Copyright 2019-2022, 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
|
||||
@ -58,7 +59,12 @@ CollectionFilterWidget::CollectionFilterWidget(QWidget *parent)
|
||||
: QWidget(parent),
|
||||
ui_(new Ui_CollectionFilterWidget),
|
||||
model_(nullptr),
|
||||
group_by_dialog_(new GroupByDialog),
|
||||
group_by_dialog_(new GroupByDialog(this)),
|
||||
groupings_manager_(nullptr),
|
||||
filter_age_menu_(nullptr),
|
||||
group_by_menu_(nullptr),
|
||||
collection_menu_(nullptr),
|
||||
group_by_group_(nullptr),
|
||||
filter_delay_(new QTimer(this)),
|
||||
filter_applies_to_model_(true),
|
||||
delay_behaviour_(DelayedOnLargeLibraries) {
|
||||
@ -114,13 +120,8 @@ CollectionFilterWidget::CollectionFilterWidget(QWidget *parent)
|
||||
filter_ages_[ui_->filter_age_three_months] = 60 * 60 * 24 * 30 * 3;
|
||||
filter_ages_[ui_->filter_age_year] = 60 * 60 * 24 * 365;
|
||||
|
||||
// "Group by ..."
|
||||
group_by_group_ = CreateGroupByActions(this);
|
||||
|
||||
group_by_menu_ = new QMenu(tr("Group by"), this);
|
||||
group_by_menu_->addActions(group_by_group_->actions());
|
||||
|
||||
QObject::connect(group_by_group_, &QActionGroup::triggered, this, &CollectionFilterWidget::GroupByClicked);
|
||||
QObject::connect(ui_->save_grouping, &QAction::triggered, this, &CollectionFilterWidget::SaveGroupBy);
|
||||
QObject::connect(ui_->manage_groupings, &QAction::triggered, this, &CollectionFilterWidget::ShowGroupingManager);
|
||||
|
||||
@ -147,8 +148,8 @@ void CollectionFilterWidget::Init(CollectionModel *model) {
|
||||
|
||||
if (model_) {
|
||||
QObject::disconnect(model_, nullptr, this, nullptr);
|
||||
QObject::disconnect(model_, nullptr, group_by_dialog_.get(), nullptr);
|
||||
QObject::disconnect(group_by_dialog_.get(), nullptr, model_, nullptr);
|
||||
QObject::disconnect(model_, nullptr, group_by_dialog_, nullptr);
|
||||
QObject::disconnect(group_by_dialog_, nullptr, model_, nullptr);
|
||||
QList<QAction*> filter_ages = filter_ages_.keys();
|
||||
for (QAction *action : filter_ages) {
|
||||
QObject::disconnect(action, &QAction::triggered, model_, nullptr);
|
||||
@ -158,9 +159,9 @@ void CollectionFilterWidget::Init(CollectionModel *model) {
|
||||
model_ = model;
|
||||
|
||||
// Connect signals
|
||||
QObject::connect(model_, &CollectionModel::GroupingChanged, group_by_dialog_.get(), &GroupByDialog::CollectionGroupingChanged);
|
||||
QObject::connect(model_, &CollectionModel::GroupingChanged, group_by_dialog_, &GroupByDialog::CollectionGroupingChanged);
|
||||
QObject::connect(model_, &CollectionModel::GroupingChanged, this, &CollectionFilterWidget::GroupingChanged);
|
||||
QObject::connect(group_by_dialog_.get(), &GroupByDialog::Accepted, model_, &CollectionModel::SetGroupBy);
|
||||
QObject::connect(group_by_dialog_, &GroupByDialog::Accepted, model_, &CollectionModel::SetGroupBy);
|
||||
|
||||
QList<QAction*> filter_ages = filter_ages_.keys();
|
||||
for (QAction *action : filter_ages) {
|
||||
@ -176,15 +177,31 @@ void CollectionFilterWidget::Init(CollectionModel *model) {
|
||||
if (s.contains(group_by_version())) version = s.value(group_by_version(), 0).toInt();
|
||||
if (version == 1) {
|
||||
model_->SetGroupBy(CollectionModel::Grouping(
|
||||
CollectionModel::GroupBy(s.value(group_by(1), static_cast<int>(CollectionModel::GroupBy_AlbumArtist)).toInt()),
|
||||
CollectionModel::GroupBy(s.value(group_by(2), static_cast<int>(CollectionModel::GroupBy_AlbumDisc)).toInt()),
|
||||
CollectionModel::GroupBy(s.value(group_by(3), static_cast<int>(CollectionModel::GroupBy_None)).toInt())));
|
||||
CollectionModel::GroupBy(s.value(group_by_key(1), static_cast<int>(CollectionModel::GroupBy_AlbumArtist)).toInt()),
|
||||
CollectionModel::GroupBy(s.value(group_by_key(2), static_cast<int>(CollectionModel::GroupBy_AlbumDisc)).toInt()),
|
||||
CollectionModel::GroupBy(s.value(group_by_key(3), static_cast<int>(CollectionModel::GroupBy_None)).toInt())), s.value(separate_albums_by_grouping_key(), false).toBool());
|
||||
}
|
||||
else {
|
||||
model_->SetGroupBy(CollectionModel::Grouping(CollectionModel::GroupBy_AlbumArtist, CollectionModel::GroupBy_AlbumDisc, CollectionModel::GroupBy_None));
|
||||
model_->SetGroupBy(CollectionModel::Grouping(CollectionModel::GroupBy_AlbumArtist, CollectionModel::GroupBy_AlbumDisc, CollectionModel::GroupBy_None), false);
|
||||
}
|
||||
s.endGroup();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void CollectionFilterWidget::SetSettingsGroup(const QString &settings_group) {
|
||||
|
||||
settings_group_ = settings_group;
|
||||
saved_groupings_settings_group_ = SavedGroupingManager::GetSavedGroupingsSettingsGroup(settings_group);
|
||||
|
||||
UpdateGroupByActions();
|
||||
|
||||
}
|
||||
|
||||
void CollectionFilterWidget::SetSettingsPrefix(const QString &prefix) {
|
||||
|
||||
settings_prefix_ = prefix;
|
||||
|
||||
}
|
||||
|
||||
void CollectionFilterWidget::ReloadSettings() {
|
||||
@ -198,21 +215,10 @@ void CollectionFilterWidget::ReloadSettings() {
|
||||
|
||||
}
|
||||
|
||||
QString CollectionFilterWidget::group_by() {
|
||||
QString CollectionFilterWidget::group_by_version() const {
|
||||
|
||||
if (settings_prefix_.isEmpty()) {
|
||||
return QString("group_by");
|
||||
}
|
||||
else {
|
||||
return QString("%1_group_by").arg(settings_prefix_);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
QString CollectionFilterWidget::group_by_version() {
|
||||
|
||||
if (settings_prefix_.isEmpty()) {
|
||||
return QString("group_by_version");
|
||||
return "group_by_version";
|
||||
}
|
||||
else {
|
||||
return QString("%1_group_by_version").arg(settings_prefix_);
|
||||
@ -220,7 +226,29 @@ QString CollectionFilterWidget::group_by_version() {
|
||||
|
||||
}
|
||||
|
||||
QString CollectionFilterWidget::group_by(const int number) { return group_by() + QString::number(number); }
|
||||
QString CollectionFilterWidget::group_by_key() const {
|
||||
|
||||
if (settings_prefix_.isEmpty()) {
|
||||
return "group_by";
|
||||
}
|
||||
else {
|
||||
return QString("%1_group_by").arg(settings_prefix_);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
QString CollectionFilterWidget::group_by_key(const int number) const { return group_by_key() + QString::number(number); }
|
||||
|
||||
QString CollectionFilterWidget::separate_albums_by_grouping_key() const {
|
||||
|
||||
if (settings_prefix_.isEmpty()) {
|
||||
return "separate_albums_by_grouping";
|
||||
}
|
||||
else {
|
||||
return QString("%1_separate_albums_by_grouping").arg(settings_prefix_);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void CollectionFilterWidget::UpdateGroupByActions() {
|
||||
|
||||
@ -229,7 +257,7 @@ void CollectionFilterWidget::UpdateGroupByActions() {
|
||||
delete group_by_group_;
|
||||
}
|
||||
|
||||
group_by_group_ = CreateGroupByActions(this);
|
||||
group_by_group_ = CreateGroupByActions(saved_groupings_settings_group_, this);
|
||||
group_by_menu_->clear();
|
||||
group_by_menu_->addActions(group_by_group_->actions());
|
||||
QObject::connect(group_by_group_, &QActionGroup::triggered, this, &CollectionFilterWidget::GroupByClicked);
|
||||
@ -239,8 +267,7 @@ void CollectionFilterWidget::UpdateGroupByActions() {
|
||||
|
||||
}
|
||||
|
||||
|
||||
QActionGroup *CollectionFilterWidget::CreateGroupByActions(QObject *parent) {
|
||||
QActionGroup *CollectionFilterWidget::CreateGroupByActions(const QString &saved_groupings_settings_group, QObject *parent) {
|
||||
|
||||
QActionGroup *ret = new QActionGroup(parent);
|
||||
|
||||
@ -267,9 +294,9 @@ QActionGroup *CollectionFilterWidget::CreateGroupByActions(QObject *parent) {
|
||||
sep1->setSeparator(true);
|
||||
ret->addAction(sep1);
|
||||
|
||||
// read saved groupings
|
||||
// Read saved groupings
|
||||
QSettings s;
|
||||
s.beginGroup(CollectionModel::kSavedGroupingsSettingsGroup);
|
||||
s.beginGroup(saved_groupings_settings_group);
|
||||
int version = s.value("version").toInt();
|
||||
if (version == 1) {
|
||||
QStringList saved = s.childKeys();
|
||||
@ -316,20 +343,38 @@ QAction *CollectionFilterWidget::CreateGroupByAction(const QString &text, QObjec
|
||||
|
||||
void CollectionFilterWidget::SaveGroupBy() {
|
||||
|
||||
QString text = QInputDialog::getText(this, tr("Grouping Name"), tr("Grouping name:"));
|
||||
if (!text.isEmpty() && model_) {
|
||||
model_->SaveGrouping(text);
|
||||
UpdateGroupByActions();
|
||||
if (!model_) return;
|
||||
|
||||
QString name = QInputDialog::getText(this, tr("Grouping Name"), tr("Grouping name:"));
|
||||
if (name.isEmpty()) return;
|
||||
|
||||
qLog(Debug) << "Saving current grouping to" << name;
|
||||
|
||||
QSettings s;
|
||||
if (settings_group_.isEmpty() || settings_group_ == CollectionSettingsPage::kSettingsGroup) {
|
||||
s.beginGroup(SavedGroupingManager::kSavedGroupingsSettingsGroup);
|
||||
}
|
||||
else {
|
||||
s.beginGroup(QString(SavedGroupingManager::kSavedGroupingsSettingsGroup) + "_" + settings_group_);
|
||||
}
|
||||
QByteArray buffer;
|
||||
QDataStream datastream(&buffer, QIODevice::WriteOnly);
|
||||
datastream << model_->GetGroupBy();
|
||||
s.setValue("version", "1");
|
||||
s.setValue(name, buffer);
|
||||
s.endGroup();
|
||||
|
||||
UpdateGroupByActions();
|
||||
|
||||
}
|
||||
|
||||
void CollectionFilterWidget::ShowGroupingManager() {
|
||||
|
||||
if (!groupings_manager_) {
|
||||
groupings_manager_ = std::make_unique<SavedGroupingManager>();
|
||||
groupings_manager_ = new SavedGroupingManager(saved_groupings_settings_group_, this);
|
||||
QObject::connect(groupings_manager_, &SavedGroupingManager::UpdateGroupByActions, this, &CollectionFilterWidget::UpdateGroupByActions);
|
||||
}
|
||||
groupings_manager_->SetFilter(this);
|
||||
|
||||
groupings_manager_->UpdateModel();
|
||||
groupings_manager_->show();
|
||||
|
||||
@ -362,20 +407,20 @@ void CollectionFilterWidget::GroupByClicked(QAction *action) {
|
||||
}
|
||||
|
||||
CollectionModel::Grouping g = action->property("group_by").value<CollectionModel::Grouping>();
|
||||
model_->SetGroupBy(g);
|
||||
model_->SetGroupBy(g, false);
|
||||
|
||||
}
|
||||
|
||||
void CollectionFilterWidget::GroupingChanged(const CollectionModel::Grouping g) {
|
||||
void CollectionFilterWidget::GroupingChanged(const CollectionModel::Grouping g, const bool separate_albums_by_grouping) {
|
||||
|
||||
if (!settings_group_.isEmpty()) {
|
||||
// Save the settings
|
||||
QSettings s;
|
||||
s.beginGroup(settings_group_);
|
||||
s.setValue(group_by_version(), 1);
|
||||
s.setValue(group_by(1), static_cast<int>(g[0]));
|
||||
s.setValue(group_by(2), static_cast<int>(g[1]));
|
||||
s.setValue(group_by(3), static_cast<int>(g[2]));
|
||||
s.setValue(group_by_key(1), static_cast<int>(g[0]));
|
||||
s.setValue(group_by_key(2), static_cast<int>(g[1]));
|
||||
s.setValue(group_by_key(3), static_cast<int>(g[2]));
|
||||
s.setValue(separate_albums_by_grouping_key(), separate_albums_by_grouping);
|
||||
s.endGroup();
|
||||
}
|
||||
|
||||
@ -386,6 +431,10 @@ void CollectionFilterWidget::GroupingChanged(const CollectionModel::Grouping g)
|
||||
|
||||
void CollectionFilterWidget::CheckCurrentGrouping(const CollectionModel::Grouping g) {
|
||||
|
||||
if (!group_by_group_) {
|
||||
UpdateGroupByActions();
|
||||
}
|
||||
|
||||
for (QAction *action : group_by_group_->actions()) {
|
||||
if (action->property("group_by").isNull()) continue;
|
||||
|
||||
|
@ -2,6 +2,7 @@
|
||||
* Strawberry Music Player
|
||||
* This file was part of Clementine.
|
||||
* Copyright 2010, David Sansome <me@davidsansome.com>
|
||||
* Copyright 2019-2022, 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
|
||||
@ -60,9 +61,8 @@ class CollectionFilterWidget : public QWidget {
|
||||
|
||||
void Init(CollectionModel *model);
|
||||
|
||||
static QActionGroup *CreateGroupByActions(QObject *parent);
|
||||
static QActionGroup *CreateGroupByActions(const QString &saved_groupings_settings_group, QObject *parent);
|
||||
|
||||
void UpdateGroupByActions();
|
||||
void SetFilterHint(const QString &hint);
|
||||
void SetApplyFilterToCollection(bool filter_applies_to_model) { filter_applies_to_model_ = filter_applies_to_model; }
|
||||
void SetDelayBehaviour(DelayBehaviour behaviour) { delay_behaviour_ = behaviour; }
|
||||
@ -73,12 +73,13 @@ class CollectionFilterWidget : public QWidget {
|
||||
QMenu *menu() const { return collection_menu_; }
|
||||
void AddMenuAction(QAction *action);
|
||||
|
||||
void SetSettingsGroup(const QString &group) { settings_group_ = group; }
|
||||
void SetSettingsPrefix(const QString &prefix) { settings_prefix_ = prefix; }
|
||||
void SetSettingsGroup(const QString &group);
|
||||
void SetSettingsPrefix(const QString &prefix);
|
||||
|
||||
QString group_by();
|
||||
QString group_by_version();
|
||||
QString group_by(const int number);
|
||||
QString group_by_version() const;
|
||||
QString group_by_key() const;
|
||||
QString group_by_key(const int number) const;
|
||||
QString separate_albums_by_grouping_key() const;
|
||||
|
||||
void ReloadSettings();
|
||||
|
||||
@ -86,6 +87,7 @@ class CollectionFilterWidget : public QWidget {
|
||||
void FocusSearchField();
|
||||
|
||||
public slots:
|
||||
void UpdateGroupByActions();
|
||||
void SetQueryMode(QueryOptions::QueryMode query_mode);
|
||||
void FocusOnFilter(QKeyEvent *e);
|
||||
|
||||
@ -99,7 +101,7 @@ class CollectionFilterWidget : public QWidget {
|
||||
void keyReleaseEvent(QKeyEvent *e) override;
|
||||
|
||||
private slots:
|
||||
void GroupingChanged(const CollectionModel::Grouping g);
|
||||
void GroupingChanged(const CollectionModel::Grouping g, const bool separate_albums_by_grouping);
|
||||
void GroupByClicked(QAction *action);
|
||||
void SaveGroupBy();
|
||||
void ShowGroupingManager();
|
||||
@ -115,8 +117,8 @@ class CollectionFilterWidget : public QWidget {
|
||||
Ui_CollectionFilterWidget *ui_;
|
||||
CollectionModel *model_;
|
||||
|
||||
std::unique_ptr<GroupByDialog> group_by_dialog_;
|
||||
std::unique_ptr<SavedGroupingManager> groupings_manager_;
|
||||
GroupByDialog *group_by_dialog_;
|
||||
SavedGroupingManager *groupings_manager_;
|
||||
|
||||
QMenu *filter_age_menu_;
|
||||
QMenu *group_by_menu_;
|
||||
@ -130,6 +132,7 @@ class CollectionFilterWidget : public QWidget {
|
||||
DelayBehaviour delay_behaviour_;
|
||||
|
||||
QString settings_group_;
|
||||
QString saved_groupings_settings_group_;
|
||||
QString settings_prefix_;
|
||||
|
||||
};
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include <functional>
|
||||
#include <algorithm>
|
||||
#include <utility>
|
||||
#include <optional>
|
||||
|
||||
#include <QObject>
|
||||
#include <QtGlobal>
|
||||
@ -71,7 +72,6 @@
|
||||
#include "covermanager/albumcoverloaderresult.h"
|
||||
#include "settings/collectionsettingspage.h"
|
||||
|
||||
const char *CollectionModel::kSavedGroupingsSettingsGroup = "SavedGroupings";
|
||||
const int CollectionModel::kPrettyCoverSize = 32;
|
||||
const char *CollectionModel::kPixmapDiskCacheDir = "pixmapcache";
|
||||
|
||||
@ -86,6 +86,7 @@ CollectionModel::CollectionModel(CollectionBackend *backend, Application *app, Q
|
||||
total_song_count_(0),
|
||||
total_artist_count_(0),
|
||||
total_album_count_(0),
|
||||
separate_albums_by_grouping_(false),
|
||||
artist_icon_(IconLoader::Load("folder-sound")),
|
||||
album_icon_(IconLoader::Load("cdcase")),
|
||||
init_task_id_(-1),
|
||||
@ -160,22 +161,6 @@ void CollectionModel::set_show_dividers(const bool show_dividers) {
|
||||
|
||||
}
|
||||
|
||||
void CollectionModel::SaveGrouping(const QString &name) {
|
||||
|
||||
qLog(Debug) << "Model, save to: " << name;
|
||||
|
||||
QByteArray buffer;
|
||||
QDataStream ds(&buffer, QIODevice::WriteOnly);
|
||||
ds << group_by_;
|
||||
|
||||
QSettings s;
|
||||
s.beginGroup(kSavedGroupingsSettingsGroup);
|
||||
s.setValue("version", "1");
|
||||
s.setValue(name, buffer);
|
||||
s.endGroup();
|
||||
|
||||
}
|
||||
|
||||
void CollectionModel::ReloadSettings() {
|
||||
|
||||
QSettings s;
|
||||
@ -239,13 +224,13 @@ void CollectionModel::SongsDiscovered(const SongList &songs) {
|
||||
CollectionItem *container = root_;
|
||||
QString key;
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
GroupBy type = group_by_[i];
|
||||
if (type == GroupBy_None) break;
|
||||
GroupBy group_by = group_by_[i];
|
||||
if (group_by == GroupBy_None) break;
|
||||
|
||||
if (!key.isEmpty()) key.append("-");
|
||||
|
||||
// Special case: if the song is a compilation and the current GroupBy level is Artists, then we want the Various Artists node :(
|
||||
if (IsArtistGroupBy(type) && song.is_compilation()) {
|
||||
if (IsArtistGroupBy(group_by) && song.is_compilation()) {
|
||||
if (container->compilation_artist_node_ == nullptr) {
|
||||
CreateCompilationArtistNode(true, container);
|
||||
}
|
||||
@ -254,7 +239,7 @@ void CollectionModel::SongsDiscovered(const SongList &songs) {
|
||||
}
|
||||
else {
|
||||
// Otherwise find the proper container at this level based on the item's key
|
||||
key.append(ContainerKey(type, song));
|
||||
key.append(ContainerKey(group_by, separate_albums_by_grouping_, song));
|
||||
|
||||
// Does it exist already?
|
||||
if (container_nodes_[i].contains(key)) {
|
||||
@ -262,7 +247,7 @@ void CollectionModel::SongsDiscovered(const SongList &songs) {
|
||||
}
|
||||
else {
|
||||
// Create the container
|
||||
container = ItemFromSong(type, true, i == 0, container, song, i);
|
||||
container = ItemFromSong(group_by, separate_albums_by_grouping_, true, i == 0, container, song, i);
|
||||
container_nodes_[i].insert(key, container);
|
||||
}
|
||||
|
||||
@ -274,7 +259,7 @@ void CollectionModel::SongsDiscovered(const SongList &songs) {
|
||||
if (!container->lazy_loaded && use_lazy_loading_) continue;
|
||||
|
||||
// We've gone all the way down to the deepest level and everything was already lazy loaded, so now we have to create the song in the container.
|
||||
song_nodes_.insert(song.id(), ItemFromSong(GroupBy_None, true, false, container, song, -1));
|
||||
song_nodes_.insert(song.id(), ItemFromSong(GroupBy_None, separate_albums_by_grouping_, true, false, container, song, -1));
|
||||
}
|
||||
|
||||
}
|
||||
@ -311,11 +296,11 @@ CollectionItem *CollectionModel::CreateCompilationArtistNode(const bool signal,
|
||||
|
||||
}
|
||||
|
||||
QString CollectionModel::ContainerKey(const GroupBy type, const Song &song) {
|
||||
QString CollectionModel::ContainerKey(const GroupBy group_by, const bool separate_albums_by_grouping, const Song &song) {
|
||||
|
||||
QString key;
|
||||
|
||||
switch (type) {
|
||||
switch (group_by) {
|
||||
case GroupBy_AlbumArtist:
|
||||
key = TextOrUnknown(song.effective_albumartist());
|
||||
break;
|
||||
@ -325,32 +310,32 @@ QString CollectionModel::ContainerKey(const GroupBy type, const Song &song) {
|
||||
case GroupBy_Album:
|
||||
key = TextOrUnknown(song.album());
|
||||
if (!song.album_id().isEmpty()) key.append("-" + song.album_id());
|
||||
if (!song.grouping().isEmpty()) key.append("-" + song.grouping());
|
||||
if (separate_albums_by_grouping && !song.grouping().isEmpty()) key.append("-" + song.grouping());
|
||||
break;
|
||||
case GroupBy_AlbumDisc:
|
||||
key = PrettyAlbumDisc(song.album(), song.disc());
|
||||
if (!song.album_id().isEmpty()) key.append("-" + song.album_id());
|
||||
if (!song.grouping().isEmpty()) key.append("-" + song.grouping());
|
||||
if (separate_albums_by_grouping && !song.grouping().isEmpty()) key.append("-" + song.grouping());
|
||||
break;
|
||||
case GroupBy_YearAlbum:
|
||||
key = PrettyYearAlbum(song.year(), song.album());
|
||||
if (!song.album_id().isEmpty()) key.append("-" + song.album_id());
|
||||
if (!song.grouping().isEmpty()) key.append("-" + song.grouping());
|
||||
if (separate_albums_by_grouping && !song.grouping().isEmpty()) key.append("-" + song.grouping());
|
||||
break;
|
||||
case GroupBy_YearAlbumDisc:
|
||||
key = PrettyYearAlbumDisc(song.year(), song.album(), song.disc());
|
||||
if (!song.album_id().isEmpty()) key.append("-" + song.album_id());
|
||||
if (!song.grouping().isEmpty()) key.append("-" + song.grouping());
|
||||
if (separate_albums_by_grouping && !song.grouping().isEmpty()) key.append("-" + song.grouping());
|
||||
break;
|
||||
case GroupBy_OriginalYearAlbum:
|
||||
key = PrettyYearAlbum(song.effective_originalyear(), song.album());
|
||||
if (!song.album_id().isEmpty()) key.append("-" + song.album_id());
|
||||
if (!song.grouping().isEmpty()) key.append("-" + song.grouping());
|
||||
if (separate_albums_by_grouping && !song.grouping().isEmpty()) key.append("-" + song.grouping());
|
||||
break;
|
||||
case GroupBy_OriginalYearAlbumDisc:
|
||||
key = PrettyYearAlbumDisc(song.effective_originalyear(), song.album(), song.disc());
|
||||
if (!song.album_id().isEmpty()) key.append("-" + song.album_id());
|
||||
if (!song.grouping().isEmpty()) key.append("-" + song.grouping());
|
||||
if (separate_albums_by_grouping && !song.grouping().isEmpty()) key.append("-" + song.grouping());
|
||||
break;
|
||||
case GroupBy_Disc:
|
||||
key = PrettyDisc(song.disc());
|
||||
@ -408,13 +393,13 @@ QString CollectionModel::ContainerKey(const GroupBy type, const Song &song) {
|
||||
|
||||
}
|
||||
|
||||
QString CollectionModel::DividerKey(const GroupBy type, CollectionItem *item) {
|
||||
QString CollectionModel::DividerKey(const GroupBy group_by, CollectionItem *item) {
|
||||
|
||||
// Items which are to be grouped under the same divider must produce the same divider key. This will only get called for top-level items.
|
||||
|
||||
if (item->sort_text.isEmpty()) return QString();
|
||||
|
||||
switch (type) {
|
||||
switch (group_by) {
|
||||
case GroupBy_AlbumArtist:
|
||||
case GroupBy_Artist:
|
||||
case GroupBy_Album:
|
||||
@ -461,16 +446,16 @@ QString CollectionModel::DividerKey(const GroupBy type, CollectionItem *item) {
|
||||
case GroupByCount:
|
||||
return QString();
|
||||
}
|
||||
qLog(Error) << "Unknown GroupBy type" << type << "for item" << item->display_text;
|
||||
qLog(Error) << "Unknown GroupBy" << group_by << "for item" << item->display_text;
|
||||
return QString();
|
||||
|
||||
}
|
||||
|
||||
QString CollectionModel::DividerDisplayText(const GroupBy type, const QString &key) {
|
||||
QString CollectionModel::DividerDisplayText(const GroupBy group_by, const QString &key) {
|
||||
|
||||
// Pretty display text for the dividers.
|
||||
|
||||
switch (type) {
|
||||
switch (group_by) {
|
||||
case GroupBy_AlbumArtist:
|
||||
case GroupBy_Artist:
|
||||
case GroupBy_Album:
|
||||
@ -513,7 +498,7 @@ QString CollectionModel::DividerDisplayText(const GroupBy type, const QString &k
|
||||
case GroupByCount:
|
||||
break;
|
||||
}
|
||||
qLog(Error) << "Unknown GroupBy type" << type << "for divider key" << key;
|
||||
qLog(Error) << "Unknown GroupBy" << group_by << "for divider key" << key;
|
||||
return QString();
|
||||
|
||||
}
|
||||
@ -726,8 +711,8 @@ QVariant CollectionModel::data(const QModelIndex &idx, const int role) const {
|
||||
if (use_pretty_covers_) {
|
||||
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 = IsAlbumGroupBy(container_type);
|
||||
GroupBy container_group_by = group_by_[item->container_level];
|
||||
is_album_node = IsAlbumGroupBy(container_group_by);
|
||||
}
|
||||
if (is_album_node) {
|
||||
// It has const behaviour some of the time - that's ok right?
|
||||
@ -741,7 +726,7 @@ QVariant CollectionModel::data(const QModelIndex &idx, const int role) const {
|
||||
|
||||
QVariant CollectionModel::data(const CollectionItem *item, const int role) const {
|
||||
|
||||
GroupBy container_type = item->type == CollectionItem::Type_Container ? group_by_[item->container_level] : GroupBy_None;
|
||||
GroupBy container_group_by = item->type == CollectionItem::Type_Container ? group_by_[item->container_level] : GroupBy_None;
|
||||
|
||||
switch (role) {
|
||||
case Qt::DisplayRole:
|
||||
@ -751,7 +736,7 @@ QVariant CollectionModel::data(const CollectionItem *item, const int role) const
|
||||
case Qt::DecorationRole:
|
||||
switch (item->type) {
|
||||
case CollectionItem::Type_Container:
|
||||
switch (container_type) {
|
||||
switch (container_group_by) {
|
||||
case GroupBy_Album:
|
||||
case GroupBy_AlbumDisc:
|
||||
case GroupBy_YearAlbum:
|
||||
@ -778,7 +763,7 @@ QVariant CollectionModel::data(const CollectionItem *item, const int role) const
|
||||
return item->type == CollectionItem::Type_Divider;
|
||||
|
||||
case Role_ContainerType:
|
||||
return container_type;
|
||||
return container_group_by;
|
||||
|
||||
case Role_Key:
|
||||
return item->key;
|
||||
@ -849,26 +834,26 @@ CollectionModel::QueryResult CollectionModel::RunQuery(CollectionItem *parent) {
|
||||
|
||||
// Information about what we want the children to be
|
||||
int child_level = parent == root_ ? 0 : parent->container_level + 1;
|
||||
GroupBy child_type = child_level >= 3 ? GroupBy_None : group_by_[child_level];
|
||||
GroupBy child_group_by = child_level >= 3 ? GroupBy_None : group_by_[child_level];
|
||||
|
||||
// Initialize the query. child_type says what type of thing we want (artists, songs, etc.)
|
||||
// Initialize the query. child_group_by says what type of thing we want (artists, songs, etc.)
|
||||
|
||||
{
|
||||
QMutexLocker l(backend_->db()->Mutex());
|
||||
QSqlDatabase db(backend_->db()->Connect());
|
||||
|
||||
CollectionQuery q(db, backend_->songs_table(), backend_->fts_table(), query_options_);
|
||||
InitQuery(child_type, &q);
|
||||
InitQuery(child_group_by, separate_albums_by_grouping_, &q);
|
||||
|
||||
// Walk up through the item's parents adding filters as necessary
|
||||
CollectionItem *p = parent;
|
||||
while (p && p->type == CollectionItem::Type_Container) {
|
||||
FilterQuery(group_by_[p->container_level], p, &q);
|
||||
FilterQuery(group_by_[p->container_level], separate_albums_by_grouping_, p, &q);
|
||||
p = p->parent;
|
||||
}
|
||||
|
||||
// Artists GroupBy is special - we don't want compilation albums appearing
|
||||
if (IsArtistGroupBy(child_type)) {
|
||||
if (IsArtistGroupBy(child_group_by)) {
|
||||
// Add the special Various artists node
|
||||
if (show_various_artists_ && HasCompilations(db, q)) {
|
||||
result.create_va = true;
|
||||
@ -902,7 +887,7 @@ void CollectionModel::PostQuery(CollectionItem *parent, const CollectionModel::Q
|
||||
|
||||
// Information about what we want the children to be
|
||||
int child_level = parent == root_ ? 0 : parent->container_level + 1;
|
||||
GroupBy child_type = child_level >= 3 ? GroupBy_None : group_by_[child_level];
|
||||
GroupBy child_group_by = child_level >= 3 ? GroupBy_None : group_by_[child_level];
|
||||
|
||||
if (result.create_va && parent->compilation_artist_node_ == nullptr) {
|
||||
CreateCompilationArtistNode(signal, parent);
|
||||
@ -911,10 +896,10 @@ void CollectionModel::PostQuery(CollectionItem *parent, const CollectionModel::Q
|
||||
// Step through the results
|
||||
for (const SqlRow &row : result.rows) {
|
||||
// Create the item - it will get inserted into the model here
|
||||
CollectionItem *item = ItemFromQuery(child_type, signal, child_level == 0, parent, row, child_level);
|
||||
CollectionItem *item = ItemFromQuery(child_group_by, separate_albums_by_grouping_, signal, child_level == 0, parent, row, child_level);
|
||||
|
||||
// Save a pointer to it for later
|
||||
if (child_type == GroupBy_None) {
|
||||
if (child_group_by == GroupBy_None) {
|
||||
song_nodes_.insert(item->metadata.id(), item);
|
||||
}
|
||||
else {
|
||||
@ -1002,34 +987,52 @@ void CollectionModel::Reset() {
|
||||
|
||||
}
|
||||
|
||||
void CollectionModel::InitQuery(const GroupBy type, CollectionQuery *q) {
|
||||
void CollectionModel::InitQuery(const GroupBy group_by, const bool separate_albums_by_grouping, CollectionQuery *q) {
|
||||
|
||||
// Say what type of thing we want to get back from the database.
|
||||
switch (type) {
|
||||
// Say what group_by of thing we want to get back from the database.
|
||||
switch (group_by) {
|
||||
case GroupBy_AlbumArtist:
|
||||
q->SetColumnSpec("DISTINCT effective_albumartist");
|
||||
break;
|
||||
case GroupBy_Artist:
|
||||
q->SetColumnSpec("DISTINCT artist");
|
||||
break;
|
||||
case GroupBy_Album:
|
||||
q->SetColumnSpec("DISTINCT album, album_id, grouping");
|
||||
case GroupBy_Album:{
|
||||
QString query("DISTINCT album, album_id");
|
||||
if (separate_albums_by_grouping) query.append(", grouping");
|
||||
q->SetColumnSpec(query);
|
||||
break;
|
||||
case GroupBy_AlbumDisc:
|
||||
q->SetColumnSpec("DISTINCT album, album_id, disc, grouping");
|
||||
}
|
||||
case GroupBy_AlbumDisc:{
|
||||
QString query("DISTINCT album, album_id, disc");
|
||||
if (separate_albums_by_grouping) query.append(", grouping");
|
||||
q->SetColumnSpec(query);
|
||||
break;
|
||||
case GroupBy_YearAlbum:
|
||||
q->SetColumnSpec("DISTINCT year, album, album_id, grouping");
|
||||
}
|
||||
case GroupBy_YearAlbum:{
|
||||
QString query("DISTINCT year, album, album_id");
|
||||
if (separate_albums_by_grouping) query.append(", grouping");
|
||||
q->SetColumnSpec(query);
|
||||
break;
|
||||
case GroupBy_YearAlbumDisc:
|
||||
q->SetColumnSpec("DISTINCT year, album, album_id, disc, grouping");
|
||||
}
|
||||
case GroupBy_YearAlbumDisc:{
|
||||
QString query("DISTINCT year, album, album_id, disc");
|
||||
if (separate_albums_by_grouping) query.append(", grouping");
|
||||
q->SetColumnSpec(query);
|
||||
break;
|
||||
case GroupBy_OriginalYearAlbum:
|
||||
q->SetColumnSpec("DISTINCT year, originalyear, album, album_id, grouping");
|
||||
}
|
||||
case GroupBy_OriginalYearAlbum:{
|
||||
QString query("DISTINCT year, originalyear, album, album_id");
|
||||
if (separate_albums_by_grouping) query.append(", grouping");
|
||||
q->SetColumnSpec(query);
|
||||
break;
|
||||
case GroupBy_OriginalYearAlbumDisc:
|
||||
q->SetColumnSpec("DISTINCT year, originalyear, album, album_id, disc, grouping");
|
||||
}
|
||||
case GroupBy_OriginalYearAlbumDisc:{
|
||||
QString query("DISTINCT year, originalyear, album, album_id, disc");
|
||||
if (separate_albums_by_grouping) query.append(", grouping");
|
||||
q->SetColumnSpec(query);
|
||||
break;
|
||||
}
|
||||
case GroupBy_Disc:
|
||||
q->SetColumnSpec("DISTINCT disc");
|
||||
break;
|
||||
@ -1074,11 +1077,11 @@ void CollectionModel::InitQuery(const GroupBy type, CollectionQuery *q) {
|
||||
|
||||
}
|
||||
|
||||
void CollectionModel::FilterQuery(const GroupBy type, CollectionItem *item, CollectionQuery *q) {
|
||||
void CollectionModel::FilterQuery(const GroupBy group_by, const bool separate_albums_by_grouping, CollectionItem *item, CollectionQuery *q) {
|
||||
|
||||
// Say how we want the query to be filtered. This is done once for each parent going up the tree.
|
||||
|
||||
switch (type) {
|
||||
switch (group_by) {
|
||||
case GroupBy_AlbumArtist:
|
||||
if (IsCompilationArtistNode(item)) {
|
||||
q->AddCompilationRequirement(true);
|
||||
@ -1102,33 +1105,33 @@ void CollectionModel::FilterQuery(const GroupBy type, CollectionItem *item, Coll
|
||||
case GroupBy_Album:
|
||||
q->AddWhere("album", item->metadata.album());
|
||||
q->AddWhere("album_id", item->metadata.album_id());
|
||||
q->AddWhere("grouping", item->metadata.grouping());
|
||||
if (separate_albums_by_grouping) q->AddWhere("grouping", item->metadata.grouping());
|
||||
break;
|
||||
case GroupBy_AlbumDisc:
|
||||
q->AddWhere("album", item->metadata.album());
|
||||
q->AddWhere("album_id", item->metadata.album_id());
|
||||
q->AddWhere("disc", item->metadata.disc());
|
||||
q->AddWhere("grouping", item->metadata.grouping());
|
||||
if (separate_albums_by_grouping) q->AddWhere("grouping", item->metadata.grouping());
|
||||
break;
|
||||
case GroupBy_YearAlbum:
|
||||
q->AddWhere("year", item->metadata.year());
|
||||
q->AddWhere("album", item->metadata.album());
|
||||
q->AddWhere("album_id", item->metadata.album_id());
|
||||
q->AddWhere("grouping", item->metadata.grouping());
|
||||
if (separate_albums_by_grouping) q->AddWhere("grouping", item->metadata.grouping());
|
||||
break;
|
||||
case GroupBy_YearAlbumDisc:
|
||||
q->AddWhere("year", item->metadata.year());
|
||||
q->AddWhere("album", item->metadata.album());
|
||||
q->AddWhere("album_id", item->metadata.album_id());
|
||||
q->AddWhere("disc", item->metadata.disc());
|
||||
q->AddWhere("grouping", item->metadata.grouping());
|
||||
if (separate_albums_by_grouping) q->AddWhere("grouping", item->metadata.grouping());
|
||||
break;
|
||||
case GroupBy_OriginalYearAlbum:
|
||||
q->AddWhere("year", item->metadata.year());
|
||||
q->AddWhere("originalyear", item->metadata.originalyear());
|
||||
q->AddWhere("album", item->metadata.album());
|
||||
q->AddWhere("album_id", item->metadata.album_id());
|
||||
q->AddWhere("grouping", item->metadata.grouping());
|
||||
if (separate_albums_by_grouping) q->AddWhere("grouping", item->metadata.grouping());
|
||||
break;
|
||||
case GroupBy_OriginalYearAlbumDisc:
|
||||
q->AddWhere("year", item->metadata.year());
|
||||
@ -1136,7 +1139,7 @@ void CollectionModel::FilterQuery(const GroupBy type, CollectionItem *item, Coll
|
||||
q->AddWhere("album", item->metadata.album());
|
||||
q->AddWhere("album_id", item->metadata.album_id());
|
||||
q->AddWhere("disc", item->metadata.disc());
|
||||
q->AddWhere("grouping", item->metadata.grouping());
|
||||
if (separate_albums_by_grouping) q->AddWhere("grouping", item->metadata.grouping());
|
||||
break;
|
||||
case GroupBy_Disc:
|
||||
q->AddWhere("disc", item->metadata.disc());
|
||||
@ -1178,15 +1181,15 @@ void CollectionModel::FilterQuery(const GroupBy type, CollectionItem *item, Coll
|
||||
break;
|
||||
case GroupBy_None:
|
||||
case GroupByCount:
|
||||
qLog(Error) << "Unknown GroupBy type" << type << "used in filter";
|
||||
qLog(Error) << "Unknown GroupBy" << group_by << "used in filter";
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
CollectionItem *CollectionModel::InitItem(const GroupBy type, const bool signal, CollectionItem *parent, const int container_level) {
|
||||
CollectionItem *CollectionModel::InitItem(const GroupBy group_by, const bool signal, CollectionItem *parent, const int container_level) {
|
||||
|
||||
CollectionItem::Type item_type = type == GroupBy_None ? CollectionItem::Type_Song : CollectionItem::Type_Container;
|
||||
CollectionItem::Type item_type = group_by == GroupBy_None ? CollectionItem::Type_Song : CollectionItem::Type_Container;
|
||||
|
||||
if (signal) beginInsertRows(ItemToIndex(parent), static_cast<int>(parent->children.count()), static_cast<int>(parent->children.count()));
|
||||
|
||||
@ -1199,25 +1202,25 @@ CollectionItem *CollectionModel::InitItem(const GroupBy type, const bool signal,
|
||||
|
||||
}
|
||||
|
||||
CollectionItem *CollectionModel::ItemFromQuery(const GroupBy type, const bool signal, const bool create_divider, CollectionItem *parent, const SqlRow &row, const int container_level) {
|
||||
CollectionItem *CollectionModel::ItemFromQuery(const GroupBy group_by, const bool separate_albums_by_grouping, const bool signal, const bool create_divider, CollectionItem *parent, const SqlRow &row, const int container_level) {
|
||||
|
||||
CollectionItem *item = InitItem(type, signal, parent, container_level);
|
||||
CollectionItem *item = InitItem(group_by, signal, parent, container_level);
|
||||
|
||||
if (parent != root_ && !parent->key.isEmpty()) {
|
||||
item->key = parent->key + "-";
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
switch (group_by) {
|
||||
case GroupBy_AlbumArtist:{
|
||||
item->metadata.set_albumartist(row.value(0).toString());
|
||||
item->key.append(ContainerKey(type, item->metadata));
|
||||
item->key.append(ContainerKey(group_by, separate_albums_by_grouping, item->metadata));
|
||||
item->display_text = TextOrUnknown(item->metadata.albumartist());
|
||||
item->sort_text = SortTextForArtist(item->metadata.albumartist());
|
||||
break;
|
||||
}
|
||||
case GroupBy_Artist:{
|
||||
item->metadata.set_artist(row.value(0).toString());
|
||||
item->key.append(ContainerKey(type, item->metadata));
|
||||
item->key.append(ContainerKey(group_by, separate_albums_by_grouping, item->metadata));
|
||||
item->display_text = TextOrUnknown(item->metadata.artist());
|
||||
item->sort_text = SortTextForArtist(item->metadata.artist());
|
||||
break;
|
||||
@ -1226,7 +1229,7 @@ CollectionItem *CollectionModel::ItemFromQuery(const GroupBy type, const bool si
|
||||
item->metadata.set_album(row.value(0).toString());
|
||||
item->metadata.set_album_id(row.value(1).toString());
|
||||
item->metadata.set_grouping(row.value(2).toString());
|
||||
item->key.append(ContainerKey(type, item->metadata));
|
||||
item->key.append(ContainerKey(group_by, separate_albums_by_grouping, item->metadata));
|
||||
item->display_text = TextOrUnknown(item->metadata.album());
|
||||
item->sort_text = SortTextForArtist(item->metadata.album());
|
||||
break;
|
||||
@ -1236,7 +1239,7 @@ CollectionItem *CollectionModel::ItemFromQuery(const GroupBy type, const bool si
|
||||
item->metadata.set_album_id(row.value(1).toString());
|
||||
item->metadata.set_disc(row.value(2).toInt());
|
||||
item->metadata.set_grouping(row.value(3).toString());
|
||||
item->key.append(ContainerKey(type, item->metadata));
|
||||
item->key.append(ContainerKey(group_by, separate_albums_by_grouping, item->metadata));
|
||||
item->display_text = PrettyAlbumDisc(item->metadata.album(), item->metadata.disc());
|
||||
item->sort_text = item->metadata.album() + SortTextForNumber(qMax(0, item->metadata.disc()));
|
||||
break;
|
||||
@ -1246,7 +1249,7 @@ CollectionItem *CollectionModel::ItemFromQuery(const GroupBy type, const bool si
|
||||
item->metadata.set_album(row.value(1).toString());
|
||||
item->metadata.set_album_id(row.value(2).toString());
|
||||
item->metadata.set_grouping(row.value(3).toString());
|
||||
item->key.append(ContainerKey(type, item->metadata));
|
||||
item->key.append(ContainerKey(group_by, separate_albums_by_grouping, item->metadata));
|
||||
item->display_text = PrettyYearAlbum(item->metadata.year(), item->metadata.album());
|
||||
item->sort_text = SortTextForNumber(qMax(0, item->metadata.year())) + item->metadata.grouping() + item->metadata.album();
|
||||
break;
|
||||
@ -1257,7 +1260,7 @@ CollectionItem *CollectionModel::ItemFromQuery(const GroupBy type, const bool si
|
||||
item->metadata.set_album_id(row.value(2).toString());
|
||||
item->metadata.set_disc(row.value(3).toInt());
|
||||
item->metadata.set_grouping(row.value(4).toString());
|
||||
item->key.append(ContainerKey(type, item->metadata));
|
||||
item->key.append(ContainerKey(group_by, separate_albums_by_grouping, item->metadata));
|
||||
item->display_text = PrettyYearAlbumDisc(item->metadata.year(), item->metadata.album(), item->metadata.disc());
|
||||
item->sort_text = SortTextForNumber(qMax(0, item->metadata.year())) + item->metadata.album() + SortTextForNumber(qMax(0, item->metadata.disc()));
|
||||
break;
|
||||
@ -1268,7 +1271,7 @@ CollectionItem *CollectionModel::ItemFromQuery(const GroupBy type, const bool si
|
||||
item->metadata.set_album(row.value(2).toString());
|
||||
item->metadata.set_album_id(row.value(3).toString());
|
||||
item->metadata.set_grouping(row.value(4).toString());
|
||||
item->key.append(ContainerKey(type, item->metadata));
|
||||
item->key.append(ContainerKey(group_by, separate_albums_by_grouping, item->metadata));
|
||||
item->display_text = PrettyYearAlbum(item->metadata.effective_originalyear(), item->metadata.album());
|
||||
item->sort_text = SortTextForNumber(qMax(0, item->metadata.effective_originalyear())) + item->metadata.grouping() + item->metadata.album();
|
||||
break;
|
||||
@ -1280,14 +1283,14 @@ CollectionItem *CollectionModel::ItemFromQuery(const GroupBy type, const bool si
|
||||
item->metadata.set_album_id(row.value(3).toString());
|
||||
item->metadata.set_disc(row.value(4).toInt());
|
||||
item->metadata.set_grouping(row.value(5).toString());
|
||||
item->key.append(ContainerKey(type, item->metadata));
|
||||
item->key.append(ContainerKey(group_by, separate_albums_by_grouping, item->metadata));
|
||||
item->display_text = PrettyYearAlbumDisc(item->metadata.effective_originalyear(), item->metadata.album(), item->metadata.disc());
|
||||
item->sort_text = SortTextForNumber(qMax(0, item->metadata.effective_originalyear())) + item->metadata.album() + SortTextForNumber(qMax(0, item->metadata.disc()));
|
||||
break;
|
||||
}
|
||||
case GroupBy_Disc:{
|
||||
item->metadata.set_disc(row.value(0).toInt());
|
||||
item->key.append(ContainerKey(type, item->metadata));
|
||||
item->key.append(ContainerKey(group_by, separate_albums_by_grouping, item->metadata));
|
||||
const int disc = qMax(0, row.value(0).toInt());
|
||||
item->display_text = PrettyDisc(disc);
|
||||
item->sort_text = SortTextForNumber(disc);
|
||||
@ -1295,7 +1298,7 @@ CollectionItem *CollectionModel::ItemFromQuery(const GroupBy type, const bool si
|
||||
}
|
||||
case GroupBy_Year:{
|
||||
item->metadata.set_year(row.value(0).toInt());
|
||||
item->key.append(ContainerKey(type, item->metadata));
|
||||
item->key.append(ContainerKey(group_by, separate_albums_by_grouping, item->metadata));
|
||||
const int year = qMax(0, item->metadata.year());
|
||||
item->display_text = QString::number(year);
|
||||
item->sort_text = SortTextForNumber(year) + " ";
|
||||
@ -1303,7 +1306,7 @@ CollectionItem *CollectionModel::ItemFromQuery(const GroupBy type, const bool si
|
||||
}
|
||||
case GroupBy_OriginalYear:{
|
||||
item->metadata.set_originalyear(row.value(0).toInt());
|
||||
item->key.append(ContainerKey(type, item->metadata));
|
||||
item->key.append(ContainerKey(group_by, separate_albums_by_grouping, item->metadata));
|
||||
const int year = qMax(0, item->metadata.originalyear());
|
||||
item->display_text = QString::number(year);
|
||||
item->sort_text = SortTextForNumber(year) + " ";
|
||||
@ -1311,35 +1314,35 @@ CollectionItem *CollectionModel::ItemFromQuery(const GroupBy type, const bool si
|
||||
}
|
||||
case GroupBy_Genre:{
|
||||
item->metadata.set_genre(row.value(0).toString());
|
||||
item->key.append(ContainerKey(type, item->metadata));
|
||||
item->key.append(ContainerKey(group_by, separate_albums_by_grouping, item->metadata));
|
||||
item->display_text = TextOrUnknown(item->metadata.genre());
|
||||
item->sort_text = SortTextForArtist(item->metadata.genre());
|
||||
break;
|
||||
}
|
||||
case GroupBy_Composer:{
|
||||
item->metadata.set_composer(row.value(0).toString());
|
||||
item->key.append(ContainerKey(type, item->metadata));
|
||||
item->key.append(ContainerKey(group_by, separate_albums_by_grouping, item->metadata));
|
||||
item->display_text = TextOrUnknown(item->metadata.composer());
|
||||
item->sort_text = SortTextForArtist(item->metadata.composer());
|
||||
break;
|
||||
}
|
||||
case GroupBy_Performer:{
|
||||
item->metadata.set_performer(row.value(0).toString());
|
||||
item->key.append(ContainerKey(type, item->metadata));
|
||||
item->key.append(ContainerKey(group_by, separate_albums_by_grouping, item->metadata));
|
||||
item->display_text = TextOrUnknown(item->metadata.performer());
|
||||
item->sort_text = SortTextForArtist(item->metadata.performer());
|
||||
break;
|
||||
}
|
||||
case GroupBy_Grouping:{
|
||||
item->metadata.set_grouping(row.value(0).toString());
|
||||
item->key.append(ContainerKey(type, item->metadata));
|
||||
item->key.append(ContainerKey(group_by, separate_albums_by_grouping, item->metadata));
|
||||
item->display_text = TextOrUnknown(item->metadata.grouping());
|
||||
item->sort_text = SortTextForArtist(item->metadata.grouping());
|
||||
break;
|
||||
}
|
||||
case GroupBy_FileType:{
|
||||
item->metadata.set_filetype(static_cast<Song::FileType>(row.value(0).toInt()));
|
||||
item->key.append(ContainerKey(type, item->metadata));
|
||||
item->key.append(ContainerKey(group_by, separate_albums_by_grouping, item->metadata));
|
||||
item->display_text = item->metadata.TextForFiletype();
|
||||
item->sort_text = item->metadata.TextForFiletype();
|
||||
break;
|
||||
@ -1348,7 +1351,7 @@ CollectionItem *CollectionModel::ItemFromQuery(const GroupBy type, const bool si
|
||||
item->metadata.set_filetype(static_cast<Song::FileType>(row.value(0).toInt()));
|
||||
item->metadata.set_samplerate(row.value(1).toInt());
|
||||
item->metadata.set_bitdepth(row.value(2).toInt());
|
||||
QString key = ContainerKey(type, item->metadata);
|
||||
QString key = ContainerKey(group_by, separate_albums_by_grouping, item->metadata);
|
||||
item->key.append(key);
|
||||
item->display_text = key;
|
||||
item->sort_text = key;
|
||||
@ -1356,7 +1359,7 @@ CollectionItem *CollectionModel::ItemFromQuery(const GroupBy type, const bool si
|
||||
}
|
||||
case GroupBy_Samplerate:{
|
||||
item->metadata.set_samplerate(row.value(0).toInt());
|
||||
item->key.append(ContainerKey(type, item->metadata));
|
||||
item->key.append(ContainerKey(group_by, separate_albums_by_grouping, item->metadata));
|
||||
const int samplerate = qMax(0, item->metadata.samplerate());
|
||||
item->display_text = QString::number(samplerate);
|
||||
item->sort_text = SortTextForNumber(samplerate) + " ";
|
||||
@ -1364,7 +1367,7 @@ CollectionItem *CollectionModel::ItemFromQuery(const GroupBy type, const bool si
|
||||
}
|
||||
case GroupBy_Bitdepth:{
|
||||
item->metadata.set_bitdepth(row.value(0).toInt());
|
||||
item->key.append(ContainerKey(type, item->metadata));
|
||||
item->key.append(ContainerKey(group_by, separate_albums_by_grouping, item->metadata));
|
||||
const int bitdepth = qMax(0, item->metadata.bitdepth());
|
||||
item->display_text = QString::number(bitdepth);
|
||||
item->sort_text = SortTextForNumber(bitdepth) + " ";
|
||||
@ -1372,7 +1375,7 @@ CollectionItem *CollectionModel::ItemFromQuery(const GroupBy type, const bool si
|
||||
}
|
||||
case GroupBy_Bitrate:{
|
||||
item->metadata.set_bitrate(row.value(0).toInt());
|
||||
item->key.append(ContainerKey(type, item->metadata));
|
||||
item->key.append(ContainerKey(group_by, separate_albums_by_grouping, item->metadata));
|
||||
const int bitrate = qMax(0, item->metadata.bitrate());
|
||||
item->display_text = QString::number(bitrate);
|
||||
item->sort_text = SortTextForNumber(bitrate) + " ";
|
||||
@ -1392,31 +1395,31 @@ CollectionItem *CollectionModel::ItemFromQuery(const GroupBy type, const bool si
|
||||
break;
|
||||
}
|
||||
|
||||
FinishItem(type, signal, create_divider, parent, item);
|
||||
FinishItem(group_by, signal, create_divider, parent, item);
|
||||
|
||||
return item;
|
||||
|
||||
}
|
||||
|
||||
CollectionItem *CollectionModel::ItemFromSong(const GroupBy type, const bool signal, const bool create_divider, CollectionItem *parent, const Song &s, const int container_level) {
|
||||
CollectionItem *CollectionModel::ItemFromSong(const GroupBy group_by, const bool separate_albums_by_grouping, const bool signal, const bool create_divider, CollectionItem *parent, const Song &s, const int container_level) {
|
||||
|
||||
CollectionItem *item = InitItem(type, signal, parent, container_level);
|
||||
CollectionItem *item = InitItem(group_by, signal, parent, container_level);
|
||||
|
||||
if (parent != root_ && !parent->key.isEmpty()) {
|
||||
item->key = parent->key + "-";
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
switch (group_by) {
|
||||
case GroupBy_AlbumArtist:{
|
||||
item->metadata.set_albumartist(s.effective_albumartist());
|
||||
item->key.append(ContainerKey(type, s));
|
||||
item->key.append(ContainerKey(group_by, separate_albums_by_grouping, s));
|
||||
item->display_text = TextOrUnknown(s.effective_albumartist());
|
||||
item->sort_text = SortTextForArtist(s.effective_albumartist());
|
||||
break;
|
||||
}
|
||||
case GroupBy_Artist:{
|
||||
item->metadata.set_artist(s.artist());
|
||||
item->key.append(ContainerKey(type, s));
|
||||
item->key.append(ContainerKey(group_by, separate_albums_by_grouping, s));
|
||||
item->display_text = TextOrUnknown(s.artist());
|
||||
item->sort_text = SortTextForArtist(s.artist());
|
||||
break;
|
||||
@ -1425,7 +1428,7 @@ CollectionItem *CollectionModel::ItemFromSong(const GroupBy type, const bool sig
|
||||
item->metadata.set_album(s.album());
|
||||
item->metadata.set_album_id(s.album_id());
|
||||
item->metadata.set_grouping(s.grouping());
|
||||
item->key.append(ContainerKey(type, s));
|
||||
item->key.append(ContainerKey(group_by, separate_albums_by_grouping, s));
|
||||
item->display_text = TextOrUnknown(s.album());
|
||||
item->sort_text = SortTextForArtist(s.album());
|
||||
break;
|
||||
@ -1435,7 +1438,7 @@ CollectionItem *CollectionModel::ItemFromSong(const GroupBy type, const bool sig
|
||||
item->metadata.set_album_id(s.album_id());
|
||||
item->metadata.set_disc(s.disc());
|
||||
item->metadata.set_grouping(s.grouping());
|
||||
item->key.append(ContainerKey(type, s));
|
||||
item->key.append(ContainerKey(group_by, separate_albums_by_grouping, s));
|
||||
item->display_text = PrettyAlbumDisc(s.album(), s.disc());
|
||||
item->sort_text = s.album() + SortTextForNumber(qMax(0, s.disc()));
|
||||
break;
|
||||
@ -1445,7 +1448,7 @@ CollectionItem *CollectionModel::ItemFromSong(const GroupBy type, const bool sig
|
||||
item->metadata.set_album(s.album());
|
||||
item->metadata.set_album_id(s.album_id());
|
||||
item->metadata.set_grouping(s.grouping());
|
||||
item->key.append(ContainerKey(type, s));
|
||||
item->key.append(ContainerKey(group_by, separate_albums_by_grouping, s));
|
||||
item->display_text = PrettyYearAlbum(s.year(), s.album());
|
||||
item->sort_text = SortTextForNumber(qMax(0, s.year())) + s.grouping() + s.album();
|
||||
break;
|
||||
@ -1456,7 +1459,7 @@ CollectionItem *CollectionModel::ItemFromSong(const GroupBy type, const bool sig
|
||||
item->metadata.set_album_id(s.album_id());
|
||||
item->metadata.set_disc(s.disc());
|
||||
item->metadata.set_grouping(s.grouping());
|
||||
item->key.append(ContainerKey(type, s));
|
||||
item->key.append(ContainerKey(group_by, separate_albums_by_grouping, s));
|
||||
item->display_text = PrettyYearAlbumDisc(s.year(), s.album(), s.disc());
|
||||
item->sort_text = SortTextForNumber(qMax(0, s.year())) + s.album() + SortTextForNumber(qMax(0, s.disc()));
|
||||
break;
|
||||
@ -1467,7 +1470,7 @@ CollectionItem *CollectionModel::ItemFromSong(const GroupBy type, const bool sig
|
||||
item->metadata.set_album(s.album());
|
||||
item->metadata.set_album_id(s.album_id());
|
||||
item->metadata.set_grouping(s.grouping());
|
||||
item->key.append(ContainerKey(type, s));
|
||||
item->key.append(ContainerKey(group_by, separate_albums_by_grouping, s));
|
||||
item->display_text = PrettyYearAlbum(s.effective_originalyear(), s.album());
|
||||
item->sort_text = SortTextForNumber(qMax(0, s.effective_originalyear())) + s.grouping() + s.album();
|
||||
break;
|
||||
@ -1479,14 +1482,14 @@ CollectionItem *CollectionModel::ItemFromSong(const GroupBy type, const bool sig
|
||||
item->metadata.set_album_id(s.album_id());
|
||||
item->metadata.set_disc(s.disc());
|
||||
item->metadata.set_grouping(s.grouping());
|
||||
item->key.append(ContainerKey(type, s));
|
||||
item->key.append(ContainerKey(group_by, separate_albums_by_grouping, s));
|
||||
item->display_text = PrettyYearAlbumDisc(s.effective_originalyear(), s.album(), s.disc());
|
||||
item->sort_text = SortTextForNumber(qMax(0, s.effective_originalyear())) + s.album() + SortTextForNumber(qMax(0, s.disc()));
|
||||
break;
|
||||
}
|
||||
case GroupBy_Disc:{
|
||||
item->metadata.set_disc(s.disc());
|
||||
item->key.append(ContainerKey(type, s));
|
||||
item->key.append(ContainerKey(group_by, separate_albums_by_grouping, s));
|
||||
const int disc = qMax(0, s.disc());
|
||||
item->display_text = PrettyDisc(disc);
|
||||
item->sort_text = SortTextForNumber(disc);
|
||||
@ -1494,7 +1497,7 @@ CollectionItem *CollectionModel::ItemFromSong(const GroupBy type, const bool sig
|
||||
}
|
||||
case GroupBy_Year:{
|
||||
item->metadata.set_year(s.year());
|
||||
item->key.append(ContainerKey(type, s));
|
||||
item->key.append(ContainerKey(group_by, separate_albums_by_grouping, s));
|
||||
const int year = qMax(0, s.year());
|
||||
item->display_text = QString::number(year);
|
||||
item->sort_text = SortTextForNumber(year) + " ";
|
||||
@ -1502,7 +1505,7 @@ CollectionItem *CollectionModel::ItemFromSong(const GroupBy type, const bool sig
|
||||
}
|
||||
case GroupBy_OriginalYear:{
|
||||
item->metadata.set_originalyear(s.effective_originalyear());
|
||||
item->key.append(ContainerKey(type, s));
|
||||
item->key.append(ContainerKey(group_by, separate_albums_by_grouping, s));
|
||||
const int year = qMax(0, s.effective_originalyear());
|
||||
item->display_text = QString::number(year);
|
||||
item->sort_text = SortTextForNumber(year) + " ";
|
||||
@ -1510,35 +1513,35 @@ CollectionItem *CollectionModel::ItemFromSong(const GroupBy type, const bool sig
|
||||
}
|
||||
case GroupBy_Genre:{
|
||||
item->metadata.set_genre(s.genre());
|
||||
item->key.append(ContainerKey(type, s));
|
||||
item->key.append(ContainerKey(group_by, separate_albums_by_grouping, s));
|
||||
item->display_text = TextOrUnknown(s.genre());
|
||||
item->sort_text = SortTextForArtist(s.genre());
|
||||
break;
|
||||
}
|
||||
case GroupBy_Composer:{
|
||||
item->metadata.set_composer(s.composer());
|
||||
item->key.append(ContainerKey(type, s));
|
||||
item->key.append(ContainerKey(group_by, separate_albums_by_grouping, s));
|
||||
item->display_text = TextOrUnknown(s.composer());
|
||||
item->sort_text = SortTextForArtist(s.composer());
|
||||
break;
|
||||
}
|
||||
case GroupBy_Performer:{
|
||||
item->metadata.set_performer(s.performer());
|
||||
item->key.append(ContainerKey(type, s));
|
||||
item->key.append(ContainerKey(group_by, separate_albums_by_grouping, s));
|
||||
item->display_text = TextOrUnknown(s.performer());
|
||||
item->sort_text = SortTextForArtist(s.performer());
|
||||
break;
|
||||
}
|
||||
case GroupBy_Grouping:{
|
||||
item->metadata.set_grouping(s.grouping());
|
||||
item->key.append(ContainerKey(type, s));
|
||||
item->key.append(ContainerKey(group_by, separate_albums_by_grouping, s));
|
||||
item->display_text = TextOrUnknown(s.grouping());
|
||||
item->sort_text = SortTextForArtist(s.grouping());
|
||||
break;
|
||||
}
|
||||
case GroupBy_FileType:{
|
||||
item->metadata.set_filetype(s.filetype());
|
||||
item->key.append(ContainerKey(type, s));
|
||||
item->key.append(ContainerKey(group_by, separate_albums_by_grouping, s));
|
||||
item->display_text = s.TextForFiletype();
|
||||
item->sort_text = s.TextForFiletype();
|
||||
break;
|
||||
@ -1547,7 +1550,7 @@ CollectionItem *CollectionModel::ItemFromSong(const GroupBy type, const bool sig
|
||||
item->metadata.set_filetype(s.filetype());
|
||||
item->metadata.set_samplerate(s.samplerate());
|
||||
item->metadata.set_bitdepth(s.bitdepth());
|
||||
QString key = ContainerKey(type, s);
|
||||
QString key = ContainerKey(group_by, separate_albums_by_grouping, s);
|
||||
item->key.append(key);
|
||||
item->display_text = key;
|
||||
item->sort_text = key;
|
||||
@ -1555,7 +1558,7 @@ CollectionItem *CollectionModel::ItemFromSong(const GroupBy type, const bool sig
|
||||
}
|
||||
case GroupBy_Samplerate:{
|
||||
item->metadata.set_samplerate(s.samplerate());
|
||||
item->key.append(ContainerKey(type, s));
|
||||
item->key.append(ContainerKey(group_by, separate_albums_by_grouping, s));
|
||||
const int samplerate = qMax(0, s.samplerate());
|
||||
item->display_text = QString::number(samplerate);
|
||||
item->sort_text = SortTextForNumber(samplerate) + " ";
|
||||
@ -1563,7 +1566,7 @@ CollectionItem *CollectionModel::ItemFromSong(const GroupBy type, const bool sig
|
||||
}
|
||||
case GroupBy_Bitdepth:{
|
||||
item->metadata.set_bitdepth(s.bitdepth());
|
||||
item->key.append(ContainerKey(type, s));
|
||||
item->key.append(ContainerKey(group_by, separate_albums_by_grouping, s));
|
||||
const int bitdepth = qMax(0, s.bitdepth());
|
||||
item->display_text = QString::number(bitdepth);
|
||||
item->sort_text = SortTextForNumber(bitdepth) + " ";
|
||||
@ -1571,7 +1574,7 @@ CollectionItem *CollectionModel::ItemFromSong(const GroupBy type, const bool sig
|
||||
}
|
||||
case GroupBy_Bitrate:{
|
||||
item->metadata.set_bitrate(s.bitrate());
|
||||
item->key.append(ContainerKey(type, s));
|
||||
item->key.append(ContainerKey(group_by, separate_albums_by_grouping, s));
|
||||
const int bitrate = qMax(0, s.bitrate());
|
||||
item->display_text = QString::number(bitrate);
|
||||
item->sort_text = SortTextForNumber(bitrate) + " ";
|
||||
@ -1592,16 +1595,16 @@ CollectionItem *CollectionModel::ItemFromSong(const GroupBy type, const bool sig
|
||||
}
|
||||
}
|
||||
|
||||
FinishItem(type, signal, create_divider, parent, item);
|
||||
FinishItem(group_by, signal, create_divider, parent, item);
|
||||
if (s.url().scheme() == "cdda") item->lazy_loaded = true;
|
||||
|
||||
return item;
|
||||
|
||||
}
|
||||
|
||||
void CollectionModel::FinishItem(const GroupBy type, const bool signal, const bool create_divider, CollectionItem *parent, CollectionItem *item) {
|
||||
void CollectionModel::FinishItem(const GroupBy group_by, const bool signal, const bool create_divider, CollectionItem *parent, CollectionItem *item) {
|
||||
|
||||
if (type == GroupBy_None) item->lazy_loaded = true;
|
||||
if (group_by == GroupBy_None) item->lazy_loaded = true;
|
||||
|
||||
if (signal) {
|
||||
endInsertRows();
|
||||
@ -1609,7 +1612,7 @@ void CollectionModel::FinishItem(const GroupBy type, const bool signal, const bo
|
||||
|
||||
// Create the divider entry if we're supposed to
|
||||
if (create_divider && show_dividers_) {
|
||||
QString divider_key = DividerKey(type, item);
|
||||
QString divider_key = DividerKey(group_by, item);
|
||||
if (!divider_key.isEmpty()) {
|
||||
item->sort_text.prepend(divider_key + " ");
|
||||
}
|
||||
@ -1621,7 +1624,7 @@ void CollectionModel::FinishItem(const GroupBy type, const bool signal, const bo
|
||||
|
||||
CollectionItem *divider = new CollectionItem(CollectionItem::Type_Divider, root_);
|
||||
divider->key = divider_key;
|
||||
divider->display_text = DividerDisplayText(type, divider_key);
|
||||
divider->display_text = DividerDisplayText(group_by, divider_key);
|
||||
divider->sort_text = divider_key + " ";
|
||||
divider->lazy_loaded = true;
|
||||
|
||||
@ -1875,12 +1878,15 @@ bool CollectionModel::canFetchMore(const QModelIndex &parent) const {
|
||||
|
||||
}
|
||||
|
||||
void CollectionModel::SetGroupBy(const Grouping g) {
|
||||
void CollectionModel::SetGroupBy(const Grouping g, const std::optional<bool> separate_albums_by_grouping) {
|
||||
|
||||
group_by_ = g;
|
||||
if (separate_albums_by_grouping) {
|
||||
separate_albums_by_grouping_ = separate_albums_by_grouping.value();
|
||||
}
|
||||
|
||||
ResetAsync();
|
||||
emit GroupingChanged(g);
|
||||
emit GroupingChanged(g, separate_albums_by_grouping_);
|
||||
|
||||
}
|
||||
|
||||
|
@ -24,6 +24,8 @@
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <optional>
|
||||
|
||||
#include <QtGlobal>
|
||||
#include <QObject>
|
||||
#include <QAbstractItemModel>
|
||||
@ -64,8 +66,6 @@ class CollectionModel : public SimpleTreeModel<CollectionItem> {
|
||||
explicit CollectionModel(CollectionBackend *backend, Application *app, QObject *parent = nullptr);
|
||||
~CollectionModel() override;
|
||||
|
||||
static const char *kSavedGroupingsSettingsGroup;
|
||||
|
||||
static const int kPrettyCoverSize;
|
||||
static const char *kPixmapDiskCacheDir;
|
||||
|
||||
@ -160,9 +160,6 @@ class CollectionModel : public SimpleTreeModel<CollectionItem> {
|
||||
// Whether or not to show letters heading in the collection view
|
||||
void set_show_dividers(const bool show_dividers);
|
||||
|
||||
// Save the current grouping
|
||||
void SaveGrouping(const QString &name);
|
||||
|
||||
// Reload settings.
|
||||
void ReloadSettings();
|
||||
|
||||
@ -195,15 +192,15 @@ class CollectionModel : public SimpleTreeModel<CollectionItem> {
|
||||
void ExpandAll(CollectionItem *item = nullptr) const;
|
||||
|
||||
const CollectionModel::Grouping GetGroupBy() const { return group_by_; }
|
||||
void SetGroupBy(const CollectionModel::Grouping g);
|
||||
void SetGroupBy(const CollectionModel::Grouping g, const std::optional<bool> separate_albums_by_grouping);
|
||||
|
||||
static QString ContainerKey(const GroupBy type, const Song &song);
|
||||
static QString ContainerKey(const GroupBy group_by, const bool separate_albums_by_grouping, const Song &song);
|
||||
|
||||
signals:
|
||||
void TotalSongCountUpdated(int count);
|
||||
void TotalArtistCountUpdated(int count);
|
||||
void TotalAlbumCountUpdated(int count);
|
||||
void GroupingChanged(CollectionModel::Grouping g);
|
||||
void GroupingChanged(CollectionModel::Grouping g, bool separate_albums_by_grouping);
|
||||
|
||||
public slots:
|
||||
void SetFilterAge(const int age);
|
||||
@ -247,22 +244,22 @@ class CollectionModel : public SimpleTreeModel<CollectionItem> {
|
||||
// Functions for working with queries and creating items.
|
||||
// When the model is reset or when a node is lazy-loaded the Collection constructs a database query to populate the items.
|
||||
// Filters are added for each parent item, restricting the songs returned to a particular album or artist for example.
|
||||
static void InitQuery(const GroupBy type, CollectionQuery *q);
|
||||
static void FilterQuery(const GroupBy type, CollectionItem *item, CollectionQuery *q);
|
||||
static void InitQuery(const GroupBy group_by, const bool separate_albums_by_grouping, CollectionQuery *q);
|
||||
static void FilterQuery(const GroupBy group_by, const bool separate_albums_by_grouping, CollectionItem *item, CollectionQuery *q);
|
||||
|
||||
// Items can be created either from a query that's been run to populate a node, or by a spontaneous SongsDiscovered emission from the backend.
|
||||
CollectionItem *ItemFromQuery(const GroupBy type, const bool signal, const bool create_divider, CollectionItem *parent, const SqlRow &row, const int container_level);
|
||||
CollectionItem *ItemFromSong(const GroupBy type, const bool signal, const bool create_divider, CollectionItem *parent, const Song &s, const int container_level);
|
||||
CollectionItem *ItemFromQuery(const GroupBy group_by, const bool separate_albums_by_grouping, const bool signal, const bool create_divider, CollectionItem *parent, const SqlRow &row, const int container_level);
|
||||
CollectionItem *ItemFromSong(const GroupBy group_by, const bool separate_albums_by_grouping, const bool signal, const bool create_divider, CollectionItem *parent, const Song &s, const int container_level);
|
||||
|
||||
// The "Various Artists" node is an annoying special case.
|
||||
CollectionItem *CreateCompilationArtistNode(const bool signal, CollectionItem *parent);
|
||||
|
||||
// Helpers for ItemFromQuery and ItemFromSong
|
||||
CollectionItem *InitItem(const GroupBy type, const bool signal, CollectionItem *parent, const int container_level);
|
||||
void FinishItem(const GroupBy type, const bool signal, const bool create_divider, CollectionItem *parent, CollectionItem *item);
|
||||
CollectionItem *InitItem(const GroupBy group_by, const bool signal, CollectionItem *parent, const int container_level);
|
||||
void FinishItem(const GroupBy group_by, const bool signal, const bool create_divider, CollectionItem *parent, CollectionItem *item);
|
||||
|
||||
static QString DividerKey(const GroupBy type, CollectionItem *item);
|
||||
static QString DividerDisplayText(const GroupBy type, const QString &key);
|
||||
static QString DividerKey(const GroupBy group_by, CollectionItem *item);
|
||||
static QString DividerDisplayText(const GroupBy group_by, const QString &key);
|
||||
|
||||
// Helpers
|
||||
static bool IsCompilationArtistNode(const CollectionItem *node) { return node == node->parent->compilation_artist_node_; }
|
||||
@ -284,6 +281,7 @@ class CollectionModel : public SimpleTreeModel<CollectionItem> {
|
||||
|
||||
QueryOptions query_options_;
|
||||
Grouping group_by_;
|
||||
bool separate_albums_by_grouping_;
|
||||
|
||||
// Keyed on database ID
|
||||
QMap<int, CollectionItem*> song_nodes_;
|
||||
|
@ -108,22 +108,31 @@ GroupByDialog::GroupByDialog(QWidget *parent) : QDialog(parent), ui_(new Ui_Grou
|
||||
GroupByDialog::~GroupByDialog() = default;
|
||||
|
||||
void GroupByDialog::Reset() {
|
||||
|
||||
ui_->combobox_first->setCurrentIndex(2); // Album Artist
|
||||
ui_->combobox_second->setCurrentIndex(3); // Album
|
||||
ui_->combobox_second->setCurrentIndex(4); // Album Disc
|
||||
ui_->combobox_third->setCurrentIndex(0); // None
|
||||
ui_->checkbox_separate_albums_by_grouping->setChecked(false);
|
||||
|
||||
}
|
||||
|
||||
void GroupByDialog::accept() {
|
||||
|
||||
emit Accepted(CollectionModel::Grouping(
|
||||
p_->mapping_.get<tag_index>().find(ui_->combobox_first->currentIndex())->group_by,
|
||||
p_->mapping_.get<tag_index>().find(ui_->combobox_second->currentIndex())->group_by,
|
||||
p_->mapping_.get<tag_index>().find(ui_->combobox_third->currentIndex())->group_by)
|
||||
p_->mapping_.get<tag_index>().find(ui_->combobox_third->currentIndex())->group_by),
|
||||
ui_->checkbox_separate_albums_by_grouping->isChecked()
|
||||
);
|
||||
QDialog::accept();
|
||||
|
||||
}
|
||||
|
||||
void GroupByDialog::CollectionGroupingChanged(const CollectionModel::Grouping g) {
|
||||
void GroupByDialog::CollectionGroupingChanged(const CollectionModel::Grouping g, const bool separate_albums_by_grouping) {
|
||||
|
||||
ui_->combobox_first->setCurrentIndex(p_->mapping_.get<tag_group_by>().find(g[0])->combo_box_index);
|
||||
ui_->combobox_second->setCurrentIndex(p_->mapping_.get<tag_group_by>().find(g[1])->combo_box_index);
|
||||
ui_->combobox_third->setCurrentIndex(p_->mapping_.get<tag_group_by>().find(g[2])->combo_box_index);
|
||||
ui_->checkbox_separate_albums_by_grouping->setChecked(separate_albums_by_grouping);
|
||||
|
||||
}
|
||||
|
@ -45,11 +45,11 @@ class GroupByDialog : public QDialog {
|
||||
~GroupByDialog() override;
|
||||
|
||||
public slots:
|
||||
void CollectionGroupingChanged(const CollectionModel::Grouping g);
|
||||
void CollectionGroupingChanged(const CollectionModel::Grouping g, const bool separate_albums_by_grouping);
|
||||
void accept() override;
|
||||
|
||||
signals:
|
||||
void Accepted(CollectionModel::Grouping g);
|
||||
void Accepted(CollectionModel::Grouping g, bool separate_albums_by_grouping);
|
||||
|
||||
private slots:
|
||||
void Reset();
|
||||
|
@ -6,8 +6,8 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>354</width>
|
||||
<height>246</height>
|
||||
<width>394</width>
|
||||
<height>273</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
@ -370,6 +370,13 @@
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="checkbox_separate_albums_by_grouping">
|
||||
<property name="text">
|
||||
<string>Separate albums by grouping tag</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="spacer_bottom">
|
||||
<property name="orientation">
|
||||
|
@ -2,7 +2,7 @@
|
||||
* Strawberry Music Player
|
||||
* This file was part of Clementine.
|
||||
* Copyright 2015, Nick Lanham <nick@afternight.org>
|
||||
* Copyright 2019-2021, Jonas Kvinge <jonas@jkvinge.net>
|
||||
* Copyright 2019-2022, 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
|
||||
@ -22,35 +22,31 @@
|
||||
#include "config.h"
|
||||
|
||||
#include <QDialog>
|
||||
#include <QWidget>
|
||||
#include <QStandardItemModel>
|
||||
#include <QItemSelectionModel>
|
||||
#include <QAbstractItemModel>
|
||||
#include <QIODevice>
|
||||
#include <QDataStream>
|
||||
#include <QByteArray>
|
||||
#include <QList>
|
||||
#include <QVariant>
|
||||
#include <QByteArray>
|
||||
#include <QString>
|
||||
#include <QStringList>
|
||||
#include <QIODevice>
|
||||
#include <QDataStream>
|
||||
#include <QKeySequence>
|
||||
#include <QPushButton>
|
||||
#include <QTreeView>
|
||||
#include <QSettings>
|
||||
#include <QtDebug>
|
||||
|
||||
#include "core/logging.h"
|
||||
#include "core/iconloader.h"
|
||||
#include "collectionfilterwidget.h"
|
||||
#include "collectionmodel.h"
|
||||
#include "savedgroupingmanager.h"
|
||||
#include "ui_savedgroupingmanager.h"
|
||||
|
||||
SavedGroupingManager::SavedGroupingManager(QWidget *parent)
|
||||
const char *SavedGroupingManager::kSavedGroupingsSettingsGroup = "SavedGroupings";
|
||||
|
||||
SavedGroupingManager::SavedGroupingManager(const QString &saved_groupings_settings_group, QWidget *parent)
|
||||
: QDialog(parent),
|
||||
ui_(new Ui_SavedGroupingManager),
|
||||
model_(new QStandardItemModel(0, 4, this)),
|
||||
filter_(nullptr) {
|
||||
saved_groupings_settings_group_(saved_groupings_settings_group) {
|
||||
|
||||
ui_->setupUi(this);
|
||||
|
||||
@ -71,7 +67,17 @@ SavedGroupingManager::SavedGroupingManager(QWidget *parent)
|
||||
|
||||
SavedGroupingManager::~SavedGroupingManager() {
|
||||
delete ui_;
|
||||
delete model_;
|
||||
}
|
||||
|
||||
QString SavedGroupingManager::GetSavedGroupingsSettingsGroup(const QString &settings_group) {
|
||||
|
||||
if (settings_group.isEmpty() || settings_group == CollectionSettingsPage::kSettingsGroup) {
|
||||
return kSavedGroupingsSettingsGroup;
|
||||
}
|
||||
else {
|
||||
return QString(kSavedGroupingsSettingsGroup) + "_" + settings_group;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
QString SavedGroupingManager::GroupByToString(const CollectionModel::GroupBy g) {
|
||||
@ -151,7 +157,7 @@ void SavedGroupingManager::UpdateModel() {
|
||||
|
||||
model_->setRowCount(0); // don't use clear, it deletes headers
|
||||
QSettings s;
|
||||
s.beginGroup(CollectionModel::kSavedGroupingsSettingsGroup);
|
||||
s.beginGroup(saved_groupings_settings_group_);
|
||||
int version = s.value("version").toInt();
|
||||
if (version == 1) {
|
||||
QStringList saved = s.childKeys();
|
||||
@ -186,7 +192,7 @@ void SavedGroupingManager::Remove() {
|
||||
|
||||
if (ui_->list->selectionModel()->hasSelection()) {
|
||||
QSettings s;
|
||||
s.beginGroup(CollectionModel::kSavedGroupingsSettingsGroup);
|
||||
s.beginGroup(saved_groupings_settings_group_);
|
||||
for (const QModelIndex &idx : ui_->list->selectionModel()->selectedRows()) {
|
||||
if (idx.isValid()) {
|
||||
qLog(Debug) << "Remove saved grouping: " << model_->item(idx.row(), 0)->text();
|
||||
@ -196,7 +202,8 @@ void SavedGroupingManager::Remove() {
|
||||
s.endGroup();
|
||||
}
|
||||
UpdateModel();
|
||||
filter_->UpdateGroupByActions();
|
||||
|
||||
emit UpdateGroupByActions();
|
||||
|
||||
}
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
* Strawberry Music Player
|
||||
* This file was part of Clementine.
|
||||
* Copyright 2015, Nick Lanham <nick@afternight.org>
|
||||
* Copyright 2019-2021, Jonas Kvinge <jonas@jkvinge.net>
|
||||
* Copyright 2019-2022, 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
|
||||
@ -40,14 +40,20 @@ class SavedGroupingManager : public QDialog {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit SavedGroupingManager(QWidget *parent = nullptr);
|
||||
explicit SavedGroupingManager(const QString &saved_groupings_settings_group, QWidget *parent = nullptr);
|
||||
~SavedGroupingManager() override;
|
||||
|
||||
static const char *kSavedGroupingsSettingsGroup;
|
||||
|
||||
static QString GetSavedGroupingsSettingsGroup(const QString &settings_group);
|
||||
|
||||
void UpdateModel();
|
||||
void SetFilter(CollectionFilterWidget *filter) { filter_ = filter; }
|
||||
|
||||
static QString GroupByToString(const CollectionModel::GroupBy g);
|
||||
|
||||
signals:
|
||||
void UpdateGroupByActions();
|
||||
|
||||
private slots:
|
||||
void UpdateButtonState();
|
||||
void Remove();
|
||||
@ -55,7 +61,7 @@ class SavedGroupingManager : public QDialog {
|
||||
private:
|
||||
Ui_SavedGroupingManager *ui_;
|
||||
QStandardItemModel *model_;
|
||||
CollectionFilterWidget *filter_;
|
||||
QString saved_groupings_settings_group_;
|
||||
};
|
||||
|
||||
#endif // SAVEDGROUPINGMANAGER_H
|
||||
|
@ -76,6 +76,7 @@
|
||||
#include "collection/collectionfilterwidget.h"
|
||||
#include "collection/collectionmodel.h"
|
||||
#include "collection/groupbydialog.h"
|
||||
#include "collection/savedgroupingmanager.h"
|
||||
#include "covermanager/albumcoverloader.h"
|
||||
#include "covermanager/albumcoverloaderoptions.h"
|
||||
#include "covermanager/albumcoverloaderresult.h"
|
||||
@ -179,7 +180,7 @@ void InternetSearchView::Init(Application *app, InternetService *service) {
|
||||
back_proxy_->sort(0);
|
||||
|
||||
// Add actions to the settings menu
|
||||
group_by_actions_ = CollectionFilterWidget::CreateGroupByActions(this);
|
||||
group_by_actions_ = CollectionFilterWidget::CreateGroupByActions(SavedGroupingManager::GetSavedGroupingsSettingsGroup(service_->settings_group()), this);
|
||||
QMenu *settings_menu = new QMenu(this);
|
||||
settings_menu->addActions(group_by_actions_->actions());
|
||||
settings_menu->addSeparator();
|
||||
|
Loading…
x
Reference in New Issue
Block a user