summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar waker <wakeroid@gmail.com>2012-04-06 10:32:38 +0200
committerGravatar waker <wakeroid@gmail.com>2012-04-06 10:32:38 +0200
commit26293f4882d7476459a0aa90e992ad67a4585375 (patch)
tree4c2e65559e5af2145ad58d7ca7e0909760e67357
parent721aae59d8d10a242850033f66ac5685ddb9e769 (diff)
added random sort (based on patch from defusix)
-rw-r--r--deadbeef.h9
-rw-r--r--playlist.c58
-rw-r--r--playlist.h5
-rw-r--r--plugins.c2
-rw-r--r--plugins/gtkui/callbacks.c27
-rw-r--r--plugins/gtkui/callbacks.h4
-rw-r--r--plugins/gtkui/deadbeef.glade9
-rw-r--r--plugins/gtkui/interface.c9
8 files changed, 113 insertions, 10 deletions
diff --git a/deadbeef.h b/deadbeef.h
index 4a127110..f5b999ad 100644
--- a/deadbeef.h
+++ b/deadbeef.h
@@ -295,6 +295,13 @@ enum {
DDB_REPLAYGAIN_TRACKPEAK,
};
+// sort order constants
+enum ddb_sort_order_t {
+ DDB_SORT_DESCENDING,
+ DDB_SORT_ASCENDING,
+ DDB_SORT_RANDOM, // available since API 1.3
+};
+
// typecasting macros
#define DB_PLUGIN(x) ((DB_plugin_t *)(x))
#define DB_CALLBACK(x) ((DB_callback_t)(x))
@@ -476,7 +483,7 @@ typedef struct {
void (*plt_copy_items) (ddb_playlist_t *to, int iter, ddb_playlist_t * from, DB_playItem_t *before, uint32_t *indices, int cnt);
void (*plt_search_reset) (ddb_playlist_t *plt);
void (*plt_search_process) (ddb_playlist_t *plt, const char *text);
- void (*plt_sort) (ddb_playlist_t *plt, int iter, int id, const char *format, int ascending);
+ void (*plt_sort) (ddb_playlist_t *plt, int iter, int id, const char *format, int order);
// add files and folders to current playlist
int (*plt_add_file) (ddb_playlist_t *plt, const char *fname, int (*cb)(DB_playItem_t *it, void *data), void *user_data);
diff --git a/playlist.c b/playlist.c
index d339d1ac..4975faf0 100644
--- a/playlist.c
+++ b/playlist.c
@@ -3174,7 +3174,13 @@ qsort_cmp_func (const void *a, const void *b) {
}
void
-plt_sort (playlist_t *playlist, int iter, int id, const char *format, int ascending) {
+plt_sort (playlist_t *playlist, int iter, int id, const char *format, int order) {
+ if (order == DDB_SORT_RANDOM) {
+ plt_sort_random (playlist, iter);
+ return;
+ }
+ int ascending = order == DDB_SORT_DESCENDING ? 0 : 1;
+
if (id == DB_COLUMN_FILENUMBER || !playlist->head[iter] || !playlist->head[iter]->next[iter]) {
return;
}
@@ -3234,6 +3240,56 @@ plt_sort (playlist_t *playlist, int iter, int id, const char *format, int ascend
}
void
+plt_sort_random (playlist_t *playlist, int iter) {
+ if (!playlist->head[iter] || !playlist->head[iter]->next[iter]) {
+ return;
+ }
+
+ LOCK;
+
+ const int playlist_count = playlist->count[iter];
+ playItem_t **array = malloc (playlist_count * sizeof (playItem_t *));
+ int idx = 0;
+ for (playItem_t *it = playlist->head[iter]; it; it = it->next[iter], idx++) {
+ array[idx] = it;
+ }
+
+ //randomize array
+ for (int swap_a = 0; swap_a < playlist_count - 1; swap_a++) {
+ //select random item above swap_a-1
+ const int swap_b = swap_a + (rand() / (float)RAND_MAX * (playlist_count - swap_a));
+
+ //swap a with b
+ playItem_t* const swap_temp = array[swap_a];
+ array[swap_a] = array[swap_b];
+ array[swap_b] = swap_temp;
+
+ }
+
+ playItem_t *prev = NULL;
+ playlist->head[iter] = 0;
+ for (idx = 0; idx < playlist->count[iter]; idx++) {
+ playItem_t *it = array[idx];
+ it->prev[iter] = prev;
+ it->next[iter] = NULL;
+ if (!prev) {
+ playlist->head[iter] = it;
+ }
+ else {
+ prev->next[iter] = it;
+ }
+ prev = it;
+ }
+ playlist->tail[iter] = array[playlist->count[iter]-1];
+
+ free (array);
+
+ plt_modified (playlist);
+
+ UNLOCK;
+}
+
+void
plt_reset_cursor (playlist_t *playlist) {
int i;
LOCK;
diff --git a/playlist.h b/playlist.h
index f5cca51f..fefb3943 100644
--- a/playlist.h
+++ b/playlist.h
@@ -400,7 +400,10 @@ void
plt_search_process (playlist_t *plt, const char *text);
void
-plt_sort (playlist_t *plt, int iter, int id, const char *format, int ascending);
+plt_sort (playlist_t *plt, int iter, int id, const char *format, int order);
+
+void
+plt_sort_random (playlist_t *plt, int iter);
// playqueue support functions
int
diff --git a/plugins.c b/plugins.c
index 4d83444b..d19139ff 100644
--- a/plugins.c
+++ b/plugins.c
@@ -172,7 +172,7 @@ static DB_functions_t deadbeef_api = {
.pl_get_item_duration = (float (*) (DB_playItem_t *it))pl_get_item_duration,
.pl_get_item_flags = (uint32_t (*) (DB_playItem_t *it))pl_get_item_flags,
.pl_set_item_flags = (void (*) (DB_playItem_t *it, uint32_t flags))pl_set_item_flags,
- .plt_sort = (void (*) (ddb_playlist_t *plt, int iter, int id, const char *format, int ascending))plt_sort,
+ .plt_sort = (void (*) (ddb_playlist_t *plt, int iter, int id, const char *format, int order))plt_sort,
.pl_items_copy_junk = (void (*)(DB_playItem_t *from, DB_playItem_t *first, DB_playItem_t *last))pl_items_copy_junk,
.pl_set_item_replaygain = (void (*)(DB_playItem_t *it, int idx, float value))pl_set_item_replaygain,
.pl_get_item_replaygain = (float (*)(DB_playItem_t *it, int idx))pl_get_item_replaygain,
diff --git a/plugins/gtkui/callbacks.c b/plugins/gtkui/callbacks.c
index 3005bc27..be18328c 100644
--- a/plugins/gtkui/callbacks.c
+++ b/plugins/gtkui/callbacks.c
@@ -1154,7 +1154,7 @@ on_sort_by_title_activate (GtkMenuItem *menuitem,
gpointer user_data)
{
ddb_playlist_t *plt = deadbeef->plt_get_curr ();
- deadbeef->plt_sort (plt, PL_MAIN, -1, "%t", 1);
+ deadbeef->plt_sort (plt, PL_MAIN, -1, "%t", DDB_SORT_ASCENDING);
deadbeef->plt_unref (plt);
DdbListview *pl = DDB_LISTVIEW (lookup_widget (mainwin, "playlist"));
@@ -1168,7 +1168,7 @@ on_sort_by_track_nr_activate (GtkMenuItem *menuitem,
gpointer user_data)
{
ddb_playlist_t *plt = deadbeef->plt_get_curr ();
- deadbeef->plt_sort (plt, PL_MAIN, -1, "%n", 1);
+ deadbeef->plt_sort (plt, PL_MAIN, -1, "%n", DDB_SORT_ASCENDING);
deadbeef->plt_unref (plt);
DdbListview *pl = DDB_LISTVIEW (lookup_widget (mainwin, "playlist"));
@@ -1182,7 +1182,7 @@ on_sort_by_album_activate (GtkMenuItem *menuitem,
gpointer user_data)
{
ddb_playlist_t *plt = deadbeef->plt_get_curr ();
- deadbeef->plt_sort (plt, PL_MAIN, -1, "%b", 1);
+ deadbeef->plt_sort (plt, PL_MAIN, -1, "%b", DDB_SORT_ASCENDING);
deadbeef->plt_unref (plt);
DdbListview *pl = DDB_LISTVIEW (lookup_widget (mainwin, "playlist"));
@@ -1196,7 +1196,7 @@ on_sort_by_artist_activate (GtkMenuItem *menuitem,
gpointer user_data)
{
ddb_playlist_t *plt = deadbeef->plt_get_curr ();
- deadbeef->plt_sort (plt, PL_MAIN, -1, "%a", 1);
+ deadbeef->plt_sort (plt, PL_MAIN, -1, "%a", DDB_SORT_ASCENDING);
deadbeef->plt_unref (plt);
DdbListview *pl = DDB_LISTVIEW (lookup_widget (mainwin, "playlist"));
@@ -1210,7 +1210,22 @@ on_sort_by_date_activate (GtkMenuItem *menuitem,
gpointer user_data)
{
ddb_playlist_t *plt = deadbeef->plt_get_curr ();
- deadbeef->plt_sort (plt, PL_MAIN, -1, "%y", 1);
+ deadbeef->plt_sort (plt, PL_MAIN, -1, "%y", DDB_SORT_ASCENDING);
+ deadbeef->plt_unref (plt);
+
+ DdbListview *pl = DDB_LISTVIEW (lookup_widget (mainwin, "playlist"));
+ ddb_listview_clear_sort (pl);
+ ddb_listview_refresh (pl, DDB_REFRESH_LIST | DDB_LIST_CHANGED);
+}
+
+
+void
+on_sort_by_random_activate (GtkMenuItem *menuitem,
+ gpointer user_data)
+{
+ ddb_playlist_t *plt = deadbeef->plt_get_curr ();
+ deadbeef->plt_sort (plt, PL_MAIN, -1, NULL, DDB_SORT_RANDOM);
+
deadbeef->plt_unref (plt);
DdbListview *pl = DDB_LISTVIEW (lookup_widget (mainwin, "playlist"));
@@ -1246,7 +1261,7 @@ on_sort_by_custom_activate (GtkMenuItem *menuitem,
deadbeef->conf_set_str ("gtkui.sortby_fmt", fmt);
ddb_playlist_t *plt = deadbeef->plt_get_curr ();
- deadbeef->plt_sort (plt, PL_MAIN, -1, fmt, order == 0 ? 1 : 0);
+ deadbeef->plt_sort (plt, PL_MAIN, -1, fmt, order == 0 ? DDB_SORT_ASCENDING : DDB_SORT_DESCENDING);
deadbeef->plt_unref (plt);
DdbListview *pl = DDB_LISTVIEW (lookup_widget (mainwin, "playlist"));
diff --git a/plugins/gtkui/callbacks.h b/plugins/gtkui/callbacks.h
index e463394d..a354baca 100644
--- a/plugins/gtkui/callbacks.h
+++ b/plugins/gtkui/callbacks.h
@@ -1149,6 +1149,10 @@ on_sort_by_date_activate (GtkMenuItem *menuitem,
gpointer user_data);
void
+on_sort_by_random_activate (GtkMenuItem *menuitem,
+ gpointer user_data);
+
+void
on_sort_by_custom_activate (GtkMenuItem *menuitem,
gpointer user_data);
diff --git a/plugins/gtkui/deadbeef.glade b/plugins/gtkui/deadbeef.glade
index cffda5b5..184b66fd 100644
--- a/plugins/gtkui/deadbeef.glade
+++ b/plugins/gtkui/deadbeef.glade
@@ -365,6 +365,15 @@
</child>
<child>
+ <widget class="GtkMenuItem" id="random1">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Random</property>
+ <property name="use_underline">True</property>
+ <signal name="activate" handler="on_sort_by_random_activate" last_modification_time="Sun, 26 Feb 2012 19:22:44 GMT"/>
+ </widget>
+ </child>
+
+ <child>
<widget class="GtkMenuItem" id="custom2">
<property name="visible">True</property>
<property name="label" translatable="yes">Custom</property>
diff --git a/plugins/gtkui/interface.c b/plugins/gtkui/interface.c
index 57db14db..84649092 100644
--- a/plugins/gtkui/interface.c
+++ b/plugins/gtkui/interface.c
@@ -69,6 +69,7 @@ create_mainwin (void)
GtkWidget *album1;
GtkWidget *artist1;
GtkWidget *date1;
+ GtkWidget *random1;
GtkWidget *custom2;
GtkWidget *separator5;
GtkWidget *preferences;
@@ -312,6 +313,10 @@ create_mainwin (void)
gtk_widget_show (date1);
gtk_container_add (GTK_CONTAINER (sort_by1_menu), date1);
+ random1 = gtk_menu_item_new_with_mnemonic (_("Random"));
+ gtk_widget_show (random1);
+ gtk_container_add (GTK_CONTAINER (sort_by1_menu), random1);
+
custom2 = gtk_menu_item_new_with_mnemonic (_("Custom"));
gtk_widget_show (custom2);
gtk_container_add (GTK_CONTAINER (sort_by1_menu), custom2);
@@ -693,6 +698,9 @@ create_mainwin (void)
g_signal_connect ((gpointer) date1, "activate",
G_CALLBACK (on_sort_by_date_activate),
NULL);
+ g_signal_connect ((gpointer) random1, "activate",
+ G_CALLBACK (on_sort_by_random_activate),
+ NULL);
g_signal_connect ((gpointer) custom2, "activate",
G_CALLBACK (on_sort_by_custom_activate),
NULL);
@@ -819,6 +827,7 @@ create_mainwin (void)
GLADE_HOOKUP_OBJECT (mainwin, album1, "album1");
GLADE_HOOKUP_OBJECT (mainwin, artist1, "artist1");
GLADE_HOOKUP_OBJECT (mainwin, date1, "date1");
+ GLADE_HOOKUP_OBJECT (mainwin, random1, "random1");
GLADE_HOOKUP_OBJECT (mainwin, custom2, "custom2");
GLADE_HOOKUP_OBJECT (mainwin, separator5, "separator5");
GLADE_HOOKUP_OBJECT (mainwin, preferences, "preferences");