commit 519f8772cc9dd5ccb7d302931f1cad149c61a4e1 Author: phantomjinx <p.g.richard...@phantomjinx.co.uk> Date: Wed Oct 26 21:59:17 2011 +0100
Provide sensible sorting for adding files and directories * Tracks have been historically added in an arbitrary way. This attempts to address this by sorting the filenames before adding the tracks. * Would be better to sort the tracks after they have been added but catching all the added tracks is not easy so this makes a satisfactory middle option. * Addresses Debian bug #547295 libgtkpod/file.c | 107 ++++++++++++++------ libgtkpod/file.h | 3 + .../playlist_display/playlist_display_actions.c | 4 + 3 files changed, 84 insertions(+), 30 deletions(-) --- diff --git a/libgtkpod/file.c b/libgtkpod/file.c index 7eed815..caa431b 100644 --- a/libgtkpod/file.c +++ b/libgtkpod/file.c @@ -361,12 +361,64 @@ add_playlist_by_filename(iTunesDB *itdb, gchar *plfile, Playlist *plitem, gint p return NULL; } +static gint compare_names (gchar* name1, gchar* name2, gpointer case_sensitive) { + gint value = compare_string(name1, name2, GPOINTER_TO_INT(case_sensitive)); + return value; +} + +/** + * Sort a list of filenames, using the tm_sort and + * tm_case_sensitive preferences to determine the + * filenames' sort order. + */ +GSList* sort_tracknames_list(GSList *names) { + /* Get the track sort order preference */ + GtkSortType sortorder = prefs_get_int("tm_sort"); + gboolean case_sensitive = prefs_get_int("tm_case_sensitive"); + + switch (sortorder) { + case SORT_ASCENDING: + return g_slist_sort_with_data (names, (GCompareDataFunc) compare_names, GINT_TO_POINTER(case_sensitive)); + case SORT_DESCENDING: + names = g_slist_sort_with_data (names, (GCompareDataFunc) compare_names, GINT_TO_POINTER(case_sensitive)); + return g_slist_reverse(names); + default: + return names; + } +} + /*------------------------------------------------------------------*\ * * * Add Dir * * * \*------------------------------------------------------------------*/ +static void recurse_directories(gchar *name, GSList **trknames, gboolean descend) { + if (g_file_test(name, G_FILE_TEST_IS_DIR)) { + GDir *dir = g_dir_open(name, 0, NULL); + if (dir != NULL) { + const gchar *next; + do { + next = g_dir_read_name(dir); + if (next != NULL) { + gchar *nextfull = g_build_filename(name, next, NULL); + if (descend || !g_file_test(nextfull, G_FILE_TEST_IS_DIR)) { + recurse_directories(nextfull, trknames, descend); + } + g_free(nextfull); + } + } + while (next != NULL); + + g_dir_close(dir); + } + } + else { + *trknames = g_slist_append(*trknames, g_strdup(name)); + } +} + + /* * Add all files in directory and subdirectories. * @@ -386,48 +438,43 @@ add_playlist_by_filename(iTunesDB *itdb, gchar *plfile, Playlist *plitem, gint p gint add_directory_by_name(iTunesDB *itdb, gchar *name, Playlist *plitem, gboolean descend, AddTrackFunc addtrackfunc, gpointer data, GError **error) { gint result = 0; GString *errors = g_string_new(""); + GSList *trknames = NULL; + GSList *tkn = NULL; g_return_val_if_fail (itdb, 0); g_return_val_if_fail (name, 0); - if (g_file_test(name, G_FILE_TEST_IS_DIR)) { - GDir *dir = g_dir_open(name, 0, NULL); - block_widgets(); - if (dir != NULL) { - const gchar *next; - do { - next = g_dir_read_name(dir); - if (next != NULL) { - gchar *nextfull = g_build_filename(name, next, NULL); - if (descend || !g_file_test(nextfull, G_FILE_TEST_IS_DIR)) { - GError *direrror = NULL; - result += add_directory_by_name(itdb, nextfull, plitem, descend, addtrackfunc, data, &direrror); - if (direrror) { - gchar *msg = g_strdup_printf("%s\n", direrror->message); - g_string_append(errors, msg); - g_free(msg); - g_error_free(direrror); - direrror = NULL; - } - } - g_free(nextfull); - } - } - while (next != NULL); + block_widgets(); - g_dir_close(dir); - } - release_widgets(); - } - else { - if (add_track_by_filename(itdb, name, plitem, descend, addtrackfunc, data, error)) + recurse_directories(name, &trknames, descend); + + trknames = sort_tracknames_list(trknames); + + tkn = trknames; + while (tkn) { + GError *trkerror = NULL; + if (add_track_by_filename(itdb, tkn->data, plitem, descend, addtrackfunc, data, &trkerror)) { result++; + } + + if (trkerror) { + gchar *msg = g_strdup_printf("%s\n", trkerror->message); + g_string_append(errors, msg); + g_free(msg); + g_error_free(trkerror); + trkerror = NULL; + } + + tkn = tkn->next; } + release_widgets(); + if (errors->len > 0) { gtkpod_log_error_printf(error, errors->str); } g_string_free(errors, TRUE); + g_slist_free_full(trknames, g_free); return result; } diff --git a/libgtkpod/file.h b/libgtkpod/file.h index cd58bc8..01ba239 100644 --- a/libgtkpod/file.h +++ b/libgtkpod/file.h @@ -95,4 +95,7 @@ gboolean read_lyrics_from_file (Track *track, gchar **lyrics); gboolean write_lyrics_to_file (Track *track); gchar *fileselection_get_file_or_dir(const gchar *title, const gchar *cur_file, GtkFileChooserAction action); + +GSList* sort_tracknames_list(GSList *names); + #endif diff --git a/plugins/playlist_display/playlist_display_actions.c b/plugins/playlist_display/playlist_display_actions.c index f153011..8f34f17 100644 --- a/plugins/playlist_display/playlist_display_actions.c +++ b/plugins/playlist_display/playlist_display_actions.c @@ -56,6 +56,7 @@ static void add_selected_dirs(GSList *names, Playlist *db_active_pl) { if (names) { gtkpod_statusbar_busy_push(); + GSList* currentnode; for (currentnode = names; currentnode; currentnode = currentnode->next) { result @@ -304,6 +305,9 @@ static void fileselection_add_files(GSList* names, Playlist *playlist) { block_widgets(); gtkpod_statusbar_busy_push(); + + names = sort_tracknames_list(names); + /* Get the filenames and add them */ for (gsl = names; gsl; gsl = gsl->next) { GError *error = NULL; ------------------------------------------------------------------------------ The demand for IT networking professionals continues to grow, and the demand for specialized networking skills is growing even more rapidly. Take a complimentary Learning@Cisco Self-Assessment and learn about Cisco certifications, training, and career opportunities. http://p.sf.net/sfu/cisco-dev2dev _______________________________________________ gtkpod-cvs2 mailing list gtkpod-cvs2@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/gtkpod-cvs2