totem r5878 - in trunk: . data po src src/plugins/screenshot



Author: pwithnall
Date: Sat Dec 27 11:45:21 2008
New Revision: 5878
URL: http://svn.gnome.org/viewvc/totem?rev=5878&view=rev

Log:
2008-12-27  Philip Withnall  <philip tecnocode co uk>

	* configure.in:
	* data/totem.ui:
	* src/Makefile.am:
	* src/plugins/screenshot/Makefile.am:
	* src/plugins/screenshot/gallery.ui:
	* src/plugins/screenshot/screenshot.totem-plugin.in:
	* src/plugins/screenshot/totem-gallery-progress.c
	(totem_gallery_progress_class_init), 
(totem_gallery_progress_init),
	(totem_gallery_progress_finalize), (totem_gallery_progress_new),
	(dialog_response_callback), (process_line), (stdout_watch_cb),
	(totem_gallery_progress_run):
	* src/plugins/screenshot/totem-gallery-progress.h:
	* src/plugins/screenshot/totem-gallery.c
	(totem_gallery_class_init), (totem_gallery_init),
	(totem_gallery_new), 
(default_screenshot_count_toggled_callback),
	(dialog_response_callback):
	* src/plugins/screenshot/totem-gallery.h:
	* src/plugins/screenshot/totem-screenshot-plugin.c
	(totem_screenshot_plugin_class_init),
	(totem_screenshot_plugin_init), (take_screenshot_action_cb),
	(take_gallery_action_cb), (window_key_press_event_cb),
	(update_state), (got_metadata_cb), (notify_logo_mode_cb),
	(disable_save_to_disk_changed_cb), (impl_activate),
	(impl_deactivate), (make_filename_for_dir),
	(totem_screenshot_plugin_setup_file_chooser),
	(totem_screenshot_plugin_update_file_chooser):
	* src/plugins/screenshot/totem-screenshot-plugin.h:
	* src/plugins/screenshot/totem-screenshot.c
	(totem_screenshot_response), (totem_screenshot_init),
	(totem_screenshot_new):
	* src/plugins/screenshot/totem-screenshot.h:
	* src/totem-menu.c:
	* src/totem-preferences.c (totem_setup_preferences):
	* src/totem-private.h:
	* src/totem-screenshot.c:
	* src/totem-screenshot.h:
	* src/totem-video-thumbnailer.c (create_gallery), (main):
	* src/totem.c (totem_action_set_mrl_with_warning),
	(on_got_metadata_event), (totem_action_handle_key_press): Add UI 
to
	allow creation of galleries, by moving the current screenshot
	dialogue out to a built-in "screenshot" plugin, and adding a
	dialogue for creating galleries, as well as a progress dialogue.
	Currently, the progress dialogue does not fully work due to pipe
	problems. (Helps: #561088)

	* po/POTFILES.in: Added screenshot plugin files.



Added:
   trunk/src/plugins/screenshot/
   trunk/src/plugins/screenshot/Makefile.am
   trunk/src/plugins/screenshot/gallery.ui
   trunk/src/plugins/screenshot/screenshot.totem-plugin.in
   trunk/src/plugins/screenshot/totem-gallery-progress.c
   trunk/src/plugins/screenshot/totem-gallery-progress.h
   trunk/src/plugins/screenshot/totem-gallery.c
   trunk/src/plugins/screenshot/totem-gallery.h
   trunk/src/plugins/screenshot/totem-screenshot-plugin.c
   trunk/src/plugins/screenshot/totem-screenshot-plugin.h
   trunk/src/plugins/screenshot/totem-screenshot.c   (contents, props changed)
      - copied, changed from r5877, /trunk/src/totem-screenshot.c
   trunk/src/plugins/screenshot/totem-screenshot.h   (contents, props changed)
      - copied, changed from r5877, /trunk/src/totem-screenshot.h
Removed:
   trunk/src/totem-screenshot.c
   trunk/src/totem-screenshot.h
Modified:
   trunk/ChangeLog
   trunk/configure.in
   trunk/data/totem.ui
   trunk/po/ChangeLog
   trunk/po/POTFILES.in
   trunk/src/Makefile.am
   trunk/src/totem-menu.c
   trunk/src/totem-preferences.c
   trunk/src/totem-private.h
   trunk/src/totem-video-thumbnailer.c
   trunk/src/totem.c

Modified: trunk/configure.in
==============================================================================
--- trunk/configure.in	(original)
+++ trunk/configure.in	Sat Dec 27 11:45:21 2008
@@ -50,7 +50,7 @@
 AC_SUBST(TOTEM_VERSION_MICRO)
 
 # The full list of plugins
-allowed_plugins="thumbnail screensaver ontop galago gromit lirc media-player-keys mythtv properties sidebar-test skipto sample-python sample-vala bemused youtube publish tracker pythonconsole jamendo opensubtitles"
+allowed_plugins="thumbnail screensaver ontop galago gromit lirc media-player-keys mythtv properties sidebar-test skipto sample-python sample-vala bemused youtube publish tracker pythonconsole jamendo opensubtitles screenshot"
 
 PLUGINDIR='${libdir}/totem/plugins'
 AC_SUBST(PLUGINDIR)
@@ -257,7 +257,8 @@
   gtk+-2.0 >= $GTK_REQS
   gmodule-2.0
   gconf-2.0
-  totem-plparser >= $TOTEM_PLPARSER_REQS])
+  totem-plparser >= $TOTEM_PLPARSER_REQS
+  cairo])
 
 PKG_CHECK_MODULES(MM, $MM)
 
@@ -843,6 +844,7 @@
 src/plugins/Makefile
 src/plugins/bemused/Makefile
 src/plugins/screensaver/Makefile
+src/plugins/screenshot/Makefile
 src/plugins/ontop/Makefile
 src/plugins/galago/Makefile
 src/plugins/gromit/Makefile

Modified: trunk/data/totem.ui
==============================================================================
--- trunk/data/totem.ui	(original)
+++ trunk/data/totem.ui	Sat Dec 27 11:45:21 2008
@@ -69,15 +69,6 @@
             </object>
          </child>
          <child>
-            <object class="GtkAction" id="take-screenshot">
-               <property name="label" translatable="yes">Take _Screenshot...</property>
-               <property name="icon-name">camera-photo</property>
-               <property name="tooltip" translatable="yes">Take a screenshot</property>
-               <signal name="activate" handler="take_screenshot_action_callback"/>
-            </object>
-            <accelerator key="S" modifiers="GDK_SHIFT_MASK"/>
-         </child>
-         <child>
             <object class="GtkAction" id="clear-playlist">
                <property name="label" translatable="yes">_Clear Playlist</property>
                <property name="icon-name">gtk-clear</property>
@@ -446,8 +437,6 @@
             <menuitem name="quit" action="quit"/>
          </menu>
          <menu name="edit" action="edit-menu">
-            <menuitem name="take-screenshot" action="take-screenshot"/>
-            <separator/>
             <menuitem name="repeat-mode" action="repeat-mode"/>
             <menuitem name="shuffle-mode" action="shuffle-mode"/>
             <separator/>

Modified: trunk/po/POTFILES.in
==============================================================================
--- trunk/po/POTFILES.in	(original)
+++ trunk/po/POTFILES.in	Sat Dec 27 11:45:21 2008
@@ -25,7 +25,6 @@
 src/totem-preferences.c
 src/totem-properties-main.c
 src/totem-properties-view.c
-src/totem-screenshot.c
 src/totem-sidebar.c
 src/totem-statusbar.c
 src/totem-subtitle-encoding.c
@@ -61,6 +60,12 @@
 [type: gettext/ini]src/plugins/publish/publish.totem-plugin.in
 [type: gettext/glade]src/plugins/publish/publish-plugin.ui
 [type: gettext/ini]src/plugins/screensaver/screensaver.totem-plugin.in
+[type: gettext/ini]src/plugins/screenshot/screenshot.totem-plugin.in
+[type: gettext/glade]src/plugins/screenshot/gallery.ui
+src/plugins/screenshot/totem-gallery.c
+src/plugins/screenshot/totem-gallery-progress.c
+src/plugins/screenshot/totem-screenshot.c
+src/plugins/screenshot/totem-screenshot-plugin.c
 [type: gettext/ini]src/plugins/skipto/skipto.totem-plugin.in
 src/plugins/skipto/totem-skipto.c
 src/plugins/skipto/totem-skipto-plugin.c

Modified: trunk/src/Makefile.am
==============================================================================
--- trunk/src/Makefile.am	(original)
+++ trunk/src/Makefile.am	Sat Dec 27 11:45:21 2008
@@ -104,8 +104,6 @@
 	totem-options.c totem-options.h			\
 	totem-playlist.c totem-playlist.h		\
 	eggfileformatchooser.c eggfileformatchooser.h	\
-	totem-screenshot.c		\
-	totem-screenshot.h		\
 	totem-session.c totem-session.h	\
 	totem-sidebar.c totem-sidebar.h \
 	totem-open-location.c totem-open-location.h \

