rhythmbox r6181 - in trunk: . plugins plugins/audiocd plugins/brasero-disc-recorder plugins/cd-recorder po
- From: jmatthew svn gnome org
- To: svn-commits-list gnome org
- Subject: rhythmbox r6181 - in trunk: . plugins plugins/audiocd plugins/brasero-disc-recorder plugins/cd-recorder po
- Date: Sun, 8 Mar 2009 09:41:24 +0000 (UTC)
Author: jmatthew
Date: Sun Mar 8 09:41:24 2009
New Revision: 6181
URL: http://svn.gnome.org/viewvc/rhythmbox?rev=6181&view=rev
Log:
2009-03-08 Jonathan Matthew <jonathan d14n org>
patch by: Philippe Rouquier <brasero-app wanadoo fr>, Bastien Nocera
<hadess hadess net> and me
* plugins/cd-recorder/rb-cd-recorder-plugin.c:
* plugins/audiocd/audiocd-ui.xml:
Slight adjustment to the way the 'duplicate CD' menu item is created;
should stop things complaining when no CD burning plugin is enabled.
* configure.ac:
* plugins/Makefile.am:
* plugins/brasero-disc-recorder/Makefile.am:
* plugins/brasero-disc-recorder/cd-recorder.rb-plugin.in:
* plugins/brasero-disc-recorder/rb-disc-recorder-plugin.c:
New CD burning plugin using Brasero. If libbrasero-media is
available, this plugin is built in preference to the
nautilus-cd-burner plugin. The two plugins use the same plugin name,
and install to the same location, so only one can be available at a
time. Fixes #536732.
Added:
trunk/plugins/brasero-disc-recorder/
trunk/plugins/brasero-disc-recorder/Makefile.am
trunk/plugins/brasero-disc-recorder/cd-recorder.rb-plugin.in
trunk/plugins/brasero-disc-recorder/rb-disc-recorder-plugin.c
Modified:
trunk/ChangeLog
trunk/configure.ac
trunk/plugins/Makefile.am
trunk/plugins/audiocd/audiocd-ui.xml
trunk/plugins/cd-recorder/rb-cd-recorder-plugin.c
trunk/po/ChangeLog
trunk/po/POTFILES.in
Modified: trunk/configure.ac
==============================================================================
--- trunk/configure.ac (original)
+++ trunk/configure.ac Sun Mar 8 09:41:24 2009
@@ -36,6 +36,7 @@
LIBGPOD_REQS=0.6
MUSICBRAINZ_REQS=2.1.0
NCB_MIN_REQS=2.21.6
+BRASERO_MIN_REQS=0.9.1
TOTEM_PLPARSER_REQS=2.22.0
VALA_REQS=0.1.0
AVAHI_REQS=0.6
@@ -364,31 +365,36 @@
fi
fi
+dnl libbrasero-media support
+have_libbrasero_media=no
+AC_ARG_WITH(libbrasero-media,
+ AC_HELP_STRING([--with-libbrasero-media],
+ [Build with libbrasero-media support]),,
+ with_libbrasero_media=auto)
+if test x"$with_libbrasero_media" != "xno"; then
+ PKG_CHECK_MODULES(LIBBRASERO_MEDIA, [libbrasero-media >= $BRASERO_MIN_REQS] gtk+-x11-2.0, have_libbrasero_media=yes, have_libbrasero_media=no)
+fi
+if test "x$have_libbrasero_media" = "xyes"; then
+ AC_DEFINE([HAVE_LIBBRASERO_MEDIA], 1, [Have libbrasero-media])
+fi
+AM_CONDITIONAL(HAVE_LIBBRASERO_MEDIA, test x$have_libbrasero_media = xyes)
+AC_SUBST(HAVE_LIBBRASERO_MEDIA)
+
dnl libnautilus-burn support
have_libnautilus_burn=no
AC_ARG_WITH(libnautilus-burn,
AC_HELP_STRING([--with-libnautilus-burn],
[Build with libnautilus-burn support]),,
with_libnautilus_burn=auto)
-if test x"$with_libnautilus_burn" != "xno"; then
+if test x"$have_libbrasero_media" = "xno" -a x"$with_libnautilus_burn" != "xno"; then
PKG_CHECK_MODULES(LIBNAUTILUS_BURN, [libnautilus-burn >= $NCB_MIN_REQS], have_libnautilus_burn=yes, have_libnautilus_burn=no)
fi
-if test "x$have_libnautilus_burn" = xyes; then
+if test "x$have_libnautilus_burn" = "xyes"; then
AC_DEFINE([HAVE_NAUTILUS_BURN], 1, [Have nautilus-burn])
fi
AM_CONDITIONAL(HAVE_NAUTILUS_BURN, test x$have_libnautilus_burn = xyes)
AC_SUBST(HAVE_NAUTILUS_BURN)
-dnl CD burning support
-AC_ARG_WITH(cd-burning,
- AC_HELP_STRING([--with-cd-burning],
- [Enable CD burning support]),,
- with_cd_burning=auto)
-enable_cd_burning=no
-if test "x$have_libnautilus_burn" = "xyes" -a "x$with_cd_burning" != "xno"; then
- enable_cd_burning=yes
-fi
-AM_CONDITIONAL(USE_CD_BURNING, test "x$enable_cd_burning" != "xno")
AC_SUBST(CFLAGS)
AC_SUBST(LDFLAGS)
@@ -806,6 +812,7 @@
plugins/coherence/upnp_coherence/Makefile
plugins/audioscrobbler/Makefile
plugins/cd-recorder/Makefile
+plugins/brasero-disc-recorder/Makefile
plugins/daap/Makefile
plugins/fmradio/Makefile
plugins/ipod/Makefile
@@ -881,8 +888,10 @@
else
AC_MSG_NOTICE([ MTP integration disabled])
fi
-if test x"$enable_cd_burning" != xno; then
- AC_MSG_NOTICE([** CD burning support enabled])
+if test x"$have_libbrasero_media" != xno; then
+ AC_MSG_NOTICE([** CD burning support enabled (using Brasero)])
+elif test x"$have_libnautilus_burn" != xno; then
+ AC_MSG_NOTICE([** CD burning support enabled (using nautilus-cd-burner)])
else
AC_MSG_NOTICE([ CD burning support disabled])
fi
Modified: trunk/plugins/Makefile.am
==============================================================================
--- trunk/plugins/Makefile.am (original)
+++ trunk/plugins/Makefile.am Sun Mar 8 09:41:24 2009
@@ -36,10 +36,13 @@
SUBDIRS += ipod
endif
-if USE_CD_BURNING
-SUBDIRS += \
- cd-recorder
-endif
+if HAVE_LIBBRASERO_MEDIA
+SUBDIRS += brasero-disc-recorder
+else
+if HAVE_NAUTILUS_BURN
+SUBDIRS += cd-recorder
+endif # HAVE_NAUTILUS_BURN
+endif # HAVE_LIBBRASERO_MEDIA
if USE_DAAP
SUBDIRS += daap
Modified: trunk/plugins/audiocd/audiocd-ui.xml
==============================================================================
--- trunk/plugins/audiocd/audiocd-ui.xml (original)
+++ trunk/plugins/audiocd/audiocd-ui.xml Sun Mar 8 09:41:24 2009
@@ -1,7 +1,7 @@
<ui>
<popup name="AudioCdSourcePopup">
<menuitem name="AudioCdSourcePopupCopyAllTracks" action="RemovableSourceCopyAllTracks"/>
- <menuitem name="AudioCdSourcePopupCopyCd" action="MusicAudioCDDuplicate" />
+ <placeholder name="PluginPlaceholder"/>
<menuitem name="AudioCdSourcePopupEjectCd" action="RemovableSourceEject"/>
</popup>
</ui>
Added: trunk/plugins/brasero-disc-recorder/Makefile.am
==============================================================================
--- (empty file)
+++ trunk/plugins/brasero-disc-recorder/Makefile.am Sun Mar 8 09:41:24 2009
@@ -0,0 +1,57 @@
+NULL =
+
+plugindir = $(PLUGINDIR)/cd-recorder
+plugin_LTLIBRARIES = libcd-recorder.la
+
+libcd_recorder_la_SOURCES = \
+ rb-disc-recorder-plugin.c \
+ $(NULL)
+
+libcd_recorder_la_LDFLAGS = $(PLUGIN_LIBTOOL_FLAGS)
+libcd_recorder_la_LIBADD = \
+ $(top_builddir)/corelib/librhythmbox-core.la \
+ $(LIBBRASERO_MEDIA_LIBS) \
+ $(NULL)
+
+INCLUDES = \
+ -DGNOMELOCALEDIR=\""$(datadir)/locale"\" \
+ -DG_LOG_DOMAIN=\"Rhythmbox\" \
+ -I$(top_srcdir) \
+ -I$(top_srcdir)/lib \
+ -I$(top_builddir)/lib \
+ -I$(top_srcdir)/rhythmdb \
+ -I$(top_srcdir)/widgets \
+ -I$(top_srcdir)/sources \
+ -I$(top_srcdir)/plugins \
+ -I$(top_srcdir)/shell \
+ -DPIXMAP_DIR=\""$(datadir)/pixmaps"\" \
+ -DSHARE_DIR=\"$(pkgdatadir)\" \
+ -DDATADIR=\""$(datadir)"\" \
+ $(RHYTHMBOX_CFLAGS) \
+ $(LIBBRASERO_MEDIA_CFLAGS) \
+ -D_XOPEN_SOURCE -D_BSD_SOURCE \
+ $(NULL)
+
+plugin_in_files = cd-recorder.rb-plugin.in
+
+%.rb-plugin: %.rb-plugin.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*po) ; $(INTLTOOL_MERGE) $(top_srcdir)/po $< $@ -d -u -c $(top_builddir)/po/.intltool-merge-cache
+
+BUILT_SOURCES = \
+ $(plugin_in_files:.rb-plugin.in=.rb-plugin) \
+ $(NULL)
+
+plugin_DATA = \
+ $(BUILT_SOURCES) \
+ $(NULL)
+
+EXTRA_DIST = \
+ $(plugin_in_files) \
+ $(NULL)
+
+CLEANFILES = \
+ $(BUILT_SOURCES) \
+ $(NULL)
+
+DISTCLEANFILES = \
+ $(BUILT_SOURCES) \
+ $(NULL)
Added: trunk/plugins/brasero-disc-recorder/cd-recorder.rb-plugin.in
==============================================================================
--- (empty file)
+++ trunk/plugins/brasero-disc-recorder/cd-recorder.rb-plugin.in Sun Mar 8 09:41:24 2009
@@ -0,0 +1,8 @@
+[RB Plugin]
+Module=cd-recorder
+IAge=1
+_Name=Audio CD Recorder
+_Description=Record audio CDs from playlists and duplicate audio CDs
+Authors=William Jon McCann, Rouquier Philippe
+Copyright=Copyright  2006 William Jon McCann,  2008-2009 Rouquier Philippe
+Website=http://www.rhythmbox.org/
Added: trunk/plugins/brasero-disc-recorder/rb-disc-recorder-plugin.c
==============================================================================
--- (empty file)
+++ trunk/plugins/brasero-disc-recorder/rb-disc-recorder-plugin.c Sun Mar 8 09:41:24 2009
@@ -0,0 +1,772 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2006 William Jon McCann <mccann jhu edu>
+ * Copyright (C) 2008 Rouquier Philippe <bonfire-app wanadoo fr>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * The Rhythmbox authors hereby grant permission for non-GPL compatible
+ * GStreamer plugins to be used and distributed together with GStreamer
+ * and Rhythmbox. This permission is above and beyond the permissions granted
+ * by the GPL license by which Rhythmbox is covered. If you modify this code
+ * you may extend this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this exception
+ * statement from your version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#define __EXTENSIONS__
+
+#include "config.h"
+
+#include <errno.h>
+#include <string.h> /* For strlen */
+#include <unistd.h>
+#include <glib/gi18n-lib.h>
+#include <gmodule.h>
+#include <gtk/gtk.h>
+#include <glib.h>
+#include <glib-object.h>
+#include <glib/gstdio.h>
+#include <gdk/gdkx.h>
+#include <brasero/brasero-media.h>
+#include <brasero/brasero-medium-monitor.h>
+
+#include <libxml/xmlerror.h>
+#include <libxml/xmlwriter.h>
+#include <libxml/parser.h>
+#include <libxml/xmlstring.h>
+#include <libxml/uri.h>
+#include <libxml/xmlsave.h>
+
+#include "rb-plugin.h"
+#include "rb-debug.h"
+#include "rb-shell.h"
+#include "rb-source.h"
+#include "rb-playlist-source.h"
+#include "rb-dialog.h"
+#include "rb-file-helpers.h"
+
+#define RB_TYPE_DISC_RECORDER_PLUGIN (rb_disc_recorder_plugin_get_type ())
+#define RB_DISC_RECORDER_PLUGIN(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), RB_TYPE_DISC_RECORDER_PLUGIN, RBDiscRecorderPlugin))
+#define RB_DISC_RECORDER_PLUGIN_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), RB_TYPE_DISC_RECORDER_PLUGIN, RBDiscRecorderPluginClass))
+#define RB_IS_DISC_RECORDER_PLUGIN(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), RB_TYPE_DISC_RECORDER_PLUGIN))
+#define RB_IS_DISC_RECORDER_PLUGIN_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), RB_TYPE_DISC_RECORDER_PLUGIN))
+#define RB_DISC_RECORDER_PLUGIN_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), RB_TYPE_DISC_RECORDER_PLUGIN, RBDiscRecorderPluginClass))
+
+typedef struct
+{
+ RBPlugin parent;
+
+ RBShell *shell;
+ GtkActionGroup *action_group;
+ guint ui_merge_id;
+
+ RBSource *selected_source;
+ guint enabled : 1;
+} RBDiscRecorderPlugin;
+
+typedef struct
+{
+ RBPluginClass parent_class;
+} RBDiscRecorderPluginClass;
+
+G_MODULE_EXPORT GType register_rb_plugin (GTypeModule *module);
+GType rb_disc_recorder_plugin_get_type (void) G_GNUC_CONST;
+
+static void rb_disc_recorder_plugin_init (RBDiscRecorderPlugin *plugin);
+static void rb_disc_recorder_plugin_finalize (GObject *object);
+static void impl_activate (RBPlugin *plugin, RBShell *shell);
+static void impl_deactivate (RBPlugin *plugin, RBShell *shell);
+static void cmd_burn_source (GtkAction *action,
+ RBDiscRecorderPlugin *pi);
+static void cmd_duplicate_cd (GtkAction *action,
+ RBDiscRecorderPlugin *pi);
+
+static GtkActionEntry rb_disc_recorder_plugin_actions [] = {
+ { "MusicPlaylistBurnToDiscPlaylist", "media-optical-audio-new", N_("_Create Audio CD..."), NULL,
+ N_("Create an audio CD from playlist"),
+ G_CALLBACK (cmd_burn_source) },
+ { "MusicAudioCDDuplicate", "media-optical-copy", N_("Duplicate Audio CD..."), NULL,
+ N_("Create a copy of this audio CD"),
+ G_CALLBACK (cmd_duplicate_cd) },
+};
+
+RB_PLUGIN_REGISTER(RBDiscRecorderPlugin, rb_disc_recorder_plugin)
+
+#define RB_RECORDER_ERROR rb_disc_recorder_error_quark ()
+
+GQuark rb_disc_recorder_error_quark (void);
+
+GQuark
+rb_disc_recorder_error_quark (void)
+{
+ static GQuark quark = 0;
+ if (! quark) {
+ quark = g_quark_from_static_string ("rb_disc_recorder_error");
+ }
+
+ return quark;
+}
+
+typedef enum
+{
+ RB_RECORDER_ERROR_NONE = 0,
+ RB_RECORDER_ERROR_GENERAL
+} RBRecorderError;
+
+static void
+rb_disc_recorder_plugin_class_init (RBDiscRecorderPluginClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ RBPluginClass *plugin_class = RB_PLUGIN_CLASS (klass);
+
+ object_class->finalize = rb_disc_recorder_plugin_finalize;
+
+ plugin_class->activate = impl_activate;
+ plugin_class->deactivate = impl_deactivate;
+}
+
+static void
+rb_disc_recorder_plugin_init (RBDiscRecorderPlugin *pi)
+{
+ rb_debug ("RBDiscRecorderPlugin initialized");
+}
+
+static void
+rb_disc_recorder_plugin_finalize (GObject *object)
+{
+ rb_debug ("RBDiscRecorderPlugin finalized");
+
+ G_OBJECT_CLASS (rb_disc_recorder_plugin_parent_class)->finalize (object);
+}
+
+static gboolean
+rb_disc_recorder_plugin_start_burning (RBDiscRecorderPlugin *pi,
+ const char *path,
+ gboolean copy)
+{
+ GtkWindow *main_window;
+ GPtrArray *array;
+ char **args, *xid_str;
+ GError *error = NULL;
+ gboolean ret;
+
+ array = g_ptr_array_new ();
+ g_ptr_array_add (array, "brasero");
+ if (copy != FALSE)
+ g_ptr_array_add (array, "-c");
+ else
+ g_ptr_array_add (array, "-r");
+ g_ptr_array_add (array, (gpointer) path);
+
+ main_window =GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (pi->selected_source)));
+ if (main_window && GTK_WIDGET (main_window)->window) {
+ int xid;
+ xid = gdk_x11_drawable_get_xid (GDK_DRAWABLE (GTK_WIDGET (main_window)->window));
+ xid_str = g_strdup_printf ("%d", xid);
+ g_ptr_array_add (array, "-x");
+ g_ptr_array_add (array, xid_str);
+ } else {
+ xid_str = NULL;
+ }
+
+ g_ptr_array_add (array, NULL);
+ args = (char **) g_ptr_array_free (array, FALSE);
+
+ ret = TRUE;
+ if (!g_spawn_async (NULL, args, NULL, G_SPAWN_SEARCH_PATH, NULL, NULL, NULL, &error)) {
+ if (copy != FALSE) {
+ rb_error_dialog (GTK_WINDOW (main_window),
+ _("Rhythmbox could not duplicate the disc"),
+ "%s", error->message);
+
+ } else {
+ rb_error_dialog (GTK_WINDOW (main_window),
+ _("Rhythmbox could not record the audio disc"),
+ "%s", error->message);
+ }
+ ret = FALSE;
+ g_error_free (error);
+ }
+
+ g_free (xid_str);
+ g_free (args);
+
+ return ret;
+}
+
+static gchar*
+rb_disc_recorder_plugin_write_audio_project (const gchar *name,
+ GtkTreeModel *model,
+ GError **error)
+{
+ GtkTreeIter iter;
+ xmlTextWriter *project;
+ xmlDocPtr doc = NULL;
+ xmlSaveCtxt *save;
+ gint success;
+ gchar *path;
+ int fd;
+ int use_errno = 0;
+
+ if (! gtk_tree_model_get_iter_first (model, &iter)) {
+ g_set_error (error,
+ RB_RECORDER_ERROR,
+ RB_RECORDER_ERROR_GENERAL,
+ _("Unable to build an audio track list"));
+ return NULL;
+ }
+
+ /* get a temporary path */
+ path = g_build_filename (g_get_tmp_dir (), "brasero-tmp-project-XXXXXX", NULL);
+ fd = g_mkstemp (path);
+ if (fd == -1) {
+ g_set_error (error,
+ RB_RECORDER_ERROR,
+ RB_RECORDER_ERROR_GENERAL,
+ _("Unable to write audio project file %s: %s"),
+ path,
+ g_strerror (errno));
+ rb_debug ("g_mkstemp failed");
+
+ g_free (path);
+ return NULL;
+ }
+
+ project = xmlNewTextWriterDoc (&doc, 0);
+ if (!project) {
+ g_remove (path);
+ g_free (path);
+ close (fd);
+
+ g_set_error (error,
+ RB_RECORDER_ERROR,
+ RB_RECORDER_ERROR_GENERAL,
+ _("Unable to write audio project"));
+
+ return NULL;
+ }
+
+ xmlTextWriterSetIndent (project, 1);
+ xmlTextWriterSetIndentString (project, (xmlChar *) "\t");
+
+ success = xmlTextWriterStartDocument (project,
+ NULL,
+ "UTF8",
+ NULL);
+ if (success < 0)
+ goto error;
+
+ success = xmlTextWriterStartElement (project, (xmlChar *) "braseroproject");
+ if (success < 0)
+ goto error;
+
+ /* write the name of the version */
+ success = xmlTextWriterWriteElement (project,
+ (xmlChar *) "version",
+ (xmlChar *) "0.2");
+ if (success < 0)
+ goto error;
+
+ if (name) {
+ success = xmlTextWriterWriteElement (project,
+ (xmlChar *) "label",
+ (xmlChar *) name);
+ if (success < 0)
+ goto error;
+ }
+
+ success = xmlTextWriterStartElement (project, (xmlChar *) "track");
+ if (success < 0)
+ goto error;
+
+ success = xmlTextWriterStartElement (project, (xmlChar *) "audio");
+ if (success < 0)
+ goto error;
+
+ do {
+ RhythmDBEntry *entry;
+ const char *str;
+ xmlChar *escaped;
+
+ gtk_tree_model_get (model, &iter, 0, &entry, -1);
+
+ str = rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_LOCATION);
+ escaped = (xmlChar *) g_uri_escape_string (str, NULL, FALSE);
+ success = xmlTextWriterWriteElement (project,
+ (xmlChar *) "uri",
+ escaped);
+ g_free (escaped);
+
+ if (success == -1)
+ goto error;
+
+ /* start of the song always 0 */
+ success = xmlTextWriterWriteElement (project,
+ (xmlChar *) "start",
+ (xmlChar *) "0");
+ if (success == -1)
+ goto error;
+
+ /* end of the song = duration (in seconds while brasero likes it
+ * in nanoseconds =( ) */
+ /* Disable this for the moment and let brasero check the size
+ * itself. In case the user chooses on the fly burning we need
+ * a more precise duration or we'd end up burning the track
+ * incompletely or with a big padding */
+ /*
+ end = g_strdup_printf ("%"G_GINT64_FORMAT, (gint64) (song->duration * 1000000000LL));
+ success = xmlTextWriterWriteElement (project,
+ (xmlChar *) "end",
+ (xmlChar *) end);
+
+ g_free (end);
+ if (success == -1)
+ goto error;
+ */
+
+ str = rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_TITLE);
+ if (str) {
+ escaped = (xmlChar *) g_uri_escape_string (str, NULL, FALSE);
+ success = xmlTextWriterWriteElement (project,
+ (xmlChar *) "title",
+ escaped);
+ g_free (escaped);
+
+ if (success == -1)
+ goto error;
+ }
+
+ str = rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_ARTIST);
+ if (str) {
+ escaped = (xmlChar *) g_uri_escape_string (str, NULL, FALSE);
+ success = xmlTextWriterWriteElement (project,
+ (xmlChar *) "artist",
+ escaped);
+ g_free (escaped);
+
+ if (success == -1)
+ goto error;
+ }
+
+ /*
+ if (song->composer) {
+ escaped = (unsigned char *) g_uri_escape_string (song->composer, NULL, FALSE);
+ success = xmlTextWriterWriteElement (project,
+ (xmlChar *) "composer",
+ escaped);
+ g_free (escaped);
+
+ if (success == -1)
+ goto error;
+ }
+ */
+ } while (gtk_tree_model_iter_next (model, &iter));
+
+ success = xmlTextWriterEndElement (project); /* audio */
+ if (success < 0)
+ goto error;
+
+ success = xmlTextWriterEndElement (project); /* track */
+ if (success < 0)
+ goto error;
+
+ success = xmlTextWriterEndElement (project); /* braseroproject */
+ if (success < 0)
+ goto error;
+
+ success = xmlTextWriterEndDocument (project);
+ if (success < 0)
+ goto end_error;
+
+ xmlFreeTextWriter (project);
+
+ save = xmlSaveToFd (fd, "UTF8", XML_SAVE_FORMAT);
+ if (save == NULL)
+ goto save_error;
+
+ if (xmlSaveDoc (save, doc) == -1)
+ goto save_error;
+
+ if (xmlSaveClose (save) == -1) {
+ use_errno = errno;
+ rb_debug ("xmlSaveClose failed");
+ goto save_error;
+ }
+
+ xmlFreeDoc (doc);
+
+ if (close (fd) == -1) {
+ use_errno = errno;
+ rb_debug ("close() failed");
+ goto save_error;
+ }
+
+ return path;
+
+error:
+ /* cleanup */
+ xmlTextWriterEndDocument (project);
+
+end_error:
+ xmlFreeTextWriter (project);
+
+save_error:
+ if (use_errno != 0) {
+ g_set_error (error,
+ RB_RECORDER_ERROR,
+ RB_RECORDER_ERROR_GENERAL,
+ _("Unable to write audio project file %s: %s"),
+ path,
+ g_strerror (use_errno));
+ } else {
+ g_set_error (error,
+ RB_RECORDER_ERROR,
+ RB_RECORDER_ERROR_GENERAL,
+ _("Unable to write audio project"));
+ }
+
+ g_remove (path);
+ g_free (path);
+ close (fd);
+
+ return NULL;
+}
+
+static void
+source_burn (RBDiscRecorderPlugin *pi,
+ RBSource *source)
+{
+ GtkWidget *parent;
+ char *name;
+ char *path;
+ GError *error = NULL;
+ GtkTreeModel *model;
+
+ g_object_get (source, "query-model", &model, NULL);
+
+ /* don't burn if the source is empty */
+ if (gtk_tree_model_iter_n_children (model, NULL) == 0) {
+ g_object_unref (model);
+ return;
+ }
+
+ name = NULL;
+ g_object_get (source, "name", &name, NULL);
+ rb_debug ("Burning playlist %s", name);
+
+ parent = gtk_widget_get_toplevel (GTK_WIDGET (source));
+
+ rb_debug ("Creating audio project");
+ path = rb_disc_recorder_plugin_write_audio_project (name, model, &error);
+ g_free (name);
+
+ if (! path) {
+ rb_error_dialog (GTK_WINDOW (parent),
+ _("Unable to create audio CD project"),
+ "%s", error->message);
+ g_error_free (error);
+ return;
+ }
+
+ rb_debug ("Starting brasero");
+ rb_disc_recorder_plugin_start_burning (pi, path, FALSE);
+ g_free (path);
+}
+
+static void
+cmd_burn_source (GtkAction *action,
+ RBDiscRecorderPlugin *pi)
+{
+ if (pi->selected_source != NULL) {
+ source_burn (pi, pi->selected_source);
+ }
+}
+
+static void
+cmd_duplicate_cd (GtkAction *action,
+ RBDiscRecorderPlugin *pi)
+{
+ gchar *device;
+ GVolume *volume;
+
+ if (!pi->selected_source)
+ return;
+
+ g_object_get (pi->selected_source, "volume", &volume, NULL);
+ if (G_IS_VOLUME (volume))
+ device = g_volume_get_identifier (volume, G_VOLUME_IDENTIFIER_KIND_UNIX_DEVICE);
+ else
+ device = NULL;
+
+ g_object_unref (volume);
+
+ rb_disc_recorder_plugin_start_burning (pi, device, TRUE);
+ g_free (device);
+}
+
+static void
+playlist_entries_changed (GtkTreeModel *model,
+ RhythmDBEntry *entry,
+ RBDiscRecorderPlugin *pi)
+{
+ int num_tracks;
+ GtkAction *action;
+
+ num_tracks = gtk_tree_model_iter_n_children (model, NULL);
+
+ action = gtk_action_group_get_action (pi->action_group, "MusicPlaylistBurnToDiscPlaylist");
+ gtk_action_set_sensitive (action, (num_tracks > 0));
+}
+
+static void
+playlist_row_inserted_cb (GtkTreeModel *model,
+ GtkTreePath *path,
+ GtkTreeIter *iter,
+ RBDiscRecorderPlugin *pi)
+{
+ RhythmDBEntry *entry = rhythmdb_query_model_iter_to_entry (RHYTHMDB_QUERY_MODEL (model), iter);
+
+ playlist_entries_changed (model, entry, pi);
+
+ rhythmdb_entry_unref (entry);
+}
+
+static gboolean
+rb_disc_recorder_has_burner (RBDiscRecorderPlugin *pi)
+{
+ BraseroMediumMonitor *monitor;
+ GSList *drives;
+
+ /* Find all drives and check capabilities */
+ monitor = brasero_medium_monitor_get_default ();
+ drives = brasero_medium_monitor_get_drives (monitor, BRASERO_DRIVE_TYPE_WRITER);
+ g_object_unref (monitor);
+
+ g_slist_foreach (drives, (GFunc) g_object_unref, NULL);
+ g_slist_free (drives);
+
+ if (drives != NULL)
+ return TRUE;
+
+ return FALSE;
+}
+
+
+static gboolean
+is_copy_available (RBDiscRecorderPlugin *pi)
+{
+ char *cmd;
+
+ if (!rb_disc_recorder_has_burner (pi))
+ return FALSE;
+
+ cmd = g_find_program_in_path ("brasero");
+ if (cmd == NULL)
+ return FALSE;
+
+ g_free (cmd);
+ return TRUE;
+}
+
+static void
+update_source (RBDiscRecorderPlugin *pi,
+ RBShell *shell)
+{
+ GtkAction *burn_action, *copy_action;
+ gboolean playlist_active, is_audiocd_active;
+ RBSource *selected_source;
+ const char *source_type;
+
+ if (pi->selected_source != NULL) {
+ RhythmDBQueryModel *model;
+
+ g_object_get (pi->selected_source, "query-model", &model, NULL);
+ g_signal_handlers_disconnect_by_func (model, playlist_row_inserted_cb, pi);
+ g_signal_handlers_disconnect_by_func (model, playlist_entries_changed, pi);
+ g_object_unref (model);
+ }
+
+ g_object_get (shell, "selected-source", &selected_source, NULL);
+
+ /* for now restrict to playlist sources */
+ playlist_active = RB_IS_PLAYLIST_SOURCE (selected_source);
+
+ source_type = G_OBJECT_TYPE_NAME (selected_source);
+ is_audiocd_active = g_str_equal (source_type, "RBAudioCdSource");
+
+ burn_action = gtk_action_group_get_action (pi->action_group,
+ "MusicPlaylistBurnToDiscPlaylist");
+ copy_action = gtk_action_group_get_action (pi->action_group,
+ "MusicAudioCDDuplicate");
+
+ if (pi->enabled && playlist_active && rb_disc_recorder_has_burner (pi)) {
+ RhythmDBQueryModel *model;
+
+ g_object_get (selected_source, "query-model", &model, NULL);
+ /* monitor for changes, to enable/disable the burn menu item */
+ g_signal_connect_object (G_OBJECT (model),
+ "row_inserted",
+ G_CALLBACK (playlist_row_inserted_cb),
+ pi, 0);
+ g_signal_connect_object (G_OBJECT (model),
+ "post-entry-delete",
+ G_CALLBACK (playlist_entries_changed),
+ pi, 0);
+
+ playlist_entries_changed (GTK_TREE_MODEL (model), NULL, pi);
+ g_object_unref (model);
+ gtk_action_set_visible (burn_action, TRUE);
+ } else {
+ gtk_action_set_visible (burn_action, FALSE);
+ }
+
+ if (pi->enabled && is_audiocd_active && is_copy_available (pi)) {
+ gtk_action_set_visible (copy_action, TRUE);
+ } else {
+ gtk_action_set_visible (copy_action, FALSE);
+ }
+
+ if (pi->selected_source != NULL) {
+ g_object_unref (pi->selected_source);
+ }
+ pi->selected_source = selected_source;
+}
+
+static void
+shell_selected_source_notify_cb (RBShell *shell,
+ GParamSpec *param,
+ RBDiscRecorderPlugin *pi)
+{
+ rb_debug ("RBDiscRecorderPlugin selected source changed");
+
+ update_source (pi, shell);
+}
+
+static struct ui_paths {
+ const char *path;
+ gboolean for_burn;
+ gboolean for_copy;
+} ui_paths[] = {
+ { "/MenuBar/MusicMenu/PlaylistMenu/PluginPlaceholder", TRUE, FALSE },
+ { "/MenuBar/MusicMenu/PluginPlaceholder", FALSE, TRUE },
+ { "/ToolBar/PluginPlaceholder", TRUE, TRUE },
+ { "/PlaylistSourcePopup/PluginPlaceholder", TRUE, FALSE },
+ { "/AutoPlaylistSourcePopup/PluginPlaceholder", TRUE, FALSE },
+ { "/QueueSourcePopup/PluginPlaceholder", TRUE, FALSE },
+ { "/AudioCdSourcePopup/PluginPlaceholder", FALSE, TRUE },
+};
+
+static void
+impl_activate (RBPlugin *plugin,
+ RBShell *shell)
+{
+ RBDiscRecorderPlugin *pi = RB_DISC_RECORDER_PLUGIN (plugin);
+ GtkUIManager *uimanager = NULL;
+ GtkAction *action;
+ int i;
+
+ pi->enabled = TRUE;
+
+ rb_debug ("RBDiscRecorderPlugin activating");
+
+ brasero_media_library_start ();
+
+ pi->shell = shell;
+
+ g_object_get (shell,
+ "ui-manager", &uimanager,
+ NULL);
+
+ g_signal_connect_object (G_OBJECT (shell),
+ "notify::selected-source",
+ G_CALLBACK (shell_selected_source_notify_cb),
+ pi, 0);
+
+ /* add UI */
+ pi->action_group = gtk_action_group_new ("DiscRecorderActions");
+ gtk_action_group_set_translation_domain (pi->action_group,
+ GETTEXT_PACKAGE);
+ gtk_action_group_add_actions (pi->action_group,
+ rb_disc_recorder_plugin_actions, G_N_ELEMENTS (rb_disc_recorder_plugin_actions),
+ pi);
+ gtk_ui_manager_insert_action_group (uimanager, pi->action_group, 0);
+ pi->ui_merge_id = gtk_ui_manager_new_merge_id (uimanager);
+ for (i = 0; i < G_N_ELEMENTS (ui_paths); i++) {
+ if (ui_paths[i].for_burn)
+ gtk_ui_manager_add_ui (uimanager,
+ pi->ui_merge_id,
+ ui_paths[i].path,
+ "MusicPlaylistBurnToDiscPlaylistMenu",
+ "MusicPlaylistBurnToDiscPlaylist",
+ GTK_UI_MANAGER_AUTO,
+ FALSE);
+ if (ui_paths[i].for_copy)
+ gtk_ui_manager_add_ui (uimanager,
+ pi->ui_merge_id,
+ ui_paths[i].path,
+ "MusicAudioCDDuplicateMenu",
+ "MusicAudioCDDuplicate",
+ GTK_UI_MANAGER_AUTO,
+ FALSE);
+ }
+ g_object_unref (uimanager);
+
+ action = gtk_action_group_get_action (pi->action_group, "MusicPlaylistBurnToDiscPlaylist");
+ /* Translators: this is the toolbar button label for */
+ /* Create Audio CD action */
+ g_object_set (action, "short-label", _("Burn"), NULL);
+
+ action = gtk_action_group_get_action (pi->action_group,
+ "MusicAudioCDDuplicate");
+ /* Translators: this is the toolbar button label for */
+ /* Duplicate Audio CD action */
+ g_object_set (action, "short-label", _("Copy CD"), NULL);
+
+ update_source (pi, shell);
+}
+
+static void
+impl_deactivate (RBPlugin *plugin,
+ RBShell *shell)
+{
+ RBDiscRecorderPlugin *pi = RB_DISC_RECORDER_PLUGIN (plugin);
+ GtkUIManager *uimanager = NULL;
+
+ pi->enabled = FALSE;
+
+ rb_debug ("RBDiscRecorderPlugin deactivating");
+
+ update_source (pi, shell);
+
+ if (pi->selected_source) {
+ g_object_unref (pi->selected_source);
+ pi->selected_source = NULL;
+ }
+
+ g_signal_handlers_disconnect_by_func (shell, shell_selected_source_notify_cb, pi);
+
+ g_object_get (shell,
+ "ui-manager", &uimanager,
+ NULL);
+
+ gtk_ui_manager_remove_ui (uimanager, pi->ui_merge_id);
+ gtk_ui_manager_remove_action_group (uimanager, pi->action_group);
+
+ g_object_unref (uimanager);
+
+ /* NOTE: don't deactivate libbrasero-media as it could be in use somewhere else */
+}
+
Modified: trunk/plugins/cd-recorder/rb-cd-recorder-plugin.c
==============================================================================
--- trunk/plugins/cd-recorder/rb-cd-recorder-plugin.c (original)
+++ trunk/plugins/cd-recorder/rb-cd-recorder-plugin.c Sun Mar 8 09:41:24 2009
@@ -386,6 +386,7 @@
{ "/PlaylistSourcePopup/PluginPlaceholder", TRUE, FALSE },
{ "/AutoPlaylistSourcePopup/PluginPlaceholder", TRUE, FALSE },
{ "/QueueSourcePopup/PluginPlaceholder", TRUE, FALSE },
+ { "/AudioCdSourcePopup/PluginPlaceholder", FALSE, TRUE },
};
static void
Modified: trunk/po/POTFILES.in
==============================================================================
--- trunk/po/POTFILES.in (original)
+++ trunk/po/POTFILES.in Sun Mar 8 09:41:24 2009
@@ -45,6 +45,8 @@
plugins/audioscrobbler/rb-audioscrobbler-entry.c
plugins/audioscrobbler/rb-audioscrobbler.c
plugins/audioscrobbler/rb-lastfm-source.c
+[type: gettext/ini]plugins/brasero-disc-recorder/cd-recorder.rb-plugin.in
+plugins/brasero-disc-recorder/rb-disc-recorder-plugin.c
[type: gettext/ini]plugins/cd-recorder/cd-recorder.rb-plugin.in
plugins/cd-recorder/rb-cd-recorder-plugin.c
plugins/cd-recorder/rb-recorder-gst.c
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]