[Xfce4-commits] <parole:master> Optional support for media tags changed using taglib

Ali Abdallah aliov at xfce.org
Fri Aug 14 19:02:01 CEST 2009


Updating branch refs/heads/master
         to d07192f2c74b1e5d70efd0e308c2959e9244bfda (commit)
       from e2d7e6f62fdf6c528e08de2ecf331d45680fd441 (commit)

commit d07192f2c74b1e5d70efd0e308c2959e9244bfda
Author: Ali Abdallah <aliov at xfce.org>
Date:   Fri Aug 14 18:30:05 2009 +0200

    Optional support for media tags changed using taglib

 TODO                                   |    1 -
 configure.ac.in                        |   23 +++-
 plugins/properties/Makefile.am         |    6 +-
 plugins/properties/stream-properties.c |  293 ++++++++++++++++++++++++++-----
 4 files changed, 272 insertions(+), 51 deletions(-)

diff --git a/TODO b/TODO
index e4b34c1..b40b356 100644
--- a/TODO
+++ b/TODO
@@ -8,7 +8,6 @@
 * ...
 
 === Plugins === 
-* Support for Taglib in the media properties plugin.
 * Write a youtube plugin.
 * Subtitle downloader.
 * ...?
diff --git a/configure.ac.in b/configure.ac.in
index 4713b06..40298c1 100644
--- a/configure.ac.in
+++ b/configure.ac.in
@@ -127,6 +127,27 @@ AC_ARG_ENABLE([properties-plugin], AC_HELP_STRING([--disable-properties-plugin],
 AC_MSG_CHECKING([whether to build the Parole stream properties plugin])
 AM_CONDITIONAL([PAROLE_PROPERTIES_PLUGIN], [test x"$ac_properties_plugin" = x"yes"])
 AC_MSG_RESULT([$ac_properties_plugin])
+TAGLIB_FOUND="no"
+if test x"$ac_properties_plugin" = x"yes"; then
+    XDT_CHECK_OPTIONAL_PACKAGE([TAGLIB], 
+    [taglib], [1.4],
+    [taglib], 
+    [tag lib], [yes])
+fi
+if test x"$TAGLIB_FOUND" = x"yes"; then
+TAGLIBC_LIBS=""
+TAGLIBC_CFLAGS=""
+AC_CHECK_LIB([tag_c], [taglib_file_new],
+[
+    AC_CHECK_HEADER([taglib/tag_c.h],
+    [
+	TAGLIBC_LIBS="-ltag_c"
+	AC_DEFINE([HAVE_TAGLIBC], [1], [Define to 1 if tag_c is found])
+    ])
+], [-lm])
+AC_SUBST([TAGLIBC_CFLAGS])
+AC_SUBST([TAGLIBC_LIBS])
+fi
 
 # Tray plugin.
 #--------------------------
@@ -197,7 +218,7 @@ echo "
 	
 	Plugins to build:
 	=================
-	Stream Properties:       	${ac_properties_plugin}
+	Stream Properties:       	${ac_properties_plugin} (With taglib $TAGLIB_FOUND)
 	System Tray icon:       	${ac_tray_plugin} (With notification $LIBNOTIFY_FOUND)
 	Window title:			${ac_window_title_plugin}
 ------------------------------------------------------
diff --git a/plugins/properties/Makefile.am b/plugins/properties/Makefile.am
index 6a8aed7..feae225 100644
--- a/plugins/properties/Makefile.am
+++ b/plugins/properties/Makefile.am
@@ -16,7 +16,11 @@ stream_properties_la_SOURCES =			\
 
 stream_properties_la_CFLAGS =			\
 	$(PLATFORM_CFLAGS)			\
-	$(GTK_CFLAGS)
+	$(GTK_CFLAGS)				\
+	$(TAGLIBC_CFLAGS)
+
+stream_properties_la_LIBADD =			\
+	$(TAGLIBC_LIBS)
 
 stream_properties_la_LDFLAGS =			\
 	-avoid-version				\
diff --git a/plugins/properties/stream-properties.c b/plugins/properties/stream-properties.c
index d47520d..1d07e98 100644
--- a/plugins/properties/stream-properties.c
+++ b/plugins/properties/stream-properties.c
@@ -22,36 +22,186 @@
 #include <config.h>
 #endif
 
+#include <stdio.h>
+#include <stdlib.h>
+
 #include <glib.h>
 #include <glib/gi18n.h>
 #include <gtk/gtk.h>
 
 #include <parole/parole.h>
 
+#ifdef HAVE_TAGLIBC
+#include <taglib/tag_c.h>
+#endif
+
 typedef struct
 {
     GtkWidget *title;
     GtkWidget *artist;
     GtkWidget *album;
     GtkWidget *year;
-    GtkWidget *comment;
+    
+#ifdef HAVE_TAGLIBC
+    GtkWidget   *save;
+    TagLib_File *tag_file;
+    gchar       *filename;
+    guint        changed;
+#endif
+    gboolean     block_edit_signal;
     
 } PluginData;
 
+enum
+{
+    TITLE_ENTRY_EDITED	= (1 << 1),
+    ARTIST_ENTRY_EDITED	= (1 << 2),
+    ALBUM_ENTRY_EDITED	= (1 << 3),
+    YEAR_ENTRY_EDITED	= (1 << 4)
+};
+
+static void
+set_widget_text (PluginData *data, GtkWidget *widget, const gchar *text)
+{
+    data->block_edit_signal = TRUE;
+#ifdef HAVE_TAGLIBC
+    gtk_entry_set_text (GTK_ENTRY (widget), text);
+#else
+    gtk_label_set_text (GTK_LABEL (widget), text);
+#endif
+    data->block_edit_signal = FALSE;
+}
+
+#ifdef HAVE_TAGLIBC
+static void
+title_entry_edited (PluginData *data)
+{
+    if (!data->block_edit_signal)
+	data->changed |= TITLE_ENTRY_EDITED;
+}
+
+static void
+artist_entry_edited (PluginData *data)
+{
+    if (!data->block_edit_signal)
+	data->changed |= ARTIST_ENTRY_EDITED;
+}
+
+static void
+album_entry_edited (PluginData *data)
+{
+    if (!data->block_edit_signal)
+	data->changed |= ALBUM_ENTRY_EDITED;
+}
+
+static void
+year_entry_edited (PluginData *data)
+{
+    if (!data->block_edit_signal)
+	data->changed |= YEAR_ENTRY_EDITED;
+}
+#endif
+
+static GtkWidget *
+new_tag_widget (void)
+{
+    GtkWidget *widget;
+    
+#ifdef HAVE_TAGLIBC
+    widget = gtk_entry_new ();
+#else
+    widget = gtk_label_new (NULL);
+#endif
+    return widget;
+}
+
 static void
 init_media_tag_entries (PluginData *data)
 {
-    gtk_entry_set_text (GTK_ENTRY (data->title), _("Unknown"));
-    gtk_entry_set_text (GTK_ENTRY (data->artist), _("Unknown"));
-    gtk_entry_set_text (GTK_ENTRY (data->album), _("Unknown"));
-    gtk_entry_set_text (GTK_ENTRY (data->year), _("Unknown"));
-    gtk_entry_set_text (GTK_ENTRY (data->comment), _("Unknown"));
+    set_widget_text (data, data->title, _("Unknown"));
+    set_widget_text (data, data->artist, _("Unknown"));
+    set_widget_text (data, data->album, _("Unknown"));
+    set_widget_text (data, data->year, _("Unknown"));
+    
+#ifdef HAVE_TAGLIBC
+    gtk_widget_set_tooltip_text (data->save, NULL);
+    data->changed = 0;
+    if ( data->filename )
+    {
+	g_free (data->filename);
+	data->filename = NULL;
+    }
+    
+    if ( data->tag_file )
+    {
+	taglib_file_free (data->tag_file);
+	data->tag_file = NULL;
+    }
+#endif
+}
+
+#ifdef HAVE_TAGLIBC
+static void
+save_media_tags (PluginData *data)
+{
+    TagLib_Tag *tag;
+    const gchar *entry;
+    gboolean save = FALSE;
+
+    if ( !data->tag_file )
+	return;
+	    
+    tag = taglib_file_tag (data->tag_file);
+    
+    if ( !tag )
+	return;
+    
+    if ( data->changed & TITLE_ENTRY_EDITED )
+    {
+	g_debug ("Saving Title");
+	entry = gtk_entry_get_text (GTK_ENTRY (data->title));
+	taglib_tag_set_title (tag, entry);
+	save = TRUE;
+    }
+    
+    if ( data->changed & ARTIST_ENTRY_EDITED )
+    {
+	g_debug ("Saving Artist");
+	entry = gtk_entry_get_text (GTK_ENTRY (data->artist));
+	taglib_tag_set_artist (tag, entry);
+	save = TRUE;
+    }
+    
+    if ( data->changed & ALBUM_ENTRY_EDITED )
+    {
+	g_debug ("Saving Album");
+	entry = gtk_entry_get_text (GTK_ENTRY (data->album));
+	taglib_tag_set_album (tag, entry);
+	save = TRUE;
+    }
+    
+    if ( data->changed & YEAR_ENTRY_EDITED )
+    {
+	g_debug ("Saving Year");
+	entry = gtk_entry_get_text (GTK_ENTRY (data->year));
+	taglib_tag_set_year (tag, (guint) atoi (entry));
+	save = TRUE;
+    }
+    
+    if ( save )
+	taglib_file_save (data->tag_file);
+    
+    data->changed = 0;
+    
+    taglib_tag_free_strings ();
 }
+#endif
 
 static GtkWidget *create_properties_widget (PluginData *data)
 {
     PangoFontDescription *pfd;
     
+    GtkWidget *frame;
     GtkWidget *label;
     GtkWidget *vbox;
     GtkWidget *table;
@@ -76,7 +226,7 @@ static GtkWidget *create_properties_widget (PluginData *data)
                       GTK_SHRINK, GTK_SHRINK,
                       2, 8);
 
-    data->title = gtk_entry_new ();
+    data->title = new_tag_widget ();
     align = gtk_alignment_new (0.0, 0.5, 0, 0);
     gtk_container_add (GTK_CONTAINER (align), data->title);
     gtk_table_attach (GTK_TABLE (table), align,
@@ -99,7 +249,7 @@ static GtkWidget *create_properties_widget (PluginData *data)
                       GTK_SHRINK, GTK_SHRINK,
                       2, 8);
 
-    data->artist = gtk_entry_new ();
+    data->artist = new_tag_widget ();
     align = gtk_alignment_new (0.0, 0.5, 0, 0);
     gtk_container_add (GTK_CONTAINER (align), data->artist);
     gtk_table_attach (GTK_TABLE (table), align,
@@ -122,7 +272,7 @@ static GtkWidget *create_properties_widget (PluginData *data)
                       GTK_SHRINK, GTK_SHRINK,
                       2, 8);
 
-    data->album = gtk_entry_new ();
+    data->album = new_tag_widget ();
     align = gtk_alignment_new (0.0, 0.5, 0, 0);
     gtk_container_add (GTK_CONTAINER (align), data->album);
     gtk_table_attach (GTK_TABLE (table), align,
@@ -145,7 +295,7 @@ static GtkWidget *create_properties_widget (PluginData *data)
                       GTK_SHRINK, GTK_SHRINK,
                       2, 8);
 
-    data->year = gtk_entry_new ();
+    data->year = new_tag_widget ();
     align = gtk_alignment_new (0.0, 0.5, 0, 0);
     gtk_container_add (GTK_CONTAINER (align), data->year);
     gtk_table_attach (GTK_TABLE (table), align,
@@ -154,41 +304,38 @@ static GtkWidget *create_properties_widget (PluginData *data)
                       2, 8);
     i++;
     
-    /*
-     * Comment
-     */
-    align = gtk_alignment_new (0.0, 0.5, 0, 0);
+    frame = gtk_frame_new (_("General"));
+    gtk_container_add (GTK_CONTAINER (frame), table);
+    gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0);
     
-    label = gtk_label_new (_("Comment:"));
-    gtk_container_add (GTK_CONTAINER(align), label);
-    gtk_widget_modify_font (label, pfd);
-    
-    gtk_table_attach (GTK_TABLE(table), align,
-		      0, 1, i, i+1, 
-                      GTK_SHRINK, GTK_SHRINK,
-                      2, 8);
-
-    data->comment = gtk_entry_new ();
+#ifdef HAVE_TAGLIBC
+    data->save = gtk_button_new_from_stock (GTK_STOCK_APPLY);
+    i++;
     align = gtk_alignment_new (0.0, 0.5, 0, 0);
-    gtk_container_add (GTK_CONTAINER (align), data->comment);
+    gtk_container_add (GTK_CONTAINER (align), data->save);
     gtk_table_attach (GTK_TABLE (table), align,
                       1, 2, i, i+1, 
                       GTK_SHRINK, GTK_SHRINK,
                       2, 8);
-    i++;
-    
-    gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, FALSE, 0);
+
+    g_signal_connect_swapped (data->save, "clicked",
+			      G_CALLBACK (save_media_tags), data);
     