Added: trunk/src/plugins/screenshot/Makefile.am
==============================================================================
--- (empty file)
+++ trunk/src/plugins/screenshot/Makefile.am	Sat Dec 27 11:45:21 2008
@@ -0,0 +1,52 @@
+modules_flags = -export_dynamic -avoid-version -module
+
+plugindir = $(PLUGINDIR)/screenshot
+uidir = $(plugindir)
+plugin_LTLIBRARIES = libscreenshot.la
+
+plugin_in_files = screenshot.totem-plugin.in
+
+%.totem-plugin: %.totem-plugin.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*po) ; $(INTLTOOL_MERGE) $(top_srcdir)/po $< $@ -d -u -c $(top_builddir)/po/.intltool-merge-cache
+
+plugin_DATA = $(plugin_in_files:.totem-plugin.in=.totem-plugin)
+ui_DATA = gallery.ui
+
+common_defines = \
+	-D_REENTRANT					\
+	-DDBUS_API_SUBJECT_TO_CHANGE			\
+	-DGNOMELOCALEDIR=\""$(datadir)/locale"\"	\
+	-DGCONF_PREFIX=\""/apps/totem"\"		\
+	-DDATADIR=\""$(datadir)"\"			\
+	-DLIBEXECDIR=\""$(libexecdir)"\"		\
+	-DBINDIR=\""$(bindir)"\"			\
+	-DTOTEM_PLUGIN_DIR=\""$(libdir)/totem/plugins"\"\
+	$(DISABLE_DEPRECATED)
+
+libscreenshot_la_SOURCES = \
+	totem-screenshot-plugin.c	\
+	totem-screenshot-plugin.h	\
+	totem-screenshot.c		\
+	totem-screenshot.h		\
+	totem-gallery.c			\
+	totem-gallery.h			\
+	totem-gallery-progress.c	\
+	totem-gallery-progress.h
+libscreenshot_la_LDFLAGS = $(modules_flags)
+libscreenshot_la_CPPFLAGS = \
+	$(common_defines)		\
+	-I$(top_srcdir)/src/backend	\
+	-I$(top_srcdir)/plparse
+
+libscreenshot_la_CFLAGS = 		\
+	$(DEPENDENCY_CFLAGS)		\
+	$(WARN_CFLAGS)			\
+	$(AM_CFLAGS)			\
+	-I$(top_srcdir)/		\
+	-I$(top_srcdir)/src		\
+	-I$(top_srcdir)/src/plugins	\
+	-I$(srcdir)/
+
+EXTRA_DIST = $(plugin_in_files) $(ui_DATA)
+
+CLEANFILES = $(plugin_DATA) $(BUILT_SOURCES)
+DISTCLEANFILES = $(plugin_DATA)

Added: trunk/src/plugins/screenshot/gallery.ui
==============================================================================
--- (empty file)
+++ trunk/src/plugins/screenshot/gallery.ui	Sat Dec 27 11:45:21 2008
@@ -0,0 +1,100 @@
+<?xml version="1.0"?>
+<interface>
+	<object class="GtkAdjustment" id="screenshot_count_adjustment">
+		<property name="upper">30</property>
+		<property name="lower">1</property>
+		<property name="page-increment">10</property>
+		<property name="step-increment">1</property>
+		<property name="page-size">10</property>
+		<property name="value">1</property>
+	</object>
+	<object class="GtkAdjustment" id="screenshot_width_adjustment">
+		<property name="upper">500</property>
+		<property name="lower">20</property>
+		<property name="page-increment">10</property>
+		<property name="step-increment">1</property>
+		<property name="page-size">10</property>
+		<property name="value">128</property>
+	</object>
+	<object class="GtkVBox" id="gallery_dialog_content">
+		<property name="spacing">2</property>
+		<child>
+			<object class="GtkTable" id="table1">
+				<property name="n-rows">4</property>
+				<property name="n-columns">2</property>
+				<property name="row-spacing">5</property>
+				<child>
+					<object class="GtkSpinButton" id="screenshot_count">
+						<property name="sensitive">False</property><!-- made sensitive when default_screenshot_count is unchecked -->
+						<property name="activates-default">True</property>
+						<property name="adjustment">screenshot_count_adjustment</property>
+					</object>
+					<packing>
+						<property name="left-attach">1</property>
+						<property name="right-attach">2</property>
+						<property name="top-attach">3</property>
+						<property name="bottom-attach">4</property>
+					</packing>
+				</child>
+				<child>
+					<object class="GtkLabel" id="label2">
+						<property name="xalign">1</property>
+						<property name="label" translatable="yes">Screenshot width:</property>
+					</object>
+					<packing>
+						<property name="top-attach">1</property>
+						<property name="bottom-attach">2</property>
+						<property name="x-options">GTK_FILL</property>
+						<property name="y-options">GTK_FILL</property>
+						<property name="x-padding">5</property>
+						<property name="y-padding">5</property>
+					</packing>
+				</child>
+				<child>
+					<object class="GtkCheckButton" id="default_screenshot_count">
+						<property name="label" translatable="yes">Calculate the number of screenshots</property>
+						<property name="active">True</property>
+						<property name="draw-indicator">True</property>
+						<signal name="toggled" handler="default_screenshot_count_toggled_callback"/>
+					</object>
+					<packing>
+						<property name="right-attach">2</property>
+						<property name="top-attach">2</property>
+						<property name="bottom-attach">3</property>
+						<property name="y-options">GTK_FILL</property>
+						<property name="y-padding">5</property>
+					</packing>
+				</child>
+				<child>
+					<object class="GtkSpinButton" id="screenshot_width">
+						<property name="activates-default">True</property>
+						<property name="adjustment">screenshot_width_adjustment</property>
+					</object>
+					<packing>
+						<property name="left-attach">1</property>
+						<property name="right-attach">2</property>
+						<property name="top-attach">1</property>
+						<property name="bottom-attach">2</property>
+					</packing>
+				</child>
+				<child>
+					<object class="GtkLabel" id="label1">
+						<property name="xalign">1</property>
+						<property name="label" translatable="yes">Number of screenshots:</property>
+					</object>
+					<packing>
+						<property name="top-attach">3</property>
+						<property name="bottom-attach">4</property>
+						<property name="x-options">GTK_FILL</property>
+						<property name="y-options">GTK_FILL</property>
+						<property name="x-padding">5</property>
+						<property name="y-padding">5</property>
+					</packing>
+				</child>
+			</object>
+			<packing>
+				<property name="padding">5</property>
+			</packing>
+		</child>
+	</object>
+</interface>

Added: trunk/src/plugins/screenshot/screenshot.totem-plugin.in
==============================================================================
--- (empty file)
+++ trunk/src/plugins/screenshot/screenshot.totem-plugin.in	Sat Dec 27 11:45:21 2008
@@ -0,0 +1,9 @@
+[Totem Plugin]
+Module=screenshot
+IAge=1
+Builtin=true
+Name=Screenshot
+Description=Allows screenshots and galleries to be taken of videos.
+Authors=Philip Withnall, Bastien Nocera
+Copyright=Copyright  2008 Philip Withnall, 2004 Bastien Nocera
+Website=http://www.gnome.org/projects/totem/

