diff options
author | Max Kellermann <max@duempel.org> | 2009-10-31 17:36:56 +0100 |
---|---|---|
committer | Max Kellermann <max@duempel.org> | 2009-10-31 17:36:56 +0100 |
commit | 1ae4e4dcd3d8a8391f48ed3a551319477964a0c3 (patch) | |
tree | e72712f1faf04861df1b2de7e576ab2b57438536 /src/songvec.c | |
parent | d099a7e46427805711521cad39ce758713c78238 (diff) | |
download | mpd-1ae4e4dcd3d8a8391f48ed3a551319477964a0c3.tar.gz mpd-1ae4e4dcd3d8a8391f48ed3a551319477964a0c3.tar.xz mpd-1ae4e4dcd3d8a8391f48ed3a551319477964a0c3.zip |
songvec: sort songs by album name first, then disc/track number
When the songs of two albums are in the same directory, all songs of
an album should be right next to each others.
Diffstat (limited to '')
-rw-r--r-- | src/songvec.c | 31 |
1 files changed, 30 insertions, 1 deletions
diff --git a/src/songvec.c b/src/songvec.c index 49486bb54..f8f83e6e8 100644 --- a/src/songvec.c +++ b/src/songvec.c @@ -37,6 +37,30 @@ tag_get_value_checked(const struct tag *tag, enum tag_type type) : NULL; } +static int +compare_utf8_string(const char *a, const char *b) +{ + if (a == NULL) + return b == NULL ? 0 : -1; + + if (b == NULL) + return 1; + + return g_utf8_collate(a, b); +} + +/** + * Compare two string tag values, ignoring case. Either one may be + * NULL. + */ +static int +compare_string_tag_item(const struct tag *a, const struct tag *b, + enum tag_type type) +{ + return compare_utf8_string(tag_get_value_checked(a, type), + tag_get_value_checked(b, type)); +} + /** * Compare two tag values which should contain an integer value * (e.g. disc or track number). Either one may be NULL. @@ -70,7 +94,12 @@ static int songvec_cmp(const void *s1, const void *s2) const struct song *b = ((const struct song * const *)s2)[0]; int ret; - /* first sort by disc */ + /* first sort by album */ + ret = compare_string_tag_item(a->tag, b->tag, TAG_ALBUM); + if (ret != 0) + return ret; + + /* then sort by disc */ ret = compare_tag_item(a->tag, b->tag, TAG_DISC); if (ret != 0) return ret; |