-    init_media_tag_entries (data);
+    g_signal_connect_swapped (data->title, "changed",
+			      G_CALLBACK (title_entry_edited), data);
     
-#ifndef HAVE_CTAG_LIB
-    gtk_entry_set_editable (GTK_ENTRY (data->title), FALSE);
-    gtk_entry_set_editable (GTK_ENTRY (data->album), FALSE);
-    gtk_entry_set_editable (GTK_ENTRY (data->artist), FALSE);
-    gtk_entry_set_editable (GTK_ENTRY (data->year), FALSE);
-    gtk_entry_set_editable (GTK_ENTRY (data->comment), FALSE);
+    g_signal_connect_swapped (data->artist, "changed",
+			      G_CALLBACK (artist_entry_edited), data);
+			      
+    g_signal_connect_swapped (data->album, "changed",
+			      G_CALLBACK (album_entry_edited), data);
+			    
+    g_signal_connect_swapped (data->year, "changed",
+			      G_CALLBACK (year_entry_edited), data);
+			      
 #endif
-
+    
+    init_media_tag_entries (data);
     return vbox;
 }
 
@@ -199,28 +346,73 @@ state_changed_cb (ParolePlugin *plugin, const ParoleStream *stream, ParoleState
 	init_media_tag_entries (data);
 }
 