Added: trunk/src/plugins/screenshot/totem-gallery-progress.c
==============================================================================
--- (empty file)
+++ trunk/src/plugins/screenshot/totem-gallery-progress.c	Sat Dec 27 11:45:21 2008
@@ -0,0 +1,246 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/* 
+ * Copyright (C) 2008 Philip Withnall <philip tecnocode co uk>
+ *
+ * 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 of the License, or
+ * (at your option) any later 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 Street, Fifth Floor, Boston, MA 02110-1301  USA.
+ *
+ * The Totem project hereby grant permission for non-gpl compatible GStreamer
+ * plugins to be used and distributed together with GStreamer and Totem. This
+ * permission are above and beyond the permissions granted by the GPL license
+ * Totem is covered by.
+ *
+ * Monday 7th February 2005: Christian Schaller: Add exception clause.
+ * See license_change file for details.
+ */
+
+#include "config.h"
+
+#include <signal.h>
+#include <unistd.h>
+#include <glib.h>
+#include <gtk/gtk.h>
+#include <glib/gi18n-lib.h>
+#include <glib/gstdio.h>
+
+#include "totem-gallery-progress.h"
+
+static void totem_gallery_progress_init (TotemGalleryProgress *self);
+static void totem_gallery_progress_finalize (GObject *object);
+static void dialog_response_callback (GtkDialog *dialog, gint response_id, TotemGalleryProgress *self);
+
+struct _TotemGalleryProgressPrivate {
+	GPid child_pid;
+	GString *line;
+	gchar *output_filename;
+	GMainLoop *loop;
+
+	GtkProgressBar *progress_bar;
+};
+
+G_DEFINE_TYPE (TotemGalleryProgress, totem_gallery_progress, GTK_TYPE_DIALOG)
+#define TOTEM_GALLERY_PROGRESS_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), TOTEM_TYPE_GALLERY_PROGRESS, TotemGalleryProgressPrivate))
+
+static void
+totem_gallery_progress_class_init (TotemGalleryProgressClass *klass)
+{
+	GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+
+	g_type_class_add_private (klass, sizeof (TotemGalleryProgressPrivate));
+
+	gobject_class->finalize = totem_gallery_progress_finalize;
+}
+
+static void
+totem_gallery_progress_init (TotemGalleryProgress *self)
+{
+	self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, TOTEM_TYPE_GALLERY_PROGRESS, TotemGalleryProgressPrivate);
+}
+
+static void
+totem_gallery_progress_finalize (GObject *object)
+{
+	TotemGalleryProgressPrivate *priv = TOTEM_GALLERY_PROGRESS_GET_PRIVATE (object);
+
+	g_spawn_close_pid (priv->child_pid);
+	g_free (priv->output_filename);
+
+	if (priv->line != NULL)
+		g_string_free (priv->line, TRUE);
+	if (priv->loop != NULL)
+		g_main_loop_unref (priv->loop);
+
+	/* Chain up to the parent class */
+	G_OBJECT_CLASS (totem_gallery_progress_parent_class)->finalize (object);
+}
+
+TotemGalleryProgress *
+totem_gallery_progress_new (GPid child_pid, const gchar *output_filename)
+{
+	TotemGalleryProgress *self;
+	GtkWidget *container;
+	gchar *label_text;
+
+	/* Create the gallery */
+	self = g_object_new (TOTEM_TYPE_GALLERY_PROGRESS, NULL);
+
+	/* Create the widget and initialise class variables */
+	self->priv->progress_bar = GTK_PROGRESS_BAR (gtk_progress_bar_new ());
+	self->priv->child_pid = child_pid;
+	self->priv->output_filename = g_strdup (output_filename);
+
+	/* Set up the window */
+	gtk_window_set_title (GTK_WINDOW (self), _("Creating Gallery..."));
+	gtk_window_set_resizable (GTK_WINDOW (self), FALSE);
+	gtk_dialog_set_has_separator (GTK_DIALOG (self), FALSE);
+	gtk_dialog_add_button (GTK_DIALOG (self), GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL);
+	gtk_dialog_set_default_response (GTK_DIALOG (self), GTK_RESPONSE_CANCEL);
+
+	/* Set the progress label */
+	label_text = g_strdup_printf (_("Saving gallery as \"%s\""), output_filename);
+	gtk_progress_bar_set_text (self->priv->progress_bar, label_text);
+	g_free (label_text);
+
+	g_signal_connect (G_OBJECT (self), "response",
+			  G_CALLBACK (dialog_response_callback), self);
+
+	/* Assemble the window */
+	container = gtk_dialog_get_content_area (GTK_DIALOG (self));
+	gtk_box_pack_start (GTK_BOX (container), GTK_WIDGET (self->priv->progress_bar), TRUE, TRUE, 5);
+
+	return self;
+}
+
+static void
+dialog_response_callback (GtkDialog *dialog, gint response_id, TotemGalleryProgress *self)
+{
+	/* Cancel the operation by killing the process */
+	kill (self->priv->child_pid, SIGINT);
+
+	/* Unlink the output file, just in case (race condition) it's already been created */
+	g_unlink (self->priv->output_filename);
+
+	/* Quit the main loop */
+	if (self->priv->loop != NULL && g_main_loop_is_running (self->priv->loop))
+		g_main_loop_quit (self->priv->loop);
+}
+
+static gboolean
+process_line (TotemGalleryProgress *self, const gchar *line)
+{
+	gfloat percent_complete;
+
+	if (sscanf (line, "%f%% complete", &percent_complete) == 1) {
+		gtk_progress_bar_set_fraction (self->priv->progress_bar, percent_complete / 100.0);
+		return TRUE;
+	}
+
+	/* Error! */
+	return FALSE;
+}
+
+static gboolean
+stdout_watch_cb (GIOChannel *source, GIOCondition condition, TotemGalleryProgress *self)
+{
+	/* Code pilfered from nautilus-burn-process.c (nautilus-cd-burner) under GPLv2+
+	 * Copyright (C) 2006 William Jon McCann <mccann jhu edu> */
+	TotemGalleryProgressPrivate *priv = self->priv;
+	gboolean retval = TRUE;
+
+	if (condition & G_IO_IN || condition & G_IO_PRI) {
+		gchar *line;
+		gchar buf[1];
+		GIOStatus status;
+
+		status = g_io_channel_read_line (source, &line, NULL, NULL, NULL);
+
+		if (status == G_IO_STATUS_NORMAL) {
+			if (priv->line != NULL) {
+				g_string_append (priv->line, line);
+				g_free (line);
+				line = g_string_free (priv->line, FALSE);
+				priv->line = NULL;
+			}
+
+			retval = process_line (self, line);
+			g_free (line);
+		} else if (status == G_IO_STATUS_AGAIN) {
+			/* A non-terminated line was read, read the data into the buffer. */
+			status = g_io_channel_read_chars (source, buf, 1, NULL, NULL);
+
+			if (status == G_IO_STATUS_NORMAL) {
+				gchar *line2;
+
+				if (priv->line == NULL)
+					priv->line = g_string_new (NULL);
+				g_string_append_c (priv->line, buf[0]);
+
+				switch (buf[0]) {
+				case '\n':
+				case '\r':
+				case '\xe2':
+				case '\0':
+					line2 = g_string_free (priv->line, FALSE);
+					priv->line = NULL;
+
+					retval = process_line (self, line2);
+					g_free (line2);
+					break;
+				default:
+					break;
+				}
+			}
+		} else if (status == G_IO_STATUS_EOF) {
+			/* Show as complete and stop processing */
+			gtk_progress_bar_set_fraction (self->priv->progress_bar, 1.0);
+			retval = FALSE;
+		}
+	} else if (condition & G_IO_HUP) {
+		retval = FALSE;
+	}
+
+	if (retval == FALSE) {
+		/* Exit the main loop; we're done processing input */
+		if (self->priv->loop != NULL && g_main_loop_is_running (self->priv->loop))
+			g_main_loop_quit (self->priv->loop);
+	}
+
+	return retval;
+}
+
+void
+totem_gallery_progress_run (TotemGalleryProgress *self, gint stdout_fd)
+{
+	TotemGalleryProgressPrivate *priv = self->priv;
+	GIOChannel *channel;
+	guint stdout_watch_id;
+
+	/* Watch the output from totem-video-thumbnailer */
+	channel = g_io_channel_unix_new (stdout_fd);
+	g_io_channel_set_flags (channel, g_io_channel_get_flags (channel) | G_IO_FLAG_NONBLOCK, NULL);
+	g_io_channel_set_encoding (channel, NULL, NULL);
+	g_io_channel_set_buffered (channel, FALSE);
+
+	stdout_watch_id = g_io_add_watch (channel, G_IO_IN | G_IO_PRI | G_IO_HUP | G_IO_ERR | G_IO_NVAL, (GIOFunc) stdout_watch_cb, self);
+
+	g_io_channel_unref (channel);
+
+	/* Listen in a recursive main loop so this function is synchronous */
+	priv->loop = g_main_loop_new (NULL, FALSE);
+	g_main_loop_run (priv->loop);
+
+	g_source_remove (stdout_watch_id);
+	g_main_loop_unref (priv->loop);
+	priv->loop = NULL;
+}

Added: trunk/src/plugins/screenshot/totem-gallery-progress.h
==============================================================================
--- (empty file)
+++ trunk/src/plugins/screenshot/totem-gallery-progress.h	Sat Dec 27 11:45:21 2008
@@ -0,0 +1,61 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/* 
+ * Copyright (C) 2008 Philip Withnall <philip tecnocode co uk>
+ *
+ * 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 of the License, or
+ * (at your option) any later 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 Street, Fifth Floor, Boston, MA 02110-1301  USA.
+ *
+ * The Totem project hereby grant permission for non-gpl compatible GStreamer
+ * plugins to be used and distributed together with GStreamer and Totem. This
+ * permission are above and beyond the permissions granted by the GPL license
+ * Totem is covered by.
+ *
+ * Monday 7th February 2005: Christian Schaller: Add exception clause.
+ * See license_change file for details.
+ */
+
+#ifndef TOTEM_GALLERY_PROGRESS_H
+#define TOTEM_GALLERY_PROGRESS_H
+
+#include <glib.h>
+#include <glib-object.h>
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+#define TOTEM_TYPE_GALLERY_PROGRESS		(totem_gallery_progress_get_type ())
+#define TOTEM_GALLERY_PROGRESS(o)		(G_TYPE_CHECK_INSTANCE_CAST ((o), TOTEM_TYPE_GALLERY_PROGRESS, TotemGalleryProgress))
+#define TOTEM_GALLERY_PROGRESS_CLASS(k)		(G_TYPE_CHECK_CLASS_CAST((k), TOTEM_TYPE_GALLERY_PROGRESS, TotemGalleryProgressClass))
+#define TOTEM_IS_GALLERY_PROGRESS(o)		(G_TYPE_CHECK_INSTANCE_TYPE ((o), TOTEM_TYPE_GALLERY_PROGRESS))
+#define TOTEM_IS_GALLERY_PROGRESS_CLASS(k)	(G_TYPE_CHECK_CLASS_TYPE ((k), TOTEM_TYPE_GALLERY_PROGRESS))
+#define TOTEM_GALLERY_PROGRESS_GET_CLASS(o)	(G_TYPE_INSTANCE_GET_CLASS ((o), TOTEM_TYPE_GALLERY_PROGRESS, TotemGalleryProgressClass))
+
+typedef struct _TotemGalleryProgressPrivate	TotemGalleryProgressPrivate;
+
+typedef struct {
+	GtkDialog parent;
+	TotemGalleryProgressPrivate *priv;
+} TotemGalleryProgress;
+
+typedef struct {
+	GtkDialogClass parent;
+} TotemGalleryProgressClass;
+
+GType totem_gallery_progress_get_type (void);
+TotemGalleryProgress *totem_gallery_progress_new (GPid child_pid, const gchar *output_filename);
+void totem_gallery_progress_run (TotemGalleryProgress *self, gint stdout_fd);
+
+G_END_DECLS
+
+#endif /* !TOTEM_GALLERY_PROGRESS_H */

