[Rhythmbox-devel] new error handling / skip unplayable patch
- From: William Jon McCann <mccannwj pha jhu edu>
- To: rhythmbox <rhythmbox-devel gnome org>
- Subject: [Rhythmbox-devel] new error handling / skip unplayable patch
- Date: Tue, 30 Nov 2004 21:55:04 -0500
Hi,
Here is a new patch that skips unplayable tracks rather than throw a
dialog (fixes #120974). It also includes a few other fixes and my last
patch to disallow drops to smart playlists.
Look ok?
Jon
* looking for rhythmbox-devel gnome org--2004/rhythmbox--main--0.9--patch-150 to compare with
* comparing to rhythmbox-devel gnome org--2004/rhythmbox--main--0.9--patch-150
A {arch}/rhythmbox/rhythmbox--main/rhythmbox--main--0.9/mccann jhu edu--2004/patch-log/patch-10
A {arch}/rhythmbox/rhythmbox--main/rhythmbox--main--0.9/mccann jhu edu--2004/patch-log/patch-11
A {arch}/rhythmbox/rhythmbox--main/rhythmbox--main--0.9/mccann jhu edu--2004/patch-log/patch-12
A {arch}/rhythmbox/rhythmbox--main/rhythmbox--main--0.9/mccann jhu edu--2004/patch-log/patch-13
M rhythmdb/rhythmdb.h
M widgets/rb-cell-renderer-pixbuf.h
M player/rb-player-gst.c
M sources/rb-sourcelist-model.c
M rhythmdb/rhythmdb.c
M rhythmdb/rhythmdb-tree.c
M widgets/rb-dialog.c
M widgets/rb-cell-renderer-pixbuf.c
M shell/rb-shell-player.c
M sources/rb-playlist-source.c
M widgets/rb-entry-view.c
* modified files
--- orig/player/rb-player-gst.c
+++ mod/player/rb-player-gst.c
@@ -1,3 +1,4 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
/*
* arch-tag: Implementation of GStreamer backends, with workarounds for bugs
*
@@ -617,7 +618,7 @@
}
}
g_timer_start (mp->priv->timer);
- } else {
+ } else {
rb_debug ("PAUSING pipeline");
if (gst_element_set_state (mp->priv->pipeline,
GST_STATE_PAUSED) == GST_STATE_FAILURE) {
--- orig/rhythmdb/rhythmdb-tree.c
+++ mod/rhythmdb/rhythmdb-tree.c
@@ -425,6 +425,7 @@
case RHYTHMDB_PROP_ALBUM_FOLDED:
case RHYTHMDB_PROP_LAST_PLAYED_STR:
case RHYTHMDB_PROP_HIDDEN:
+ case RHYTHMDB_PROP_PLAYBACK_ERROR:
case RHYTHMDB_NUM_PROPERTIES:
g_assert_not_reached ();
break;
@@ -703,6 +704,7 @@
case RHYTHMDB_PROP_ALBUM_FOLDED:
case RHYTHMDB_PROP_LAST_PLAYED_STR:
case RHYTHMDB_PROP_HIDDEN:
+ case RHYTHMDB_PROP_PLAYBACK_ERROR:
case RHYTHMDB_NUM_PROPERTIES:
break;
}
--- orig/rhythmdb/rhythmdb.c
+++ mod/rhythmdb/rhythmdb.c
@@ -1,3 +1,4 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
/*
* arch-tag: Implementation of RhythmDB - Rhythmbox backend queryable database
*
@@ -864,6 +865,7 @@
rhythmdb_entry_finalize (RhythmDBEntry *entry)
{
g_free (entry->location);
+ g_free (entry->playback_error);
rb_refstring_unref (entry->title);
rb_refstring_unref (entry->genre);
rb_refstring_unref (entry->artist);
@@ -1865,6 +1867,10 @@
g_free (entry->location);
entry->location = g_value_dup_string (value);
break;
+ case RHYTHMDB_PROP_PLAYBACK_ERROR:
+ g_free (entry->playback_error);
+ entry->playback_error = g_value_dup_string (value);
+ break;
case RHYTHMDB_PROP_MOUNTPOINT:
g_free (entry->mountpoint);
entry->mountpoint = g_value_dup_string (value);
@@ -2552,6 +2558,7 @@
ENUM_ENTRY (RHYTHMDB_PROP_ARTIST_FOLDED, "Artist folded (gchararray) [artist-folded]"),
ENUM_ENTRY (RHYTHMDB_PROP_ALBUM_FOLDED, "Album folded (gchararray) [album-folded]"),
ENUM_ENTRY (RHYTHMDB_PROP_LAST_PLAYED_STR, "Last Played (gchararray) [last-played-str]"),
+ ENUM_ENTRY (RHYTHMDB_PROP_PLAYBACK_ERROR, "Playback error string (gchararray) [playback-error]"),
ENUM_ENTRY (RHYTHMDB_PROP_HIDDEN, "Visibility (gboolean) [visibility]"),
{ 0, 0, 0 }
};
--- orig/rhythmdb/rhythmdb.h
+++ mod/rhythmdb/rhythmdb.h
@@ -1,3 +1,4 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
/*
* arch-tag: Header for RhythmDB - Rhythmbox backend queryable database
*
@@ -97,6 +98,7 @@
RHYTHMDB_PROP_ALBUM_FOLDED,
RHYTHMDB_PROP_LAST_PLAYED_STR,
RHYTHMDB_PROP_HIDDEN,
+ RHYTHMDB_PROP_PLAYBACK_ERROR,
RHYTHMDB_NUM_PROPERTIES
} RhythmDBPropType;
@@ -160,6 +162,9 @@
/* cached data */
RBRefString *last_played_str;
+ /* playback error string */
+ char *playback_error;
+
/* visibility (to hide entries on unmounted volumes) */
gboolean hidden;
} RhythmDBEntry;
@@ -210,6 +215,8 @@
return entry->mountpoint;
case RHYTHMDB_PROP_LAST_PLAYED_STR:
return rb_refstring_get (entry->last_played_str);
+ case RHYTHMDB_PROP_PLAYBACK_ERROR:
+ return entry->playback_error;
default:
g_assert_not_reached ();
return NULL;
--- orig/shell/rb-shell-player.c
+++ mod/shell/rb-shell-player.c
@@ -1,3 +1,4 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
/*
* arch-tag: Implementation of main playback logic object
*
@@ -982,9 +983,8 @@
rb_shell_player_open_entry (RBShellPlayer *player, RhythmDBEntry *entry, GError **error)
{
rb_shell_player_open_location (player, entry->location, error);
- if (*error == NULL)
+ if (error == NULL || *error == NULL)
return;
-
fprintf (stderr, "Got error opening \"%s\": %s\n",
entry->location, (*error)->message);
}
@@ -1006,6 +1006,32 @@
}
static void
+rb_shell_player_set_entry_playback_error (RBShellPlayer *player,
+ RhythmDBEntry *entry,
+ char *message)
+{
+ GValue value = { 0, };
+
+ g_return_if_fail (RB_IS_SHELL_PLAYER (player));
+
+ g_value_init (&value, G_TYPE_STRING);
+ g_value_set_string (&value, message);
+ rhythmdb_entry_set (player->priv->db,
+ entry,
+ RHYTHMDB_PROP_PLAYBACK_ERROR,
+ &value);
+ g_value_unset (&value);
+ rhythmdb_commit (player->priv->db);
+}
+
+static gboolean
+do_next_idle (RBShellPlayer *player)
+{
+ rb_shell_player_do_next (player);
+ return FALSE;
+}
+
+static void
rb_shell_player_set_playing_entry (RBShellPlayer *player, RhythmDBEntry *entry)
{
GError *error = NULL;
@@ -1022,14 +1048,19 @@
rb_shell_player_play (player, &error);
}
+ rb_entry_view_set_playing_entry (songs, entry);
+
if (error != NULL) {
- rb_error_dialog (NULL, _("Couldn't start playback"),
- "%s", error->message);
+ rb_shell_player_set_entry_playback_error (player, entry, error->message);
+
return;
+ } else {
+ rb_debug ("Success!");
+ /* clear error on successful playback */
+ g_free (entry->playback_error);
+ entry->playback_error = NULL;
}
- rb_debug ("Success!");
- rb_entry_view_set_playing_entry (songs, entry);
rb_shell_player_sync_with_source (player);
rb_shell_player_sync_buttons (player);
}
@@ -1936,6 +1967,12 @@
rb_shell_player_error (RBShellPlayer *player, GError *err,
gboolean lock)
{
+ RBEntryView *songs;
+ RhythmDBEntry *entry;
+
+ songs = rb_source_get_entry_view (player->priv->source);
+ entry = rb_entry_view_get_playing_entry (songs);
+
if (player->priv->handling_error) {
rb_debug ("ignoring error: %s", err->message);
return;
@@ -1944,12 +1981,24 @@
if (lock != FALSE)
GDK_THREADS_ENTER ();
+ player->priv->handling_error = TRUE;
+
rb_shell_player_disable_buffering (player);
rb_debug ("error: %s", err->message);
- rb_shell_player_set_playing_source (player, NULL);
- rb_error_dialog (NULL, _("Playback error"),
- "%s", err->message);
+ rb_shell_player_set_entry_playback_error (player, entry, err->message);
+
+ switch (rb_source_handle_eos (player->priv->source)) {
+ case RB_SOURCE_EOF_ERROR:
+ rb_error_dialog (NULL, _("Stream error"),
+ _("Unexpected end of stream!"));
+ rb_shell_player_set_playing_source (player, NULL);
+ break;
+ case RB_SOURCE_EOF_NEXT:
+ g_idle_add ((GSourceFunc)do_next_idle, player);
+ break;
+ }
+
player->priv->handling_error = FALSE;
rb_debug ("exiting error hander");
@@ -1961,9 +2010,10 @@
error_cb (RBPlayer *mmplayer, GError *err, gpointer data)
{
RBShellPlayer *player = RB_SHELL_PLAYER (data);
+
if (player->priv->handling_error)
return;
- player->priv->handling_error = TRUE;
+
rb_shell_player_error (player, err, TRUE);
}
--- orig/sources/rb-playlist-source.c
+++ mod/sources/rb-playlist-source.c
@@ -577,7 +577,6 @@
GList *list;
RBPlaylistSource *source = RB_PLAYLIST_SOURCE (asource);
-
if (data->type == gdk_atom_intern ("text/uri-list", TRUE)) {
list = gnome_vfs_uri_list_parse (data->data);
--- orig/sources/rb-sourcelist-model.c
+++ mod/sources/rb-sourcelist-model.c
@@ -339,7 +339,7 @@
gtk_tree_model_get (GTK_TREE_MODEL (model), &iter,
RB_SOURCELIST_MODEL_COLUMN_SOURCE, &source, -1);
- return rb_source_can_rename (source);
+ return rb_source_can_cut (source);
}
return FALSE;
@@ -356,6 +356,8 @@
if (g_list_find (targets, gdk_atom_intern ("text/uri-list", TRUE))) {
if (!dest_path)
return FALSE;
+ if (!path_is_droppable (RB_SOURCELIST_MODEL (model), dest_path))
+ return FALSE;
*pos = GTK_TREE_VIEW_DROP_INTO_OR_BEFORE;
return TRUE;
}
--- orig/widgets/rb-cell-renderer-pixbuf.c
+++ mod/widgets/rb-cell-renderer-pixbuf.c
@@ -1,3 +1,4 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
/* rbcellrendererpixbuf.c
*
* arch-tag: Implementation of Rhythmbox pixbuf GtkTreeView cell renderer
@@ -24,6 +25,8 @@
#include <config.h>
#include <libgnome/gnome-i18n.h>
#include <stdlib.h>
+#include <gtk/gtktreeview.h>
+#include <gtk/gtkiconfactory.h>
#include "rb-cell-renderer-pixbuf.h"
#include "rb-cut-and-paste-code.h"
@@ -52,13 +55,26 @@
GdkRectangle *cell_area,
GdkRectangle *expose_area,
guint flags);
-
+static gboolean rb_cell_renderer_pixbuf_activate (GtkCellRenderer *cell,
+ GdkEvent *event,
+ GtkWidget *widget,
+ const gchar *path,
+ GdkRectangle *background_area,
+ GdkRectangle *cell_area,
+ GtkCellRendererState flags);
enum {
PROP_ZERO,
PROP_PIXBUF
};
+enum
+{
+ PIXBUF_CLICKED,
+ LAST_SIGNAL
+};
+
+static guint rb_cell_renderer_pixbuf_signals [LAST_SIGNAL] = { 0 };
GtkType
rb_cell_renderer_pixbuf_get_type (void)
@@ -89,6 +105,9 @@
static void
rb_cell_renderer_pixbuf_init (RBCellRendererPixbuf *cellpixbuf)
{
+
+ /* set the renderer able to be activated */
+ GTK_CELL_RENDERER (cellpixbuf)->mode = GTK_CELL_RENDERER_MODE_ACTIVATABLE;
}
static void
@@ -102,6 +121,7 @@
cell_class->get_size = rb_cell_renderer_pixbuf_get_size;
cell_class->render = rb_cell_renderer_pixbuf_render;
+ cell_class->activate = rb_cell_renderer_pixbuf_activate;
g_object_class_install_property (object_class,
PROP_PIXBUF,
@@ -111,6 +131,17 @@
GDK_TYPE_PIXBUF,
G_PARAM_READABLE |
G_PARAM_WRITABLE));
+
+ rb_cell_renderer_pixbuf_signals[PIXBUF_CLICKED] =
+ g_signal_new ("pixbuf-clicked",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (RBCellRendererPixbufClass, pixbuf_clicked),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__STRING,
+ G_TYPE_NONE,
+ 1,
+ G_TYPE_STRING);
}
static void
@@ -296,3 +327,34 @@
g_object_unref (pixbuf);
}
+
+
+static gboolean
+rb_cell_renderer_pixbuf_activate (GtkCellRenderer *cell,
+ GdkEvent *event,
+ GtkWidget *widget,
+ const gchar *path,
+ GdkRectangle *background_area,
+ GdkRectangle *cell_area,
+ GtkCellRendererState flags)
+{
+ int mouse_x, mouse_y, icon_width;
+ RBCellRendererPixbuf *cellpixbuf = (RBCellRendererPixbuf *) cell;
+
+ g_return_val_if_fail (RB_IS_CELL_RENDERER_PIXBUF (cellpixbuf), FALSE);
+
+ gtk_icon_size_lookup (GTK_ICON_SIZE_MENU, &icon_width, NULL);
+ gtk_widget_get_pointer (widget, &mouse_x, &mouse_y);
+ gtk_tree_view_widget_to_tree_coords (GTK_TREE_VIEW (widget),
+ mouse_x,
+ mouse_y,
+ &mouse_x,
+ &mouse_y);
+
+ /* ensure the user clicks within the good cell */
+ if (mouse_x - cell_area->x >= 0
+ && mouse_x - cell_area->x <= cell_area->width) {
+ g_signal_emit (G_OBJECT (cellpixbuf), rb_cell_renderer_pixbuf_signals [PIXBUF_CLICKED], 0, path);
+ }
+ return TRUE;
+}
--- orig/widgets/rb-cell-renderer-pixbuf.h
+++ mod/widgets/rb-cell-renderer-pixbuf.h
@@ -50,6 +50,8 @@
struct _RBCellRendererPixbufClass
{
GtkCellRendererClass parent_class;
+
+ void (*pixbuf_clicked) (GtkTreePath *path);
};
GtkType rb_cell_renderer_pixbuf_get_type (void);
--- orig/widgets/rb-dialog.c
+++ mod/widgets/rb-dialog.c
@@ -54,13 +54,13 @@
primary);
gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
- text);
+ "%s", text);
gtk_container_set_border_width (GTK_CONTAINER (dialog), 6);
- gtk_dialog_run (GTK_DIALOG (dialog));
+ g_signal_connect (dialog, "response", G_CALLBACK (gtk_widget_destroy), NULL);
- gtk_widget_destroy (dialog);
+ gtk_widget_show (dialog);
g_free (text);
}
--- orig/widgets/rb-entry-view.c
+++ mod/widgets/rb-entry-view.c
@@ -1,3 +1,4 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
/*
* arch-tag: Implementation of widget to display RhythmDB entries
*
@@ -24,6 +25,7 @@
#include <gtk/gtktreeselection.h>
#include <gtk/gtkcellrenderertext.h>
#include <gtk/gtkiconfactory.h>
+#include <gtk/gtkstock.h>
#include <gtk/gtktooltips.h>
#include <gdk/gdkkeysyms.h>
#include <config.h>
@@ -105,6 +107,9 @@
const char *path,
double rating,
RBEntryView *view);
+static void rb_entry_view_pixbuf_clicked_cb (RBEntryView *view,
+ const char *path,
+ RBCellRendererPixbuf *cellpixbuf);
static gboolean rb_entry_view_button_press_cb (GtkTreeView *treeview,
GdkEventButton *event,
RBEntryView *view);
@@ -142,6 +147,7 @@
GdkPixbuf *playing_pixbuf;
GdkPixbuf *paused_pixbuf;
+ GdkPixbuf *error_pixbuf;
char *sorting_key;
guint sorting_gconf_notification_id;
@@ -398,6 +404,10 @@
RB_STOCK_PAUSED,
GTK_ICON_SIZE_MENU,
NULL);
+ view->priv->error_pixbuf = gtk_widget_render_icon (dummy,
+ GTK_STOCK_CLOSE,
+ GTK_ICON_SIZE_MENU,
+ NULL);
gtk_widget_destroy (dummy);
view->priv->propid_column_map = g_hash_table_new (NULL, NULL);
@@ -433,6 +443,7 @@
g_object_unref (G_OBJECT (view->priv->playing_pixbuf));
g_object_unref (G_OBJECT (view->priv->paused_pixbuf));
+ g_object_unref (G_OBJECT (view->priv->error_pixbuf));
g_free (view->priv->sorting_key);
@@ -830,6 +841,8 @@
pixbuf = view->priv->playing_pixbuf;
else if (entry == view->priv->playing_entry)
pixbuf = view->priv->paused_pixbuf;
+ else if (entry->playback_error)
+ pixbuf = view->priv->error_pixbuf;
else
pixbuf = NULL;
@@ -1363,6 +1376,10 @@
gtk_icon_size_lookup (GTK_ICON_SIZE_MENU, &width, NULL);
gtk_tree_view_column_set_fixed_width (column, width + 5);
gtk_tree_view_append_column (GTK_TREE_VIEW (view->priv->treeview), column);
+ g_signal_connect_swapped (renderer,
+ "pixbuf-clicked",
+ G_CALLBACK (rb_entry_view_pixbuf_clicked_cb),
+ G_OBJECT (view));
gtk_tooltips_set_tip (GTK_TOOLTIPS (tooltip), GTK_WIDGET (column->button),
_("Now Playing"), NULL);
@@ -1432,6 +1449,27 @@
g_value_unset (&value);
}
+static void
+rb_entry_view_pixbuf_clicked_cb (RBEntryView *view,
+ const char *path_string,
+ RBCellRendererPixbuf *cellpixbuf)
+{
+ GtkTreePath *path;
+ RhythmDBEntry *entry;
+
+ g_return_if_fail (path_string != NULL);
+
+ path = gtk_tree_path_new_from_string (path_string);
+ entry = entry_from_tree_path (view, path);
+
+ gtk_tree_path_free (path);
+
+ if (entry->playback_error) {
+ rb_error_dialog (NULL, _("Playback Error"),
+ "%s", entry->playback_error);
+ }
+}
+
void
rb_entry_view_set_playing_entry (RBEntryView *view,
RhythmDBEntry *entry)
* added files
--- /dev/null
+++ /home/mccannwj/cvs/foo/rhythmbox--main--0.9--patch-149/,,what-changed rhythmbox--main--0 9--patch-150--rhythmbox-devel gnome org--2004/new-files-archive/./{arch}/rhythmbox/rhythmbox--main/rhythmbox--main--0.9/mccann jhu edu--2004/patch-log/patch-10
@@ -0,0 +1,13 @@
+Revision: rhythmbox--main--0.9--patch-10
+Archive: mccann jhu edu--2004
+Creator: William Jon McCann <mccann jhu edu>
+Date: Tue Nov 23 15:19:03 EST 2004
+Standard-date: 2004-11-23 20:19:03 GMT
+Modified-files: sources/rb-playlist-source.c
+ sources/rb-sourcelist-model.c
+New-patches: mccann jhu edu--2004/rhythmbox--main--0.9--patch-10
+Summary: Disallow drop into smart playlists. Fixes #140232.
+Keywords:
+
+
+
--- /dev/null
+++ /home/mccannwj/cvs/foo/rhythmbox--main--0.9--patch-149/,,what-changed rhythmbox--main--0 9--patch-150--rhythmbox-devel gnome org--2004/new-files-archive/./{arch}/rhythmbox/rhythmbox--main/rhythmbox--main--0.9/mccann jhu edu--2004/patch-log/patch-11
@@ -0,0 +1,14 @@
+Revision: rhythmbox--main--0.9--patch-11
+Archive: mccann jhu edu--2004
+Creator: William Jon McCann <mccann jhu edu>
+Date: Mon Nov 29 18:50:00 EST 2004
+Standard-date: 2004-11-29 23:50:00 GMT
+Modified-files: rhythmdb/rhythmdb-tree.c
+ rhythmdb/rhythmdb.c rhythmdb/rhythmdb.h
+ shell/rb-shell-player.c widgets/rb-entry-view.c
+New-patches: mccann jhu edu--2004/rhythmbox--main--0.9--patch-11
+Summary: Fix for bug #120974: Skip unplayable songs.
+Keywords:
+
+
+
--- /dev/null
+++ /home/mccannwj/cvs/foo/rhythmbox--main--0.9--patch-149/,,what-changed rhythmbox--main--0 9--patch-150--rhythmbox-devel gnome org--2004/new-files-archive/./{arch}/rhythmbox/rhythmbox--main/rhythmbox--main--0.9/mccann jhu edu--2004/patch-log/patch-12
@@ -0,0 +1,13 @@
+Revision: rhythmbox--main--0.9--patch-12
+Archive: mccann jhu edu--2004
+Creator: William Jon McCann <mccann jhu edu>
+Date: Tue Nov 30 17:04:16 EST 2004
+Standard-date: 2004-11-30 22:04:16 GMT
+Modified-files: player/rb-player-gst.c
+ shell/rb-shell-player.c widgets/rb-dialog.c
+New-patches: mccann jhu edu--2004/rhythmbox--main--0.9--patch-12
+Summary: Fix crasher with rb-dialog. Move error handling to error callback.
+Keywords:
+
+
+
--- /dev/null
+++ /home/mccannwj/cvs/foo/rhythmbox--main--0.9--patch-149/,,what-changed rhythmbox--main--0 9--patch-150--rhythmbox-devel gnome org--2004/new-files-archive/./{arch}/rhythmbox/rhythmbox--main/rhythmbox--main--0.9/mccann jhu edu--2004/patch-log/patch-13
@@ -0,0 +1,14 @@
+Revision: rhythmbox--main--0.9--patch-13
+Archive: mccann jhu edu--2004
+Creator: William Jon McCann <mccann jhu edu>
+Date: Tue Nov 30 21:29:03 EST 2004
+Standard-date: 2004-12-01 02:29:03 GMT
+Modified-files: widgets/rb-cell-renderer-pixbuf.c
+ widgets/rb-cell-renderer-pixbuf.h widgets/rb-dialog.c
+ widgets/rb-entry-view.c
+New-patches: mccann jhu edu--2004/rhythmbox--main--0.9--patch-13
+Summary: Make rb-error-dialog non-modal. Click on error pixbuf column to display playback error.
+Keywords:
+
+
+
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]