Move the GroupBy enum into library so we can get a QMetaEnum from it. Tidy up the logic for the "group by" options by moving it into properties in the .ui file.
This commit is contained in:
parent
3c60423e18
commit
2d12b59951
172
src/library.cpp
172
src/library.cpp
|
@ -22,6 +22,7 @@
|
|||
|
||||
#include <QStringList>
|
||||
#include <QUrl>
|
||||
#include <QMetaEnum>
|
||||
|
||||
#include <boost/bind.hpp>
|
||||
|
||||
|
@ -40,6 +41,10 @@ Library::Library(EngineBase* engine, QObject* parent)
|
|||
no_cover_icon_(":nocover.png")
|
||||
{
|
||||
root_->lazy_loaded = true;
|
||||
|
||||
group_by_[0] = GroupBy_Artist;
|
||||
group_by_[1] = GroupBy_Album;
|
||||
group_by_[2] = GroupBy_None;
|
||||
}
|
||||
|
||||
Library::~Library() {
|
||||
|
@ -127,13 +132,13 @@ void Library::SongsDiscovered(const SongList& songs) {
|
|||
|
||||
// Find parent containers in the tree
|
||||
LibraryItem* container = root_;
|
||||
for (int i=0 ; i<3 ; ++i) {
|
||||
QueryOptions::GroupBy type = query_options_.group_by[i];
|
||||
if (type == QueryOptions::GroupBy_None) break;
|
||||
for (int i=0 ; i<kMaxLevels ; ++i) {
|
||||
GroupBy type = group_by_[i];
|
||||
if (type == GroupBy_None) break;
|
||||
|
||||
// Special case: if we're at the top level and the song is a compilation
|
||||
// and the top level is Artists, then we want the Various Artists node :(
|
||||
if (i == 0 && type == QueryOptions::GroupBy_Artist && song.is_compilation()) {
|
||||
if (i == 0 && type == GroupBy_Artist && song.is_compilation()) {
|
||||
if (compilation_artist_node_ == NULL)
|
||||
CreateCompilationArtistNode(true, root_);
|
||||
container = compilation_artist_node_;
|
||||
|
@ -141,15 +146,15 @@ void Library::SongsDiscovered(const SongList& songs) {
|
|||
// Otherwise find the proper container based on the item's key
|
||||
QString key;
|
||||
switch (type) {
|
||||
case QueryOptions::GroupBy_Album: key = song.album(); break;
|
||||
case QueryOptions::GroupBy_Artist: key = song.artist(); break;
|
||||
case QueryOptions::GroupBy_Composer: key = song.composer(); break;
|
||||
case QueryOptions::GroupBy_Genre: key = song.genre(); break;
|
||||
case QueryOptions::GroupBy_Year:
|
||||
case GroupBy_Album: key = song.album(); break;
|
||||
case GroupBy_Artist: key = song.artist(); break;
|
||||
case GroupBy_Composer: key = song.composer(); break;
|
||||
case GroupBy_Genre: key = song.genre(); break;
|
||||
case GroupBy_Year:
|
||||
key = QString::number(qMax(0, song.year())); break;
|
||||
case QueryOptions::GroupBy_YearAlbum:
|
||||
case GroupBy_YearAlbum:
|
||||
key = PrettyYearAlbum(qMax(0, song.year()), song.album()); break;
|
||||
case QueryOptions::GroupBy_None: Q_ASSERT(0); break;
|
||||
case GroupBy_None: Q_ASSERT(0); break;
|
||||
}
|
||||
|
||||
if (!container_nodes_[i].contains(key)) {
|
||||
|
@ -173,7 +178,7 @@ void Library::SongsDiscovered(const SongList& songs) {
|
|||
// We've gone all the way down to the lowest level, so now we have to
|
||||
// create the song in the container.
|
||||
song_nodes_[song.id()] =
|
||||
ItemFromSong(QueryOptions::GroupBy_None, true, false, container, song);
|
||||
ItemFromSong(GroupBy_None, true, false, container, song);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -193,51 +198,51 @@ LibraryItem* Library::CreateCompilationArtistNode(bool signal, LibraryItem* pare
|
|||
return compilation_artist_node_;
|
||||
}
|
||||
|
||||
QString Library::DividerKey(QueryOptions::GroupBy type,
|
||||
QString Library::DividerKey(GroupBy type,
|
||||
LibraryItem* item) const {
|
||||
if (item->sort_text.isEmpty())
|
||||
return QString();
|
||||
|
||||
switch (type) {
|
||||
case QueryOptions::GroupBy_Album:
|
||||
case QueryOptions::GroupBy_Artist:
|
||||
case QueryOptions::GroupBy_Composer:
|
||||
case QueryOptions::GroupBy_Genre:
|
||||
case GroupBy_Album:
|
||||
case GroupBy_Artist:
|
||||
case GroupBy_Composer:
|
||||
case GroupBy_Genre:
|
||||
if (item->sort_text[0].isDigit())
|
||||
return "0";
|
||||
if (item->sort_text[0] == ' ')
|
||||
return QString();
|
||||
return QString(item->sort_text[0]);
|
||||
|
||||
case QueryOptions::GroupBy_Year:
|
||||
case GroupBy_Year:
|
||||
return QString::number(item->sort_text.toInt() / 10 * 10);
|
||||
|
||||
case QueryOptions::GroupBy_YearAlbum:
|
||||
case GroupBy_YearAlbum:
|
||||
return QString::number(item->metadata.year());
|
||||
|
||||
case QueryOptions::GroupBy_None:
|
||||
case GroupBy_None:
|
||||
default:
|
||||
Q_ASSERT(0);
|
||||
return QString();
|
||||
}
|
||||
}
|
||||
|
||||
QString Library::DividerDisplayText(QueryOptions::GroupBy type,
|
||||
QString Library::DividerDisplayText(GroupBy type,
|
||||
const QString& key) const {
|
||||
switch (type) {
|
||||
case QueryOptions::GroupBy_Album:
|
||||
case QueryOptions::GroupBy_Artist:
|
||||
case QueryOptions::GroupBy_Composer:
|
||||
case QueryOptions::GroupBy_Genre:
|
||||
case GroupBy_Album:
|
||||
case GroupBy_Artist:
|
||||
case GroupBy_Composer:
|
||||
case GroupBy_Genre:
|
||||
if (key == "0")
|
||||
return "0-9";
|
||||
// fallthrough
|
||||
|
||||
case QueryOptions::GroupBy_Year:
|
||||
case QueryOptions::GroupBy_YearAlbum:
|
||||
case GroupBy_Year:
|
||||
case GroupBy_YearAlbum:
|
||||
return key;
|
||||
|
||||
case QueryOptions::GroupBy_None:
|
||||
case GroupBy_None:
|
||||
default:
|
||||
Q_ASSERT(0);
|
||||
return QString();
|
||||
|
@ -283,7 +288,7 @@ void Library::SongsDeleted(const SongList& songs) {
|
|||
|
||||
// Maybe consider its divider node
|
||||
if (node->container_level == 0)
|
||||
divider_keys << DividerKey(query_options_.group_by[0], node);
|
||||
divider_keys << DividerKey(group_by_[0], node);
|
||||
|
||||
// Special case the Various Artists node
|
||||
if (node == compilation_artist_node_)
|
||||
|
@ -305,7 +310,7 @@ void Library::SongsDeleted(const SongList& songs) {
|
|||
|
||||
bool found = false;
|
||||
foreach (LibraryItem* node, container_nodes_[0].values()) {
|
||||
if (DividerKey(query_options_.group_by[0], node) == divider_key) {
|
||||
if (DividerKey(group_by_[0], node) == divider_key) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
|
@ -330,9 +335,9 @@ QVariant Library::data(const QModelIndex& index, int role) const {
|
|||
}
|
||||
|
||||
QVariant Library::data(const LibraryItem* item, int role) const {
|
||||
QueryOptions::GroupBy container_type =
|
||||
GroupBy container_type =
|
||||
item->type == LibraryItem::Type_Container ?
|
||||
query_options_.group_by[item->container_level] : QueryOptions::GroupBy_None;
|
||||
group_by_[item->container_level] : GroupBy_None;
|
||||
|
||||
switch (role) {
|
||||
case Qt::DisplayRole:
|
||||
|
@ -342,9 +347,9 @@ QVariant Library::data(const LibraryItem* item, int role) const {
|
|||
switch (item->type)
|
||||
case LibraryItem::Type_Container:
|
||||
switch (container_type) {
|
||||
case QueryOptions::GroupBy_Album:
|
||||
case GroupBy_Album:
|
||||
return album_icon_;
|
||||
case QueryOptions::GroupBy_Artist:
|
||||
case GroupBy_Artist:
|
||||
return artist_icon_;
|
||||
default:
|
||||
break;
|
||||
|
@ -380,21 +385,21 @@ void Library::LazyPopulate(LibraryItem* parent, bool signal) {
|
|||
|
||||
// Information about what we want the children to be
|
||||
int child_level = parent->container_level + 1;
|
||||
QueryOptions::GroupBy child_type = query_options_.group_by[child_level];
|
||||
GroupBy child_type = group_by_[child_level];
|
||||
|
||||
// Initialise the query
|
||||
LibraryQuery q(query_options_);
|
||||
InitQuery(child_type, &q);
|
||||
|
||||
// Top-level artists is special - we don't want compilation albums appearing
|
||||
if (child_level == 0 && child_type == QueryOptions::GroupBy_Artist) {
|
||||
if (child_level == 0 && child_type == GroupBy_Artist) {
|
||||
q.AddCompilationRequirement(false);
|
||||
}
|
||||
|
||||
// Walk up through the item's parents adding filters as necessary
|
||||
LibraryItem* p = parent;
|
||||
while (p != root_) {
|
||||
FilterQuery(query_options_.group_by[p->container_level], p, &q);
|
||||
FilterQuery(group_by_[p->container_level], p, &q);
|
||||
p = p->parent;
|
||||
}
|
||||
|
||||
|
@ -410,7 +415,7 @@ void Library::LazyPopulate(LibraryItem* parent, bool signal) {
|
|||
item->container_level = child_level;
|
||||
|
||||
// Save a pointer to it for later
|
||||
if (child_type == QueryOptions::GroupBy_None)
|
||||
if (child_type == GroupBy_None)
|
||||
song_nodes_[item->metadata.id()] = item;
|
||||
else
|
||||
container_nodes_[child_level][item->key] = item;
|
||||
|
@ -430,7 +435,7 @@ void Library::Reset() {
|
|||
root_->lazy_loaded = false;
|
||||
|
||||
// Various artists?
|
||||
if (query_options_.group_by[0] == QueryOptions::GroupBy_Artist &&
|
||||
if (group_by_[0] == GroupBy_Artist &&
|
||||
backend_->Worker()->HasCompilations(query_options_))
|
||||
CreateCompilationArtistNode(false, root_);
|
||||
|
||||
|
@ -440,36 +445,36 @@ void Library::Reset() {
|
|||
reset();
|
||||
}
|
||||
|
||||
void Library::InitQuery(QueryOptions::GroupBy type, LibraryQuery* q) {
|
||||
void Library::InitQuery(GroupBy type, LibraryQuery* q) {
|
||||
switch (type) {
|
||||
case QueryOptions::GroupBy_Artist:
|
||||
case GroupBy_Artist:
|
||||
q->SetColumnSpec("DISTINCT artist");
|
||||
break;
|
||||
case QueryOptions::GroupBy_Album:
|
||||
case GroupBy_Album:
|
||||
q->SetColumnSpec("DISTINCT album");
|
||||
break;
|
||||
case QueryOptions::GroupBy_Composer:
|
||||
case GroupBy_Composer:
|
||||
q->SetColumnSpec("DISTINCT composer");
|
||||
break;
|
||||
case QueryOptions::GroupBy_YearAlbum:
|
||||
case GroupBy_YearAlbum:
|
||||
q->SetColumnSpec("DISTINCT year, album");
|
||||
break;
|
||||
case QueryOptions::GroupBy_Year:
|
||||
case GroupBy_Year:
|
||||
q->SetColumnSpec("DISTINCT year");
|
||||
break;
|
||||
case QueryOptions::GroupBy_Genre:
|
||||
case GroupBy_Genre:
|
||||
q->SetColumnSpec("DISTINCT genre");
|
||||
break;
|
||||
case QueryOptions::GroupBy_None:
|
||||
case GroupBy_None:
|
||||
q->SetColumnSpec("ROWID, " + QString(Song::kColumnSpec));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Library::FilterQuery(QueryOptions::GroupBy type, LibraryItem* item,
|
||||
void Library::FilterQuery(GroupBy type, LibraryItem* item,
|
||||
LibraryQuery* q) {
|
||||
switch (type) {
|
||||
case QueryOptions::GroupBy_Artist:
|
||||
case GroupBy_Artist:
|
||||
if (item == compilation_artist_node_)
|
||||
q->AddCompilationRequirement(true);
|
||||
else {
|
||||
|
@ -478,32 +483,32 @@ void Library::FilterQuery(QueryOptions::GroupBy type, LibraryItem* item,
|
|||
q->AddWhere("artist", item->key);
|
||||
}
|
||||
break;
|
||||
case QueryOptions::GroupBy_Album:
|
||||
case GroupBy_Album:
|
||||
q->AddWhere("album", item->key);
|
||||
break;
|
||||
case QueryOptions::GroupBy_YearAlbum:
|
||||
case GroupBy_YearAlbum:
|
||||
q->AddWhere("year", item->metadata.year());
|
||||
q->AddWhere("album", item->metadata.album());
|
||||
break;
|
||||
case QueryOptions::GroupBy_Year:
|
||||
case GroupBy_Year:
|
||||
q->AddWhere("year", item->key);
|
||||
break;
|
||||
case QueryOptions::GroupBy_Composer:
|
||||
case GroupBy_Composer:
|
||||
q->AddWhere("composer", item->key);
|
||||
break;
|
||||
case QueryOptions::GroupBy_Genre:
|
||||
case GroupBy_Genre:
|
||||
q->AddWhere("genre", item->key);
|
||||
break;
|
||||
case QueryOptions::GroupBy_None:
|
||||
case GroupBy_None:
|
||||
Q_ASSERT(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
LibraryItem* Library::InitItem(QueryOptions::GroupBy type,
|
||||
LibraryItem* Library::InitItem(GroupBy type,
|
||||
bool signal, LibraryItem *parent) {
|
||||
LibraryItem::Type item_type =
|
||||
type == QueryOptions::GroupBy_None ? LibraryItem::Type_Song :
|
||||
type == GroupBy_None ? LibraryItem::Type_Song :
|
||||
LibraryItem::Type_Container;
|
||||
|
||||
if (signal)
|
||||
|
@ -514,20 +519,20 @@ LibraryItem* Library::InitItem(QueryOptions::GroupBy type,
|
|||
return new LibraryItem(item_type, parent);
|
||||
}
|
||||
|
||||
LibraryItem* Library::ItemFromQuery(QueryOptions::GroupBy type,
|
||||
LibraryItem* Library::ItemFromQuery(GroupBy type,
|
||||
bool signal, bool create_divider,
|
||||
LibraryItem* parent, const LibraryQuery& q) {
|
||||
LibraryItem* item = InitItem(type, signal, parent);
|
||||
int year = 0;
|
||||
|
||||
switch (type) {
|
||||
case QueryOptions::GroupBy_Artist:
|
||||
case GroupBy_Artist:
|
||||
item->key = q.Value(0).toString();
|
||||
item->display_text = TextOrUnknown(item->key);
|
||||
item->sort_text = SortTextForArtist(item->key);
|
||||
break;
|
||||
|
||||
case QueryOptions::GroupBy_YearAlbum:
|
||||
case GroupBy_YearAlbum:
|
||||
year = qMax(0, q.Value(0).toInt());
|
||||
item->metadata.set_year(year);
|
||||
item->metadata.set_album(q.Value(1).toString());
|
||||
|
@ -535,21 +540,21 @@ LibraryItem* Library::ItemFromQuery(QueryOptions::GroupBy type,
|
|||
item->sort_text = SortTextForYear(year) + item->metadata.album();
|
||||
break;
|
||||
|
||||
case QueryOptions::GroupBy_Year:
|
||||
case GroupBy_Year:
|
||||
year = qMax(0, q.Value(0).toInt());
|
||||
item->key = QString::number(year);
|
||||
item->sort_text = SortTextForYear(year);
|
||||
break;
|
||||
|
||||
case QueryOptions::GroupBy_Composer:
|
||||
case QueryOptions::GroupBy_Genre:
|
||||
case QueryOptions::GroupBy_Album:
|
||||
case GroupBy_Composer:
|
||||
case GroupBy_Genre:
|
||||
case GroupBy_Album:
|
||||
item->key = q.Value(0).toString();
|
||||
item->display_text = TextOrUnknown(item->key);
|
||||
item->sort_text = SortText(item->key);
|
||||
break;
|
||||
|
||||
case QueryOptions::GroupBy_None:
|
||||
case GroupBy_None:
|
||||
item->metadata.InitFromQuery(q);
|
||||
item->key = item->metadata.title();
|
||||
item->display_text = item->metadata.PrettyTitleWithArtist();
|
||||
|
@ -560,20 +565,20 @@ LibraryItem* Library::ItemFromQuery(QueryOptions::GroupBy type,
|
|||
return item;
|
||||
}
|
||||
|
||||
LibraryItem* Library::ItemFromSong(QueryOptions::GroupBy type,
|
||||
LibraryItem* Library::ItemFromSong(GroupBy type,
|
||||
bool signal, bool create_divider,
|
||||
LibraryItem* parent, const Song& s) {
|
||||
LibraryItem* item = InitItem(type, signal, parent);
|
||||
int year = 0;
|
||||
|
||||
switch (type) {
|
||||
case QueryOptions::GroupBy_Artist:
|
||||
case GroupBy_Artist:
|
||||
item->key = s.artist();
|
||||
item->display_text = TextOrUnknown(item->key);
|
||||
item->sort_text = SortTextForArtist(item->key);
|
||||
break;
|
||||
|
||||
case QueryOptions::GroupBy_YearAlbum:
|
||||
case GroupBy_YearAlbum:
|
||||
year = qMax(0, s.year());
|
||||
item->metadata.set_year(year);
|
||||
item->metadata.set_album(s.album());
|
||||
|
@ -581,20 +586,20 @@ LibraryItem* Library::ItemFromSong(QueryOptions::GroupBy type,
|
|||
item->sort_text = SortTextForYear(year) + s.album();
|
||||
break;
|
||||
|
||||
case QueryOptions::GroupBy_Year:
|
||||
case GroupBy_Year:
|
||||
year = qMax(0, s.year());
|
||||
item->key = QString::number(year);
|
||||
item->sort_text = SortTextForYear(year);
|
||||
break;
|
||||
|
||||
case QueryOptions::GroupBy_Composer: item->key = s.composer();
|
||||
case QueryOptions::GroupBy_Genre: if (item->key.isNull()) item->key = s.genre();
|
||||
case QueryOptions::GroupBy_Album: if (item->key.isNull()) item->key = s.album();
|
||||
case GroupBy_Composer: item->key = s.composer();
|
||||
case GroupBy_Genre: if (item->key.isNull()) item->key = s.genre();
|
||||
case GroupBy_Album: if (item->key.isNull()) item->key = s.album();
|
||||
item->display_text = TextOrUnknown(item->key);
|
||||
item->sort_text = SortText(item->key);
|
||||
break;
|
||||
|
||||
case QueryOptions::GroupBy_None:
|
||||
case GroupBy_None:
|
||||
item->metadata = s;
|
||||
item->key = s.title();
|
||||
item->display_text = s.PrettyTitleWithArtist();
|
||||
|
@ -605,10 +610,10 @@ LibraryItem* Library::ItemFromSong(QueryOptions::GroupBy type,
|
|||
return item;
|
||||
}
|
||||
|
||||
void Library::FinishItem(QueryOptions::GroupBy type,
|
||||
void Library::FinishItem(GroupBy type,
|
||||
bool signal, bool create_divider,
|
||||
LibraryItem *parent, LibraryItem *item) {
|
||||
if (type == QueryOptions::GroupBy_None)
|
||||
if (type == GroupBy_None)
|
||||
item->lazy_loaded = true;
|
||||
|
||||
if (signal)
|
||||
|
@ -767,11 +772,20 @@ bool Library::canFetchMore(const QModelIndex &parent) const {
|
|||
return !item->lazy_loaded;
|
||||
}
|
||||
|
||||
void Library::SetGroupBy(QueryOptions::GroupBy g[3]) {
|
||||
query_options_.group_by[0] = g[0];
|
||||
query_options_.group_by[1] = g[1];
|
||||
query_options_.group_by[2] = g[2];
|
||||
void Library::SetGroupBy(GroupBy g[kMaxLevels]) {
|
||||
group_by_[0] = g[0];
|
||||
group_by_[1] = g[1];
|
||||
group_by_[2] = g[2];
|
||||
|
||||
if (!waiting_for_threads_)
|
||||
Reset();
|
||||
}
|
||||
|
||||
QMetaEnum Library::GroupByEnum() const {
|
||||
const QMetaObject* o = metaObject();
|
||||
for (int i=0 ; i<o->enumeratorCount() ; ++i) {
|
||||
if (o->enumerator(i).name() == QString("GroupBy"))
|
||||
return o->enumerator(i);
|
||||
}
|
||||
return QMetaEnum();
|
||||
}
|
||||
|
|
|
@ -35,6 +35,7 @@ class LibraryDirectoryModel;
|
|||
|
||||
class Library : public SimpleTreeModel<LibraryItem> {
|
||||
Q_OBJECT
|
||||
Q_ENUMS(GroupBy);
|
||||
|
||||
public:
|
||||
Library(EngineBase* engine, QObject* parent = 0);
|
||||
|
@ -48,6 +49,20 @@ class Library : public SimpleTreeModel<LibraryItem> {
|
|||
Role_Artist,
|
||||
};
|
||||
|
||||
// These values get saved in QSettings - don't change them
|
||||
enum GroupBy {
|
||||
GroupBy_None = 0,
|
||||
GroupBy_Artist = 1,
|
||||
GroupBy_Album = 2,
|
||||
GroupBy_YearAlbum = 3,
|
||||
GroupBy_Year = 4,
|
||||
GroupBy_Composer = 5,
|
||||
GroupBy_Genre = 6,
|
||||
};
|
||||
QMetaEnum GroupByEnum() const;
|
||||
|
||||
static const int kMaxLevels = 3;
|
||||
|
||||
// Useful for tests. The library takes ownership.
|
||||
void set_backend_factory(BackgroundThreadFactory<LibraryBackendInterface>* factory);
|
||||
void set_watcher_factory(BackgroundThreadFactory<LibraryWatcher>* factory);
|
||||
|
@ -81,7 +96,7 @@ class Library : public SimpleTreeModel<LibraryItem> {
|
|||
public slots:
|
||||
void SetFilterAge(int age);
|
||||
void SetFilterText(const QString& text);
|
||||
void SetGroupBy(QueryOptions::GroupBy g[3]);
|
||||
void SetGroupBy(GroupBy g[kMaxLevels]);
|
||||
|
||||
protected:
|
||||
void LazyPopulate(LibraryItem* item) { LazyPopulate(item, false); }
|
||||
|
@ -101,20 +116,17 @@ class Library : public SimpleTreeModel<LibraryItem> {
|
|||
void Initialise();
|
||||
|
||||
// Functions for working with queries and creating items
|
||||
void InitQuery(QueryOptions::GroupBy type, LibraryQuery* q);
|
||||
void FilterQuery(QueryOptions::GroupBy type,
|
||||
LibraryItem* item,LibraryQuery* q);
|
||||
LibraryItem* ItemFromQuery(QueryOptions::GroupBy type,
|
||||
bool signal, bool create_divider,
|
||||
void InitQuery(GroupBy type, LibraryQuery* q);
|
||||
void FilterQuery(GroupBy type, LibraryItem* item,LibraryQuery* q);
|
||||
LibraryItem* ItemFromQuery(GroupBy type, bool signal, bool create_divider,
|
||||
LibraryItem* parent, const LibraryQuery& q);
|
||||
LibraryItem* ItemFromSong(QueryOptions::GroupBy type,
|
||||
bool signal, bool create_divider,
|
||||
LibraryItem* ItemFromSong(GroupBy type, bool signal, bool create_divider,
|
||||
LibraryItem* parent, const Song& s);
|
||||
LibraryItem* CreateCompilationArtistNode(bool signal, LibraryItem* parent);
|
||||
|
||||
// Helpers for ItemFromQuery and ItemFromSong
|
||||
LibraryItem* InitItem(QueryOptions::GroupBy type, bool signal, LibraryItem* parent);
|
||||
void FinishItem(QueryOptions::GroupBy type, bool signal, bool create_divider,
|
||||
LibraryItem* InitItem(GroupBy type, bool signal, LibraryItem* parent);
|
||||
void FinishItem(GroupBy type, bool signal, bool create_divider,
|
||||
LibraryItem* parent, LibraryItem* item);
|
||||
|
||||
// Functions for manipulating text
|
||||
|
@ -125,8 +137,8 @@ class Library : public SimpleTreeModel<LibraryItem> {
|
|||
QString SortTextForArtist(QString artist) const;
|
||||
QString SortTextForYear(int year) const;
|
||||
|
||||
QString DividerKey(QueryOptions::GroupBy type, LibraryItem* item) const;
|
||||
QString DividerDisplayText(QueryOptions::GroupBy type, const QString& key) const;
|
||||
QString DividerKey(GroupBy type, LibraryItem* item) const;
|
||||
QString DividerDisplayText(GroupBy type, const QString& key) const;
|
||||
|
||||
// Helpers
|
||||
QVariant data(const LibraryItem* item, int role) const;
|
||||
|
@ -143,12 +155,13 @@ class Library : public SimpleTreeModel<LibraryItem> {
|
|||
int waiting_for_threads_;
|
||||
|
||||
QueryOptions query_options_;
|
||||
GroupBy group_by_[kMaxLevels];
|
||||
|
||||
// Keyed on database ID
|
||||
QMap<int, LibraryItem*> song_nodes_;
|
||||
|
||||
// Keyed on whatever the key is for that level - artist, album, year, etc.
|
||||
QMap<QString, LibraryItem*> container_nodes_[3];
|
||||
QMap<QString, LibraryItem*> container_nodes_[kMaxLevels];
|
||||
|
||||
// Keyed on a letter, a year, a century, etc.
|
||||
QMap<QString, LibraryItem*> divider_nodes_;
|
||||
|
|
|
@ -24,9 +24,6 @@
|
|||
QueryOptions::QueryOptions()
|
||||
: max_age(-1)
|
||||
{
|
||||
group_by[0] = GroupBy_Artist;
|
||||
group_by[1] = GroupBy_Album;
|
||||
group_by[2] = GroupBy_None;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -28,20 +28,7 @@ class Song;
|
|||
struct QueryOptions {
|
||||
QueryOptions();
|
||||
|
||||
// These values get saved in QSettings - don't change them
|
||||
enum GroupBy {
|
||||
GroupBy_None = 0,
|
||||
GroupBy_Artist = 1,
|
||||
GroupBy_Album = 2,
|
||||
GroupBy_YearAlbum = 3,
|
||||
GroupBy_Year = 4,
|
||||
GroupBy_Composer = 5,
|
||||
GroupBy_Genre = 6,
|
||||
};
|
||||
|
||||
bool Matches(const Song& song) const;
|
||||
|
||||
GroupBy group_by[3];
|
||||
QString filter;
|
||||
int max_age;
|
||||
};
|
||||
|
|
|
@ -179,7 +179,7 @@ void LibraryView::contextMenuEvent(QContextMenuEvent *e) {
|
|||
->mapToSource(context_menu_index_);
|
||||
|
||||
int type = library_->data(context_menu_index_, Library::Role_ContainerType).toInt();
|
||||
bool enable_various = type == QueryOptions::GroupBy_Album;
|
||||
bool enable_various = type == Library::GroupBy_Album;
|
||||
|
||||
show_in_various_->setEnabled(enable_various);
|
||||
no_show_in_various_->setEnabled(enable_various);
|
||||
|
|
|
@ -234,21 +234,21 @@ MainWindow::MainWindow(QNetworkAccessManager* network, QWidget *parent)
|
|||
connect(ui_.library_filter_clear, SIGNAL(clicked()), SLOT(ClearLibraryFilter()));
|
||||
|
||||
// "Group by ..."
|
||||
QActionGroup* group_by_group = new QActionGroup(this);
|
||||
group_by_group->addAction(ui_.group_by_artist);
|
||||
group_by_group->addAction(ui_.group_by_artist_album);
|
||||
group_by_group->addAction(ui_.group_by_artist_yearalbum);
|
||||
group_by_group->addAction(ui_.group_by_album);
|
||||
group_by_group->addAction(ui_.group_by_genre_album);
|
||||
group_by_group->addAction(ui_.group_by_genre_artist_album);
|
||||
group_by_group->addAction(ui_.group_by_advanced);
|
||||
connect(group_by_group, SIGNAL(triggered(QAction*)), SLOT(GroupByClicked(QAction*)));
|
||||
group_by_group_ = new QActionGroup(this);
|
||||
group_by_group_->addAction(ui_.group_by_artist);
|
||||
group_by_group_->addAction(ui_.group_by_artist_album);
|
||||
group_by_group_->addAction(ui_.group_by_artist_yearalbum);
|
||||
group_by_group_->addAction(ui_.group_by_album);
|
||||
group_by_group_->addAction(ui_.group_by_genre_album);
|
||||
group_by_group_->addAction(ui_.group_by_genre_artist_album);
|
||||
group_by_group_->addAction(ui_.group_by_advanced);
|
||||
connect(group_by_group_, SIGNAL(triggered(QAction*)), SLOT(GroupByClicked(QAction*)));
|
||||
|
||||
// Library config menu
|
||||
QMenu* library_menu = new QMenu(this);
|
||||
library_menu->addActions(filter_age_group->actions());
|
||||
library_menu->addSeparator();
|
||||
library_menu->addActions(group_by_group->actions());
|
||||
library_menu->addActions(group_by_group_->actions());
|
||||
library_menu->addSeparator();
|
||||
library_menu->addAction(tr("Configure library..."), library_config_dialog_, SLOT(show()));
|
||||
ui_.library_options->setMenu(library_menu);
|
||||
|
@ -335,10 +335,10 @@ MainWindow::MainWindow(QNetworkAccessManager* network, QWidget *parent)
|
|||
|
||||
ui_.file_view->SetPath(settings_.value("file_path", QDir::homePath()).toString());
|
||||
|
||||
QueryOptions::GroupBy g[3];
|
||||
g[0] = QueryOptions::GroupBy(settings_.value("group_by1", int(QueryOptions::GroupBy_Artist)).toInt());
|
||||
g[1] = QueryOptions::GroupBy(settings_.value("group_by2", int(QueryOptions::GroupBy_Album)).toInt());
|
||||
g[2] = QueryOptions::GroupBy(settings_.value("group_by3", int(QueryOptions::GroupBy_None)).toInt());
|
||||
Library::GroupBy g[Library::kMaxLevels];
|
||||
g[0] = Library::GroupBy(settings_.value("group_by1", int(Library::GroupBy_Artist)).toInt());
|
||||
g[1] = Library::GroupBy(settings_.value("group_by2", int(Library::GroupBy_Album)).toInt());
|
||||
g[2] = Library::GroupBy(settings_.value("group_by3", int(Library::GroupBy_None)).toInt());
|
||||
library_->SetGroupBy(g);
|
||||
UpdateGroupBySelection(g);
|
||||
|
||||
|
@ -799,33 +799,21 @@ void MainWindow::PlaylistRemoveCurrent() {
|
|||
}
|
||||
|
||||
void MainWindow::GroupByClicked(QAction* action) {
|
||||
QueryOptions::GroupBy g[3];
|
||||
g[0] = QueryOptions::GroupBy_None;
|
||||
g[1] = QueryOptions::GroupBy_None;
|
||||
g[2] = QueryOptions::GroupBy_None;
|
||||
Library::GroupBy g[Library::kMaxLevels];
|
||||
for (int i=0 ; i<Library::kMaxLevels ; ++i)
|
||||
g[i] = Library::GroupBy_None;
|
||||
|
||||
if (action == ui_.group_by_album) {
|
||||
g[0] = QueryOptions::GroupBy_Album;
|
||||
} else if (action == ui_.group_by_artist) {
|
||||
g[0] = QueryOptions::GroupBy_Artist;
|
||||
} else if (action == ui_.group_by_artist_album) {
|
||||
g[0] = QueryOptions::GroupBy_Artist;
|
||||
g[1] = QueryOptions::GroupBy_Album;
|
||||
} else if (action == ui_.group_by_artist_yearalbum) {
|
||||
g[0] = QueryOptions::GroupBy_Artist;
|
||||
g[1] = QueryOptions::GroupBy_YearAlbum;
|
||||
} else if (action == ui_.group_by_genre_album) {
|
||||
g[0] = QueryOptions::GroupBy_Genre;
|
||||
g[1] = QueryOptions::GroupBy_Album;
|
||||
} else if (action == ui_.group_by_genre_artist_album) {
|
||||
g[0] = QueryOptions::GroupBy_Genre;
|
||||
g[1] = QueryOptions::GroupBy_Artist;
|
||||
g[2] = QueryOptions::GroupBy_Album;
|
||||
} else {
|
||||
qWarning() << "Unknown action in" << __PRETTY_FUNCTION__;
|
||||
QStringList group_by = action->property("group_by").toStringList();
|
||||
if (group_by.isEmpty()) {
|
||||
qWarning() << __PRETTY_FUNCTION__ << ": Unknown action";
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i=0 ; i<group_by.size() && i<Library::kMaxLevels ; ++i) {
|
||||
g[i] = Library::GroupBy(
|
||||
library_->GroupByEnum().keyToValue(group_by[i].toUtf8().constData()));
|
||||
}
|
||||
|
||||
library_->SetGroupBy(g);
|
||||
|
||||
settings_.setValue("group_by1", int(g[0]));
|
||||
|
@ -833,31 +821,21 @@ void MainWindow::GroupByClicked(QAction* action) {
|
|||
settings_.setValue("group_by3", int(g[2]));
|
||||
}
|
||||
|
||||
void MainWindow::UpdateGroupBySelection(QueryOptions::GroupBy g[3]) {
|
||||
if (g[0] == QueryOptions::GroupBy_Album &&
|
||||
g[1] == QueryOptions::GroupBy_None &&
|
||||
g[2] == QueryOptions::GroupBy_None)
|
||||
ui_.group_by_album->setChecked(true);
|
||||
else if (g[0] == QueryOptions::GroupBy_Artist &&
|
||||
g[1] == QueryOptions::GroupBy_None &&
|
||||
g[2] == QueryOptions::GroupBy_None)
|
||||
ui_.group_by_artist->setChecked(true);
|
||||
else if (g[0] == QueryOptions::GroupBy_Artist &&
|
||||
g[1] == QueryOptions::GroupBy_Album &&
|
||||
g[2] == QueryOptions::GroupBy_None)
|
||||
ui_.group_by_artist_album->setChecked(true);
|
||||
else if (g[0] == QueryOptions::GroupBy_Artist &&
|
||||
g[1] == QueryOptions::GroupBy_YearAlbum &&
|
||||
g[2] == QueryOptions::GroupBy_None)
|
||||
ui_.group_by_artist_yearalbum->setChecked(true);
|
||||
else if (g[0] == QueryOptions::GroupBy_Genre &&
|
||||
g[1] == QueryOptions::GroupBy_Album &&
|
||||
g[2] == QueryOptions::GroupBy_None)
|
||||
ui_.group_by_genre_album->setChecked(true);
|
||||
else if (g[0] == QueryOptions::GroupBy_Genre &&
|
||||
g[1] == QueryOptions::GroupBy_Artist &&
|
||||
g[2] == QueryOptions::GroupBy_Album)
|
||||
ui_.group_by_genre_artist_album->setChecked(true);
|
||||
else
|
||||
ui_.group_by_advanced->setChecked(true);
|
||||
void MainWindow::UpdateGroupBySelection(Library::GroupBy g[Library::kMaxLevels]) {
|
||||
foreach (QAction* action, group_by_group_->actions()) {
|
||||
QStringList group_by = action->property("group_by").toStringList();
|
||||
bool match = true;
|
||||
for (int i=0 ; i<group_by.size() && i<Library::kMaxLevels ; ++i) {
|
||||
if (g[i] != library_->GroupByEnum().keyToValue(group_by[i].toUtf8().constData())) {
|
||||
match = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (match) {
|
||||
action->setChecked(true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
ui_.group_by_advanced->setChecked(true);
|
||||
}
|
||||
|
|
|
@ -107,7 +107,7 @@ class MainWindow : public QMainWindow {
|
|||
|
||||
private:
|
||||
void SaveGeometry();
|
||||
void UpdateGroupBySelection(QueryOptions::GroupBy g[3]);
|
||||
void UpdateGroupBySelection(Library::GroupBy g[Library::kMaxLevels]);
|
||||
|
||||
private:
|
||||
static const int kStateVersion;
|
||||
|
@ -138,6 +138,7 @@ class MainWindow : public QMainWindow {
|
|||
QAction* playlist_play_pause_;
|
||||
QAction* playlist_stop_after_;
|
||||
QModelIndex playlist_menu_index_;
|
||||
QActionGroup* group_by_group_;
|
||||
|
||||
QSortFilterProxyModel* library_sort_model_;
|
||||
|
||||
|
|
|
@ -763,6 +763,13 @@
|
|||
<property name="text">
|
||||
<string>Group by Artist</string>
|
||||
</property>
|
||||
<property name="group_by" stdset="0">
|
||||
<stringlist>
|
||||
<string>GroupBy_Artist</string>
|
||||
<string>GroupBy_None</string>
|
||||
<string>GroupBy_None</string>
|
||||
</stringlist>
|
||||
</property>
|
||||
</action>
|
||||
<action name="group_by_artist_album">
|
||||
<property name="checkable">
|
||||
|
@ -771,6 +778,13 @@
|
|||
<property name="text">
|
||||
<string>Group by Artist/Album</string>
|
||||
</property>
|
||||
<property name="group_by" stdset="0">
|
||||
<stringlist>
|
||||
<string>GroupBy_Artist</string>
|
||||
<string>GroupBy_Album</string>
|
||||
<string>GroupBy_None</string>
|
||||
</stringlist>
|
||||
</property>
|
||||
</action>
|
||||
<action name="group_by_artist_yearalbum">
|
||||
<property name="checkable">
|
||||
|
@ -779,6 +793,13 @@
|
|||
<property name="text">
|
||||
<string>Group by Artist/Year - Album</string>
|
||||
</property>
|
||||
<property name="group_by" stdset="0">
|
||||
<stringlist>
|
||||
<string>GroupBy_Artist</string>
|
||||
<string>GroupBy_YearAlbum</string>
|
||||
<string>GroupBy_None</string>
|
||||
</stringlist>
|
||||
</property>
|
||||
</action>
|
||||
<action name="group_by_album">
|
||||
<property name="checkable">
|
||||
|
@ -787,6 +808,13 @@
|
|||
<property name="text">
|
||||
<string>Group by Album</string>
|
||||
</property>
|
||||
<property name="group_by" stdset="0">
|
||||
<stringlist>
|
||||
<string>GroupBy_Album</string>
|
||||
<string>GroupBy_None</string>
|
||||
<string>GroupBy_None</string>
|
||||
</stringlist>
|
||||
</property>
|
||||
</action>
|
||||
<action name="group_by_genre_album">
|
||||
<property name="checkable">
|
||||
|
@ -795,6 +823,13 @@
|
|||
<property name="text">
|
||||
<string>Group by Genre/Album</string>
|
||||
</property>
|
||||
<property name="group_by" stdset="0">
|
||||
<stringlist>
|
||||
<string>GroupBy_Genre</string>
|
||||
<string>GroupBy_Album</string>
|
||||
<string>GroupBy_None</string>
|
||||
</stringlist>
|
||||
</property>
|
||||
</action>
|
||||
<action name="group_by_genre_artist_album">
|
||||
<property name="checkable">
|
||||
|
@ -803,6 +838,13 @@
|
|||
<property name="text">
|
||||
<string>Group by Genre/Artist/Album</string>
|
||||
</property>
|
||||
<property name="group_by" stdset="0">
|
||||
<stringlist>
|
||||
<string>GroupBy_Genre</string>
|
||||
<string>GroupBy_Artist</string>
|
||||
<string>GroupBy_Album</string>
|
||||
</stringlist>
|
||||
</property>
|
||||
</action>
|
||||
<action name="group_by_advanced">
|
||||
<property name="checkable">
|
||||
|
|
Loading…
Reference in New Issue