Added: trunk/src/plugins/screenshot/totem-gallery.c
==============================================================================
--- (empty file)
+++ trunk/src/plugins/screenshot/totem-gallery.c	Sat Dec 27 11:45:21 2008
@@ -0,0 +1,175 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/* 
+ * Copyright (C) 2008 Philip Withnall <philip tecnocode co uk>
+ *
+ * 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 of the License, or
+ * (at your option) any later 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 Street, Fifth Floor, Boston, MA 02110-1301  USA.
+ *
+ * The Totem project hereby grant permission for non-gpl compatible GStreamer
+ * plugins to be used and distributed together with GStreamer and Totem. This
+ * permission are above and beyond the permissions granted by the GPL license
+ * Totem is covered by.
+ *
+ * Monday 7th February 2005: Christian Schaller: Add exception clause.
+ * See license_change file for details.
+ */
+
+#include "config.h"
+
+#include <glib.h>
+#include <gtk/gtk.h>
+#include <glib/gi18n-lib.h>
+
+#include "totem-gallery.h"
+#include "totem-gallery-progress.h"
+#include "totem-screenshot-plugin.h"
+
+static void totem_gallery_init (TotemGallery *self);
+static void dialog_response_callback (GtkDialog *dialog, gint response_id, TotemGallery *self);
+
+/* GtkBuilder callbacks */
+void default_screenshot_count_toggled_callback (GtkToggleButton *toggle_button, TotemGallery *self);
+
+struct _TotemGalleryPrivate {
+	Totem *totem;
+	GtkCheckButton *default_screenshot_count;
+	GtkSpinButton *screenshot_count;
+	GtkSpinButton *screenshot_width;
+};
+
+G_DEFINE_TYPE (TotemGallery, totem_gallery, GTK_TYPE_FILE_CHOOSER_DIALOG)
+#define TOTEM_GALLERY_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), TOTEM_TYPE_GALLERY, TotemGalleryPrivate))
+
+static void
+totem_gallery_class_init (TotemGalleryClass *klass)
+{
+	g_type_class_add_private (klass, sizeof (TotemGalleryPrivate));
+}
+
+static void
+totem_gallery_init (TotemGallery *self)
+{
+	self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, TOTEM_TYPE_GALLERY, TotemGalleryPrivate);
+}
+
+TotemGallery *
+totem_gallery_new (Totem *totem, TotemPlugin *plugin)
+{
+	TotemGallery *gallery;
+	GtkWidget *container;
+	GtkBuilder *builder;
+
+	/* Create the gallery and its interface */
+	gallery = g_object_new (TOTEM_TYPE_GALLERY, NULL);
+
+	builder = totem_plugin_load_interface (plugin, "gallery.ui", TRUE, NULL, gallery);
+	if (builder == NULL) {
+		g_object_unref (gallery);
+		return NULL;
+	}
+
+	/* Grab the widgets */
+	gallery->priv->default_screenshot_count = GTK_CHECK_BUTTON (gtk_builder_get_object (builder, "default_screenshot_count"));
+	gallery->priv->screenshot_count = GTK_SPIN_BUTTON (gtk_builder_get_object (builder, "screenshot_count"));
+	gallery->priv->screenshot_width = GTK_SPIN_BUTTON (gtk_builder_get_object (builder, "screenshot_width"));
+
+	gallery->priv->totem = totem;
+
+	gtk_window_set_title (GTK_WINDOW (gallery), _("Save Gallery"));
+	gtk_file_chooser_set_action (GTK_FILE_CHOOSER (gallery), GTK_FILE_CHOOSER_ACTION_SAVE);
+	gtk_file_chooser_set_do_overwrite_confirmation (GTK_FILE_CHOOSER (gallery), TRUE);
+	/*gtk_window_set_resizable (GTK_WINDOW (gallery), FALSE);
+	gtk_dialog_set_has_separator (GTK_DIALOG (gallery), TRUE);*/
+	gtk_dialog_add_buttons (GTK_DIALOG (gallery),
+			GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+			GTK_STOCK_SAVE, GTK_RESPONSE_OK,
+			NULL);
+	gtk_dialog_set_default_response (GTK_DIALOG (gallery), GTK_RESPONSE_OK);
+
+	g_signal_connect (G_OBJECT (gallery), "response",
+			  G_CALLBACK (dialog_response_callback), gallery);
+
+	container = GTK_WIDGET (gtk_builder_get_object (builder,
+				"gallery_dialog_content"));
+	gtk_file_chooser_set_extra_widget (GTK_FILE_CHOOSER (gallery), container);
+	totem_screenshot_plugin_setup_file_chooser (GTK_FILE_CHOOSER (gallery), N_("Screenshot%d.jpg"));
+
+	gtk_widget_show_all (GTK_WIDGET (gallery));
+
+	g_object_unref (builder);
+
+	return gallery;
+}
+
+void
+default_screenshot_count_toggled_callback (GtkToggleButton *toggle_button, TotemGallery *self)
+{
+	/* Only have the screenshot count spin button sensitive when the default screenshot count
+	 * check button is unchecked. */
+	gtk_widget_set_sensitive (GTK_WIDGET (self->priv->screenshot_count), !gtk_toggle_button_get_active (toggle_button));
+}
+
+static void
+dialog_response_callback (GtkDialog *dialog, gint response_id, TotemGallery *self)
+{
+	gchar *filename, *video_mrl, *argv[9];
+	guint screenshot_count, i;
+	gint stdout_fd;
+	GPid child_pid;
+	GtkWidget *progress_dialog;
+	GError *error = NULL;
+
+	if (response_id != GTK_RESPONSE_OK)
+		return;
+	gtk_widget_hide (GTK_WIDGET (dialog));
+
+	if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (self->priv->default_screenshot_count)) == TRUE)
+		screenshot_count = 0;
+	else
+		screenshot_count = gtk_spin_button_get_value_as_int (self->priv->screenshot_count);
+
+	filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (self));
+	video_mrl = totem_get_current_mrl (self->priv->totem);
+	totem_screenshot_plugin_update_file_chooser (filename);
+
+	/* Build the command and arguments to pass it */
+	argv[0] = "totem-video-thumbnailer";
+	argv[1] = "-j"; /* JPEG mode */
+	argv[2] = "-l"; /* don't limit resources */
+	argv[3] = "-p"; /* print progress */
+	argv[4] = g_strdup_printf ("--gallery=%u", screenshot_count); /* number of screenshots to output */
+	argv[5] = g_strdup_printf ("--size=%u", gtk_spin_button_get_value_as_int (self->priv->screenshot_width)); /* screenshot width */
+	argv[6] = video_mrl; /* video to thumbnail */
+	argv[7] = filename; /* output filename */
+	argv[8] = NULL;
+
+	/* Run the command */
+	if (g_spawn_async_with_pipes (NULL, argv, NULL, G_SPAWN_SEARCH_PATH, NULL, NULL,
+				      &child_pid, NULL, &stdout_fd, NULL, &error) == FALSE) {
+		g_warning ("Error spawning totem-video-thumbnailer: %s", error->message);
+		g_error_free (error);
+		goto error;
+	}
+
+	/* Create the progress dialogue */
+	progress_dialog = GTK_WIDGET (totem_gallery_progress_new (child_pid, filename));
+	gtk_widget_show_all (progress_dialog);
+	totem_gallery_progress_run (TOTEM_GALLERY_PROGRESS (progress_dialog), stdout_fd);
+	gtk_widget_destroy (progress_dialog);
+
+error:
+	/* Free argv */
+	for (i = 4; i < G_N_ELEMENTS (argv); i++)
+		g_free (argv[i]);
+}

Added: trunk/src/plugins/screenshot/totem-gallery.h
==============================================================================
--- (empty file)
+++ trunk/src/plugins/screenshot/totem-gallery.h	Sat Dec 27 11:45:21 2008
@@ -0,0 +1,63 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/* 
+ * Copyright (C) 2008 Philip Withnall <philip tecnocode co uk>
+ *
+ * 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 of the License, or
+ * (at your option) any later 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 Street, Fifth Floor, Boston, MA 02110-1301  USA.
+ *
+ * The Totem project hereby grant permission for non-gpl compatible GStreamer
+ * plugins to be used and distributed together with GStreamer and Totem. This
+ * permission are above and beyond the permissions granted by the GPL license
+ * Totem is covered by.
+ *
+ * Monday 7th February 2005: Christian Schaller: Add exception clause.
+ * See license_change file for details.
+ */
+
+#ifndef TOTEM_GALLERY_H
+#define TOTEM_GALLERY_H
+
+#include <glib.h>
+#include <glib-object.h>
+#include <gtk/gtk.h>
+
+#include "totem-plugin.h"
+#include "totem.h"
+
+G_BEGIN_DECLS
+
+#define TOTEM_TYPE_GALLERY		(totem_gallery_get_type ())
+#define TOTEM_GALLERY(o)		(G_TYPE_CHECK_INSTANCE_CAST ((o), TOTEM_TYPE_GALLERY, TotemGallery))
+#define TOTEM_GALLERY_CLASS(k)		(G_TYPE_CHECK_CLASS_CAST((k), TOTEM_TYPE_GALLERY, TotemGalleryClass))
+#define TOTEM_IS_GALLERY(o)		(G_TYPE_CHECK_INSTANCE_TYPE ((o), TOTEM_TYPE_GALLERY))
+#define TOTEM_IS_GALLERY_CLASS(k)	(G_TYPE_CHECK_CLASS_TYPE ((k), TOTEM_TYPE_GALLERY))
+#define TOTEM_GALLERY_GET_CLASS(o)	(G_TYPE_INSTANCE_GET_CLASS ((o), TOTEM_TYPE_GALLERY, TotemGalleryClass))
+
+typedef struct _TotemGalleryPrivate	TotemGalleryPrivate;
+
+typedef struct {
+	GtkFileChooserDialog parent;
+	TotemGalleryPrivate *priv;
+} TotemGallery;
+
+typedef struct {
+	GtkFileChooserDialogClass parent;
+} TotemGalleryClass;
+
+GType totem_gallery_get_type (void);
+TotemGallery *totem_gallery_new (Totem *totem, TotemPlugin *plugin);
+
+G_END_DECLS
+
+#endif /* !TOTEM_GALLERY_H */

