diff options
author | Aleksejs Popovs <me@popoffka.ru> | 2014-05-01 19:21:22 +0300 |
---|---|---|
committer | Alexey Yakovenko <waker@users.sourceforge.net> | 2014-05-01 18:55:17 +0200 |
commit | fc44e817e339017737e3063c050414301de4d671 (patch) | |
tree | 91b9c592b367b39706f8f074796c50287d0d5c32 | |
parent | 102e78d943cf640a73a1b6aa13e3a6343f07ca1a (diff) |
added "stop playback after current album finishes" functionality
-rw-r--r-- | plugins/gtkui/callbacks.c | 8 | ||||
-rw-r--r-- | plugins/gtkui/callbacks.h | 8 | ||||
-rw-r--r-- | plugins/gtkui/deadbeef.glade | 30 | ||||
-rw-r--r-- | plugins/gtkui/gtkui.c | 4 | ||||
-rw-r--r-- | plugins/gtkui/hotkeys.c | 1 | ||||
-rw-r--r-- | plugins/gtkui/interface.c | 18 | ||||
-rw-r--r-- | plugins/gtkui/prefwin.c | 10 | ||||
-rw-r--r-- | plugins/hotkeys/hotkeys.c | 19 | ||||
-rw-r--r-- | streamer.c | 81 |
9 files changed, 177 insertions, 2 deletions
diff --git a/plugins/gtkui/callbacks.c b/plugins/gtkui/callbacks.c index d75fb0df..51de7a9d 100644 --- a/plugins/gtkui/callbacks.c +++ b/plugins/gtkui/callbacks.c @@ -470,6 +470,14 @@ on_stop_after_current_activate (GtkMenuItem *menuitem, } void +on_stop_after_album_activate (GtkMenuItem *menuitem, + gpointer user_data) +{ + deadbeef->conf_set_int ("playlist.stop_after_album", gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (menuitem))); + deadbeef->sendmessage (DB_EV_CONFIGCHANGED, 0, 0, 0); +} + +void on_cursor_follows_playback_activate (GtkMenuItem *menuitem, gpointer user_data) { diff --git a/plugins/gtkui/callbacks.h b/plugins/gtkui/callbacks.h index b38d5f2e..bbd33f0e 100644 --- a/plugins/gtkui/callbacks.h +++ b/plugins/gtkui/callbacks.h @@ -1308,3 +1308,11 @@ on_auto_size_columns_toggled (GtkToggleButton *togglebutton, void on_searchentry_activate (GtkEntry *entry, gpointer user_data); + +void +on_stop_after_album_activate (GtkMenuItem *menuitem, + gpointer user_data); + +void +on_reset_autostopalbum_toggled (GtkToggleButton *togglebutton, + gpointer user_data); diff --git a/plugins/gtkui/deadbeef.glade b/plugins/gtkui/deadbeef.glade index 90ce9db5..b75b4589 100644 --- a/plugins/gtkui/deadbeef.glade +++ b/plugins/gtkui/deadbeef.glade @@ -582,6 +582,16 @@ </widget> </child> + <child> + <widget class="GtkCheckMenuItem" id="stop_after_album"> + <property name="visible">True</property> + <property name="label" translatable="yes">Stop after current album</property> + <property name="use_underline">True</property> + <property name="active">False</property> + <signal name="activate" handler="on_stop_after_album_activate" last_modification_time="Thu, 01 May 2014 15:14:26 GMT"/> + </widget> + </child> + <child> <widget class="GtkSeparatorMenuItem" id="separator11"> <property name="visible">True</property> @@ -2849,6 +2859,26 @@ Album</property> <property name="fill">False</property> </packing> </child> + + <child> + <widget class="GtkCheckButton" id="reset_autostopalbum"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="label" translatable="yes">Auto-reset "Stop after current album"</property> + <property name="use_underline">True</property> + <property name="relief">GTK_RELIEF_NORMAL</property> + <property name="focus_on_click">True</property> + <property name="active">False</property> + <property name="inconsistent">False</property> + <property name="draw_indicator">True</property> + <signal name="toggled" handler="on_reset_autostopalbum_toggled" last_modification_time="Thu, 01 May 2014 15:30:01 GMT"/> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> </widget> <packing> <property name="tab_expand">False</property> diff --git a/plugins/gtkui/gtkui.c b/plugins/gtkui/gtkui.c index 6f3760a9..5d2dedeb 100644 --- a/plugins/gtkui/gtkui.c +++ b/plugins/gtkui/gtkui.c @@ -596,6 +596,10 @@ gtkui_on_configchanged (void *data) { int stop_after_current = deadbeef->conf_get_int ("playlist.stop_after_current", 0); gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (lookup_widget (mainwin, "stop_after_current")), stop_after_current ? TRUE : FALSE); + // stop after current album + int stop_after_album = deadbeef->conf_get_int ("playlist.stop_after_album", 0); + gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (lookup_widget (mainwin, "stop_after_album")), stop_after_album ? TRUE : FALSE); + // embolden current track gtkui_embolden_current_track = deadbeef->conf_get_int ("gtkui.embolden_current_track", 0); diff --git a/plugins/gtkui/hotkeys.c b/plugins/gtkui/hotkeys.c index 7111703f..e8bffef9 100644 --- a/plugins/gtkui/hotkeys.c +++ b/plugins/gtkui/hotkeys.c @@ -929,6 +929,7 @@ gtkui_set_default_hotkeys (void) { deadbeef->conf_set_str ("hotkey.key29", "v 0 0 stop"); deadbeef->conf_set_str ("hotkey.key30", "b 0 0 next"); deadbeef->conf_set_str ("hotkey.key31", "n 0 0 playback_random"); + deadbeef->conf_set_str ("hotkey.key32", "\"Ctrl k\" 0 0 toggle_stop_after_album"); deadbeef->conf_save (); } diff --git a/plugins/gtkui/interface.c b/plugins/gtkui/interface.c index 29318d0a..5550996c 100644 --- a/plugins/gtkui/interface.c +++ b/plugins/gtkui/interface.c @@ -96,6 +96,7 @@ create_mainwin (void) GtkWidget *scroll_follows_playback; GtkWidget *cursor_follows_playback; GtkWidget *stop_after_current; + GtkWidget *stop_after_album; GtkWidget *separator11; GtkWidget *jump_to_current_track1; GtkWidget *Help; @@ -386,6 +387,10 @@ create_mainwin (void) gtk_widget_show (stop_after_current); gtk_container_add (GTK_CONTAINER (Playback_menu), stop_after_current); + stop_after_album = gtk_check_menu_item_new_with_mnemonic (_("Stop after current album")); + gtk_widget_show (stop_after_album); + gtk_container_add (GTK_CONTAINER (Playback_menu), stop_after_album); + separator11 = gtk_separator_menu_item_new (); gtk_widget_show (separator11); gtk_container_add (GTK_CONTAINER (Playback_menu), separator11); @@ -591,6 +596,9 @@ create_mainwin (void) g_signal_connect ((gpointer) stop_after_current, "activate", G_CALLBACK (on_stop_after_current_activate), NULL); + g_signal_connect ((gpointer) stop_after_album, "activate", + G_CALLBACK (on_stop_after_album_activate), + NULL); g_signal_connect ((gpointer) jump_to_current_track1, "activate", G_CALLBACK (on_jump_to_current_track1_activate), NULL); @@ -679,6 +687,7 @@ create_mainwin (void) GLADE_HOOKUP_OBJECT (mainwin, scroll_follows_playback, "scroll_follows_playback"); GLADE_HOOKUP_OBJECT (mainwin, cursor_follows_playback, "cursor_follows_playback"); GLADE_HOOKUP_OBJECT (mainwin, stop_after_current, "stop_after_current"); + GLADE_HOOKUP_OBJECT (mainwin, stop_after_album, "stop_after_album"); GLADE_HOOKUP_OBJECT (mainwin, separator11, "separator11"); GLADE_HOOKUP_OBJECT (mainwin, jump_to_current_track1, "jump_to_current_track1"); GLADE_HOOKUP_OBJECT (mainwin, Help, "Help"); @@ -1515,6 +1524,7 @@ create_prefwin (void) GtkWidget *resume_last_session; GtkWidget *ignore_archives; GtkWidget *reset_autostop; + GtkWidget *reset_autostopalbum; GtkWidget *label39; GtkWidget *vbox29; GtkWidget *hbox80; @@ -1843,6 +1853,10 @@ create_prefwin (void) gtk_widget_show (reset_autostop); gtk_box_pack_start (GTK_BOX (vbox8), reset_autostop, FALSE, FALSE, 0); + reset_autostopalbum = gtk_check_button_new_with_mnemonic (_("Auto-reset \"Stop after current album\"")); + gtk_widget_show (reset_autostopalbum); + gtk_box_pack_start (GTK_BOX (vbox8), reset_autostopalbum, FALSE, FALSE, 0); + label39 = gtk_label_new (_("Playback")); gtk_widget_show (label39); gtk_notebook_set_tab_label (GTK_NOTEBOOK (notebook), gtk_notebook_get_nth_page (GTK_NOTEBOOK (notebook), 1), label39); @@ -2661,6 +2675,9 @@ create_prefwin (void) g_signal_connect ((gpointer) reset_autostop, "toggled", G_CALLBACK (on_reset_autostop_toggled), NULL); + g_signal_connect ((gpointer) reset_autostopalbum, "toggled", + G_CALLBACK (on_reset_autostopalbum_toggled), + NULL); g_signal_connect ((gpointer) dsp_add, "clicked", G_CALLBACK (on_dsp_add_clicked), NULL); @@ -2872,6 +2889,7 @@ create_prefwin (void) GLADE_HOOKUP_OBJECT (prefwin, resume_last_session, "resume_last_session"); GLADE_HOOKUP_OBJECT (prefwin, ignore_archives, "ignore_archives"); GLADE_HOOKUP_OBJECT (prefwin, reset_autostop, "reset_autostop"); + GLADE_HOOKUP_OBJECT (prefwin, reset_autostopalbum, "reset_autostopalbum"); GLADE_HOOKUP_OBJECT (prefwin, label39, "label39"); GLADE_HOOKUP_OBJECT (prefwin, vbox29, "vbox29"); GLADE_HOOKUP_OBJECT (prefwin, hbox80, "hbox80"); diff --git a/plugins/gtkui/prefwin.c b/plugins/gtkui/prefwin.c index e59ca6df..00b68fbc 100644 --- a/plugins/gtkui/prefwin.c +++ b/plugins/gtkui/prefwin.c @@ -215,6 +215,9 @@ gtkui_run_preferences_dlg (void) { // reset autostop gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (lookup_widget (w, "reset_autostop")), deadbeef->conf_get_int ("playlist.stop_after_current_reset", 0)); + // reset album autostop + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (lookup_widget (w, "reset_autostopalbum")), deadbeef->conf_get_int ("playlist.stop_after_album_reset", 0)); + // titlebar text gtk_entry_set_text (GTK_ENTRY (lookup_widget (w, "titlebar_format_playing")), deadbeef->conf_get_str_fast ("gtkui.titlebar_playing", "%a - %t - DeaDBeeF-%V")); gtk_entry_set_text (GTK_ENTRY (lookup_widget (w, "titlebar_format_stopped")), deadbeef->conf_get_str_fast ("gtkui.titlebar_stopped", "DeaDBeeF-%V")); @@ -1068,6 +1071,13 @@ on_reset_autostop_toggled (GtkToggleButton *togglebutton, deadbeef->conf_set_int ("playlist.stop_after_current_reset", gtk_toggle_button_get_active (togglebutton)); } +void +on_reset_autostopalbum_toggled (GtkToggleButton *togglebutton, + gpointer user_data) +{ + deadbeef->conf_set_int ("playlist.stop_after_album_reset", gtk_toggle_button_get_active (togglebutton)); +} + void diff --git a/plugins/hotkeys/hotkeys.c b/plugins/hotkeys/hotkeys.c index 9ad4aead..f1deaac8 100644 --- a/plugins/hotkeys/hotkeys.c +++ b/plugins/hotkeys/hotkeys.c @@ -745,6 +745,15 @@ action_toggle_stop_after_current_cb (struct DB_plugin_action_s *action, int ctx) return 0; } +int +action_toggle_stop_after_album_cb (struct DB_plugin_action_s *action, int ctx) { + int var = deadbeef->conf_get_int ("playlist.stop_after_album", 0); + var = 1 - var; + deadbeef->conf_set_int ("playlist.stop_after_album", var); + deadbeef->sendmessage (DB_EV_CONFIGCHANGED, 0, 0, 0); + return 0; +} + static DB_plugin_action_t action_reload_metadata = { .title = "Reload Metadata", .name = "reload_metadata", @@ -1058,10 +1067,18 @@ static DB_plugin_action_t action_toggle_stop_after_current = { .next = &action_volume_down }; +static DB_plugin_action_t action_toggle_stop_after_album = { + .title = "Playback/Toggle Stop After Current Album", + .name = "toggle_stop_after_album", + .flags = DB_ACTION_COMMON, + .callback2 = action_toggle_stop_after_album_cb, + .next = &action_toggle_stop_after_current +}; + static DB_plugin_action_t * hotkeys_get_actions (DB_playItem_t *it) { - return &action_toggle_stop_after_current; + return &action_toggle_stop_after_album; } // define plugin interface @@ -86,6 +86,7 @@ static int autoconv_16_to_24 = 0; static int trace_bufferfill = 0; static int stop_after_current = 0; +static int stop_after_album = 0; static int streaming_terminate; @@ -356,6 +357,61 @@ send_trackinfochanged (playItem_t *track) { messagepump_push_event ((ddb_event_t*)ev, 0, 0); } +int stop_after_album_check (playItem_t *cur, playItem_t *next) { + if (!stop_after_album) { + return 0; + } + + if (!cur) { + return 0; + } + + if (!next) { + streamer_buffering = 0; + streamer_set_nextsong (-2, -2); + if (conf_get_int ("playlist.stop_after_album_reset", 0)) { + conf_set_int ("playlist.stop_after_album", 0); + stop_after_album = 0; + deadbeef->sendmessage (DB_EV_CONFIGCHANGED, 0, 0, 0); + } + } + + const char *cur_artist = pl_find_meta_raw (cur, "artist"); + const char *next_artist = pl_find_meta_raw (next, "artist"); + + const char *cur_album = pl_find_meta_raw (cur, "album"); + const char *next_album = pl_find_meta_raw (next, "album"); + + const char *cur_aa = pl_find_meta_raw (cur, "band"); + if (!cur_aa) { + cur_aa = pl_find_meta_raw (cur, "album artist"); + } + if (!cur_aa) { + cur_aa = pl_find_meta_raw (cur, "albumartist"); + } + const char *next_aa = pl_find_meta_raw (next, "band"); + if (!next_aa) { + next_aa = pl_find_meta_raw (next, "album artist"); + } + if (!next_aa) { + next_aa = pl_find_meta_raw (next, "albumartist"); + } + + if ((cur_artist == next_artist) && (cur_album == next_album) && (cur_aa == next_aa)) { + return 0; + } + + streamer_buffering = 0; + streamer_set_nextsong (-2, -2); + if (conf_get_int ("playlist.stop_after_album_reset", 0)) { + conf_set_int ("playlist.stop_after_album", 0); + stop_after_album = 0; + deadbeef->sendmessage (DB_EV_CONFIGCHANGED, 0, 0, 0); + } + + return 1; +} + int streamer_move_to_nextsong (int reason) { trace ("streamer_move_to_nextsong (%d)\n", reason); @@ -363,10 +419,18 @@ streamer_move_to_nextsong (int reason) { if (!streamer_playlist) { streamer_playlist = plt_get_curr (); } + + playItem_t *curr = playlist_track; + while (pl_playqueue_getcount ()) { trace ("pl_playqueue_getnext\n"); playItem_t *it = pl_playqueue_getnext (); if (it) { + if (stop_after_album_check(curr, it)) { + pl_unlock (); + return -1; + } + pl_playqueue_pop (); int r = str_get_idx_of (it); if (r >= 0) { @@ -398,7 +462,6 @@ streamer_move_to_nextsong (int reason) { } } - playItem_t *curr = playlist_track; if (reason == 1) { if (streamer_playlist) { plt_unref (streamer_playlist); @@ -445,6 +508,13 @@ streamer_move_to_nextsong (int reason) { } } playItem_t *it = pmin; + // although it is possible that, although it == NULL, reshuffling the playlist + // will result in the next track belonging to the same album as this one, this + // is most likely not what the user wants. + if (stop_after_album_check(curr, it)) { + pl_unlock (); + return -1; + } if (!it) { // all songs played, reshuffle and try again if (pl_loop_mode == PLAYBACK_MODE_LOOP_ALL) { // loop @@ -479,6 +549,10 @@ streamer_move_to_nextsong (int reason) { } } playItem_t *it = pmin; + if (stop_after_album_check(curr, it)) { + pl_unlock (); + return -1; + } if (!it) { // all songs played, reshuffle and try again if (pl_loop_mode == PLAYBACK_MODE_LOOP_ALL || reason == 1) { // loop @@ -516,6 +590,10 @@ streamer_move_to_nextsong (int reason) { else { it = streamer_playlist->head[PL_MAIN]; } + if (stop_after_album_check(curr, it)) { + pl_unlock (); + return -1; + } if (!it) { trace ("streamer_move_nextsong: was last track\n"); if (pl_loop_mode == PLAYBACK_MODE_LOOP_ALL) { @@ -2493,6 +2571,7 @@ streamer_configchanged (void) { trace_bufferfill = conf_get_int ("streamer.trace_buffer_fill",0); stop_after_current = conf_get_int ("playlist.stop_after_current", 0); + stop_after_album = conf_get_int ("playlist.stop_after_album", 0); char mapstr[2048]; deadbeef->conf_get_str ("network.ctmapping", DDB_DEFAULT_CTMAPPING, mapstr, sizeof (mapstr)); |