[Rhythmbox-devel] Patch: repeat one button



I've always been somewhat annoyed that Rhythmbox didn't come with a repeat one feature built into the GUI, so I went ahead and patched the current source from git (0.12.3) to provide one. This patch replaces the Repeat toggle action with a Repeat action that switches between Repeat Off, Repeat All, and Repeat One. It uses modified code from the previous Repeat One patch in order to actually implement the repeat one play order: http://www.mail-archive.com/rhythmbox-devel gnome org/msg01669.html
--
Brian Nguyen
mtxcoll gmail com
diff --git a/plugins/lirc/rb-lirc-plugin.c b/plugins/lirc/rb-lirc-plugin.c
index 44f6879..59e8e04 100644
--- a/plugins/lirc/rb-lirc-plugin.c
+++ b/plugins/lirc/rb-lirc-plugin.c
@@ -148,15 +148,15 @@ rb_lirc_plugin_read_code (GIOChannel *source,
 			rb_shell_player_stop (plugin->shell_player);
 		} else if (strcmp (str, RB_IR_COMMAND_SHUFFLE) == 0) {
 			gboolean shuffle;
-			gboolean repeat;
+			unsigned repeat;
 			if (rb_shell_player_get_playback_state (plugin->shell_player, &shuffle, &repeat)) {
 				rb_shell_player_set_playback_state (plugin->shell_player, !shuffle, repeat);
 			}
 		} else if (strcmp (str, RB_IR_COMMAND_REPEAT) == 0) {
 			gboolean shuffle;
-			gboolean repeat;
+			unsigned repeat;
 			if (rb_shell_player_get_playback_state (plugin->shell_player, &shuffle, &repeat)) {
-				rb_shell_player_set_playback_state (plugin->shell_player, shuffle, !repeat);
+				rb_shell_player_set_playback_state (plugin->shell_player, shuffle, RB_SHELL_PLAYER_NEXT_REPEAT(repeat));
 			}
 		} else if (strcmp (str, RB_IR_COMMAND_NEXT) == 0) {
 			rb_shell_player_do_next (plugin->shell_player, NULL);
diff --git a/plugins/mmkeys/rb-mmkeys-plugin.c b/plugins/mmkeys/rb-mmkeys-plugin.c
index 88ba0bc..b19e501 100644
--- a/plugins/mmkeys/rb-mmkeys-plugin.c
+++ b/plugins/mmkeys/rb-mmkeys-plugin.c
@@ -116,13 +116,15 @@ media_player_key_pressed (DBusGProxy *proxy,
 	} else if (strcmp (key, "Next") == 0) {
 		rb_shell_player_do_next (plugin->shell_player, NULL);
 	} else if (strcmp (key, "Repeat") == 0) {
-		gboolean shuffle, repeat;
+		gboolean shuffle;
+        unsigned repeat;
 
 		if (rb_shell_player_get_playback_state (plugin->shell_player, &shuffle, &repeat)) {
-			rb_shell_player_set_playback_state (plugin->shell_player, shuffle, !repeat);
+			rb_shell_player_set_playback_state (plugin->shell_player, shuffle, RB_SHELL_PLAYER_NEXT_REPEAT(repeat));
 		}
 	} else if (strcmp (key, "Shuffle") == 0) {
-		gboolean shuffle, repeat;
+		gboolean shuffle;
+        unsigned repeat;
 
 		if (rb_shell_player_get_playback_state (plugin->shell_player, &shuffle, &repeat)) {
 			rb_shell_player_set_playback_state (plugin->shell_player, !shuffle, repeat);
diff --git a/shell/Makefile.am b/shell/Makefile.am
index f42c85b..a88a366 100644
--- a/shell/Makefile.am
+++ b/shell/Makefile.am
@@ -72,6 +72,8 @@ librbshell_la_SOURCES =              			\
 	rb-play-order-linear.h				\
 	rb-play-order-linear-loop.c			\
 	rb-play-order-linear-loop.h			\
+	rb-play-order-linear-loop-one.c		\
+	rb-play-order-linear-loop-one.h		\
 	rb-play-order-queue.c				\
 	rb-play-order-queue.h				\
 	rb-play-order-shuffle.c				\
diff --git a/shell/rb-shell-player.c b/shell/rb-shell-player.c
index c2cc720..6157590 100644
--- a/shell/rb-shell-player.c
+++ b/shell/rb-shell-player.c
@@ -91,6 +91,7 @@
 /* Play Orders */
 #include "rb-play-order-linear.h"
 #include "rb-play-order-linear-loop.h"
+#include "rb-play-order-linear-loop-one.h"
 #include "rb-play-order-shuffle.h"
 #include "rb-play-order-random-equal-weights.h"
 #include "rb-play-order-random-by-age.h"
@@ -98,9 +99,9 @@
 #include "rb-play-order-random-by-age-and-rating.h"
 #include "rb-play-order-queue.h"
 
-static const char* const state_to_play_order[2][2] =
-	{{"linear",	"linear-loop"},
-	 {"shuffle",	"random-by-age-and-rating"}};
+static const char* const state_to_play_order[2][3] =
+	{{"linear",	"linear-loop", "linear-loop-one-no-shuffle"},
+	 {"shuffle",	"random-by-age-and-rating", "linear-loop-one-shuffle"}};
 
 static void rb_shell_player_class_init (RBShellPlayerClass *klass);
 static void rb_shell_player_init (RBShellPlayer *shell_player);
@@ -312,6 +313,9 @@ static GtkActionEntry rb_shell_player_actions [] =
 	{ "ControlNext", GTK_STOCK_MEDIA_NEXT, N_("_Next"), "<alt>Right",
 	  N_("Start playing the next song"),
 	  G_CALLBACK (rb_shell_player_cmd_next) },
+	{ "ControlRepeat", GNOME_MEDIA_REPEAT, N_("Repeat Off"), "<control>R",
+	  N_("Play first song again after all songs are played"),
+	  G_CALLBACK (rb_shell_player_repeat_changed_cb) },
 	{ "ControlVolumeUp", NULL, N_("_Increase Volume"), "<control>Up",
 	  N_("Increase playback volume"),
 	  G_CALLBACK (rb_shell_player_cmd_volume_up) },
@@ -329,9 +333,6 @@ static GtkToggleActionEntry rb_shell_player_toggle_entries [] =
 	{ "ControlShuffle", GNOME_MEDIA_SHUFFLE, N_("Sh_uffle"), "<control>U",
 	  N_("Play songs in a random order"),
 	  G_CALLBACK (rb_shell_player_shuffle_changed_cb) },
-	{ "ControlRepeat", GNOME_MEDIA_REPEAT, N_("_Repeat"), "<control>R",
-	  N_("Play first song again after all songs are played"),
-	  G_CALLBACK (rb_shell_player_repeat_changed_cb) },
 	{ "ViewSongPositionSlider", NULL, N_("_Song Position Slider"), NULL,
 	  N_("Change the visibility of the song position slider"),
 	  G_CALLBACK (rb_shell_player_view_song_position_slider_changed_cb), TRUE },
@@ -920,6 +921,10 @@ rb_shell_player_init (RBShellPlayer *player)
 					RB_TYPE_LINEAR_PLAY_ORDER, FALSE);
 	rb_shell_player_add_play_order (player, "linear-loop", N_("Linear looping"),
 					RB_TYPE_LINEAR_PLAY_ORDER_LOOP, FALSE);
+	rb_shell_player_add_play_order (player, "linear-loop-one-no-shuffle", N_("Loop one track, shuffle unset"),
+					RB_TYPE_LINEAR_PLAY_ORDER_LOOP_ONE, FALSE);
+	rb_shell_player_add_play_order (player, "linear-loop-one-shuffle", N_("Loop one track, shuffle set"),
+					RB_TYPE_LINEAR_PLAY_ORDER_LOOP_ONE, FALSE);
 	rb_shell_player_add_play_order (player, "shuffle", N_("Shuffle"),
 					RB_TYPE_SHUFFLE_PLAY_ORDER, FALSE);
 	rb_shell_player_add_play_order (player, "random-equal-weights", N_("Random with equal weights"),
@@ -1736,7 +1741,7 @@ gconf_play_order_changed (GConfClient *client,
 gboolean
 rb_shell_player_get_playback_state (RBShellPlayer *player,
 				    gboolean *shuffle,
-				    gboolean *repeat)
+				    unsigned *repeat)
 {
 	int i, j;
 	char *play_order;
@@ -1756,8 +1761,8 @@ rb_shell_player_get_playback_state (RBShellPlayer *player,
 	return FALSE;
 
 found:
-	*shuffle = i > 0;
-	*repeat = j > 0;
+	*shuffle = i;
+	*repeat = j;
 	g_free (play_order);
 	return TRUE;
 }
@@ -1787,9 +1792,9 @@ rb_shell_player_set_play_order (RBShellPlayer *player,
 void
 rb_shell_player_set_playback_state (RBShellPlayer *player,
 				    gboolean shuffle,
-				    gboolean repeat)
+				    unsigned repeat)
 {
-	const char *neworder = state_to_play_order[shuffle ? 1 : 0][repeat ? 1 : 0];
+	const char *neworder = state_to_play_order[shuffle ? 1 : 0][repeat];
 	rb_shell_player_set_play_order (player, neworder);
 }
 
@@ -2390,7 +2395,8 @@ rb_shell_player_playpause (RBShellPlayer *player,
 static void
 rb_shell_player_sync_control_state (RBShellPlayer *player)
 {
-	gboolean shuffle, repeat;
+	gboolean shuffle;
+    unsigned repeat;
 	GtkAction *action;
 	rb_debug ("syncing control state");
 
@@ -2403,7 +2409,20 @@ rb_shell_player_sync_control_state (RBShellPlayer *player)
 	gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), shuffle);
 	action = gtk_action_group_get_action (player->priv->actiongroup,
 					      "ControlRepeat");
-	gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), repeat);
+
+	switch (repeat) {
+		case RB_SHELL_PLAYER_REPEAT_OFF:
+        	gtk_action_set_label(action,_("Repeat Off"));
+			break;
+		case RB_SHELL_PLAYER_REPEAT_ONE:
+        	gtk_action_set_label(action,_("Repeat One"));
+			break;
+		case RB_SHELL_PLAYER_REPEAT_ALL:
+        	gtk_action_set_label(action,_("Repeat All"));
+			break;
+		default:
+			return;
+	}
 }
 
 static void
@@ -2600,9 +2619,8 @@ static void
 rb_shell_player_shuffle_changed_cb (GtkAction *action,
 				    RBShellPlayer *player)
 {
-	const char *neworder;
 	gboolean shuffle = FALSE;
-	gboolean repeat = FALSE;
+	unsigned repeat = RB_SHELL_PLAYER_REPEAT_OFF;
 
 	if (player->priv->syncing_state)
 		return;
@@ -2612,27 +2630,25 @@ rb_shell_player_shuffle_changed_cb (GtkAction *action,
 	rb_shell_player_get_playback_state (player, &shuffle, &repeat);
 
 	shuffle = !shuffle;
-	neworder = state_to_play_order[shuffle ? 1 : 0][repeat ? 1 : 0];
-	rb_shell_player_set_play_order (player, neworder);
+    rb_shell_player_set_playback_state (player, shuffle, repeat);
 }
 
 static void
 rb_shell_player_repeat_changed_cb (GtkAction *action,
 				   RBShellPlayer *player)
 {
-	const char *neworder;
 	gboolean shuffle = FALSE;
-	gboolean repeat = FALSE;
-	rb_debug ("repeat changed");
+	unsigned repeat = RB_SHELL_PLAYER_REPEAT_OFF;
 
 	if (player->priv->syncing_state)
 		return;
 
 	rb_shell_player_get_playback_state (player, &shuffle, &repeat);
 
-	repeat = !repeat;
-	neworder = state_to_play_order[shuffle ? 1 : 0][repeat ? 1 : 0];
-	rb_shell_player_set_play_order (player, neworder);
+	repeat = RB_SHELL_PLAYER_NEXT_REPEAT(repeat);
+
+    rb_shell_player_sync_control_state (player);
+    rb_shell_player_set_playback_state (player, shuffle, repeat);
 }
 
 static void
diff --git a/shell/rb-shell-player.h b/shell/rb-shell-player.h
index 105198b..01b12e9 100644
--- a/shell/rb-shell-player.h
+++ b/shell/rb-shell-player.h
@@ -45,6 +45,16 @@ G_BEGIN_DECLS
 #define RB_IS_SHELL_PLAYER_CLASS(k)  (G_TYPE_CHECK_CLASS_TYPE ((k), RB_TYPE_SHELL_PLAYER))
 #define RB_SHELL_PLAYER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), RB_TYPE_SHELL_PLAYER, RBShellPlayerClass))
 
+typedef enum {
+    RB_SHELL_PLAYER_REPEAT_OFF, 
+    RB_SHELL_PLAYER_REPEAT_ALL, 
+    RB_SHELL_PLAYER_REPEAT_ONE, 
+    RB_SHELL_PLAYER_SIZE_REPEAT,
+} RBShellPlayerRepeatType;
+
+#define RB_SHELL_PLAYER_NEXT_SHUFFLE(x) (!(x))
+#define RB_SHELL_PLAYER_NEXT_REPEAT(x) (((x) + 1) % RB_SHELL_PLAYER_SIZE_REPEAT)
+
 typedef enum
 {
 	RB_SHELL_PLAYER_ERROR_PLAYLIST_PARSE_ERROR,
@@ -134,11 +144,11 @@ gboolean		rb_shell_player_get_playing_path(RBShellPlayer *player,
 							 GError **error);
 
 void			rb_shell_player_set_playback_state(RBShellPlayer *player,
-							   gboolean shuffle, gboolean repeat);
+							   gboolean shuffle, unsigned repeat);
 
 gboolean                rb_shell_player_get_playback_state(RBShellPlayer *player,
 							   gboolean *shuffle,
-							   gboolean *repeat);
+							   unsigned *repeat);
 
 RhythmDBEntry *         rb_shell_player_get_playing_entry (RBShellPlayer *player);
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]