Added: trunk/src/plugins/screenshot/totem-screenshot-plugin.c
==============================================================================
--- (empty file)
+++ trunk/src/plugins/screenshot/totem-screenshot-plugin.c	Sat Dec 27 11:45:21 2008
@@ -0,0 +1,356 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/* 
+ * Copyright (C) 2008 Philip Withnall <philip tecnocode co uk>
+ *
+ * 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 of the License, or
+ * (at your option) any later 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 Street, Fifth Floor, Boston, MA 02110-1301  USA.
+ *
+ * The Totem project hereby grant permission for non-gpl compatible GStreamer
+ * plugins to be used and distributed together with GStreamer and Totem. This
+ * permission are above and beyond the permissions granted by the GPL license
+ * Totem is covered by.
+ *
+ * Monday 7th February 2005: Christian Schaller: Add exception clause.
+ * See license_change file for details.
+ */
+
+#include "config.h"
+
+#include <glib/gi18n-lib.h>
+#include <gmodule.h>
+#include <string.h>
+#include <gdk/gdkkeysyms.h>
+#include <gconf/gconf-client.h>
+
+#ifdef HAVE_XFREE
+#include <X11/XF86keysym.h>
+#endif
+
+#include "totem-screenshot-plugin.h"
+#include "totem-screenshot.h"
+#include "totem-gallery.h"
+#include "totem-uri.h"
+#include "backend/bacon-video-widget.h"
+
+struct TotemScreenshotPluginPrivate {
+	Totem *totem;
+	BaconVideoWidget *bvw;
+
+	gulong got_metadata_signal;
+	gulong notify_logo_mode_signal;
+	gulong key_press_event_signal;
+
+	guint gconf_id;
+	gboolean save_to_disk;
+
+	guint ui_merge_id;
+	GtkActionGroup *action_group;
+};
+
+G_MODULE_EXPORT GType register_totem_plugin		(GTypeModule *module);
+
+static void totem_screenshot_plugin_init		(TotemScreenshotPlugin *plugin);
+static gboolean impl_activate				(TotemPlugin *plugin, TotemObject *totem, GError **error);
+static void impl_deactivate				(TotemPlugin *plugin, TotemObject *totem);
+
+TOTEM_PLUGIN_REGISTER (TotemScreenshotPlugin, totem_screenshot_plugin)
+
+static void
+totem_screenshot_plugin_class_init (TotemScreenshotPluginClass *klass)
+{
+	TotemPluginClass *plugin_class = TOTEM_PLUGIN_CLASS (klass);
+
+	g_type_class_add_private (klass, sizeof (TotemScreenshotPluginPrivate));
+
+	plugin_class->activate = impl_activate;
+	plugin_class->deactivate = impl_deactivate;
+}
+
+static void
+totem_screenshot_plugin_init (TotemScreenshotPlugin *plugin)
+{
+	plugin->priv = G_TYPE_INSTANCE_GET_PRIVATE (plugin, TOTEM_TYPE_SCREENSHOT_PLUGIN, TotemScreenshotPluginPrivate);
+}
+
+static void
+take_screenshot_action_cb (GtkAction *action, TotemScreenshotPlugin *self)
+{
+	TotemScreenshotPluginPrivate *priv = self->priv;
+	GdkPixbuf *pixbuf;
+	GtkWidget *dialog;
+	GError *err = NULL;
+
+	if (bacon_video_widget_get_logo_mode (priv->bvw) != FALSE)
+		return;
+
+	if (bacon_video_widget_can_get_frames (priv->bvw, &err) == FALSE) {
+		if (err == NULL)
+			return;
+
+		totem_action_error (_("Totem could not get a screenshot of the video."), err->message, priv->totem);
+		g_error_free (err);
+		return;
+	}
+
+	pixbuf = bacon_video_widget_get_current_frame (priv->bvw);
+	if (pixbuf == NULL) {
+		totem_action_error (_("Totem could not get a screenshot of the video."), _("This is not supposed to happen; please file a bug report."), priv->totem);
+		return;
+	}
+
+	dialog = totem_screenshot_new (pixbuf);
+
+	gtk_dialog_run (GTK_DIALOG (dialog));
+	gtk_widget_destroy (dialog);
+	g_object_unref (pixbuf);
+}
+
+static void
+take_gallery_action_cb (GtkAction *action, TotemScreenshotPlugin *self)
+{
+	Totem *totem = self->priv->totem;
+	GtkDialog *dialog;
+
+	if (bacon_video_widget_get_logo_mode (self->priv->bvw) != FALSE)
+		return;
+
+	dialog = GTK_DIALOG (totem_gallery_new (totem, TOTEM_PLUGIN (self)));
+
+	gtk_widget_show (GTK_WIDGET (dialog));
+	gtk_dialog_run (dialog);
+	gtk_widget_destroy (GTK_WIDGET (dialog));
+}
+
+static gboolean
+window_key_press_event_cb (GtkWidget *window, GdkEventKey *event, TotemScreenshotPlugin *self)
+{
+	switch (event->keyval) {
+#ifdef HAVE_XFREE
+	case XF86XK_Save:
+		take_screenshot_action_cb (NULL, self);
+		break;
+#endif /* HAVE_XFREE */
+	case GDK_s:
+	case GDK_S:
+		if (event->state & GDK_CONTROL_MASK)
+			take_screenshot_action_cb (NULL, self);
+		else
+			return FALSE;
+		break;
+	default:
+		return FALSE;
+	}
+
+	return TRUE;
+}
+
+static void
+update_state (TotemScreenshotPlugin *self)
+{
+	TotemScreenshotPluginPrivate *priv = self->priv;
+	gboolean sensitive;
+	GtkAction *action;
+
+	sensitive = bacon_video_widget_can_get_frames (priv->bvw, NULL) &&
+		    (bacon_video_widget_get_logo_mode (priv->bvw) == FALSE) &&
+		    priv->save_to_disk;
+
+	action = gtk_action_group_get_action (priv->action_group, "take-screenshot");
+	gtk_action_set_sensitive (action, sensitive);
+	action = gtk_action_group_get_action (priv->action_group, "take-gallery");
+	gtk_action_set_sensitive (action, sensitive);
+}
+
+static void
+got_metadata_cb (BaconVideoWidget *bvw, TotemScreenshotPlugin *self)
+{
+	update_state (self);
+}
+
+static void
+notify_logo_mode_cb (GObject *object, GParamSpec *pspec, TotemScreenshotPlugin *self)
+{
+	update_state (self);
+}
+
+static void
+disable_save_to_disk_changed_cb (GConfClient *client, guint connection_id, GConfEntry *entry, TotemScreenshotPlugin *self)
+{
+	self->priv->save_to_disk = !gconf_client_get_bool (client, "/desktop/gnome/lockdown/disable_save_to_disk", NULL);
+}
+
+static gboolean
+impl_activate (TotemPlugin *plugin, TotemObject *totem, GError **error)
+{
+	GtkWindow *window;
+	GtkUIManager *manager;
+	GConfClient *client;
+	TotemScreenshotPlugin *self = TOTEM_SCREENSHOT_PLUGIN (plugin);
+	TotemScreenshotPluginPrivate *priv = self->priv;
+	const GtkActionEntry menu_entries[] = {
+		{ "take-screenshot", "camera-photo", N_("Take _Screenshot..."), "<Shift>S", N_("Take a screenshot"), G_CALLBACK (take_screenshot_action_cb) },
+		{ "take-gallery", "camera-photo", N_("Take Screenshot _Gallery..."), NULL, N_("Take a gallery of screenshots"), G_CALLBACK (take_gallery_action_cb) }
+	};
+
+	priv->totem = totem;
+	priv->bvw = BACON_VIDEO_WIDGET (totem_get_video_widget (totem));
+	priv->got_metadata_signal = g_signal_connect (G_OBJECT (priv->bvw),
+						      "got-metadata",
+						      G_CALLBACK (got_metadata_cb),
+						      self);
+	priv->notify_logo_mode_signal = g_signal_connect (G_OBJECT (priv->bvw),
+							  "notify::logo-mode",
+							  G_CALLBACK (notify_logo_mode_cb),
+							  self);
+
+	/* Key press handler */
+	window = totem_get_main_window (totem);
+	priv->key_press_event_signal = g_signal_connect (G_OBJECT (window),
+							 "key-press-event", 
+							 G_CALLBACK (window_key_press_event_cb),
+							 self);
+	g_object_unref (window);
+
+	/* Install the menu */
+	priv->action_group = gtk_action_group_new ("screenshot_group");
+	gtk_action_group_set_translation_domain (priv->action_group, GETTEXT_PACKAGE);
+	gtk_action_group_add_actions (priv->action_group, menu_entries,
+				      G_N_ELEMENTS (menu_entries), self);
+
+	manager = totem_get_ui_manager (totem);
+
+	gtk_ui_manager_insert_action_group (manager, priv->action_group, -1);
+	g_object_unref (priv->action_group);
+
+	priv->ui_merge_id = gtk_ui_manager_new_merge_id (manager);
+	gtk_ui_manager_add_ui (manager, priv->ui_merge_id,
+			       "/ui/tmw-menubar/edit/repeat-mode", "take-screenshot",
+			       "take-screenshot", GTK_UI_MANAGER_AUTO, TRUE);
+	gtk_ui_manager_add_ui (manager, priv->ui_merge_id,
+			       "/ui/tmw-menubar/edit/repeat-mode", "take-gallery",
+			       "take-gallery", GTK_UI_MANAGER_AUTO, TRUE);
+	gtk_ui_manager_add_ui (manager, priv->ui_merge_id,
+			       "/ui/tmw-menubar/edit/repeat-mode", NULL,
+			       NULL, GTK_UI_MANAGER_SEPARATOR, TRUE);
+
+	/* Set up a GConf watch for lockdown keys */
+	client = gconf_client_get_default ();
+	priv->gconf_id = gconf_client_notify_add (client, "/desktop/gnome/lockdown/disable_save_to_disk",
+						  (GConfClientNotifyFunc) disable_save_to_disk_changed_cb,
+						  self, NULL, NULL);
+	disable_save_to_disk_changed_cb (client, priv->gconf_id, NULL, self);
+	g_object_unref (client);
+
+	/* Update the menu entries' states */
+	update_state (self);
+
+	return TRUE;
+}
+
+static void
+impl_deactivate	(TotemPlugin *plugin, TotemObject *totem)
+{
+	TotemScreenshotPluginPrivate *priv = TOTEM_SCREENSHOT_PLUGIN (plugin)->priv;
+	GtkWindow *window;
+	GtkUIManager *manager;
+	GConfClient *client;
+
+	/* Disconnect signal handlers */
+	g_signal_handler_disconnect (G_OBJECT (priv->bvw), priv->got_metadata_signal);
+	g_signal_handler_disconnect (G_OBJECT (priv->bvw), priv->notify_logo_mode_signal);
+
+	window = totem_get_main_window (totem);
+	g_signal_handler_disconnect (G_OBJECT (window), priv->key_press_event_signal);
+	g_object_unref (window);
+
+	/* Disconnect from GConf */
+	client = gconf_client_get_default ();
+	gconf_client_notify_remove (client, priv->gconf_id);
+	g_object_unref (client);
+
+	/* Remove the menu */
+	manager = totem_get_ui_manager (totem);
+	gtk_ui_manager_remove_ui (manager, priv->ui_merge_id);
+	gtk_ui_manager_remove_action_group (manager, priv->action_group);
+
+	g_object_unref (priv->bvw);
+}
+
+static char *
+make_filename_for_dir (const char *directory, const char *format)
+{
+	char *fullpath, *filename;
+	guint i = 1;
+
+	filename = g_strdup_printf (_(format), i);
+	fullpath = g_build_filename (directory, filename, NULL);
+
+	while (g_file_test (fullpath, G_FILE_TEST_EXISTS) != FALSE && i < G_MAXINT) {
+		i++;
+		g_free (filename);
+		g_free (fullpath);
+
+		filename = g_strdup_printf (_(format), i);
+		fullpath = g_build_filename (directory, filename, NULL);
+	}
+
+	g_free (fullpath);
+
+	return filename;
+}
+
+void
+totem_screenshot_plugin_setup_file_chooser (GtkFileChooser *file_chooser, const char *filename_format)
+{
+	GConfClient *client;
+	char *path, *filename;
+
+	/* Set the default path */
+	client = gconf_client_get_default ();
+	path = gconf_client_get_string (client,
+					"/apps/totem/screenshot_save_path",
+					NULL);
+	g_object_unref (client);
+
+	/* Default to the Pictures directory */
+	if (path == NULL || path[0] == '\0') {
+		g_free (path);
+		path = totem_pictures_dir ();
+		/* No pictures dir, then it's the home dir */
+		if (path == NULL)
+			path = g_strdup (g_get_home_dir ());
+	}
+
+	gtk_file_chooser_set_current_folder (file_chooser, path);
+	filename = make_filename_for_dir (path, filename_format);
+	g_free (path);
+
+	gtk_file_chooser_set_current_name (file_chooser, filename);
+	g_free (filename);
+}
+
+void
+totem_screenshot_plugin_update_file_chooser (const char *filename)
+{
+	GConfClient *client;
+	char *dir;
+
+	client = gconf_client_get_default ();
+	dir = g_path_get_dirname (filename);
+	gconf_client_set_string (client,
+				 "/apps/totem/screenshot_save_path",
+				 dir, NULL);
+	g_free (dir);
+	g_object_unref (client);
+}

