diff --git a/ChangeLog b/ChangeLog index 857b1328912424aa08e230c098cc23a7516a063d..9780168ca7786ef42a5c84e0424a491e4a70a6e9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,16 @@ +2009-07-31: 11:30 Ali aliov@xfce.org + * Support for Recent played media files. + * Better configuration loading based GValues. + * Register posix signal handler. + * Much better cdda support. + * Patch the makefile by Enrico Tröger to fix issue with + generating the enum types. + * Fix the sound image menu items size. + * Double clicks a file close the media chooser dialog. + * Remove grey border in fullscreen mode. + * Set the main window name to Parole Media Player. + * Fix the expander packing style in the savelist chooser. + 2009-07-30: Ali aliov@xfce.org * Supports for Aspect ratio views. * Remember the size of the main window set. diff --git a/TODO b/TODO index f7c06018943053b162a12dee0f8aaa72d03c89cf..e4b34c11d6c804486d3b157f6a7ad743c59937bd 100644 --- a/TODO +++ b/TODO @@ -2,7 +2,6 @@ * Complete the shortcut keys. * Handle missing gstreamer plugins. * Support scale ratio view. -* Better support for cdda. * Support some playlist title entity. * Use pixel-aspect-ratio info when calculating the aspect ratio. diff --git a/data/interfaces/mediachooser.ui b/data/interfaces/mediachooser.ui index 25e37aca1ea6064f844a49a7f137c0ecc1cf7198..991065fa29da3f7cf28652b0be43fbb5e9674d0d 100644 --- a/data/interfaces/mediachooser.ui +++ b/data/interfaces/mediachooser.ui @@ -12,6 +12,7 @@ 5 vertical 1 + diff --git a/data/interfaces/parole-settings.ui b/data/interfaces/parole-settings.ui index 4b422b6781163d93bbdbefa29694750833006488..d9d3f33afd23ed3c9d6fd720290ce2319b70ac9c 100644 --- a/data/interfaces/parole-settings.ui +++ b/data/interfaces/parole-settings.ui @@ -21,86 +21,6 @@ True vertical 10 - - - True - 0 - none - - - True - 12 - - - True - vertical - 5 - - - Enable visualization when playing audio file - True - True - False - Changing this will take effect after parole is restarted or a new media file is loaded. - True - - - - 0 - - - - - True - 2 - - - True - Visualization type: - - - False - False - 0 - - - - - True - liststore1 - - - - - 0 - - - - - 1 - - - - - 1 - - - - - - - - - True - <b>Audio</b> - True - - - - - 0 - - True @@ -262,6 +182,85 @@ + + 0 + + + + + True + 0 + none + + + True + 12 + + + True + vertical + 5 + + + Enable visualization when playing audio file + True + True + False + True + + + + 0 + + + + + True + 2 + + + True + Visualization type: + + + False + False + 0 + + + + + True + liststore1 + + + + + 0 + + + + + 1 + + + + + 1 + + + + + + + + + True + <b>Audio</b> + True + + + 1 @@ -282,7 +281,7 @@ 5 - Automatically load subtitle when playing movie file + Automatically load subtitles when playing movie file True True False diff --git a/data/interfaces/parole.ui b/data/interfaces/parole.ui index 6f3cdf13e7e69b2607b981af762cd34633cc9321..663d64cbaad541f5afc942ed0249bf7e83ad06c4 100644 --- a/data/interfaces/parole.ui +++ b/data/interfaces/parole.ui @@ -3,6 +3,7 @@ + Parole Media Player center 780 480 @@ -219,7 +220,7 @@ True - + Mute True image12 @@ -227,7 +228,7 @@ - + Volume Up True image11 @@ -237,7 +238,7 @@ - + Volume Down True image10 @@ -286,6 +287,7 @@ True True False + False True 0 @@ -378,13 +380,18 @@ - - - - - - - + + True + + + True + True + + + + + 4 + diff --git a/data/interfaces/save-playlist.ui b/data/interfaces/save-playlist.ui index e3e17559e0acca6812e6957ae365d74a0743c910..481f00727e9aa7f37fb00e6cac3a8dd3b9405e12 100644 --- a/data/interfaces/save-playlist.ui +++ b/data/interfaces/save-playlist.ui @@ -21,8 +21,6 @@ 5 - 480 - 300 normal False save @@ -74,6 +72,8 @@ + False + False 2 diff --git a/parole/Makefile.am b/parole/Makefile.am index 7e9a38ba1e39663cbd98cfd961cca3fbd7f30b88..c4bb5ceb7ea7810454f408e82ccaa197e6c43a25 100644 --- a/parole/Makefile.am +++ b/parole/Makefile.am @@ -10,18 +10,11 @@ INCLUDES = \ -DLOCALEDIR=\"$(localedir)\" \ -DG_LOG_DOMAIN=\"parole\" \ -DPAROLE_PLUGINS_DIR=\"$(libdir)/parole-$(PAROLE_VERSION_API)\"\ - $(GTK_CFLAGS) \ - $(GLIB_CFLAGS) \ - $(GOBJECT_CFLAGS) \ $(GTHREAD_CFLAGS) \ $(GIO_CFLAGS) \ - $(DBUS_CFLAGS) \ $(DBUS_GLIB_CFLAGS) \ $(LIBXFCE4GUI_CFLAGS) \ - $(LIBXFCE4UTIL_CFLAGS) \ - $(GST_CFLAGS) \ $(GST_VIDEO_CFLAGS) \ - $(GST_BASE_CFLAGS) \ $(GST_INTERFACES_CFLAGS) PAROLE_LDFLAGS = \ @@ -30,17 +23,10 @@ PAROLE_LDFLAGS = \ -export-symbols-regex "^[[^_]].*" PAROLE_LIBS = \ - $(GTK_LIBS) \ - $(GLIB_LIBS) \ - $(GOBJECT_LIBS) \ $(GTHREAD_LIBS) \ $(GIO_LIBS) \ - $(DBUS_LIBS) \ $(DBUS_GLIB_LIBS) \ $(LIBXFCE4GUI_LIBS) \ - $(LIBXFCE4UTIL_LIBS) \ - $(GST_LIBS) \ - $(GST_BASE_LIBS) \ $(GST_VIDEO_LIBS) \ $(GST_INTERFACES_LIBS) @@ -134,8 +120,7 @@ parole_media_player_SOURCES = \ main.c parole_media_player_LDADD = \ - libparole.la \ - $(PAROLE_LIBS) + libparole.la parole_media_player_LDFLAGS = \ $(PAROLE_LDFLAGS) @@ -167,9 +152,9 @@ stamp-enum-gtypes.h: $(parole_glib_enum_headers) Makefile --fprod "/* enumerations from \"@filename@\" */\n" \ --vhead "GType @enum_name@_get_type (void);\n#define ENUM_GTYPE_@ENUMSHORT@ (@enum_name@_get_type())\n" \ --ftail "G_END_DECLS\n\n#endif /* __ENUM_GTYPES_H__ */" \ - $(parole_glib_enum_headers) ) > xgen-enum \ - && (cmp -s xgen-enum enum-gtypes.h || cp xgen-enum enum-gtypes.h) \ - && rm -f xgen-enum \ + $(parole_glib_enum_headers) ) > xgen-enum.h \ + && (cmp -s xgen-enum.h enum-gtypes.h || cp xgen-enum.h enum-gtypes.h) \ + && rm -f xgen-enum.h \ && echo timestamp > $(@F) enum-gtypes.c: $(parole_glib_enum_headers) Makefile @@ -184,9 +169,9 @@ enum-gtypes.c: $(parole_glib_enum_headers) Makefile --vhead "GType\n@enum_name@_get_type (void)\n{\n static GType etype = 0;\n if (etype == 0) {\n static const G@Type@Value values[] = {" \ --vprod " { @VALUENAME@, \"@VALUENAME@\", \"@valuenick@\" }," \ --vtail " { 0, NULL, NULL }\n };\n etype = g_@type@_register_static (\"@EnumName@\", values);\n }\n return etype;\n}\n" \ - $(parole_glib_enum_headers) ) >> xgen-enum \ - && cp xgen-enum enum-gtypes.c \ - && rm -f xgen-enum + $(parole_glib_enum_headers) ) >> xgen-enum.c \ + && cp xgen-enum.c enum-gtypes.c \ + && rm -f xgen-enum.c org.parole.media.list.h: $(srcdir)/org.parole.media.list.xml dbus-binding-tool --mode=glib-server --prefix=parole_media_list $< >$@ diff --git a/parole/main.c b/parole/main.c index f5260e4525a8c3a63fbeaea71e26d30f133b712d..0458ec5894632485c2e636558e1120785f8df826 100644 --- a/parole/main.c +++ b/parole/main.c @@ -58,6 +58,14 @@ show_version (void) exit (EXIT_SUCCESS); } +static void +parole_sig_handler (gint sig, gpointer data) +{ + ParolePlayer *player = (ParolePlayer *) data; + + parole_player_terminate (player); +} + static void parole_send_play_disc (DBusGProxy *proxy, const gchar *uri) { @@ -203,6 +211,27 @@ int main (int argc, char **argv) parole_media_list_add_files (list, filenames); } } + + if ( xfce_posix_signal_handler_init (&error)) + { + xfce_posix_signal_handler_set_handler(SIGHUP, + parole_sig_handler, + player, NULL); + + xfce_posix_signal_handler_set_handler(SIGINT, + parole_sig_handler, + player, NULL); + + xfce_posix_signal_handler_set_handler(SIGTERM, + parole_sig_handler, + player, NULL); + } + else + { + g_warning ("Unable to set up POSIX signal handlers: %s", error->message); + g_error_free (error); + } + plugins = parole_plugins_manager_new (); parole_plugins_manager_load_plugins (plugins); g_object_unref (builder); diff --git a/parole/parole-conf.c b/parole/parole-conf.c index 73409ce9f9c7a86a053ff5cf9e12a64e52abe803..b4a234e24b38f12a36fd0a20cb84aa8b00d9ad68 100644 --- a/parole/parole-conf.c +++ b/parole/parole-conf.c @@ -37,22 +37,7 @@ struct ParoleConfPrivate { - gchar *vis_sink; - gboolean enable_vis; - gboolean enable_subtitle; - gchar *subtitle_font; - gchar *subtitle_encoding; - - gboolean repeat; - gboolean shuffle; - - gint brightness; - gint contrast; - gint hue; - gint saturation; - ParoleAspectRatio aspect_ratio; - gint window_width; - gint window_height; + GValue *values; }; static gpointer parole_conf_object = NULL; @@ -85,81 +70,43 @@ static void parole_conf_set_property (GObject *object, GParamSpec *pspec) { ParoleConf *conf; + GValue *dst; + GValue save_dst = { 0, }; + conf = PAROLE_CONF (object); + + dst = conf->priv->values + prop_id; - switch (prop_id) + if ( !G_IS_VALUE (dst) ) { - case PROP_VIS_ENABLED: - conf->priv->enable_vis = g_value_get_boolean (value); - g_object_notify (G_OBJECT (conf), pspec->name); - parole_rc_write_entry_bool ("VIS_ENABLED", PAROLE_RC_GROUP_GENERAL, conf->priv->enable_vis); - break; - case PROP_SUBTITLE_ENCODING: - if ( conf->priv->subtitle_encoding ) - g_free (conf->priv->subtitle_encoding); - conf->priv->subtitle_encoding = g_value_dup_string (value); - parole_rc_write_entry_string ("SUBTITLE_ENCODING", PAROLE_RC_GROUP_GENERAL, conf->priv->subtitle_encoding); - break; - case PROP_VIS_NAME: - if ( conf->priv->vis_sink ) - g_free (conf->priv->vis_sink); - conf->priv->vis_sink = g_value_dup_string (value); - parole_rc_write_entry_string ("VIS_NAME", PAROLE_RC_GROUP_GENERAL, conf->priv->vis_sink); - break; - case PROP_SUBTITLE_ENABLED: - conf->priv->enable_subtitle = g_value_get_boolean (value); - parole_rc_write_entry_bool ("ENABLE_SUBTITLE", PAROLE_RC_GROUP_GENERAL, conf->priv->enable_subtitle); - break; - case PROP_SUBTITLE_FONT: - if ( conf->priv->subtitle_font ) - g_free (conf->priv->subtitle_font); - conf->priv->subtitle_font = g_value_dup_string (value); - parole_rc_write_entry_string ("SUBTITLE_FONT", PAROLE_RC_GROUP_GENERAL, conf->priv->subtitle_font); - break; - case PROP_REPEAT: - conf->priv->repeat = g_value_get_boolean (value); - parole_rc_write_entry_bool ("REPEAT", PAROLE_RC_GROUP_GENERAL, conf->priv->repeat); - break; - case PROP_SHUFFLE: - conf->priv->shuffle = g_value_get_boolean (value); - parole_rc_write_entry_bool ("SHUFFLE", PAROLE_RC_GROUP_GENERAL, conf->priv->shuffle); - break; - case PROP_SATURATION: - conf->priv->saturation = g_value_get_int (value); - parole_rc_write_entry_int ("SATURATION", PAROLE_RC_GROUP_GENERAL, conf->priv->saturation); - break; - case PROP_HUE: - conf->priv->hue = g_value_get_int (value); - parole_rc_write_entry_int ("HUE", PAROLE_RC_GROUP_GENERAL, conf->priv->hue); - break; - case PROP_CONTRAST: - conf->priv->contrast = g_value_get_int (value); - parole_rc_write_entry_int ("CONTRAST", PAROLE_RC_GROUP_GENERAL, conf->priv->contrast); - break; - case PROP_BRIGHTNESS: - conf->priv->brightness = g_value_get_int (value); - parole_rc_write_entry_int ("BRIGHTNESS", PAROLE_RC_GROUP_GENERAL, conf->priv->brightness); - break; - case PROP_ASPECT_RATIO: - conf->priv->aspect_ratio = g_value_get_enum (value); - parole_rc_write_entry_int ("ASPECT_RATIO", PAROLE_RC_GROUP_GENERAL, conf->priv->aspect_ratio); - break; - case PROP_WINDOW_WIDTH: - conf->priv->window_width = g_value_get_int (value); - parole_rc_write_entry_int ("WINDOW_WIDTH", PAROLE_RC_GROUP_GENERAL, conf->priv->window_width); - break; - case PROP_WINDOW_HEIGHT: - conf->priv->window_height = g_value_get_int (value); - parole_rc_write_entry_int ("WINDOW_HEIGHT", PAROLE_RC_GROUP_GENERAL, conf->priv->window_height); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - goto out; + g_value_init (dst, pspec->value_type); + g_param_value_set_default (pspec, dst); + } + + if ( g_param_values_cmp (pspec, value, dst) != 0 ) + { + g_value_copy (value, dst); + g_object_notify (object, pspec->name); + + if ( pspec->value_type != G_TYPE_STRING ) + { + g_value_init (&save_dst, G_TYPE_STRING); + + if ( G_LIKELY (g_value_transform (value, &save_dst)) ) + { + g_object_set_property (G_OBJECT (conf), pspec->name, &save_dst); + parole_rc_write_entry_string (pspec->name, PAROLE_RC_GROUP_GENERAL, g_value_get_string (&save_dst)); + } + else + g_warning ("Unable to save property : %s", pspec->name); + + g_value_unset (&save_dst); + } + else + { + parole_rc_write_entry_string (pspec->name, PAROLE_RC_GROUP_GENERAL, g_value_get_string (value)); + } } - g_object_notify (G_OBJECT (conf), pspec->name); - -out: - ; } static void parole_conf_get_property (GObject *object, @@ -168,55 +115,22 @@ static void parole_conf_get_property (GObject *object, GParamSpec *pspec) { ParoleConf *conf; + GValue *src; + conf = PAROLE_CONF (object); - - switch (prop_id) + + src = conf->priv->values + prop_id; + + if (G_VALUE_HOLDS (src, pspec->value_type)) + { + if (G_LIKELY (pspec->value_type == G_TYPE_STRING)) + g_value_set_static_string (value, g_value_get_string (src)); + else + g_value_copy (src, value); + } + else { - case PROP_SUBTITLE_ENCODING: - g_value_set_string (value, conf->priv->subtitle_encoding); - break; - case PROP_VIS_ENABLED: - g_value_set_boolean (value, conf->priv->enable_vis); - break; - case PROP_VIS_NAME: - g_value_set_string (value, conf->priv->vis_sink); - break; - case PROP_SUBTITLE_ENABLED: - g_value_set_boolean (value, conf->priv->enable_subtitle); - break; - case PROP_SUBTITLE_FONT: - g_value_set_string (value, conf->priv->subtitle_font); - break; - case PROP_REPEAT: - g_value_set_boolean (value, conf->priv->repeat); - break; - case PROP_SHUFFLE: - g_value_set_boolean (value, conf->priv->shuffle); - break; - case PROP_SATURATION: - g_value_set_int (value, conf->priv->saturation); - break; - case PROP_HUE: - g_value_set_int (value, conf->priv->hue); - break; - case PROP_CONTRAST: - g_value_set_int (value, conf->priv->contrast); - break; - case PROP_BRIGHTNESS: - g_value_set_int (value, conf->priv->brightness); - break; - case PROP_ASPECT_RATIO: - g_value_set_enum (value, conf->priv->aspect_ratio); - break; - case PROP_WINDOW_WIDTH: - g_value_set_int (value, conf->priv->window_width); - break; - case PROP_WINDOW_HEIGHT: - g_value_set_int (value, conf->priv->window_height); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; + g_param_value_set_default (pspec, value); } } @@ -224,14 +138,49 @@ static void parole_conf_finalize (GObject *object) { ParoleConf *conf; + guint i; conf = PAROLE_CONF (object); - g_free (conf->priv->vis_sink); - g_free (conf->priv->subtitle_font); - g_free (conf->priv->subtitle_encoding); + for ( i = 0; i < N_PROP; i++) + { + if ( G_IS_VALUE (conf->priv->values + i) ) + g_value_unset (conf->priv->values + i); + } + + g_free (conf->priv->values); G_OBJECT_CLASS (parole_conf_parent_class)->finalize (object); + +} + +static void +transform_string_to_boolean (const GValue *src, + GValue *dst) +{ + g_value_set_boolean (dst, !g_strcmp0 (g_value_get_string (src), "TRUE")); +} + +static void +transform_string_to_int (const GValue *src, + GValue *dst) +{ + g_value_set_int (dst, strtol (g_value_get_string (src), NULL, 10)); +} + +static void +transform_string_to_enum (const GValue *src, + GValue *dst) +{ + GEnumClass *genum_class; + GEnumValue *genum_value; + + genum_class = g_type_class_peek (G_VALUE_TYPE (dst)); + genum_value = g_enum_get_value_by_name (genum_class, g_value_get_string (src)); + + if (G_UNLIKELY (genum_value == NULL)) + genum_value = genum_class->values; + g_value_set_enum (dst, genum_value->value); } static void @@ -244,6 +193,15 @@ parole_conf_class_init (ParoleConfClass *klass) object_class->get_property = parole_conf_get_property; object_class->set_property = parole_conf_set_property; + if (!g_value_type_transformable (G_TYPE_STRING, G_TYPE_INT)) + g_value_register_transform_func (G_TYPE_STRING, G_TYPE_INT, transform_string_to_int); + + if (!g_value_type_transformable (G_TYPE_STRING, G_TYPE_BOOLEAN)) + g_value_register_transform_func (G_TYPE_STRING, G_TYPE_BOOLEAN, transform_string_to_boolean); + + if (!g_value_type_transformable (G_TYPE_STRING, ENUM_GTYPE_ASPECT_RATIO)) + g_value_register_transform_func (G_TYPE_STRING, ENUM_GTYPE_ASPECT_RATIO, transform_string_to_enum); + g_object_class_install_property (object_class, PROP_VIS_ENABLED, g_param_spec_boolean ("vis-enabled", @@ -255,28 +213,28 @@ parole_conf_class_init (ParoleConfClass *klass) PROP_VIS_NAME, g_param_spec_string ("vis-name", NULL, NULL, - NULL, + "none", G_PARAM_READWRITE)); g_object_class_install_property (object_class, PROP_SUBTITLE_ENCODING, g_param_spec_string ("subtitle-encoding", NULL, NULL, - NULL, + "UTF-8", G_PARAM_READWRITE)); g_object_class_install_property (object_class, PROP_SUBTITLE_ENABLED, g_param_spec_boolean ("enable-subtitle", NULL, NULL, - FALSE, + TRUE, G_PARAM_READWRITE)); g_object_class_install_property (object_class, PROP_SUBTITLE_FONT, g_param_spec_string ("subtitle-font", NULL, NULL, - NULL, + "Sans 12", G_PARAM_READWRITE)); g_object_class_install_property (object_class, @@ -357,25 +315,78 @@ parole_conf_class_init (ParoleConfClass *klass) g_type_class_add_private (klass, sizeof (ParoleConfPrivate)); } +static void +parole_conf_load (ParoleConf *conf) +{ + XfceRc *rc; + const gchar *name; + const gchar *str; + GParamSpec **pspecs, *pspec; + guint nspecs, i; + GValue src = { 0, }, dst = { 0, }; + + rc = parole_get_resource_file (PAROLE_RC_GROUP_GENERAL, TRUE); + + if ( G_UNLIKELY (rc == NULL ) ) + { + g_warning ("Unable to lookup rc file in : %s\n", PAROLE_RESOURCE_FILE); + return; + } + + g_object_freeze_notify (G_OBJECT (conf)); + + pspecs = g_object_class_list_properties (G_OBJECT_GET_CLASS (conf), &nspecs); + + g_value_init (&src, G_TYPE_STRING); + + for ( i = 0; i < nspecs; i++) + { + pspec = pspecs[i]; + name = g_param_spec_get_name (pspec); + + str = xfce_rc_read_entry (rc, pspec->name, NULL); + + if ( str ) + { + g_value_set_static_string (&src, str); + + if ( pspec->value_type == G_TYPE_STRING ) + { + g_object_set_property (G_OBJECT (conf), name, &src); + } + else + { + g_value_init (&dst, G_PARAM_SPEC_VALUE_TYPE (pspec)); + + if ( G_LIKELY (g_value_transform (&src, &dst))) + { + g_object_set_property (G_OBJECT (conf), name, &dst); + } + else + { + g_warning ("Unable to load property %s", name); + } + + g_value_unset (&dst); + } + } + } + + xfce_rc_close (rc); + g_value_unset (&src); + g_object_thaw_notify (G_OBJECT (conf)); + g_free (pspecs); +} + static void parole_conf_init (ParoleConf *conf) { conf->priv = PAROLE_CONF_GET_PRIVATE (conf); - conf->priv->enable_vis = parole_rc_read_entry_bool ("VIS_ENABLED", PAROLE_RC_GROUP_GENERAL, FALSE); - conf->priv->vis_sink = g_strdup (parole_rc_read_entry_string ("VIS_NAME", PAROLE_RC_GROUP_GENERAL, "none")); - conf->priv->enable_subtitle = parole_rc_read_entry_bool ("ENABLE_SUBTITLE", PAROLE_RC_GROUP_GENERAL, TRUE); - conf->priv->subtitle_font = g_strdup (parole_rc_read_entry_string ("SUBTITLE_FONT", PAROLE_RC_GROUP_GENERAL, "Sans 12")); - conf->priv->subtitle_encoding = g_strdup (parole_rc_read_entry_string ("SUBTITLE_ENCODING", PAROLE_RC_GROUP_GENERAL, "UTF8")); - conf->priv->repeat = parole_rc_read_entry_bool ("REPEAT", PAROLE_RC_GROUP_GENERAL, FALSE); - conf->priv->shuffle = parole_rc_read_entry_bool ("SHUFFLE", PAROLE_RC_GROUP_GENERAL, FALSE); - conf->priv->saturation = parole_rc_read_entry_int ("SATURATION", PAROLE_RC_GROUP_GENERAL, 0); - conf->priv->hue = parole_rc_read_entry_int ("HUE", PAROLE_RC_GROUP_GENERAL, 0); - conf->priv->contrast = parole_rc_read_entry_int ("CONTRAST", PAROLE_RC_GROUP_GENERAL, 0); - conf->priv->brightness = parole_rc_read_entry_int ("BRIGHTNESS", PAROLE_RC_GROUP_GENERAL, 0); - conf->priv->aspect_ratio = parole_rc_read_entry_int ("ASPECT_RATIO", PAROLE_RC_GROUP_GENERAL, PAROLE_ASPECT_RATIO_NONE); - conf->priv->window_width = parole_rc_read_entry_int ("WINDOW_WIDTH", PAROLE_RC_GROUP_GENERAL, 780); - conf->priv->window_height = parole_rc_read_entry_int ("WINDOW_HEIGHT", PAROLE_RC_GROUP_GENERAL, 480); + conf->priv->values = g_new0 (GValue, N_PROP); + + parole_conf_load (conf); + } ParoleConf * diff --git a/parole/parole-disc-menu.c b/parole/parole-disc-menu.c index ec5ba9832e3c533f3de2d63e6636eb4e9b4dbfaf..8860f9dbca8d5698abe1ce3608083cf58b79825c 100644 --- a/parole/parole-disc-menu.c +++ b/parole/parole-disc-menu.c @@ -26,6 +26,8 @@ #include #include +#include + #include "parole-disc-menu.h" #include "parole-builder.h" #include "parole-statusbar.h" @@ -39,11 +41,13 @@ static void parole_disc_menu_finalize (GObject *object); struct ParoleDiscMenuPrivate { ParoleGst *gst; - + ParoleMediaType current_media_type; GtkWidget *next_chapter; GtkWidget *prev_chapter; GtkWidget *dvd_menu; GtkWidget *chapter_menu; + GtkWidget *info; + GtkWidget *eventboxinfo; }; G_DEFINE_TYPE (ParoleDiscMenu, parole_disc_menu, G_TYPE_OBJECT) @@ -53,15 +57,23 @@ parole_disc_menu_hide (ParoleDiscMenu *menu) { gtk_widget_hide (menu->priv->next_chapter); gtk_widget_hide (menu->priv->prev_chapter); + gtk_widget_hide (menu->priv->info); + gtk_widget_hide (menu->priv->eventboxinfo); //gtk_widget_hide (menu->priv->dvd_menu); //gtk_widget_hide (menu->priv->chapter_menu); } static void -parole_disc_menu_show (ParoleDiscMenu *menu) +parole_disc_menu_show (ParoleDiscMenu *menu, gboolean show_label) { gtk_widget_show (menu->priv->next_chapter); gtk_widget_show (menu->priv->prev_chapter); + + if ( show_label ) + { + gtk_widget_show (menu->priv->eventboxinfo); + gtk_widget_show (menu->priv->info); + } //gtk_widget_show (menu->priv->dvd_menu); //gtk_widget_show (menu->priv->chapter_menu); @@ -75,40 +87,71 @@ parole_disc_menu_media_state_cb (ParoleGst *gst, const ParoleStream *stream, if ( state < PAROLE_MEDIA_STATE_PAUSED ) { + gtk_label_set_markup (GTK_LABEL (menu->priv->info), NULL); parole_disc_menu_hide (menu); } - else + else if ( state == PAROLE_MEDIA_STATE_PLAYING ) { g_object_get (G_OBJECT (stream), "media-type", &media_type, NULL); + if ( media_type == PAROLE_MEDIA_TYPE_DVD ) { - parole_disc_menu_show (menu); + gtk_button_set_label (GTK_BUTTON (menu->priv->next_chapter), _("Next Chapter")); + gtk_button_set_label (GTK_BUTTON (menu->priv->prev_chapter), _("Previous Chapter")); + parole_disc_menu_show (menu, FALSE); + } + else if ( media_type == PAROLE_MEDIA_TYPE_CDDA ) + { + guint num_tracks; + guint current; + gchar *text; + gtk_button_set_label (GTK_BUTTON (menu->priv->next_chapter), _("Next Track")); + gtk_button_set_label (GTK_BUTTON (menu->priv->prev_chapter), _("Previous Track")); + + g_object_get (G_OBJECT (stream), + "num-tracks", &num_tracks, + "track", ¤t, + NULL); + + text = g_strdup_printf ("%s %i/%i", _("Playing Track"), current, num_tracks); + + gtk_label_set_markup (GTK_LABEL (menu->priv->info), text); + + g_free (text); + parole_disc_menu_show (menu, TRUE); } + menu->priv->current_media_type = media_type; } } static void -parole_disc_next_chapter_cb (ParoleDiscMenu *menu) +parole_disc_menu_next_chapter_cb (ParoleDiscMenu *menu) { - parole_gst_next_dvd_chapter (menu->priv->gst); + if ( menu->priv->current_media_type == PAROLE_MEDIA_TYPE_DVD ) + parole_gst_next_dvd_chapter (menu->priv->gst); + else if ( menu->priv->current_media_type == PAROLE_MEDIA_TYPE_CDDA) + parole_gst_next_cdda_track (menu->priv->gst); } static void -parole_disc_prev_chapter_cb (ParoleDiscMenu *menu) +parole_disc_menu_prev_chapter_cb (ParoleDiscMenu *menu) { - parole_gst_prev_dvd_chapter (menu->priv->gst); + if ( menu->priv->current_media_type == PAROLE_MEDIA_TYPE_DVD ) + parole_gst_prev_dvd_chapter (menu->priv->gst); + else if ( menu->priv->current_media_type == PAROLE_MEDIA_TYPE_CDDA) + parole_gst_prev_cdda_track (menu->priv->gst); } static void -parole_disc_dvd_menu_cb (ParoleDiscMenu *menu) +parole_disc_menu_dvd_menu_cb (ParoleDiscMenu *menu) { } static void -parole_disc_chapter_menu_cb (ParoleDiscMenu *menu) +parole_disc_menu_chapter_menu_cb (ParoleDiscMenu *menu) { } @@ -127,6 +170,8 @@ static void parole_disc_menu_init (ParoleDiscMenu *menu) { GtkBuilder *builder; + GdkColor color; + menu->priv = PAROLE_DISC_MENU_GET_PRIVATE (menu); builder = parole_builder_get_main_interface (); @@ -135,19 +180,25 @@ parole_disc_menu_init (ParoleDiscMenu *menu) menu->priv->prev_chapter = GTK_WIDGET (gtk_builder_get_object (builder, "prev-chapter")); menu->priv->chapter_menu = GTK_WIDGET (gtk_builder_get_object (builder, "chapter-menu")); menu->priv->dvd_menu = GTK_WIDGET (gtk_builder_get_object (builder, "dvd-menu")); + menu->priv->info = GTK_WIDGET (gtk_builder_get_object (builder, "info")); + menu->priv->eventboxinfo = GTK_WIDGET (gtk_builder_get_object (builder, "eventboxinfo")); + gdk_color_parse ("black", &color); + gtk_widget_modify_bg (menu->priv->eventboxinfo, GTK_STATE_NORMAL, &color); + + menu->priv->current_media_type = PAROLE_MEDIA_TYPE_UNKNOWN; g_signal_connect_swapped (menu->priv->next_chapter, "clicked", - G_CALLBACK (parole_disc_next_chapter_cb), menu); + G_CALLBACK (parole_disc_menu_next_chapter_cb), menu); g_signal_connect_swapped (menu->priv->prev_chapter, "clicked", - G_CALLBACK (parole_disc_prev_chapter_cb), menu); + G_CALLBACK (parole_disc_menu_prev_chapter_cb), menu); g_signal_connect_swapped (menu->priv->dvd_menu, "clicked", - G_CALLBACK (parole_disc_dvd_menu_cb), menu); + G_CALLBACK (parole_disc_menu_dvd_menu_cb), menu); g_signal_connect_swapped (menu->priv->chapter_menu, "clicked", - G_CALLBACK (parole_disc_chapter_menu_cb), menu); + G_CALLBACK (parole_disc_menu_chapter_menu_cb), menu); menu->priv->gst = PAROLE_GST (parole_gst_new ()); @@ -179,3 +230,13 @@ gboolean parole_disc_menu_visible (ParoleDiscMenu *menu) { return (GTK_WIDGET_VISIBLE (menu->priv->next_chapter)); } + +void parole_disc_menu_seek_next (ParoleDiscMenu *menu) +{ + parole_disc_menu_next_chapter_cb (menu); +} + +void parole_disc_menu_seek_prev (ParoleDiscMenu *menu) +{ + parole_disc_menu_prev_chapter_cb (menu); +} diff --git a/parole/parole-disc-menu.h b/parole/parole-disc-menu.h index 83a1c80461e7de6d561f02fd9e4d710152f4a5d1..6eef24b9044aba070242a8c3131435132d459180 100644 --- a/parole/parole-disc-menu.h +++ b/parole/parole-disc-menu.h @@ -48,6 +48,10 @@ ParoleDiscMenu *parole_disc_menu_new (void); gboolean parole_disc_menu_visible (ParoleDiscMenu *menu); +void parole_disc_menu_seek_next (ParoleDiscMenu *menu); + +void parole_disc_menu_seek_prev (ParoleDiscMenu *menu); + G_END_DECLS #endif /* __PAROLE_DISC_MENU_H */ diff --git a/parole/parole-disc.c b/parole/parole-disc.c index 10fe8be9acb47c7a2f022416256aefbf3c23cd5f..4ba37b3a887f4376cec4b225e82581ecd05ddf95 100644 --- a/parole/parole-disc.c +++ b/parole/parole-disc.c @@ -76,81 +76,106 @@ parole_disc_media_activate_cb (GtkWidget *widget, ParoleDisc *disc) g_signal_emit (G_OBJECT (disc), signals [DISC_SELECTED], 0, uri); } +static MountData * +parole_disc_get_mount_data (ParoleDisc *disc, const gchar *label, const gchar *uri, ParoleDiscKind kind) +{ + MountData *data; + GtkWidget *img; + + data = g_new0 (MountData, 1); + data->kind = kind; + data->uri = g_strdup (uri); + + data->mi = gtk_image_menu_item_new_with_label (label); + + img = gtk_image_new_from_stock (GTK_STOCK_CDROM, GTK_ICON_SIZE_MENU); + gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (data->mi), + img); + gtk_widget_show (data->mi); + gtk_widget_show (img); + + g_object_set_data_full (G_OBJECT (data->mi), + "uri", data->uri, + (GDestroyNotify) g_free); + + gtk_menu_shell_insert (GTK_MENU_SHELL (disc->priv->media_menu), data->mi, 2); + g_signal_connect (data->mi, "activate", + G_CALLBACK (parole_disc_media_activate_cb), disc); + return data; +} + static void parole_disc_add_mount_to_menu (ParoleDisc *disc, GMount *mount) { - MountData *data; GFile *file; gchar **content_type; guint i; + ParoleDiscKind kind; + gchar *uri; file = g_mount_get_root (mount); - data = g_new0 (MountData, 1); - data->kind = PAROLE_DISC_UNKNOWN; - + if ( g_file_has_uri_scheme (file, "cdda") ) + { + kind = PAROLE_DISC_CDDA; + uri = g_strdup ("cdda:/"); + goto got_cdda; + } + content_type = g_content_type_guess_for_tree (file); - + for ( i = 0; content_type && content_type[i]; i++) { + TRACE ("Checking disc content type : %s", content_type[i]); + if ( !g_strcmp0 (content_type[i], "x-content/video-dvd") ) { - data->kind = PAROLE_DISC_DVD; - data->uri = g_strdup ("dvd:/"); + kind = PAROLE_DISC_DVD; + uri = g_strdup ("dvd:/"); break; } else if ( !g_strcmp0 (content_type[i], "x-content/video-vcd") ) { - data->kind = PAROLE_DISC_VCD; - data->uri = g_strdup ("vcd:/"); + kind = PAROLE_DISC_VCD; + uri = g_strdup ("vcd:/"); break; } else if ( !g_strcmp0 (content_type[i], "x-content/video-svcd") ) { - data->kind = PAROLE_DISC_SVCD; - data->uri = g_strdup ("svcd:/"); + kind = PAROLE_DISC_SVCD; + uri = g_strdup ("svcd:/"); break; } else if ( !g_strcmp0 (content_type[i], "x-content/audio-cdda") ) { - data->kind = PAROLE_DISC_CDDA; - data->uri = g_strdup ("cdda:/"); + kind = PAROLE_DISC_CDDA; + uri = g_strdup ("cdda:/"); break; } } if ( content_type ) g_strfreev (content_type); - - if ( data->kind != PAROLE_DISC_UNKNOWN ) + +got_cdda: + if ( kind != PAROLE_DISC_UNKNOWN ) { - GtkWidget *img; + MountData *data; gchar *name; gchar *label; + name = g_mount_get_name (mount); label = g_strdup_printf ("%s %s", _("Play Disc"), name); - data->mi = gtk_image_menu_item_new_with_label (label); - - img = gtk_image_new_from_stock (GTK_STOCK_CDROM, GTK_ICON_SIZE_MENU); - gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (data->mi), - img); - gtk_widget_show (data->mi); - gtk_widget_show (img); - - g_object_set_data_full (G_OBJECT (data->mi), - "uri", data->uri, - (GDestroyNotify) g_free); + data = parole_disc_get_mount_data (disc, label, uri, kind); + g_free (uri); - gtk_menu_shell_insert (GTK_MENU_SHELL (disc->priv->media_menu), data->mi, 2); - g_signal_connect (data->mi, "activate", - G_CALLBACK (parole_disc_media_activate_cb), disc); + g_ptr_array_add (disc->priv->array, data); g_free (label); g_free (name); - g_ptr_array_add (disc->priv->array, data); } - else - g_free (data); + + g_object_unref (file); } static void @@ -169,10 +194,14 @@ parole_disc_add_drive (ParoleDisc *disc, GDrive *drive) GMount *mount; volume = g_list_nth_data (list, i); + TRACE ("Volume name %s", g_volume_get_name (volume)); + mount = g_volume_get_mount (volume); if ( mount ) { + TRACE ("Mount name : %s", g_mount_get_name (mount)); parole_disc_add_mount_to_menu (disc, mount); + g_object_unref (mount); } } @@ -195,7 +224,8 @@ parole_disc_get_drives (ParoleDisc *disc) { GDrive *drive; drive = g_list_nth_data (list, i); - if ( g_drive_can_eject (drive) ) + + if ( g_drive_can_eject (drive) && g_drive_has_media (drive) ) parole_disc_add_drive (disc, drive); } diff --git a/parole/parole-gst.c b/parole/parole-gst.c index 3fb06523a27bc3aadf13ca894755f033f8680122..75b120ea0742f1616cf4d759b397a54d96bfca6d 100644 --- a/parole/parole-gst.c +++ b/parole/parole-gst.c @@ -52,8 +52,13 @@ (G_TYPE_INSTANCE_GET_PRIVATE ((o), PAROLE_TYPE_GST, ParoleGstPrivate)) static void parole_gst_play_file_internal (ParoleGst *gst); + static void parole_gst_change_state (ParoleGst *gst, GstState new); + +static void parole_gst_seek_cdda_track (ParoleGst *gst, + gint track) G_GNUC_UNUSED; + struct ParoleGstPrivate { GstElement *playbin; @@ -116,12 +121,11 @@ parole_gst_finalize (GObject *object) g_object_unref (gst->priv->stream); g_object_unref (gst->priv->playbin); g_object_unref (gst->priv->bus); - + g_object_unref (gst->priv->conf); g_object_unref (gst->priv->logo); + g_mutex_free (gst->priv->lock); - g_object_unref (gst->priv->conf); - G_OBJECT_CLASS (parole_gst_parent_class)->finalize (object); } @@ -560,14 +564,47 @@ parole_gst_query_capabilities (ParoleGst *gst) gst_query_unref (query); } +static void +parole_gst_query_cdda_tracks (ParoleGst *gst) +{ + GstFormat format; + gint64 duration; + gint tracks; + + format = gst_format_get_by_nick ("track"); + + if ( format != GST_FORMAT_UNDEFINED ) + { + gst_element_query_duration (gst->priv->playbin, &format, &duration); + + tracks = (gint) duration; + + TRACE ("CDDA source has %d tacks", tracks); + + g_object_set (G_OBJECT (gst->priv->stream), + "num-tracks", tracks, + NULL); + } +} + static void parole_gst_query_duration (ParoleGst *gst) { + ParoleMediaType media_type; gint64 absolute_duration = 0; gdouble duration = 0; gboolean live; - GstFormat gst_time = GST_FORMAT_TIME; + GstFormat gst_time; + + g_object_get (G_OBJECT (gst->priv->stream), + "media-type", &media_type, + NULL); + + if ( media_type == PAROLE_MEDIA_TYPE_CDDA ) + parole_gst_query_cdda_tracks (gst); + + gst_time = GST_FORMAT_TIME; gst_element_query_duration (gst->priv->playbin, &gst_time, @@ -577,7 +614,9 @@ parole_gst_query_duration (ParoleGst *gst) { duration = absolute_duration / ((gdouble) 60 * 1000 * 1000 * 1000); live = ( absolute_duration == 0 ); + TRACE ("Duration %e is_live=%d", duration, live); + g_object_set (G_OBJECT (gst->priv->stream), "absolute-duration", absolute_duration, "duration", duration, @@ -817,7 +856,7 @@ static void parole_gst_evaluate_state (ParoleGst *gst, GstState old, GstState new, GstState pending) { TRACE ("State change new %i old %i pending %i", new, old, pending); - + gst->priv->state = new; parole_gst_tick (gst); @@ -828,10 +867,12 @@ parole_gst_evaluate_state (ParoleGst *gst, GstState old, GstState new, GstState switch (gst->priv->state) { case GST_STATE_PLAYING: + { gst->priv->media_state = PAROLE_MEDIA_STATE_PLAYING; g_signal_emit (G_OBJECT (gst), signals [MEDIA_STATE], 0, gst->priv->stream, PAROLE_MEDIA_STATE_PLAYING); break; + } case GST_STATE_PAUSED: if ( old == GST_STATE_READY ) { @@ -839,8 +880,11 @@ parole_gst_evaluate_state (ParoleGst *gst, GstState old, GstState new, GstState parole_gst_query_capabilities (gst); parole_gst_query_info (gst); } - if ( gst->priv->update_color_balance && gst->priv->target == GST_STATE_PLAYING ) - parole_gst_set_video_color_balance (gst); + if ( gst->priv->target == GST_STATE_PLAYING ) + { + if ( gst->priv->update_color_balance ) + parole_gst_set_video_color_balance (gst); + } gst->priv->media_state = PAROLE_MEDIA_STATE_PAUSED; g_signal_emit (G_OBJECT (gst), signals [MEDIA_STATE], 0, @@ -891,7 +935,25 @@ out: } static void -parole_gst_get_meta_data (ParoleGst *gst, GstTagList *tag) +parole_gst_get_meta_data_cdda (ParoleGst *gst, GstTagList *tag) +{ + guint num_tracks; + guint track; + + if (gst_tag_list_get_uint (tag, GST_TAG_TRACK_NUMBER, &track) && + gst_tag_list_get_uint (tag, GST_TAG_TRACK_COUNT, &num_tracks)) + { + g_object_set (G_OBJECT (gst->priv->stream), + "num-tracks", num_tracks, + "track", track, + NULL); + TRACE ("num_tracks=%i track=%i", num_tracks, track); + g_signal_emit (G_OBJECT (gst), signals [MEDIA_TAG], 0, gst->priv->stream); + } +} + +static void +parole_gst_get_meta_data_local_file (ParoleGst *gst, GstTagList *tag) { gchar *str; GDate *date; @@ -950,6 +1012,29 @@ parole_gst_get_meta_data (ParoleGst *gst, GstTagList *tag) NULL); g_signal_emit (G_OBJECT (gst), signals [MEDIA_TAG], 0, gst->priv->stream); + +} + +static void +parole_gst_get_meta_data (ParoleGst *gst, GstTagList *tag) +{ + ParoleMediaType media_type; + + g_object_get (G_OBJECT (gst->priv->stream), + "media-type", &media_type, + NULL); + + switch ( media_type ) + { + case PAROLE_MEDIA_TYPE_LOCAL_FILE: + parole_gst_get_meta_data_local_file (gst, tag); + break; + case PAROLE_MEDIA_TYPE_CDDA: + parole_gst_get_meta_data_cdda (gst, tag); + break; + default: + break; + } } static void @@ -984,11 +1069,36 @@ parole_gst_bus_event (GstBus *bus, GstMessage *msg, gpointer data) switch (GST_MESSAGE_TYPE (msg)) { case GST_MESSAGE_EOS: + { + ParoleMediaType media_type; + gint current_track; + TRACE ("End of stream"); + + g_object_get (G_OBJECT (gst->priv->stream), + "media-type", &media_type, + NULL); + if ( media_type == PAROLE_MEDIA_TYPE_CDDA ) + { + gint num_tracks; + g_object_get (G_OBJECT (gst->priv->stream), + "num-tracks", &num_tracks, + "track", ¤t_track, + NULL); + + TRACE ("------------------Current track %d Number of tracks %d", current_track, num_tracks); + if ( num_tracks != current_track ) + { + parole_gst_seek_cdda_track (gst, current_track); + break; + } + } + gst->priv->media_state = PAROLE_MEDIA_STATE_FINISHED; g_signal_emit (G_OBJECT (gst), signals [MEDIA_STATE], 0, gst->priv->stream, PAROLE_MEDIA_STATE_FINISHED); break; + } case GST_MESSAGE_ERROR: { GError *error = NULL; @@ -1286,27 +1396,70 @@ parole_gst_button_release_event (GtkWidget *widget, GdkEventButton *ev) return ret; } +static void parole_gst_seek_cdda_track (ParoleGst *gst, + gint track) +{ + TRACE ("Track %d", track); + + if ( !gst_element_seek (gst->priv->playbin, 1.0, gst_format_get_by_nick ("track"), + GST_SEEK_FLAG_FLUSH, GST_SEEK_TYPE_SET, + track, + GST_SEEK_TYPE_NONE, + 0) ) + g_warning ("Seek to track %d failed ", track); +} + static void -parole_gst_change_dvd_chapter (ParoleGst *gst, gint level) +parole_gst_seek_by_format (ParoleGst *gst, GstFormat format, gint step) { - GstFormat format; - gint64 val; + gint64 val = 1; - format = gst_format_get_by_nick ("chapter"); - - if ( format != GST_FORMAT_UNDEFINED ) + if ( gst_element_query_position (gst->priv->playbin, &format, &val) ) { - if ( gst_element_query_position (gst->priv->playbin, &format, &val) ) + val += step; + if ( !gst_element_seek (gst->priv->playbin, 1.0, format, + GST_SEEK_FLAG_FLUSH, GST_SEEK_TYPE_SET, + val, + GST_SEEK_TYPE_NONE, + 0) ) { - val += level; - gst_element_seek (gst->priv->playbin, 1.0, format, - GST_SEEK_FLAG_FLUSH, GST_SEEK_TYPE_SET, - val, - GST_SEEK_TYPE_NONE, - 0); + g_warning ("Seek failed : %s", gst_format_get_name (format)); } } + else + { + g_warning ("Failed to query element position: %s", gst_format_get_name (format)); + } +} + +static void +parole_gst_change_dvd_chapter (ParoleGst *gst, gint level) +{ + GstFormat format; + + // FIXME: Do we really need to get the nich each time? + format = gst_format_get_by_nick ("chapter"); + + parole_gst_seek_by_format (gst, format, level); +} + +static void +parole_gst_change_cdda_track (ParoleGst *gst, gint level) +{ + GstFormat format; + + format = gst_format_get_by_nick ("track"); + parole_gst_seek_by_format (gst, format, level); +} + +ParoleMediaType parole_gst_get_current_stream_type (ParoleGst *gst) +{ + ParoleMediaType type; + g_object_get (G_OBJECT (gst->priv->stream), + "media-type", &type, + NULL); + return type; } static void @@ -1560,7 +1713,6 @@ void parole_gst_terminate (ParoleGst *gst) } } } - parole_gst_change_state (gst, GST_STATE_NULL); } @@ -1643,6 +1795,33 @@ void parole_gst_prev_dvd_chapter (ParoleGst *gst) parole_gst_change_dvd_chapter (gst, -1); } +void parole_gst_next_cdda_track (ParoleGst *gst) +{ + parole_gst_change_cdda_track (gst, 1); +} + +void parole_gst_prev_cdda_track (ParoleGst *gst) +{ + parole_gst_change_cdda_track (gst, -1); +} + +gint parole_gst_get_current_cdda_track (ParoleGst *gst) +{ + GstFormat format; + gint64 pos; + gint ret_val = 1; + + format = gst_format_get_by_nick ("track"); + + if ( gst_element_query_position (gst->priv->playbin, &format, &pos) ) + { + TRACE ("Pos %lld", pos); + ret_val = (gint) pos; + } + + return ret_val; +} + gdouble parole_gst_get_stream_duration (ParoleGst *gst) { gdouble dur; diff --git a/parole/parole-gst.h b/parole/parole-gst.h index 67f572a39d2ffa0bb9010711bfcb00aac73bbf55..301f87922cfbc4579e7c656e5b5f40bd0a95c249 100644 --- a/parole/parole-gst.h +++ b/parole/parole-gst.h @@ -112,6 +112,14 @@ void parole_gst_next_dvd_chapter (ParoleGst *gst); void parole_gst_prev_dvd_chapter (ParoleGst *gst); +void parole_gst_next_cdda_track (ParoleGst *gst); + +void parole_gst_prev_cdda_track (ParoleGst *gst); + +gint parole_gst_get_current_cdda_track (ParoleGst *gst); + +ParoleMediaType parole_gst_get_current_stream_type (ParoleGst *gst); + gdouble parole_gst_get_stream_duration (ParoleGst *gst); gdouble parole_gst_get_stream_position (ParoleGst *gst); diff --git a/parole/parole-mediachooser.c b/parole/parole-mediachooser.c index 7d88f39fa306e19df1994b07f346f248b419555b..52aeaa012e4844b300635ee63946776838b38820 100644 --- a/parole/parole-mediachooser.c +++ b/parole/parole-mediachooser.c @@ -53,6 +53,9 @@ void parole_media_chooser_close (GtkWidget *widget, void media_chooser_folder_changed_cb (GtkWidget *widget, gpointer data); +void media_chooser_file_activate_cb (GtkFileChooser *filechooser, + ParoleMediaChooser *chooser); + enum { MEDIA_FILES_OPENED, @@ -123,6 +126,11 @@ parole_media_chooser_open (GtkWidget *widget, ParoleMediaChooser *chooser) gtk_widget_destroy (GTK_WIDGET (chooser)); } +void media_chooser_file_activate_cb (GtkFileChooser *filechooser, ParoleMediaChooser *chooser) +{ + parole_media_chooser_open (NULL, chooser); +} + static void parole_media_chooser_open_internal (GtkWidget *chooser) { diff --git a/parole/parole-player.c b/parole/parole-player.c index 00012b3881a744015eb518a6c563eecc15a498e5..d94e0f186b8f675508891a70e4aaa0c0b56c7b78 100644 --- a/parole/parole-player.c +++ b/parole/parole-player.c @@ -173,6 +173,8 @@ struct ParolePlayerPrivate ParoleConf *conf; ParoleDiscMenu *disc_menu; ParoleSession *session; + + GtkRecentManager *recent; GtkWidget *gst; @@ -295,11 +297,14 @@ void parole_player_show_hide_playlist (GtkButton *button, ParolePlayer *player) static void parole_player_change_range_value (ParolePlayer *player, gdouble value) { - player->priv->internal_range_change = TRUE; + if ( !player->priv->user_seeking ) + { + player->priv->internal_range_change = TRUE; - gtk_range_set_value (GTK_RANGE (player->priv->range), value); + gtk_range_set_value (GTK_RANGE (player->priv->range), value); - player->priv->internal_range_change = FALSE; + player->priv->internal_range_change = FALSE; + } } static void @@ -417,19 +422,23 @@ parole_player_save_uri (ParolePlayer *player, const ParoleStream *stream) gboolean save = TRUE; gchar **lines = NULL; guint i; + + g_object_get (G_OBJECT (stream), + "uri", &uri, + NULL); g_object_get (G_OBJECT (stream), "media-type", &media_type, NULL); if ( media_type == PAROLE_MEDIA_TYPE_LOCAL_FILE ) - return; + { + gtk_recent_manager_add_item (player->priv->recent, uri); + goto out; + } lines = parole_get_history (); - g_object_get (G_OBJECT (stream), - "uri", &uri, - NULL); if (lines ) { for ( i = 0; lines[i]; i++) @@ -448,6 +457,7 @@ parole_player_save_uri (ParolePlayer *player, const ParoleStream *stream) } g_strfreev (lines); +out: g_free (uri); } @@ -480,9 +490,11 @@ parole_player_playing (ParolePlayer *player, const ParoleStream *stream) if ( seekable ) { + player->priv->internal_range_change = TRUE; gtk_range_set_range (GTK_RANGE (player->priv->range), 0, duration); gtk_widget_set_sensitive (player->priv->seekf, TRUE); gtk_widget_set_sensitive (player->priv->seekb, TRUE); + player->priv->internal_range_change = FALSE; } else { @@ -747,6 +759,7 @@ parole_player_range_value_changed (GtkRange *range, ParolePlayer *player) { value = gtk_range_get_value (GTK_RANGE (range)); player->priv->user_seeking = TRUE; + TRACE ("Sending a seek request with value :%e", value); parole_gst_seek (PAROLE_GST (player->priv->gst), value); player->priv->user_seeking = FALSE; } @@ -825,13 +838,13 @@ parole_player_stop_menu_item_activate (ParolePlayer *player) static void parole_player_next_menu_item_activate (ParolePlayer *player) { - parole_gst_next_dvd_chapter (PAROLE_GST (player->priv->gst)); + parole_disc_menu_seek_next (player->priv->disc_menu); } static void parole_player_previous_menu_item_activate (ParolePlayer *player) { - parole_gst_prev_dvd_chapter (PAROLE_GST (player->priv->gst)); + parole_disc_menu_seek_prev (player->priv->disc_menu); } static void @@ -915,9 +928,12 @@ parole_player_show_menu (ParolePlayer *player, guint button, guint activate_time GtkWidget *menu, *mi, *img; gboolean sensitive; gboolean dvd_menu; + ParoleMediaType media_type; dvd_menu = parole_disc_menu_visible (player->priv->disc_menu); + media_type = parole_gst_get_current_stream_type (PAROLE_GST (player->priv->gst)); + menu = gtk_menu_new (); /*Play menu item @@ -936,7 +952,8 @@ parole_player_show_menu (ParolePlayer *player, guint button, guint activate_time G_CALLBACK (parole_player_play_menu_item_activate), player); gtk_menu_shell_append (GTK_MENU_SHELL (menu), mi); - /*Seek Forward. + /* + * Seek Forward. */ mi = gtk_image_menu_item_new_from_stock (GTK_STOCK_MEDIA_FORWARD, NULL); @@ -946,7 +963,8 @@ parole_player_show_menu (ParolePlayer *player, guint button, guint activate_time G_CALLBACK (parole_player_seekf_cb), player); gtk_menu_shell_append (GTK_MENU_SHELL (menu), mi); - /*Seek backward. + /* + * Seek backward. */ mi = gtk_image_menu_item_new_from_stock (GTK_STOCK_MEDIA_REWIND, NULL); @@ -956,7 +974,8 @@ parole_player_show_menu (ParolePlayer *player, guint button, guint activate_time G_CALLBACK (parole_player_seekb_cb), player); gtk_menu_shell_append (GTK_MENU_SHELL (menu), mi); - /*Stop menu item + /* + * Stop menu item */ mi = gtk_image_menu_item_new_from_stock (GTK_STOCK_MEDIA_STOP, NULL); @@ -966,9 +985,10 @@ parole_player_show_menu (ParolePlayer *player, guint button, guint activate_time G_CALLBACK (parole_player_stop_menu_item_activate), player); gtk_menu_shell_append (GTK_MENU_SHELL (menu), mi); - /*Next chapter menu item + /* + * Next chapter menu item */ - mi = gtk_image_menu_item_new_with_label (_("Next Chapter")); + mi = gtk_image_menu_item_new_with_label (media_type == PAROLE_MEDIA_TYPE_CDDA ? _("Next Track") : _("Next Chapter")); img = gtk_image_new_from_stock (GTK_STOCK_MEDIA_NEXT, GTK_ICON_SIZE_MENU); gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (mi),img); gtk_widget_set_sensitive (mi, (player->priv->state == PAROLE_MEDIA_STATE_PLAYING) && dvd_menu); @@ -977,9 +997,10 @@ parole_player_show_menu (ParolePlayer *player, guint button, guint activate_time G_CALLBACK (parole_player_next_menu_item_activate), player); gtk_menu_shell_append (GTK_MENU_SHELL (menu), mi); - /*Previous chapter menu item + /* + * Previous chapter menu item */ - mi = gtk_image_menu_item_new_with_label (_("Previous Chapter")); + mi = gtk_image_menu_item_new_with_label (media_type == PAROLE_MEDIA_TYPE_CDDA ? _("Previous Track") : _("Previous Chapter")); img = gtk_image_new_from_stock (GTK_STOCK_MEDIA_PREVIOUS, GTK_ICON_SIZE_MENU); gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (mi), img); @@ -1303,6 +1324,21 @@ parole_gst_set_default_aspect_ratio (ParolePlayer *player, GtkBuilder *builder) TRUE); } +static void +parole_player_set_sound_menu_items_image (GtkBuilder *builder) +{ + GtkWidget *img; + + img = gtk_image_new_from_icon_name ("audio-volume-muted", GTK_ICON_SIZE_MENU); + gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (gtk_builder_get_object (builder, "volume-mute-menu")), img); + + img = gtk_image_new_from_icon_name ("audio-volume-high", GTK_ICON_SIZE_MENU); + gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (gtk_builder_get_object (builder, "volume-up-menu")), img); + + img = gtk_image_new_from_icon_name ("audio-volume-low", GTK_ICON_SIZE_MENU); + gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (gtk_builder_get_object (builder, "volume-down-menu")), img); +} + gboolean parole_player_configure_event_cb (GtkWidget *widget, GdkEventConfigure *ev, ParolePlayer *player) { @@ -1365,6 +1401,9 @@ parole_player_init (ParolePlayer *player) player->priv->buffering = FALSE; player->priv->row = NULL; + player->priv->recent = gtk_recent_manager_get_default (); + + parole_player_set_sound_menu_items_image (builder); /* * Gst signals */ @@ -1492,3 +1531,8 @@ void parole_player_play_uri_disc (ParolePlayer *player, const gchar *uri) { parole_player_disc_selected_cb (NULL, uri, player); } + +void parole_player_terminate (ParolePlayer *player) +{ + parole_player_delete_event_cb (NULL, NULL, player); +} diff --git a/parole/parole-player.h b/parole/parole-player.h index e182358beca8db849b85a61993ad2ad52c5106dc..fbbed42ed4594b6361194b35794c06e8b9a35f6d 100644 --- a/parole/parole-player.h +++ b/parole/parole-player.h @@ -53,6 +53,8 @@ ParoleMediaList *parole_player_get_media_list (ParolePlayer *player); void parole_player_play_uri_disc (ParolePlayer *player, const gchar *uri); +void parole_player_terminate (ParolePlayer *player); + G_END_DECLS #endif /* __PAROLE_PLAYER_H */ diff --git a/parole/parole-rc-utils.c b/parole/parole-rc-utils.c index 5f6e353fc41f5b01f38fcd5f42fa5b6f17282075..d965fe7c0aa2eb36eaa17ecde97d18afe920c80e 100644 --- a/parole/parole-rc-utils.c +++ b/parole/parole-rc-utils.c @@ -28,19 +28,15 @@ #include -#include - #include "parole-rc-utils.h" -#define MEDIA_PLAYER_RESOURCE_FILE "xfce4/parole/parole-media-player.rc" -#define HISTORY_FILE "xfce4/parole/history" - -static XfceRc * -open_resource_file (const gchar *group, gboolean readonly) +XfceRc * +parole_get_resource_file (const gchar *group, gboolean readonly) { gchar *file; XfceRc *rc; - file = xfce_resource_save_location (XFCE_RESOURCE_CONFIG, MEDIA_PLAYER_RESOURCE_FILE, TRUE); + + file = xfce_resource_save_location (XFCE_RESOURCE_CONFIG, PAROLE_RESOURCE_FILE, TRUE); rc = xfce_rc_simple_open (file, readonly); if (rc) @@ -53,7 +49,7 @@ open_resource_file (const gchar *group, gboolean readonly) void parole_rc_write_entry_bool (const gchar *property, const gchar *group, gboolean value) { - XfceRc *rc = open_resource_file (group, FALSE); + XfceRc *rc = parole_get_resource_file (group, FALSE); xfce_rc_write_bool_entry (rc, property, value); xfce_rc_close (rc); @@ -61,7 +57,7 @@ void parole_rc_write_entry_bool (const gchar *property, const gchar *group, gboo void parole_rc_write_entry_int (const gchar *property, const gchar *group, gint value) { - XfceRc *rc = open_resource_file (group, FALSE); + XfceRc *rc = parole_get_resource_file (group, FALSE); xfce_rc_write_int_entry (rc, property, value); xfce_rc_close (rc); @@ -69,7 +65,7 @@ void parole_rc_write_entry_int (const gchar *property, const gchar *group, gint void parole_rc_write_entry_string (const gchar *property, const gchar *group, const gchar *value) { - XfceRc *rc = open_resource_file (group, FALSE); + XfceRc *rc = parole_get_resource_file (group, FALSE); xfce_rc_write_entry (rc, property, value); xfce_rc_close (rc); @@ -77,7 +73,7 @@ void parole_rc_write_entry_string (const gchar *property, const gchar *group, co void parole_rc_write_entry_list (const gchar *property, const gchar *group, gchar **value) { - XfceRc *rc = open_resource_file (group, FALSE); + XfceRc *rc = parole_get_resource_file (group, FALSE); xfce_rc_write_list_entry (rc, property, value, ";"); xfce_rc_close (rc); @@ -85,7 +81,7 @@ void parole_rc_write_entry_list (const gchar *property, const gchar *group, gcha gboolean parole_rc_read_entry_bool (const gchar *property, const gchar *group, gboolean fallback) { - XfceRc *rc = open_resource_file (group, TRUE); + XfceRc *rc = parole_get_resource_file (group, TRUE); gboolean ret_val = fallback; if ( rc ) @@ -99,7 +95,7 @@ gboolean parole_rc_read_entry_bool (const gchar *property, const gchar *group, g gint parole_rc_read_entry_int (const gchar *property, const gchar *group, gint fallback) { - XfceRc *rc = open_resource_file (group, TRUE); + XfceRc *rc = parole_get_resource_file (group, TRUE); gint ret_val = fallback; if ( rc ) @@ -114,7 +110,7 @@ gint parole_rc_read_entry_int (const gchar *property, const gchar *group, gint f const gchar *parole_rc_read_entry_string (const gchar *property, const gchar *group, const gchar *fallback) { const gchar *ret_val = fallback; - XfceRc *rc = open_resource_file (group, TRUE); + XfceRc *rc = parole_get_resource_file (group, TRUE); if ( rc ) { @@ -128,7 +124,7 @@ const gchar *parole_rc_read_entry_string (const gchar *property, const gchar *gr gchar **parole_rc_read_entry_list (const gchar *property, const gchar *group) { gchar **ret_val = NULL; - XfceRc *rc = open_resource_file (group, TRUE); + XfceRc *rc = parole_get_resource_file (group, TRUE); if ( rc ) { @@ -146,7 +142,7 @@ gchar **parole_get_history (void) gchar *contents = NULL; gsize length = 0; - history = xfce_resource_lookup (XFCE_RESOURCE_CACHE, HISTORY_FILE); + history = xfce_resource_lookup (XFCE_RESOURCE_CACHE, PAROLE_HISTORY_FILE); if (history && g_file_get_contents (history, &contents, &length, NULL)) { @@ -163,7 +159,7 @@ void parole_insert_line_history (const gchar *line) { gchar *history = NULL; - history = xfce_resource_save_location (XFCE_RESOURCE_CACHE, HISTORY_FILE, TRUE); + history = xfce_resource_save_location (XFCE_RESOURCE_CACHE, PAROLE_HISTORY_FILE, TRUE); if ( history ) { diff --git a/parole/parole-rc-utils.h b/parole/parole-rc-utils.h index 4ac7314dcd5d74f1a20415ecfad0062bfff9c775..e7b9440705db48f0a558ef539e9c38527430f875 100644 --- a/parole/parole-rc-utils.h +++ b/parole/parole-rc-utils.h @@ -21,9 +21,17 @@ #ifndef __RC_UTILS_ #define __RC_UTILS_ +#include + +#define PAROLE_RESOURCE_FILE "xfce4/parole/parole-media-player.rc" +#define PAROLE_HISTORY_FILE "xfce4/parole/history" + #define PAROLE_RC_GROUP_GENERAL "General" #define PAROLE_RC_GROUP_PLUGINS "Plugins" +XfceRc *parole_get_resource_file (const gchar *group, + gboolean readonly); + void parole_rc_write_entry_bool (const gchar *property, const gchar *group, gboolean value); diff --git a/parole/parole-stream.c b/parole/parole-stream.c index 262d8e2355c3550be59a27280ae58d3a90e3ec7a..8cae8287b9d412cfdd3f12acf24d851bc31fb7a0 100644 --- a/parole/parole-stream.c +++ b/parole/parole-stream.c @@ -59,7 +59,8 @@ struct _ParoleStreamPrivate gint video_w; gint video_h; gint64 absolute_duration; - + guint tracks; + guint track; gchar *title; gchar *artist; gchar *year; @@ -78,6 +79,8 @@ enum PROP_HAS_AUDIO, PROP_HAS_VIDEO, PROP_SEEKABLE, + PROP_TRACKS, + PROP_TRACK, PROP_TAG_AVAILABLE, PROP_DURATION, PROP_ABSOLUTE_DURATION, @@ -109,6 +112,8 @@ parole_stream_get_media_type_from_uri (ParoleStream *stream, const gchar *uri) type = PAROLE_MEDIA_TYPE_SVCD; else if ( g_str_has_prefix (uri, "cdda:/") ) type = PAROLE_MEDIA_TYPE_CDDA; + else if ( g_str_has_prefix (uri, "dvb:/") ) + type = PAROLE_MEDIA_TYPE_DVB; else type = PAROLE_MEDIA_TYPE_UNKNOWN; @@ -151,6 +156,12 @@ static void parole_stream_set_property (GObject *object, case PROP_SEEKABLE: PAROLE_STREAM_GET_PRIVATE (stream)->seekable = g_value_get_boolean (value); break; + case PROP_TRACKS: + PAROLE_STREAM_GET_PRIVATE (stream)->tracks = g_value_get_uint (value); + break; + case PROP_TRACK: + PAROLE_STREAM_GET_PRIVATE (stream)->track = g_value_get_uint (value); + break; case PROP_TAG_AVAILABLE: PAROLE_STREAM_GET_PRIVATE (stream)->tag_available = g_value_get_boolean (value); break; @@ -218,6 +229,12 @@ static void parole_stream_get_property (GObject *object, case PROP_DURATION: g_value_set_double (value, PAROLE_STREAM_GET_PRIVATE (stream)->duration); break; + case PROP_TRACKS: + g_value_set_uint (value, PAROLE_STREAM_GET_PRIVATE (stream)->tracks); + break; + case PROP_TRACK: + g_value_set_uint (value, PAROLE_STREAM_GET_PRIVATE (stream)->track); + break; case PROP_TAG_AVAILABLE: g_value_set_double (value, PAROLE_STREAM_GET_PRIVATE (stream)->tag_available); break; @@ -431,7 +448,36 @@ parole_stream_class_init (ParoleStreamClass *klass) 0, G_MAXINT, 0, G_PARAM_READWRITE)); + + /** + * ParoleStream:num-tracks: + * + * Number of tracks in the cdda source, only valid if + * ParoleStream:media-type: is PAROLE_MEDIA_TYPE_CDDA. + * + * Since: 0.1 + **/ + g_object_class_install_property (object_class, + PROP_TRACKS, + g_param_spec_uint ("num-tracks", + NULL, NULL, + 1, 99, + 1, + G_PARAM_READWRITE)); + /** + * ParoleStream:track: + * + * + * Since: 0.1 + **/ + g_object_class_install_property (object_class, + PROP_TRACK, + g_param_spec_uint ("track", + NULL, NULL, + 1, 99, + 1, + G_PARAM_READWRITE)); /** * ParoleStream:title: * @@ -536,6 +582,8 @@ void parole_stream_init_properties (ParoleStream *stream) priv->media_type = PAROLE_MEDIA_TYPE_UNKNOWN; priv->video_h = 0; priv->video_w = 0; + priv->tracks = 1; + priv->track = 1; PAROLE_STREAM_FREE_STR_PROP (priv->title); PAROLE_STREAM_FREE_STR_PROP (priv->uri); diff --git a/parole/parole-stream.h b/parole/parole-stream.h index a4fbbfd2c46707680c431a2df8cefa5b5d0b48cc..902656373085dc3a7a532d143fb025e80871e20f 100644 --- a/parole/parole-stream.h +++ b/parole/parole-stream.h @@ -37,6 +37,7 @@ typedef enum PAROLE_MEDIA_TYPE_VCD, PAROLE_MEDIA_TYPE_SVCD, PAROLE_MEDIA_TYPE_DVD, + PAROLE_MEDIA_TYPE_DVB, PAROLE_MEDIA_TYPE_REMOTE } ParoleMediaType; diff --git a/parole/parole-utils.c b/parole/parole-utils.c index 2bc6a3b921356b99c44bbe805f61ab7b85d67d5a..751e0856eb03203864e7e18840cf1f085ec5c6af 100644 --- a/parole/parole-utils.c +++ b/parole/parole-utils.c @@ -350,8 +350,8 @@ gchar *parole_get_subtitle_path (const gchar *uri) gboolean parole_is_uri_disc (const gchar *uri) { - if ( !g_strcmp0 (uri, "dvd:/") || !g_strcmp0 (uri, "vcd:/") - || !g_strcmp0 (uri, "svcd:/") || !g_strcmp0 (uri, "cdda:/")) + if ( g_str_has_prefix (uri, "dvd:/") || g_str_has_prefix (uri, "vcd:/") + || g_str_has_prefix (uri, "svcd:/") || g_str_has_prefix (uri, "cdda:/")) return TRUE; else return FALSE; diff --git a/po/parole-media-player.pot b/po/parole-media-player.pot index b37a701d4b2fe8b08368a284222549acb9e191bf..8c0af1e09df5c0e9b4a3583d9863d3c04acaf34f 100644 --- a/po/parole-media-player.pot +++ b/po/parole-media-player.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2009-07-27 18:02+0200\n" +"POT-Creation-Date: 2009-07-31 23:30+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -17,29 +17,106 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" #: ../data/interfaces/parole.ui.h:1 -msgid "Media player" +msgid "16:9 (Widescreen)" msgstr "" #: ../data/interfaces/parole.ui.h:2 -msgid "Plugins" +msgid "20:9 (DVB)" msgstr "" #: ../data/interfaces/parole.ui.h:3 -msgid "_Edit" +msgid "4:3 (TV)" msgstr "" #: ../data/interfaces/parole.ui.h:4 -msgid "_Help" +msgid "Aspect Ratio" msgstr "" #: ../data/interfaces/parole.ui.h:5 -msgid "_Media" +msgid "Auto" msgstr "" #: ../data/interfaces/parole.ui.h:6 +msgid "Chapter Menu" +msgstr "" + +#: ../data/interfaces/parole.ui.h:7 +msgid "DVD Menu" +msgstr "" + +#: ../data/interfaces/parole.ui.h:8 +msgid "Media player" +msgstr "" + +#: ../data/interfaces/parole.ui.h:9 +msgid "Mute" +msgstr "" + +#: ../data/interfaces/parole.ui.h:10 ../parole/parole-player.c:991 +msgid "Next Chapter" +msgstr "" + +#: ../data/interfaces/parole.ui.h:11 +msgid "None" +msgstr "" + +#: ../data/interfaces/parole.ui.h:12 ../data/desktop/parole.desktop.in.in.h:1 +#: ../parole/parole-player.c:220 +msgid "Parole Media Player" +msgstr "" + +#: ../data/interfaces/parole.ui.h:13 +msgid "Plugins" +msgstr "" + +#: ../data/interfaces/parole.ui.h:14 ../parole/parole-player.c:1003 +msgid "Previous Chapter" +msgstr "" + +#: ../data/interfaces/parole.ui.h:15 +msgid "Repeat" +msgstr "" + +#: ../data/interfaces/parole.ui.h:16 +msgid "Shuffle" +msgstr "" + +#: ../data/interfaces/parole.ui.h:17 +msgid "Sound" +msgstr "" + +#: ../data/interfaces/parole.ui.h:18 +msgid "Square" +msgstr "" + +#: ../data/interfaces/parole.ui.h:19 +msgid "Volume Down" +msgstr "" + +#: ../data/interfaces/parole.ui.h:20 +msgid "Volume Up" +msgstr "" + +#: ../data/interfaces/parole.ui.h:21 +msgid "_Edit" +msgstr "" + +#: ../data/interfaces/parole.ui.h:22 +msgid "_Help" +msgstr "" + +#: ../data/interfaces/parole.ui.h:23 +msgid "_Media" +msgstr "" + +#: ../data/interfaces/parole.ui.h:24 msgid "_View" msgstr "" +#: ../data/interfaces/parole.ui.h:25 +msgid "gtk-leave-fullscreen" +msgstr "" + #: ../data/interfaces/plugins.ui.h:1 msgid "Author:" msgstr "" @@ -85,7 +162,7 @@ msgid "Subtitles" msgstr "" #: ../data/interfaces/parole-settings.ui.h:4 -msgid "Automatically load subtitle when playing movie file" +msgid "Automatically load subtitles when playing movie file" msgstr "" #: ../data/interfaces/parole-settings.ui.h:5 @@ -93,25 +170,23 @@ msgid "Brightness:" msgstr "" #: ../data/interfaces/parole-settings.ui.h:6 -msgid "" -"Changing this will take effect after parole is restarted or a new media file " -"is loaded." +msgid "Contrast:" msgstr "" #: ../data/interfaces/parole-settings.ui.h:7 -msgid "Contrast:" +msgid "Enable visualization when playing audio file" msgstr "" #: ../data/interfaces/parole-settings.ui.h:8 -msgid "Enable visualization when playing audio file" +msgid "Encoding: " msgstr "" #: ../data/interfaces/parole-settings.ui.h:9 -msgid "Encoding: " +msgid "Font:" msgstr "" #: ../data/interfaces/parole-settings.ui.h:10 -msgid "Font:" +msgid "Hue:" msgstr "" #: ../data/interfaces/parole-settings.ui.h:11 @@ -123,6 +198,14 @@ msgid "Parole Settings" msgstr "" #: ../data/interfaces/parole-settings.ui.h:13 +msgid "Reset To Defaults" +msgstr "" + +#: ../data/interfaces/parole-settings.ui.h:14 +msgid "Saturation:" +msgstr "" + +#: ../data/interfaces/parole-settings.ui.h:15 msgid "Visualization type:" msgstr "" @@ -134,116 +217,134 @@ msgstr "" msgid "Select File Types (By Extension)" msgstr "" -#: ../data/desktop/parole.desktop.in.in.h:1 ../parole/parole-player.c:154 -msgid "Parole Media Player" +#: ../parole/main.c:52 +#, c-format +msgid "" +"\n" +"Parole Media Player %s\n" +"\n" +"Part of the Xfce Goodies Project\n" +"http://goodies.xfce.org\n" +"\n" +"Licensed under the GNU GPL.\n" +"\n" msgstr "" -#: ../parole/main.c:135 +#: ../parole/main.c:156 msgid "Open a new instance" msgstr "" -#: ../parole/main.c:136 +#: ../parole/main.c:157 +msgid "Version information" +msgstr "" + +#: ../parole/main.c:158 msgid "Media to play" msgstr "" -#: ../parole/main.c:152 +#: ../parole/main.c:172 #, c-format msgid "Type '%s --help' for usage." msgstr "" -#: ../parole/parole-gst.c:806 -msgid "Error in changing state to ready" -msgstr "" - -#: ../parole/parole-gst.c:855 +#: ../parole/parole-gst.c:1271 msgid "" "Unable to load playbin GStreamer plugin, check your GStreamer installation" msgstr "" -#: ../parole/parole-gst.c:870 +#: ../parole/parole-gst.c:1287 msgid "" "Unable to load video GStreamer plugin, check your GStreamer installation" msgstr "" -#: ../parole/parole-mediachooser.c:171 +#: ../parole/parole-mediachooser.c:154 msgid "Add media files" msgstr "" -#: ../parole/parole-mediachooser.c:190 +#: ../parole/parole-mediachooser.c:173 msgid "Add" msgstr "" -#: ../parole/parole-mediachooser.c:210 -msgid "Open location..." -msgstr "" - -#: ../parole/parole-mediachooser.c:212 -msgid "Open location of media file or live stream" -msgstr "" - -#: ../parole/parole-medialist.c:380 +#: ../parole/parole-medialist.c:381 msgid "Error saving playlist file" msgstr "" -#: ../parole/parole-medialist.c:380 +#: ../parole/parole-medialist.c:381 msgid "Permission denied" msgstr "" -#: ../parole/parole-medialist.c:389 +#: ../parole/parole-medialist.c:390 msgid "Unknown playlist format, Please select a support playlist format" msgstr "" -#: ../parole/parole-medialist.c:455 ../parole/parole-player.c:963 +#: ../parole/parole-medialist.c:456 ../parole/parole-player.c:1461 msgid "Playlist" msgstr "" -#: ../parole/parole-medialist.c:462 +#: ../parole/parole-medialist.c:463 msgid "M3U Playlists" msgstr "" -#: ../parole/parole-medialist.c:470 +#: ../parole/parole-medialist.c:471 msgid "PLS Playlists" msgstr "" -#: ../parole/parole-medialist.c:478 +#: ../parole/parole-medialist.c:479 msgid "Advanced Stream Redirector" msgstr "" -#: ../parole/parole-medialist.c:486 +#: ../parole/parole-medialist.c:487 msgid "Shareable Playlist" msgstr "" -#: ../parole/parole-medialist.c:760 +#: ../parole/parole-medialist.c:788 msgid "Media list" msgstr "" -#: ../parole/parole-player.c:175 +#: ../parole/parole-player.c:283 msgid "Hide playlist" msgstr "" -#: ../parole/parole-player.c:184 +#: ../parole/parole-player.c:292 msgid "Show playlist" msgstr "" -#: ../parole/parole-player.c:338 ../parole/parole-statusbar.c:125 -#: ../parole/parole-statusbar.c:127 -msgid "Playing" +#: ../parole/parole-player.c:501 +msgid "Media stream is not seekable" +msgstr "" + +#. +#. * Next chapter menu item +#. +#: ../parole/parole-player.c:991 +msgid "Next Track" msgstr "" -#: ../parole/parole-player.c:339 -msgid "Media stream is not seekable" +#. +#. * Previous chapter menu item +#. +#: ../parole/parole-player.c:1003 +msgid "Previous Track" msgstr "" -#: ../parole/parole-player.c:357 ../parole/parole-player.c:370 -msgid "Paused" +#: ../parole/parole-statusbar.c:59 +msgid "Buffering" msgstr "" -#: ../parole/parole-player.c:388 +#: ../parole/parole-statusbar.c:76 msgid "Stopped" msgstr "" -#: ../parole/parole-statusbar.c:137 -msgid "Buffering" +#: ../parole/parole-statusbar.c:80 +msgid "Finished" +msgstr "" + +#: ../parole/parole-statusbar.c:87 ../parole/parole-statusbar.c:95 +msgid "Paused" +msgstr "" + +#: ../parole/parole-statusbar.c:116 +msgid "Live stream:" msgstr "" #: ../parole/parole-filters.c:57 @@ -270,7 +371,7 @@ msgstr "" msgid "translator-credits" msgstr "" -#: ../parole/parole-disc.c:131 +#: ../parole/parole-disc.c:168 msgid "Play Disc" msgstr "" @@ -441,6 +542,14 @@ msgstr "" msgid "Vietnamese" msgstr "" +#: ../parole/parole-open-location.c:171 +msgid "Open location..." +msgstr "" + +#: ../parole/parole-open-location.c:173 +msgid "Open location of media file or live stream" +msgstr "" + #: ../plugins/properties/stream-properties.c:44 #: ../plugins/properties/stream-properties.c:45 #: ../plugins/properties/stream-properties.c:46 @@ -479,28 +588,28 @@ msgstr "" msgid "Read media properties" msgstr "" -#: ../plugins/tray/tray-icon.c:203 +#: ../plugins/tray/tray-icon.c:222 msgid "Playing:" msgstr "" -#: ../plugins/tray/tray-icon.c:203 +#: ../plugins/tray/tray-icon.c:222 msgid "Duration:" msgstr "" -#: ../plugins/tray/tray-icon.c:328 +#: ../plugins/tray/tray-icon.c:347 msgid "Tray icon plugin" msgstr "" -#: ../plugins/tray/tray-icon.c:337 +#: ../plugins/tray/tray-icon.c:356 msgid "Enable notification" msgstr "" #. Construct function -#: ../plugins/tray/tray-icon.c:408 +#: ../plugins/tray/tray-icon.c:427 msgid "Tray icon" msgstr "" #. Title -#: ../plugins/tray/tray-icon.c:409 +#: ../plugins/tray/tray-icon.c:428 msgid "Show icon in the system tray" msgstr ""