summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: a00c1bb)
raw | patch | inline | side by side (parent: a00c1bb)
author | Patrick Hallen <patrick.hallen@rwth-aachen.de> | |
Sat, 7 Mar 2009 15:23:56 +0000 (16:23 +0100) | ||
committer | Patrick Hallen <patrick.hallen@rwth-aachen.de> | |
Sat, 7 Mar 2009 15:23:56 +0000 (16:23 +0100) |
Sort the filelist with the correct linguastically rule for the current
locale, with directories first, after that songs and playlist files last.
This fixes bug 2092.
locale, with directories first, after that songs and playlist files last.
This fixes bug 2092.
src/filelist.c | patch | blob | history | |
src/filelist.h | patch | blob | history | |
src/mpdclient.c | patch | blob | history | |
src/screen_search.c | patch | blob | history |
diff --git a/src/filelist.c b/src/filelist.c
index 97636eee6bf25edea67b625395c02a13eec3aae4..92e63792bee59f68fd5600e440c694b0cc6cfd8f 100644 (file)
--- a/src/filelist.c
+++ b/src/filelist.c
return compare_func(a, b);
}
+/* Sorts the whole filelist, at the moment used by filelist_search */
void
-filelist_sort(struct filelist *filelist, GCompareFunc compare_func)
+filelist_sort_all(struct filelist *filelist, GCompareFunc compare_func)
{
g_ptr_array_sort_with_data(filelist->entries,
- filelist_compare_indirect,
- compare_func);
+ filelist_compare_indirect,
+ compare_func);
+}
+
+
+/* Only sorts the directories and playlist files.
+ * The songs stay in the order it came from mpd. */
+void
+filelist_sort_dir_play(struct filelist *filelist, GCompareFunc compare_func)
+{
+ unsigned first, last;
+ const mpd_InfoEntity *iter;
+
+ assert(filelist && filelist->entries);
+
+ if (filelist->entries->len < 2)
+ return;
+ iter = ((struct filelist_entry*) g_ptr_array_index(filelist->entries, 0))->entity;
+ /* This can only happen at the beginning of the filelist,
+ * because NULL stands for "[..]" */
+ if (iter == NULL) {
+ iter = ((struct filelist_entry*) g_ptr_array_index(filelist->entries, 1))->entity;
+ first = 1;
+ }
+ else
+ first = 0;
+ /* find the last directory entry */
+ for (last = first+1; last < filelist->entries->len; last++) {
+ iter = ((struct filelist_entry*) g_ptr_array_index(filelist->entries, last))->entity;
+ if (iter->type != MPD_INFO_ENTITY_TYPE_DIRECTORY)
+ break;
+ }
+ if (last == filelist->entries->len - 1)
+ last++;
+ /* sort the directories */
+ if (last - first > 1)
+ g_qsort_with_data(filelist->entries->pdata + first,
+ last - first, sizeof(gpointer),
+ filelist_compare_indirect, compare_func);
+ /* find the first playlist entry */
+ for (first = last; first < filelist->entries->len; first++) {
+ iter = ((struct filelist_entry*) g_ptr_array_index(filelist->entries, first))->entity;
+ if (iter->type == MPD_INFO_ENTITY_TYPE_PLAYLISTFILE)
+ break;
+ }
+ /* sort the playlist entries */
+ if (filelist->entries->len - first > 1)
+ g_qsort_with_data(filelist->entries->pdata + first,
+ filelist->entries->len - first, sizeof(gpointer),
+ filelist_compare_indirect, compare_func);
}
int
diff --git a/src/filelist.h b/src/filelist.h
index d8db5a46acf5715f072621e2f616243325502f93..3ad6cc2acbe72305d791a7b7121d3e819f9a6c30 100644 (file)
--- a/src/filelist.h
+++ b/src/filelist.h
void
filelist_move(struct filelist *filelist, struct filelist *from);
+/* Sorts the whole filelist, at the moment used by filelist_search */
void
-filelist_sort(struct filelist *filelist, GCompareFunc compare_func);
+filelist_sort_all(struct filelist *filelist, GCompareFunc compare_func);
+
+/* Only sorts the directories and playlist files.
+ * The songs stay in the order it came from mpd. */
+void
+filelist_sort_dir_play(struct filelist *filelist, GCompareFunc compare_func);
int
filelist_find_song(struct filelist *flist, const struct mpd_song *song);
diff --git a/src/mpdclient.c b/src/mpdclient.c
index f8f5ba72c42fff3c8f20503aaba206e07792b86f..a1766d9a47baf9e5beb5a668b9fb8de76c3496ac 100644 (file)
--- a/src/mpdclient.c
+++ b/src/mpdclient.c
/* filelist sorting functions */
static gint
-compare_filelistentry_dir(gconstpointer filelist_entry1,
+compare_filelistentry(gconstpointer filelist_entry1,
gconstpointer filelist_entry2)
{
const mpd_InfoEntity *e1, *e2;
e1 = ((const filelist_entry_t *)filelist_entry1)->entity;
e2 = ((const filelist_entry_t *)filelist_entry2)->entity;
- if (e1 && e2 &&
- e1->type == MPD_INFO_ENTITY_TYPE_DIRECTORY &&
- e2->type == MPD_INFO_ENTITY_TYPE_DIRECTORY)
- n = g_utf8_collate(e1->info.directory->path,
- e2->info.directory->path);
-
+ if (e1 && e2 && e1->type == e2->type) {
+ switch (e1->type) {
+ case MPD_INFO_ENTITY_TYPE_DIRECTORY:
+ n = g_utf8_collate(e1->info.directory->path,
+ e2->info.directory->path);
+ break;
+ case MPD_INFO_ENTITY_TYPE_SONG:
+ break;
+ case MPD_INFO_ENTITY_TYPE_PLAYLISTFILE:
+ n = g_utf8_collate(e1->info.playlistFile->path,
+ e2->info.playlistFile->path);
+ }
+ }
return n;
}
{
mpdclient_filelist_t *filelist;
mpd_InfoEntity *entity;
- gboolean has_dirs_only = TRUE;
mpd_sendLsInfoCommand(c->connection, path);
filelist = filelist_new(path);
while ((entity=mpd_getNextInfoEntity(c->connection))) {
filelist_append(filelist, entity);
-
- if (has_dirs_only && entity->type != MPD_INFO_ENTITY_TYPE_DIRECTORY) {
- has_dirs_only = FALSE;
- }
}
/* If there's an error, ignore it. We'll return an empty filelist. */
mpdclient_finish_command(c);
- // If there are only directory entities in the filelist, we sort it
- if (has_dirs_only)
- filelist_sort(filelist, compare_filelistentry_dir);
+ filelist_sort_dir_play(filelist, compare_filelistentry);
return filelist;
}
diff --git a/src/screen_search.c b/src/screen_search.c
index f9b51450b662fbc8b858ff4baf2df1e0f1f60189..f290e04d38a0d80af2e4f88296a37d78dd5165b9 100644 (file)
--- a/src/screen_search.c
+++ b/src/screen_search.c
filelist_free(list2);
}
- filelist_sort(list, compare_filelistentry_format);
+ filelist_sort_all(list, compare_filelistentry_format);
} else {
list = mpdclient_filelist_search(c, FALSE, table, filter_utf8);
if (list == NULL)