Added: trunk/src/plugins/screenshot/totem-screenshot-plugin.h
==============================================================================
--- (empty file)
+++ trunk/src/plugins/screenshot/totem-screenshot-plugin.h	Sat Dec 27 11:45:21 2008
@@ -0,0 +1,64 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/* 
+ * Copyright (C) 2008 Philip Withnall <philip tecnocode co uk>
+ *
+ * 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 of the License, or
+ * (at your option) any later 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 Street, Fifth Floor, Boston, MA 02110-1301  USA.
+ *
+ * The Totem project hereby grant permission for non-gpl compatible GStreamer
+ * plugins to be used and distributed together with GStreamer and Totem. This
+ * permission are above and beyond the permissions granted by the GPL license
+ * Totem is covered by.
+ *
+ * Monday 7th February 2005: Christian Schaller: Add exception clause.
+ * See license_change file for details.
+ */
+
+#ifndef TOTEM_SCREENSHOT_PLUGIN_H
+#define TOTEM_SCREENSHOT_PLUGIN_H
+
+#include <glib.h>
+
+#include "totem.h"
+#include "totem-plugin.h"
+
+G_BEGIN_DECLS
+
+#define TOTEM_TYPE_SCREENSHOT_PLUGIN		(totem_screenshot_plugin_get_type ())
+#define TOTEM_SCREENSHOT_PLUGIN(o)		(G_TYPE_CHECK_INSTANCE_CAST ((o), TOTEM_TYPE_SCREENSHOT_PLUGIN, TotemScreenshotPlugin))
+#define TOTEM_SCREENSHOT_PLUGIN_CLASS(k)	(G_TYPE_CHECK_CLASS_CAST((k), TOTEM_TYPE_SCREENSHOT_PLUGIN, TotemScreenshotPluginClass))
+#define TOTEM_IS_SCREENSHOT_PLUGIN(o)		(G_TYPE_CHECK_INSTANCE_TYPE ((o), TOTEM_TYPE_SCREENSHOT_PLUGIN))
+#define TOTEM_IS_SCREENSHOT_PLUGIN_CLASS(k)	(G_TYPE_CHECK_CLASS_TYPE ((k), TOTEM_TYPE_SCREENSHOT_PLUGIN))
+#define TOTEM_SCREENSHOT_PLUGIN_GET_CLASS(o)	(G_TYPE_INSTANCE_GET_CLASS ((o), TOTEM_TYPE_SCREENSHOT_PLUGIN, TotemScreenshotPluginClass))
+
+typedef struct TotemScreenshotPluginPrivate	TotemScreenshotPluginPrivate;
+
+typedef struct {
+	TotemPlugin parent;
+	TotemScreenshotPluginPrivate *priv;
+} TotemScreenshotPlugin;
+
+typedef struct {
+	TotemPluginClass parent_class;
+} TotemScreenshotPluginClass;
+
+GType totem_screenshot_plugin_get_type (void) G_GNUC_CONST;
+G_MODULE_EXPORT GType register_totem_plugin (GTypeModule *module);
+
+void totem_screenshot_plugin_setup_file_chooser (GtkFileChooser *file_chooser, const char *filename_format);
+void totem_screenshot_plugin_update_file_chooser (const char *filename);
+
+G_END_DECLS
+
+#endif /* !TOTEM_SCREENSHOT_PLUGIN_H */

Copied: trunk/src/plugins/screenshot/totem-screenshot.c (from r5877, /trunk/src/totem-screenshot.c)
==============================================================================
--- /trunk/src/totem-screenshot.c	(original)
+++ trunk/src/plugins/screenshot/totem-screenshot.c	Sat Dec 27 11:45:21 2008
@@ -1,24 +1,29 @@
 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/* totem-screenshot.c
-
-   Copyright (C) 2004 Bastien Nocera
-
-   The Gnome Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Library General Public License as
-   published by the Free Software Foundation; either version 2 of the
-   License, or (at your option) any later version.
-
-   The Gnome Library 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
-   Library General Public License for more details.
-
-   You should have received a copy of the GNU Library General Public
-   License along with the Gnome Library; see the file COPYING.LIB.  If not,
-   write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-   Boston, MA 02110-1301  USA.
-
-   Author: Bastien Nocera <hadess hadess net>
+/* 
+ * Copyright (C) 2004 Bastien Nocera
+ * Copyright (C) 2008 Philip Withnall <philip tecnocode co uk>
+ *
+ * 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 of the License, or
+ * (at your option) any later 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 Street, Fifth Floor, Boston, MA 02110-1301  USA.
+ *
+ * The Totem project hereby grant permission for non-gpl compatible GStreamer
+ * plugins to be used and distributed together with GStreamer and Totem. This
+ * permission are above and beyond the permissions granted by the GPL license
+ * Totem is covered by.
+ *
+ * Monday 7th February 2005: Christian Schaller: Add exception clause.
+ * See license_change file for details.
  */
 
 #include "config.h"
@@ -27,7 +32,6 @@
 #include <glib/gi18n.h>
 #include <glib/gstdio.h>
 #include <gtk/gtk.h>
-#include <gconf/gconf-client.h>
 #include <string.h>
 #include <sys/types.h>
 #include <unistd.h>
@@ -36,6 +40,7 @@
 #include "debug.h"
 #include "totem-interface.h"
 #include "totem-uri.h"
+#include "totem-screenshot-plugin.h"
 
 struct TotemScreenshotPrivate
 {
@@ -48,32 +53,7 @@
 static void totem_screenshot_class_init (TotemScreenshotClass *class);
 static void totem_screenshot_init       (TotemScreenshot      *screenshot);
 
-G_DEFINE_TYPE(TotemScreenshot, totem_screenshot, GTK_TYPE_DIALOG)
-
-static char *
-totem_screenshot_make_filename_for_dir (const char *directory)
-{
-	char *fullpath, *filename;
-	guint i = 1;
-
-	filename = g_strdup_printf (_("Screenshot%d.png"), i);
-	fullpath = g_build_filename (directory, filename, NULL);
-
-	while (g_file_test (fullpath, G_FILE_TEST_EXISTS) != FALSE
-	       && i < G_MAXINT)
-	{
-		i++;
-		g_free (filename);
-		g_free (fullpath);
-
-		filename = g_strdup_printf (_("Screenshot%d.png"), i);
-		fullpath = g_build_filename (directory, filename, NULL);
-	}
-
-	g_free (fullpath);
-
-	return filename;
-}
+G_DEFINE_TYPE (TotemScreenshot, totem_screenshot, GTK_TYPE_DIALOG)
 
 static void
 totem_screenshot_temp_file_create (TotemScreenshot *screenshot)
@@ -151,44 +131,31 @@
 totem_screenshot_response (GtkDialog *dialog, int response)
 {
 	TotemScreenshot *screenshot = TOTEM_SCREENSHOT (dialog);
-	char *filename = NULL;
-	char *dir;
+	char *filename;
 	GError *err = NULL;
-	GConfClient *client;
 
 	if (response != GTK_RESPONSE_ACCEPT)
 		return;
 
 	filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (screenshot->_priv->chooser));
 
-	if (gdk_pixbuf_save (screenshot->_priv->pixbuf,
-			     filename, "png", &err, NULL) == FALSE)
-	{
-		totem_interface_error
-			(_("There was an error saving the screenshot."),
-			 err->message,
-			 GTK_WINDOW (screenshot));
+	if (gdk_pixbuf_save (screenshot->_priv->pixbuf, filename, "png", &err, NULL) == FALSE) {
+		totem_interface_error (_("There was an error saving the screenshot."),
+				       err->message,
+			 	       GTK_WINDOW (screenshot));
 		g_error_free (err);
 		g_free (filename);
 		return;
 	}
 
-	client = gconf_client_get_default ();
-	dir = g_path_get_dirname (filename);
+	totem_screenshot_plugin_update_file_chooser (filename);
 	g_free (filename);
-	gconf_client_set_string (client,
-				 "/apps/totem/screenshot_save_path",
-				 dir, NULL);
-	g_free (dir);
-	g_object_unref (G_OBJECT (client));
 }
 
 static void
 totem_screenshot_init (TotemScreenshot *screenshot)
 {
 	GtkWidget *box;
-	GConfClient *client;
-	char *path, *filename;
 
 	screenshot->_priv = g_new0 (TotemScreenshotPrivate, 1);
 
@@ -229,29 +196,8 @@
 			GDK_ACTION_COPY);
 	gtk_drag_source_add_uri_targets (GTK_WIDGET (screenshot->_priv->image));
 
-	/* Set the default path */
-	client = gconf_client_get_default ();
-	path = gconf_client_get_string (client,
-					"/apps/totem/screenshot_save_path",
-					NULL);
-	g_object_unref (client);
-
-	/* Default to the Pictures directory */
-	if (path == NULL || path[0] == '\0') {
-		g_free (path);
-		path = totem_pictures_dir ();
-		/* No pictures dir, then it's the home dir */
-		if (path == NULL)
-			path = g_strdup (g_get_home_dir ());
-	}
-
-	gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (screenshot->_priv->chooser),
-					     path);
-	filename = totem_screenshot_make_filename_for_dir (path);
-	g_free (path);
-	gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (screenshot->_priv->chooser),
-					   filename);
-	g_free (filename);
+	/* Set the default path and filename */
+	totem_screenshot_plugin_setup_file_chooser (GTK_FILE_CHOOSER (screenshot->_priv->chooser), N_("Screenshot%d.png"));
 
 	gtk_widget_show_all (GTK_DIALOG (screenshot)->vbox);
 }
