chiark / gitweb /
Work on playlist right-click menu
[disorder] / disobedience / playlists.c
index 6ba78bc99f297c95488f2241a9da46def58b4eaf..2673e1c526ddb325ab6ced81a212790dc6a00a35 100644 (file)
@@ -48,6 +48,12 @@ static void playlist_list_received_playlists(void *v,
 static void playlist_editor_fill(const char *event,
                                  void *eventdata,
                                  void *callbackdata);
+static int playlist_playall_sensitive(void *extra);
+static void playlist_playall_activate(GtkMenuItem *menuitem,
+                                      gpointer user_data);
+static int playlist_remove_sensitive(void *extra) ;
+static void playlist_remove_activate(GtkMenuItem *menuitem,
+                                     gpointer user_data);
 
 /** @brief Playlist editing window */
 static GtkWidget *playlist_window;
@@ -60,13 +66,19 @@ static const struct queue_column playlist_columns[] = {
   { "Length", column_length,   0,        COL_RIGHT }
 };
 
-/** @brief Pop-up menu for playlist editor */
-// TODO some of these may not be generic enough yet - check!
+/** @brief Pop-up menu for playlist editor
+ *
+ * Status:
+ * - track properties works but, bizarrely, raises the main window
+ * - play track works
+ * - play playlist works
+ * - select/deselect all work
+ */
 static struct menuitem playlist_menuitems[] = {
   { "Track properties", ql_properties_activate, ql_properties_sensitive, 0, 0 },
   { "Play track", ql_play_activate, ql_play_sensitive, 0, 0 },
-  //{ "Play playlist", ql_playall_activate, ql_playall_sensitive, 0, 0 },
-  { "Remove track from queue", ql_remove_activate, ql_remove_sensitive, 0, 0 },
+  { "Play playlist", playlist_playall_activate, playlist_playall_sensitive, 0, 0 },
+  { "Remove track from queue", playlist_remove_activate, playlist_remove_sensitive, 0, 0 },
   { "Select all tracks", ql_selectall_activate, ql_selectall_sensitive, 0, 0 },
   { "Deselect all tracks", ql_selectnone_activate, ql_selectnone_sensitive, 0, 0 },
 };
@@ -144,6 +156,12 @@ static void playlist_list_received_playlists(void attribute((unused)) *v,
 
 /* Playlists menu ----------------------------------------------------------- */
 
+static void playlist_menu_playing(void attribute((unused)) *v,
+                                  const char *err) {
+  if(err)
+    popup_protocol_error(0, err);
+}
+
 /** @brief Play received playlist contents
  *
  * Passed as a completion callback by menu_activate_playlist().
@@ -156,7 +174,7 @@ static void playlist_menu_received_content(void attribute((unused)) *v,
     return;
   }
   for(int n = 0; n < nvec; ++n)
-    disorder_eclient_play(client, vec[n], NULL, NULL);
+    disorder_eclient_play(client, vec[n], playlist_menu_playing, NULL);
 }
 
 /** @brief Called to activate a playlist
@@ -667,7 +685,6 @@ static void playlists_editor_received_tracks(void *v,
     /* Synthesize a unique ID so that the selection survives updates.  Tracks
      * can appear more than once in the queue so we can't use raw track names,
      * so we add a serial number to the start. */
-    /* TODO but this doesn't work for some reason */
     int *serialp = hash_find(h, vec[n]), serial = serialp ? *serialp : 0;
     byte_xasprintf((char **)&q->id, "%d-%s", serial++, vec[n]);
     hash_add(h, vec[0], &serial, HASH_INSERT_OR_REPLACE);
@@ -700,6 +717,57 @@ static GtkWidget *playlists_editor_create(void) {
   return w;
 }
 
+/* Playlist editor right-click menu ---------------------------------------- */
+
+/** @brief Called to determine whether the playlist is playable */
+static int playlist_playall_sensitive(void attribute((unused)) *extra) {
+  /* If there's no playlist obviously we can't play it */
+  if(!playlist_picker_selected)
+    return FALSE;
+  /* If it's empty we can't play it */
+  if(!ql_playlist.q)
+    return FALSE;
+  /* Otherwise we can */
+  return TRUE;
+}
+
+/** @brief Called to play the selected playlist */
+static void playlist_playall_activate(GtkMenuItem attribute((unused)) *menuitem,
+                                      gpointer attribute((unused)) user_data) {
+  if(!playlist_picker_selected)
+    return;
+  /* Re-use the menu-based activation callback */
+  disorder_eclient_playlist_get(client, playlist_menu_received_content,
+                                playlist_picker_selected, NULL);
+}
+
+/** @brief Called to determine whether the playlist is playable */
+static int playlist_remove_sensitive(void attribute((unused)) *extra) {
+  /* If there's no playlist obviously we can't remove from it */
+  if(!playlist_picker_selected)
+    return FALSE;
+  /* If no tracks are selected we cannot remove them */
+  if(!gtk_tree_selection_count_selected_rows(ql_playlist.selection))
+    return FALSE;
+  /* We're good to go */
+  return TRUE;
+}
+
+/** @brief Called to play the selected playlist */
+static void playlist_remove_activate(GtkMenuItem attribute((unused)) *menuitem,
+                                     gpointer attribute((unused)) user_data) {
+  if(!playlist_picker_selected)
+    return;
+  /* To safely remove rows we must:
+   * - take a lock
+   * - fetch the playlist
+   * - delete the selected rows
+   * - store the playlist
+   * - release the lock
+   */
+  fprintf(stderr, "remove tracks\n");   /* TODO */
+}
+
 /* Playlists window --------------------------------------------------------- */
 
 /** @brief Keypress handler */