+#ifdef HAVE_TAGLIBC
+static void
+disable_tag_save (GtkWidget *widget)
+{
+    gtk_widget_set_sensitive (widget, FALSE);
+    gtk_widget_set_tooltip_text (widget, _("Stream doesn't support tags changes"));
+}
+
+static void
+enable_tag_save (GtkWidget *widget)
+{
+    gtk_widget_set_sensitive (widget, TRUE);
+    gtk_widget_set_tooltip_text (widget, _("Save media tags changes"));
+}
+#endif
+
 static void
 tag_message_cb (ParolePlugin *plugin, const ParoleStream *stream, PluginData *data)
 {
     gchar *str = NULL;
+#ifdef HAVE_TAGLIBC
+    gchar *uri = NULL;
+    GError *error = NULL;
+#endif
     
     g_object_get (G_OBJECT (stream),
 		  "title", &str,
+#ifdef HAVE_TAGLIBC
+		  "uri", &uri,
+#endif
 		  NULL);
-		  
-    if ( str )
+    
+#ifdef HAVE_TAGLIBC
+    if ( data->filename )
     {
-	gtk_entry_set_text (GTK_ENTRY (data->title), str);
-	g_free (str);
+	g_free (data->filename);
+	data->filename = NULL;
     }
     
-    g_object_get (G_OBJECT (stream),
-		  "comment", &str,
-		  NULL);
-		  
+    if ( data->tag_file )
+    {
+	taglib_file_free (data->tag_file);
+	data->tag_file = NULL;
+    }
+    
+    data->filename = g_filename_from_uri (uri, NULL, &error);
+    
+    if ( G_UNLIKELY (error) )
+    {
+	g_critical ("Unablet to convert uri : %s to filename : %s", uri, error->message);
+	g_error_free (error);
+	disable_tag_save (data->save);
+    }
+    else
+    {
+	data->tag_file = taglib_file_new (data->filename);
+	
+	if ( !data->tag_file )
+	    disable_tag_save (data->save);
+	else
+	    enable_tag_save (data->save);
+    }
+#endif
+
     if ( str )
     {
-	gtk_entry_set_text (GTK_ENTRY (data->comment), str);
+	set_widget_text (data, data->title, str);
 	g_free (str);
     }
     
@@ -230,7 +422,7 @@ tag_message_cb (ParolePlugin *plugin, const ParoleStream *stream, PluginData *da
 		  
     if ( str )
     {
-	gtk_entry_set_text (GTK_ENTRY (data->artist), str);
+	set_widget_text (data, data->artist, str);
 	g_free (str);
     }
     
@@ -240,7 +432,7 @@ tag_message_cb (ParolePlugin *plugin, const ParoleStream *stream, PluginData *da
 		  
     if ( str )
     {
-	gtk_entry_set_text (GTK_ENTRY (data->year), str);
+	set_widget_text (data, data->year, str);
 	g_free (str);
     }
     
@@ -250,9 +442,14 @@ tag_message_cb (ParolePlugin *plugin, const ParoleStream *stream, PluginData *da
 		  
     if ( str )
     {
-	gtk_entry_set_text (GTK_ENTRY (data->album), str);
+	set_widget_text (data, data->album, str);
 	g_free (str);
     }
+
+#ifdef HAVE_TAGLIBC
+    if ( uri )
+	g_free (uri);
+#endif
     
 }
 



More information about the Xfce4-commits mailing list