@@ -279,7 +225,7 @@
 	TotemScreenshot *screenshot;
 	int width, height;
 
-	screenshot = TOTEM_SCREENSHOT (g_object_new (GTK_TYPE_SCREENSHOT, NULL));
+	screenshot = TOTEM_SCREENSHOT (g_object_new (TOTEM_TYPE_SCREENSHOT, NULL));
 
 	height = 200;
 	width = height * gdk_pixbuf_get_width (screen_image)

Copied: trunk/src/plugins/screenshot/totem-screenshot.h (from r5877, /trunk/src/totem-screenshot.h)
==============================================================================
--- /trunk/src/totem-screenshot.h	(original)
+++ trunk/src/plugins/screenshot/totem-screenshot.h	Sat Dec 27 11:45:21 2008
@@ -1,23 +1,29 @@
-/* totem-screenshot.h: Simple screenshot dialog
-
-   Copyright (C) 2004 Bastien Nocera <hadess hadess net>
-
-   The Gnome Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Library General Public License as
-   published by the Free Software Foundation; either version 2 of the
-   License, or (at your option) any later version.
-
-   The Gnome Library 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
-   Library General Public License for more details.
-
-   You should have received a copy of the GNU Library General Public
-   License along with the Gnome Library; see the file COPYING.LIB.  If not,
-   write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-   Boston, MA 02110-1301  USA.
-
-   Author: Bastien Nocera <hadess hadess net>
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/* 
+ * Copyright (C) 2004 Bastien Nocera
+ * Copyright (C) 2008 Philip Withnall <philip tecnocode co uk>
+ *
+ * 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 of the License, or
+ * (at your option) any later 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 Street, Fifth Floor, Boston, MA 02110-1301  USA.
+ *
+ * The Totem project hereby grant permission for non-gpl compatible GStreamer
+ * plugins to be used and distributed together with GStreamer and Totem. This
+ * permission are above and beyond the permissions granted by the GPL license
+ * Totem is covered by.
+ *
+ * Monday 7th February 2005: Christian Schaller: Add exception clause.
+ * See license_change file for details.
  */
 
 #ifndef TOTEM_SCREENSHOT_H
@@ -27,11 +33,11 @@
 
 G_BEGIN_DECLS
 
-#define GTK_TYPE_SCREENSHOT            (totem_screenshot_get_type ())
-#define TOTEM_SCREENSHOT(obj)          (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_SCREENSHOT, TotemScreenshot))
-#define TOTEM_SCREENSHOT_CLASS(klass)  (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_SCREENSHOT, TotemScreenshotClass))
-#define GTK_IS_SCREENSHOT(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_SCREENSHOT))
-#define GTK_IS_SCREENSHOT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_SCREENSHOT))
+#define TOTEM_TYPE_SCREENSHOT			(totem_screenshot_get_type ())
+#define TOTEM_SCREENSHOT(obj)			(G_TYPE_CHECK_INSTANCE_CAST ((obj), TOTEM_TYPE_SCREENSHOT, TotemScreenshot))
+#define TOTEM_SCREENSHOT_CLASS(klass)		(G_TYPE_CHECK_CLASS_CAST ((klass), TOTEM_TYPE_SCREENSHOT, TotemScreenshotClass))
+#define TOTEM_IS_SCREENSHOT(obj)		(G_TYPE_CHECK_INSTANCE_TYPE ((obj), TOTEM_TYPE_SCREENSHOT))
+#define TOTEM_IS_SCREENSHOT_CLASS(klass)	(G_TYPE_CHECK_CLASS_TYPE ((klass), TOTEM_TYPE_SCREENSHOT))
 
 typedef struct TotemScreenshot	       TotemScreenshot;
 typedef struct TotemScreenshotClass    TotemScreenshotClass;
@@ -46,9 +52,9 @@
 	GtkDialogClass parent_class;
 };
 
-GType    totem_screenshot_get_type (void);
-GtkWidget *totem_screenshot_new      (GdkPixbuf *playing_pix);
+GType totem_screenshot_get_type (void);
+GtkWidget *totem_screenshot_new (GdkPixbuf *playing_pix);
 
 G_END_DECLS
 
-#endif /* TOTEM_SCREENSHOT_H */
+#endif /* !TOTEM_SCREENSHOT_H */

Modified: trunk/src/totem-menu.c
==============================================================================
--- trunk/src/totem-menu.c	(original)
+++ trunk/src/totem-menu.c	Sat Dec 27 11:45:21 2008
@@ -43,7 +43,6 @@
 void properties_action_callback (GtkAction *action, Totem *totem);
 void play_action_callback (GtkAction *action, Totem *totem);
 void quit_action_callback (GtkAction *action, Totem *totem);
-void take_screenshot_action_callback (GtkAction *action, Totem *totem);
 void preferences_action_callback (GtkAction *action, Totem *totem);
 void fullscreen_action_callback (GtkAction *action, Totem *totem);
 void zoom_1_2_action_callback (GtkAction *action, Totem *totem);
@@ -1018,12 +1017,6 @@
 }
 
 void
-take_screenshot_action_callback (GtkAction *action, Totem *totem)
-{
-	totem_action_take_screenshot (totem);
-}
-
-void
 preferences_action_callback (GtkAction *action, Totem *totem)
 {
 	gtk_widget_show (totem->prefs);

Modified: trunk/src/totem-preferences.c
==============================================================================
--- trunk/src/totem-preferences.c	(original)
+++ trunk/src/totem-preferences.c	Sat Dec 27 11:45:21 2008
@@ -290,20 +290,6 @@
 			G_CALLBACK (checkbutton3_toggled_cb), totem);
 }
 
-static void
-disable_save_to_disk_changed_cb (GConfClient *client, guint cnxn_id,
-		GConfEntry *entry, Totem *totem)
-{
-	GtkWidget *item;
-	gboolean locked;
-
-	locked = gconf_client_get_bool (totem->gc,
-			"/desktop/gnome/lockdown/disable_save_to_disk", NULL);
-	item = GTK_WIDGET (gtk_builder_get_object (totem->xml,
-			"tmw_take_screenshot_menu_item"));
-	gtk_widget_set_sensitive (item, !locked);
-}
-
 void
 connection_combobox_changed (GtkComboBox *combobox, Totem *totem)
 {
@@ -509,11 +495,6 @@
 			totem, NULL, NULL);
 	gconf_client_add_dir (totem->gc, "/desktop/gnome/lockdown",
 			GCONF_CLIENT_PRELOAD_ONELEVEL, NULL);
-	gconf_client_notify_add (totem->gc,
-			"/desktop/gnome/lockdown/disable_save_to_disk",
-			(GConfClientNotifyFunc)
-			disable_save_to_disk_changed_cb,
-			totem, NULL, NULL);
 
 	/* Work-around builder dialogue not parenting properly for
 	 * On top windows */
@@ -674,14 +655,6 @@
 			(GConfClientNotifyFunc) deinterlace_changed_cb,
 			totem, NULL, NULL);
 
