From b6c07212668b7d9397b81a92c44d60f6dfdf548a Mon Sep 17 00:00:00 2001 From: Timo Hirvonen Date: Sat, 24 May 2008 16:56:47 +0300 Subject: [PATCH] Remove fuzzy artist name fixing, add fuzzy_artist_sort and pretty_artist_name options Artist name fixing doesn't seem to be very useful in practice so remove it. Also remove raw_name from struct artist because we can always store real artist name to artist.name and skip "the " when needed. fuzzy_artist_sort when enabled makes sorting ignore "the " in front of artist names. So artists starting with "the " are not clumped together. Defaults to false (old behavior). pretty_artist_name when turned on changes displayed artist name so that leading "the " is removed and ", The" is added at end the name. This is useful with fuzzy_artist_sort. Defaults to false. --- lib.h | 3 +- options.c | 38 +++++++++++++++++++ options.h | 2 + tree.c | 123 ++++++++++++++++++++++++------------------------------------ ui_curses.c | 8 +++- 5 files changed, 98 insertions(+), 76 deletions(-) diff --git a/lib.h b/lib.h index 13f82cc..709b597 100644 --- a/lib.h +++ b/lib.h @@ -47,8 +47,6 @@ struct artist { /* list of albums */ struct list_head album_head; - - char *raw_name; char *name; /* albums visible for this artist in the tree_win? */ @@ -88,6 +86,7 @@ void lib_set_view(int view); int lib_for_each(int (*cb)(void *data, struct track_info *ti), void *data); struct track_info *tree_set_selected(void); +void tree_sort_artists(void); void tree_add_track(struct tree_track *track); void tree_remove(struct tree_track *track); void tree_remove_sel(void); diff --git a/options.c b/options.c index dfc44c2..4ea5427 100644 --- a/options.c +++ b/options.c @@ -45,6 +45,8 @@ int set_term_title = 1; int play_library = 1; int repeat = 0; int shuffle = 0; +int pretty_artist_name; +int fuzzy_artist_sort; int colors[NR_COLORS] = { -1, @@ -498,6 +500,40 @@ static void toggle_play_sorted(unsigned int id) update_statusline(); } +static void get_fuzzy_artist_sort(unsigned int id, char *buf) +{ + strcpy(buf, bool_names[fuzzy_artist_sort]); +} + +static void set_fuzzy_artist_sort(unsigned int id, const char *buf) +{ + if (parse_bool(buf, &fuzzy_artist_sort)) + tree_sort_artists(); +} + +static void toggle_fuzzy_artist_sort(unsigned int id) +{ + fuzzy_artist_sort ^= 1; + tree_sort_artists(); +} + +static void get_pretty_artist_name(unsigned int id, char *buf) +{ + strcpy(buf, bool_names[pretty_artist_name]); +} + +static void set_pretty_artist_name(unsigned int id, const char *buf) +{ + parse_bool(buf, &pretty_artist_name); + lib_tree_win->changed = 1; +} + +static void toggle_pretty_artist_name(unsigned int id) +{ + pretty_artist_name ^= 1; + lib_tree_win->changed = 1; +} + const char * const aaa_mode_names[] = { "all", "artist", "album", NULL }; @@ -784,6 +820,7 @@ static const struct { DN(buffer_seconds) DT(confirm_run) DT(continue) + DT(fuzzy_artist_sort) DN(id3_default_charset) DN(lib_sort) DN(output_plugin) @@ -791,6 +828,7 @@ static const struct { DN(pl_sort) DT(play_library) DT(play_sorted) + DT(pretty_artist_name) DT(repeat) DT(repeat_current) DT(replaygain) diff --git a/options.h b/options.h index 7606e4a..78e2f99 100644 --- a/options.h +++ b/options.h @@ -92,6 +92,8 @@ extern int set_term_title; extern int play_library; extern int repeat; extern int shuffle; +extern int pretty_artist_name; +extern int fuzzy_artist_sort; extern const char * const aaa_mode_names[]; extern const char * const view_names[NR_VIEWS + 1]; diff --git a/tree.c b/tree.c index 4b7359d..d7ca73b 100644 --- a/tree.c +++ b/tree.c @@ -5,10 +5,11 @@ #include "lib.h" #include "search_mode.h" #include "xmalloc.h" -#include "xstrjoin.h" #include "comment.h" #include "utils.h" #include "debug.h" +#include "mergesort.h" +#include "options.h" struct searchable *tree_searchable; struct window *lib_tree_win; @@ -325,7 +326,6 @@ static inline void tree_win_get_selected(struct artist **artist, struct album ** static void artist_free(struct artist *artist) { - free(artist->raw_name); free(artist->name); free(artist); } @@ -397,15 +397,7 @@ static const char *artist_name_skip_the(const char *a) return a; } -static int artist_name_cmp(const char *a, const char *b) -{ - a = artist_name_skip_the(a); - b = artist_name_skip_the(b); - - return u_strcasecmp(a, b); -} - -static void find_artist_and_album(const char *artist_raw_name, +static void find_artist_and_album(const char *artist_name, const char *album_name, struct artist **_artist, struct album **_album) { @@ -415,7 +407,7 @@ static void find_artist_and_album(const char *artist_raw_name, list_for_each_entry(artist, &lib_artist_head, node) { int res; - res = artist_name_cmp(artist->raw_name, artist_raw_name); + res = u_strcasecmp(artist->name, artist_name); if (res == 0) { *_artist = artist; list_for_each_entry(album, &artist->album_head, node) { @@ -446,23 +438,51 @@ static int special_name_cmp(const char *a, const char *b) static void insert_artist(struct artist *artist) { + const char *a = artist->name; struct list_head *item; + if (fuzzy_artist_sort) + a = artist_name_skip_the(a); + list_for_each(item, &lib_artist_head) { - if (special_name_cmp(artist->name, to_artist(item)->name) < 0) + const char *b = to_artist(item)->name; + + if (fuzzy_artist_sort) + b = artist_name_skip_the(b); + + if (special_name_cmp(a, b) < 0) break; } /* add before item */ list_add_tail(&artist->node, item); } -static struct artist *add_artist(const char *name, const char *raw_name) +static int artist_cmp(const struct list_head *a, const struct list_head *b) +{ + return special_name_cmp(to_artist(a)->name, to_artist(b)->name); +} + +static int fuzzy_artist_cmp(const struct list_head *a, const struct list_head *b) +{ + return special_name_cmp(artist_name_skip_the(to_artist(a)->name), + artist_name_skip_the(to_artist(b)->name)); +} + +void tree_sort_artists(void) +{ + if (fuzzy_artist_sort) + list_mergesort(&lib_artist_head, fuzzy_artist_cmp); + else + list_mergesort(&lib_artist_head, artist_cmp); + window_changed(lib_tree_win); +} + +static struct artist *add_artist(const char *name) { struct artist *artist; artist = xnew(struct artist, 1); artist->name = xstrdup(name); - artist->raw_name = xstrdup(raw_name); list_init(&artist->album_head); artist->expanded = 0; @@ -521,22 +541,10 @@ static void album_add_track(struct album *album, struct tree_track *track) list_add_tail(&track->node, item); } -static void remove_artist(struct artist *artist); - -static void update_artist_name(struct artist *artist, char *new_name) -{ - free(artist->name); - artist->name = new_name; /* no need to make a copy here */ - - list_del(&artist->node); - insert_artist(artist); - window_changed(lib_tree_win); -} - void tree_add_track(struct tree_track *track) { const struct track_info *ti = tree_track_info(track); - const char *album_name, *artist_name, *artist_name_fancy = NULL; + const char *album_name, *artist_name; struct artist *artist; struct album *album; int date; @@ -545,50 +553,30 @@ void tree_add_track(struct tree_track *track) artist_name = ""; album_name = ""; } else { - const char *compilation; - - artist_name = keyvals_get_val(ti->comments, "artist"); album_name = keyvals_get_val(ti->comments, "album"); - artist_name_fancy = keyvals_get_val(ti->comments, "albumartistsort"); - if (!artist_name_fancy) - artist_name_fancy = keyvals_get_val(ti->comments, "albumartist"); - if (!artist_name_fancy) - artist_name_fancy = keyvals_get_val(ti->comments, "artistsort"); + artist_name = keyvals_get_val(ti->comments, "albumartistsort"); + if (!artist_name) + artist_name= keyvals_get_val(ti->comments, "albumartist"); + if (!artist_name) + artist_name= keyvals_get_val(ti->comments, "artistsort"); + if (!artist_name) { + const char *compilation = keyvals_get_val(ti->comments, "compilation"); + if (compilation && (!strcasecmp(compilation, "1") || + !strcasecmp(compilation, "yes"))) + artist_name = ""; + } + if (!artist_name) + artist_name = keyvals_get_val(ti->comments, "artist"); if (artist_name == NULL) artist_name = ""; if (album_name == NULL) album_name = ""; - compilation = keyvals_get_val(ti->comments, "compilation"); - if (compilation && (!strcasecmp(compilation, "1") - || !strcasecmp(compilation, "yes"))) { - /* Store all compilations under compilations */ - artist_name = ""; - } } find_artist_and_album(artist_name, album_name, &artist, &album); - - /* update artist name if better one is available */ - if (artist) { - if (artist_name_fancy && - u_strcasecmp(artist->name, artist_name_fancy)) - /* we've got a new fancy name */ - update_artist_name(artist, xstrdup(artist_name_fancy)); - else if (!artist_name_fancy) { - const char *artist_name_no_the = artist_name_skip_the(artist_name); - - if (artist_name_no_the != artist_name && - !u_strncasecmp(artist->name, - artist_name_no_the, - strlen(artist->name))) - /* same name, but starting with "The" */ - update_artist_name(artist, xstrjoin(artist_name_no_the, ", The")); - } - } - if (album) { album_add_track(album, track); @@ -608,19 +596,8 @@ void tree_add_track(struct tree_track *track) /* album is not selected => no need to update track_win */ } } else { - const char *artist_name_no_the = artist_name_skip_the(artist_name); - - if (artist_name_fancy) - artist = add_artist(artist_name_fancy, artist_name); - else if (artist_name_no_the == artist_name) - artist = add_artist(artist_name, artist_name); - else { - char *artist_name_full = xstrjoin(artist_name_no_the, ", The"); - artist = add_artist(artist_name_full, artist_name); - free(artist_name_full); - } - date = comments_get_date(ti->comments, "date"); + artist = add_artist(artist_name); album = artist_add_album(artist, album_name, date); album_add_track(album, track); diff --git a/ui_curses.c b/ui_curses.c index 348cde3..2b5882e 100644 --- a/ui_curses.c +++ b/ui_curses.c @@ -407,6 +407,7 @@ static void print_tree(struct window *win, int row, struct iter *iter) struct artist *artist; struct album *album; struct iter sel; + char buf[256]; int current, selected, active, pos; artist = iter_to_artist(iter); @@ -431,11 +432,16 @@ static void print_tree(struct window *win, int row, struct iter *iter) pos = 0; print_buffer[pos++] = ' '; - str = artist->name; if (album) { print_buffer[pos++] = ' '; print_buffer[pos++] = ' '; str = album->name; + } else { + str = artist->name; + if (pretty_artist_name && !strncasecmp(str, "the ", 4)) { + snprintf(buf, sizeof(buf), "%s, The", str + 4); + str = buf; + } } pos += format_str(print_buffer + pos, str, tree_win_w - pos - 1); print_buffer[pos++] = ' '; -- 2.11.4.GIT