-	/* Save to disk Lockdown */
-	action = gtk_action_group_get_action (totem->main_action_group,
-			"take-screenshot");
-	gtk_action_set_sensitive (action,
-			!gconf_client_get_bool (totem->gc,
-				"/desktop/gnome/lockdown/disable_save_to_disk",
-				NULL));
-
 	/* Subtitle font selection */
 	item = gtk_builder_get_object (totem->xml, "font_sel_button");
 	gtk_font_button_set_title (GTK_FONT_BUTTON (item),

Modified: trunk/src/totem-private.h
==============================================================================
--- trunk/src/totem-private.h	(original)
+++ trunk/src/totem-private.h	Sat Dec 27 11:45:21 2008
@@ -176,7 +176,6 @@
 void	totem_action_open			(Totem *totem);
 void	totem_action_open_location		(Totem *totem);
 void	totem_action_eject			(Totem *totem);
-void	totem_action_take_screenshot		(Totem *totem);
 void	totem_action_zoom_relative		(Totem *totem, int off_pct);
 void	totem_action_zoom_reset			(Totem *totem);
 void	totem_action_show_help			(Totem *totem);

Modified: trunk/src/totem-video-thumbnailer.c
==============================================================================
--- trunk/src/totem-video-thumbnailer.c	(original)
+++ trunk/src/totem-video-thumbnailer.c	Sat Dec 27 11:45:21 2008
@@ -50,6 +50,11 @@
 #define PROGRESS_DEBUG(format...) { if (verbose != FALSE) g_message (format); }
 #endif
 
+/* The main() function controls progress in the first and last 10% */
+#define PRINT_PROGRESS(p) { g_printf ("%f%% complete\n", p); }
+#define MIN_PROGRESS 10.0
+#define MAX_PROGRESS 90.0
+
 #define BORING_IMAGE_VARIANCE 256.0		/* Tweak this if necessary */
 #define GALLERY_MIN 3				/* minimum number of screenshots in a gallery */
 #define GALLERY_MAX 30				/* maximum number of screenshots in a gallery */
@@ -59,6 +64,7 @@
 static gboolean output_size = 128;
 static gboolean time_limit = TRUE;
 static gboolean verbose = FALSE;
+static gboolean print_progress = FALSE;
 static gboolean g_fatal_warnings = FALSE;
 static gint gallery = -1;
 static gint64 second_index = -1;
@@ -608,6 +614,9 @@
 		PROGRESS_DEBUG ("Composited screenshot from %" G_GINT64_FORMAT " seconds (address %u) at (%u,%u).",
 				pos, GPOINTER_TO_UINT (screenshot), x, y);
 
+		/* We print progress in the range 10% (MIN_PROGRESS) to 50% (MAX_PROGRESS - MIN_PROGRESS) / 2.0 */
+		PRINT_PROGRESS (MIN_PROGRESS + (current_row * columns + current_column) * (((MAX_PROGRESS - MIN_PROGRESS) / gallery) / 2.0));
+
 		current_column = (current_column + 1) % columns;
 		x += output_size + x_padding;
 		if (current_column == 0) {
@@ -697,6 +706,9 @@
 				x - layout_width - 0.02 * output_size,
 				y - layout_height - 0.02 * scale * screenshot_height);
 
+		/* We print progress in the range 50% (MAX_PROGRESS - MIN_PROGRESS) / 2.0) to 90% (MAX_PROGRESS) */
+		PRINT_PROGRESS (MIN_PROGRESS + (MAX_PROGRESS - MIN_PROGRESS) / 2.0 + (current_row * columns + current_column) * (((MAX_PROGRESS - MIN_PROGRESS) / gallery) / 2.0));
+
 		g_free (timestamp_text);
 
 		current_column = (current_column + 1) % columns;
@@ -727,6 +739,7 @@
 	{ "time", 't', 0, G_OPTION_ARG_INT64, &second_index, "Choose this time (in seconds) as the thumbnail (can't be used with --gallery)", NULL },
 	{ "g-fatal-warnings", 0, 0, G_OPTION_ARG_NONE, &g_fatal_warnings, "Make all warnings fatal", NULL },
 	{ "gallery", 'g', 0, G_OPTION_ARG_INT, &gallery, "Output a gallery of the given number (0 is default) of screenshots (can't be used with --time)", NULL },
+	{ "print-progress", 'p', 0, G_OPTION_ARG_NONE, &print_progress, "Only print progress updates (can't be used with --verbose)", NULL },
  	{ G_OPTION_REMAINING, '\0', 0, G_OPTION_ARG_FILENAME_ARRAY, &filenames, NULL, "[FILE...]" },
 	{ NULL }
 };
@@ -772,7 +785,8 @@
 	}
 
 	if (filenames == NULL || g_strv_length (filenames) != 2 ||
-	    (second_index != -1 && gallery != -1)) {
+	    (second_index != -1 && gallery != -1) ||
+	    (print_progress == TRUE && verbose == TRUE)) {
 		char *help;
 		help = g_option_context_get_help (context, FALSE, NULL);
 		g_print ("%s", help);
@@ -783,6 +797,7 @@
 	output = filenames[1];
 
 	PROGRESS_DEBUG("Initialised libraries, about to create video widget");
+	PRINT_PROGRESS (2.0);
 
 	bvw = BACON_VIDEO_WIDGET (bacon_video_widget_new (-1, -1, BVW_USE_TYPE_CAPTURE, &err));
 	if (err != NULL) {
@@ -798,6 +813,7 @@
 			  &data);
 
 	PROGRESS_DEBUG("Video widget created");
+	PRINT_PROGRESS (6.0);
 
 	if (time_limit != FALSE)
 		totem_resources_monitor_start (input, 0);
@@ -814,6 +830,7 @@
 
 	PROGRESS_DEBUG("Opened video file: '%s'", input);
 	PROGRESS_DEBUG("About to play file");
+	PRINT_PROGRESS (8.0);
 
 	bacon_video_widget_play (bvw, &err);
 	if (err != NULL) {
@@ -823,6 +840,7 @@
 		exit (1);
 	}
 	PROGRESS_DEBUG("Started playing file");
+	PRINT_PROGRESS (10.0);
 
 	if (gallery == -1) {
 		/* If the user has told us to use a frame at a specific second 
@@ -832,6 +850,7 @@
 			pixbuf = capture_frame_at_time (bvw, input, output, second_index);
 		else
 			pixbuf = capture_interesting_frame (bvw, input, output);
+		PRINT_PROGRESS (90.0);
 	} else {
 		/* We're producing a gallery of screenshots from throughout the file */
 		pixbuf = create_gallery (bvw, input, output);
@@ -841,6 +860,7 @@
 	bacon_video_widget_close (bvw);
 	totem_resources_monitor_stop ();
 	gtk_widget_destroy (GTK_WIDGET (bvw));
+	PRINT_PROGRESS (92.0);
 
 	if (pixbuf == NULL) {
 		g_print ("totem-video-thumbnailer couldn't get a picture from "
@@ -851,6 +871,7 @@
 	PROGRESS_DEBUG("Saving captured screenshot");
 	save_pixbuf (pixbuf, output, input, output_size, FALSE);
 	g_object_unref (pixbuf);
+	PRINT_PROGRESS (100.0);
 
 	return 0;
 }

Modified: trunk/src/totem.c
==============================================================================
--- trunk/src/totem.c	(original)
+++ trunk/src/totem.c	Sat Dec 27 11:45:21 2008
@@ -52,7 +52,6 @@
 #include "totem-statusbar.h"
 #include "totem-time-label.h"
 #include "totem-session.h"
-#include "totem-screenshot.h"
 #include "totem-sidebar.h"
 #include "totem-menu.h"
 #include "totem-options.h"
@@ -913,44 +912,6 @@
 	gtk_widget_show (GTK_WIDGET (totem->open_location));
 }
 
-void
-totem_action_take_screenshot (Totem *totem)
-{
-	GdkPixbuf *pixbuf;
-	GtkWidget *dialog;
-	char *filename;
-	GError *err = NULL;
-
-	if (bacon_video_widget_get_logo_mode (totem->bvw) != FALSE)
-		return;
-
-	if (bacon_video_widget_can_get_frames (totem->bvw, &err) == FALSE)
-	{
-		if (err == NULL)
-			return;
-
-		totem_action_error (_("Totem could not get a screenshot of that film."), err->message, totem);
-		g_error_free (err);
-		return;
-	}
-
-	pixbuf = bacon_video_widget_get_current_frame (totem->bvw);
-	if (pixbuf == NULL)
-	{
-		totem_action_error (_("Totem could not get a screenshot of that film."), _("This is not supposed to happen; please file a bug report."), totem);
-		return;
-	}
-
-	filename = g_build_filename (DATADIR,
-			"totem", "screenshot.ui", NULL);
-	dialog = totem_screenshot_new (pixbuf);
-	g_free (filename);
-
-	gtk_dialog_run (GTK_DIALOG (dialog));
-	gtk_widget_destroy (dialog);
-	g_object_unref (pixbuf);
-}
-
 static char *
 totem_get_nice_name_for_stream (Totem *totem)
 {
@@ -1087,9 +1048,6 @@
 		totem_action_set_sensitivity ("next-chapter", FALSE);
 		totem_action_set_sensitivity ("previous-chapter", FALSE);
 
-		/* Take a screenshot */
-		totem_action_set_sensitivity ("take-screenshot", FALSE);
-
 		/* Clear the playlist */
 		totem_action_set_sensitivity ("clear-playlist", FALSE);
 
@@ -1129,9 +1087,6 @@
 		totem_action_set_sensitivity ("volume-down", caps && volume > VOLUME_EPSILON);
 		totem->volume_sensitive = caps;
 
-		/* Take a screenshot */
-		totem_action_set_sensitivity ("take-screenshot", retval);
-
 		/* Clear the playlist */
 		totem_action_set_sensitivity ("clear-playlist", retval);
 
@@ -1802,9 +1757,6 @@
 		g_free (name);
 	}
 	
-	totem_action_set_sensitivity ("take-screenshot",
-				      bacon_video_widget_can_get_frames (bvw, NULL));
-	
 	on_playlist_change_name (TOTEM_PLAYLIST (totem->playlist), totem);
 }
 
@@ -2855,19 +2807,6 @@
 #endif /* HAVE_XFREE */
 		totem_action_zoom_relative (totem, ZOOM_IN_OFFSET);
 		break;
-#ifdef HAVE_XFREE
-	case XF86XK_Save:
-		totem_action_take_screenshot (totem);
-		break;
-#endif /* HAVE_XFREE */
-	case GDK_s:
-	case GDK_S:
-		if (event->state & GDK_CONTROL_MASK) {
-			totem_action_take_screenshot (totem);
-		} else {
-			return FALSE;
-		}
-		break;
 	case GDK_t:
 	case GDK_T:
 #ifdef HAVE_XFREE



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