Commit 9e6246e9 authored by Ali Abdallah's avatar Ali Abdallah

* main.c show gtk and gst command line options.

	* parole-medialist.c, allow multiple selection, so handle list up 
	and down+remove when multiple rows are selected.
	* Show a button for fast tracks selection when playing cdda.

(Old svn revision: 7906)
parent 8e2554a6
2009-08-11: aliov@xfce.org
* main.c show gtk and gst command line options.
* parole-medialist.c, allow multiple selection, so handle list up
and down+remove when multiple rows are selected.
* Show a button for fast tracks selection when playing cdda.
2009-08-06: 14:30 Ali aliov@xfce.org
* parole-gst.c Implement a timeout handler to check state change
failure, can potentially happen on live streams.
......
......@@ -325,73 +325,100 @@
<property name="orientation">vertical</property>
<property name="spacing">5</property>
<child>
<object class="GtkHBox" id="dvd-box">
<property name="visible">True</property>
<child>
<object class="GtkButton" id="prev-chapter">
<property name="label" translatable="yes">Previous Chapter</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="no_show_all">True</property>
<property name="image">image1</property>
</object>
<packing>
<property name="expand">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkButton" id="dvd-menu">
<property name="label" translatable="yes">DVD Menu</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="no_show_all">True</property>
<property name="image">image2</property>
</object>
<packing>
<property name="expand">False</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkButton" id="chapter-menu">
<property name="label" translatable="yes">Chapter Menu</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="no_show_all">True</property>
<property name="image">image3</property>
</object>
<packing>
<property name="expand">False</property>
<property name="position">2</property>
</packing>
</child>
<object class="GtkEventBox" id="disc-box">
<property name="no_show_all">True</property>
<child>
<object class="GtkButton" id="next-chapter">
<property name="label" translatable="yes">Next Chapter</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="no_show_all">True</property>
<property name="image">image4</property>
</object>
<packing>
<property name="expand">False</property>
<property name="position">3</property>
</packing>
</child>
<child>
<object class="GtkEventBox" id="eventboxinfo">
<property name="no_show_all">True</property>
<object class="GtkHBox" id="disc-menu-box">
<property name="visible">True</property>
<property name="spacing">5</property>
<child>
<object class="GtkButton" id="prev-chapter">
<property name="label" translatable="yes">Previous Chapter</property>
<property name="can_focus">False</property>
<property name="receives_default">False</property>
<property name="no_show_all">True</property>
<property name="image">image1</property>
<property name="relief">none</property>
</object>
<packing>
<property name="expand">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="info">
<object class="GtkButton" id="dvd-menu">
<property name="label" translatable="yes">DVD Menu</property>
<property name="can_focus">False</property>
<property name="receives_default">False</property>
<property name="no_show_all">True</property>
<property name="use_markup">True</property>
<property name="image">image2</property>
<property name="relief">none</property>
</object>
<packing>
<property name="expand">False</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkButton" id="chapter-menu">
<property name="label" translatable="yes">Chapter Menu</property>
<property name="can_focus">False</property>
<property name="receives_default">False</property>
<property name="no_show_all">True</property>
<property name="image">image3</property>
<property name="relief">none</property>
</object>
<packing>
<property name="expand">False</property>
<property name="position">2</property>
</packing>
</child>
<child>
<object class="GtkEventBox" id="eventboxinfo">
<property name="no_show_all">True</property>
<child>
<object class="GtkLabel" id="info">
<property name="no_show_all">True</property>
<property name="use_markup">True</property>
</object>
</child>
</object>
<packing>
<property name="position">3</property>
</packing>
</child>
<child>
<placeholder/>
</child>
<child>
<object class="GtkButton" id="select-track">
<property name="label" translatable="yes">Select Track</property>
<property name="can_focus">False</property>
<property name="receives_default">False</property>
<property name="no_show_all">True</property>
<property name="image">image13</property>
<property name="relief">none</property>
</object>
<packing>
<property name="expand">False</property>
<property name="position">5</property>
</packing>
</child>
<child>
<object class="GtkButton" id="next-chapter">
<property name="label" translatable="yes">Next Chapter</property>
<property name="can_focus">False</property>
<property name="receives_default">False</property>
<property name="no_show_all">True</property>
<property name="image">image4</property>
<property name="relief">none</property>
</object>
<packing>
<property name="expand">False</property>
<property name="position">6</property>
</packing>
</child>
</object>
<packing>
<property name="position">4</property>
</packing>
</child>
</object>
<packing>
......@@ -448,11 +475,10 @@
<property name="visible">True</property>
<property name="sensitive">False</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="receives_default">False</property>
<property name="image">image7</property>
<property name="relief">none</property>
<property name="focus_on_click">False</property>
<accelerator key="s" signal="clicked"/>
<signal name="clicked" handler="parole_player_stop_clicked"/>
</object>
<packing>
......@@ -545,6 +571,7 @@
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="no_show_all">True</property>
<property name="relief">none</property>
<property name="use_stock">True</property>
<signal name="clicked" handler="parole_player_leave_fs_cb"/>
</object>
......@@ -681,22 +708,21 @@
<property name="visible">True</property>
<property name="stock">gtk-network</property>
</object>
<object class="GtkImage" id="image1">
<object class="GtkImage" id="image10">
<property name="visible">True</property>
<property name="stock">gtk-media-previous</property>
<property name="icon_name">audio-volume-low</property>
</object>
<object class="GtkImage" id="image2">
<object class="GtkImage" id="image11">
<property name="visible">True</property>
<property name="stock">gtk-index</property>
<property name="icon_name">audio-volume-high</property>
</object>
<object class="GtkImage" id="image3">
<object class="GtkImage" id="image12">
<property name="visible">True</property>
<property name="no_show_all">True</property>
<property name="stock">gtk-index</property>
<property name="icon_name">audio-volume-muted</property>
</object>
<object class="GtkImage" id="image4">
<object class="GtkImage" id="image18">
<property name="visible">True</property>
<property name="stock">gtk-media-next</property>
<property name="stock">gtk-go-forward</property>
</object>
<object class="GtkImage" id="image6">
<property name="visible">True</property>
......@@ -714,20 +740,25 @@
<property name="visible">True</property>
<property name="stock">gtk-media-forward</property>
</object>
<object class="GtkImage" id="image18">
<object class="GtkImage" id="image1">
<property name="visible">True</property>
<property name="stock">gtk-go-forward</property>
<property name="stock">gtk-media-previous</property>
</object>
<object class="GtkImage" id="image10">
<object class="GtkImage" id="image2">
<property name="visible">True</property>
<property name="icon_name">audio-volume-low</property>
<property name="stock">gtk-index</property>
</object>
<object class="GtkImage" id="image11">
<object class="GtkImage" id="image3">
<property name="visible">True</property>
<property name="icon_name">audio-volume-high</property>
<property name="no_show_all">True</property>
<property name="stock">gtk-index</property>
</object>
<object class="GtkImage" id="image12">
<object class="GtkImage" id="image4">
<property name="visible">True</property>
<property name="icon_name">audio-volume-muted</property>
<property name="stock">gtk-media-next</property>
</object>
<object class="GtkImage" id="image13">
<property name="visible">True</property>
<property name="stock">gtk-cdrom</property>
</object>
</interface>
......@@ -17,7 +17,6 @@
<property name="can_focus">True</property>
<property name="headers_visible">False</property>
<property name="show_expanders">False</property>
<signal name="cursor_changed" handler="parole_media_list_cursor_changed_cb"/>
<signal name="row_activated" handler="parole_media_list_row_activated_cb"/>
<signal name="button_release_event" handler="parole_media_list_button_release_event"/>
<signal name="drag_data_received" handler="parole_media_list_drag_data_received_cb"/>
......
......@@ -54,7 +54,6 @@ show_version (void)
"Part of the Xfce Goodies Project\n"
"http://goodies.xfce.org\n\n"
"Licensed under the GNU GPL.\n\n"), VERSION);
exit (EXIT_SUCCESS);
}
......@@ -145,7 +144,8 @@ int main (int argc, char **argv)
ParolePlayer *player;
ParolePluginsManager *plugins;
GtkBuilder *builder;
GOptionContext *ctx;
GOptionGroup *gst_option_group;
GError *error = NULL;
gchar **filenames = NULL;
gboolean new_instance = FALSE;
......@@ -164,28 +164,30 @@ int main (int argc, char **argv)
xfce_textdomain (GETTEXT_PACKAGE, LOCALEDIR, "UTF-8");
if ( !gtk_init_with_args (&argc, &argv, (gchar *)"", option_entries, (gchar *)PACKAGE, &error))
gtk_init (&argc, &argv);
ctx = g_option_context_new (NULL);
gst_option_group = gst_init_get_option_group ();
g_option_context_add_main_entries (ctx, option_entries, GETTEXT_PACKAGE);
g_option_context_set_translation_domain (ctx, GETTEXT_PACKAGE);
g_option_context_add_group (ctx, gst_option_group);
g_option_context_add_group (ctx, gtk_get_option_group (TRUE));
if ( !g_option_context_parse (ctx, &argc, &argv, &error) )
{
if (G_LIKELY (error) )
{
g_printerr ("%s: %s.\n", G_LOG_DOMAIN, error->message);
g_printerr (_("Type '%s --help' for usage."), G_LOG_DOMAIN);
g_printerr ("\n");
g_error_free (error);
}
else
{
g_error ("Unable to open display.");
}
return EXIT_FAILURE;
g_print ("%s\n", error->message);
g_print ("Type %s --help to list all available command line options", argv[0]);
g_error_free (error);
g_option_context_free (ctx);
return EXIT_FAILURE;
}
g_option_context_free (ctx);
if ( version )
show_version ();
gst_init (NULL, NULL);
if ( !new_instance && parole_dbus_name_has_owner (PAROLE_DBUS_NAME) )
{
TRACE ("Parole is already running");
......
......@@ -42,12 +42,18 @@ struct ParoleDiscMenuPrivate
{
ParoleGst *gst;
ParoleMediaType current_media_type;
GtkWidget *disc_track;
GtkWidget *disc_box;
GtkWidget *next_chapter;
GtkWidget *prev_chapter;
GtkWidget *dvd_menu;
GtkWidget *chapter_menu;
GtkWidget *info;
GtkWidget *eventboxinfo;
guint tracks;
};
G_DEFINE_TYPE (ParoleDiscMenu, parole_disc_menu, G_TYPE_OBJECT)
......@@ -55,10 +61,12 @@ G_DEFINE_TYPE (ParoleDiscMenu, parole_disc_menu, G_TYPE_OBJECT)
static void
parole_disc_menu_hide (ParoleDiscMenu *menu)
{
gtk_widget_hide (menu->priv->disc_track);
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->disc_box);
//gtk_widget_hide (menu->priv->dvd_menu);
//gtk_widget_hide (menu->priv->chapter_menu);
}
......@@ -73,9 +81,12 @@ parole_disc_menu_show (ParoleDiscMenu *menu, gboolean show_label)
{
gtk_widget_show (menu->priv->eventboxinfo);
gtk_widget_show (menu->priv->info);
gtk_widget_show (menu->priv->disc_track);
}
//gtk_widget_show (menu->priv->dvd_menu);
//gtk_widget_show (menu->priv->dvd_menu);
//gtk_widget_show (menu->priv->chapter_menu);
gtk_widget_show (menu->priv->disc_box);
}
......@@ -84,6 +95,7 @@ parole_disc_menu_media_state_cb (ParoleGst *gst, const ParoleStream *stream,
ParoleMediaState state, ParoleDiscMenu *menu)
{
ParoleMediaType media_type;
menu->priv->tracks = 0;
if ( state < PAROLE_MEDIA_STATE_PAUSED )
{
......@@ -121,6 +133,7 @@ parole_disc_menu_media_state_cb (ParoleGst *gst, const ParoleStream *stream,
g_free (text);
parole_disc_menu_show (menu, TRUE);
menu->priv->tracks = num_tracks;
}
menu->priv->current_media_type = media_type;
}
......@@ -156,6 +169,58 @@ parole_disc_menu_chapter_menu_cb (ParoleDiscMenu *menu)
}
static void
track_menu_item_activated_cb (GtkWidget *widget, ParoleDiscMenu *menu)
{
guint track;
track = GPOINTER_TO_UINT ( g_object_get_data (G_OBJECT (widget), "track"));
parole_gst_seek_cdda (menu->priv->gst, track);
}
static void
parole_disc_menu_show_disc_track_menu (ParoleDiscMenu *disc_menu, guint button, guint activate_time)
{
GtkWidget *menu, *mi, *img;
gchar track[128];
guint i;
menu = gtk_menu_new ();
for ( i = 0; i < disc_menu->priv->tracks; i++)
{
img = gtk_image_new_from_stock (GTK_STOCK_CDROM, GTK_ICON_SIZE_MENU);
g_snprintf (track, 128, _("Track %i"), i+1);
mi = gtk_image_menu_item_new_with_label (track);
gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (mi), img);
gtk_widget_show (mi);
gtk_menu_shell_append (GTK_MENU_SHELL (menu), mi);
g_object_set_data (G_OBJECT (mi), "track", GUINT_TO_POINTER (i+1));
g_signal_connect (mi, "activate",
G_CALLBACK (track_menu_item_activated_cb), disc_menu);
}
g_signal_connect_swapped (menu, "selection-done",
G_CALLBACK (gtk_widget_destroy), menu);
gtk_menu_popup (GTK_MENU (menu),
NULL, NULL,
NULL, NULL,
button, activate_time);
}
static gboolean
parole_disc_menu_show_disc_track (GtkWidget *widget, GdkEventButton *ev, ParoleDiscMenu *menu)
{
if ( ev->button == 1 )
{
parole_disc_menu_show_disc_track_menu (menu, ev->button, ev->time);
}
return FALSE;
}
static void
parole_disc_menu_class_init (ParoleDiscMenuClass *klass)
{
......@@ -174,20 +239,29 @@ parole_disc_menu_init (ParoleDiscMenu *menu)
menu->priv = PAROLE_DISC_MENU_GET_PRIVATE (menu);
menu->priv->tracks = 0;
builder = parole_builder_get_main_interface ();
menu->priv->disc_track = GTK_WIDGET (gtk_builder_get_object (builder, "select-track"));
menu->priv->next_chapter = GTK_WIDGET (gtk_builder_get_object (builder, "next-chapter"));
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"));
menu->priv->disc_box = GTK_WIDGET (gtk_builder_get_object (builder, "disc-box"));
gdk_color_parse ("black", &color);
gtk_widget_modify_bg (menu->priv->eventboxinfo, GTK_STATE_NORMAL, &color);
gtk_widget_modify_bg (menu->priv->disc_box, GTK_STATE_NORMAL, &color);
menu->priv->current_media_type = PAROLE_MEDIA_TYPE_UNKNOWN;
g_signal_connect (menu->priv->disc_track, "button-press-event",
G_CALLBACK (parole_disc_menu_show_disc_track), menu);
g_signal_connect_swapped (menu->priv->next_chapter, "clicked",
G_CALLBACK (parole_disc_menu_next_chapter_cb), menu);
......@@ -226,7 +300,7 @@ parole_disc_menu_new (void)
return menu;
}
gboolean parole_disc_menu_visible (ParoleDiscMenu *menu)
gboolean parole_disc_menu_visible (ParoleDiscMenu *menu)
{
return (GTK_WIDGET_VISIBLE (menu->priv->next_chapter));
}
......@@ -240,3 +314,7 @@ void parole_disc_menu_seek_prev (ParoleDiscMenu *menu)
{
parole_disc_menu_prev_chapter_cb (menu);
}
void parole_disc_menu_set_fullscreen (ParoleDiscMenu *menu, gboolean fullscreen)
{
}
......@@ -52,6 +52,9 @@ void parole_disc_menu_seek_next (ParoleDiscMenu *menu);
void parole_disc_menu_seek_prev (ParoleDiscMenu *menu);
void parole_disc_menu_set_fullscreen (ParoleDiscMenu *menu,
gboolean fullscreen);
G_END_DECLS
#endif /* __PAROLE_DISC_MENU_H */
......@@ -644,16 +644,12 @@ parole_gst_load_subtitle (ParoleGst *gst)
gchar *sub;
gchar *sub_uri;
gboolean sub_enabled;
gboolean has_video;
g_object_get (G_OBJECT (gst->priv->stream),
"media-type", &type,
"has-video", &has_video,
NULL);
PAROLE_DEBUG_ENUM_FULL (type, ENUM_GTYPE_MEDIA_TYPE, " has_video=%d", has_video);
if ( type != PAROLE_MEDIA_TYPE_LOCAL_FILE || !has_video)
if ( type != PAROLE_MEDIA_TYPE_LOCAL_FILE)
return;
g_object_get (G_OBJECT (gst->priv->conf),
......@@ -1182,6 +1178,8 @@ parole_gst_change_state (ParoleGst *gst, GstState new)
{
GstStateChangeReturn ret;
TRACE ("Changing state to %d", new);
ret = gst_element_set_state (GST_ELEMENT (gst->priv->playbin), new);
switch (ret)
......@@ -1233,14 +1231,16 @@ parole_gst_play_file_internal (ParoleGst *gst)
"uri", &uri,
NULL);
TRACE ("Processing uri : %s", uri);
g_object_set (G_OBJECT (gst->priv->playbin),
"uri", uri,
"suburi", NULL,
NULL);
parole_gst_load_subtitle (gst);
parole_gst_change_state (gst, GST_STATE_PLAYING);
g_free (uri);
}
......@@ -1670,6 +1670,21 @@ parole_gst_new (void)
return GTK_WIDGET (parole_gst_object);
}
static gboolean
parole_gst_play_idle (gpointer data)
{
ParoleGst *gst;
gst = PAROLE_GST (data);
if ( gst->priv->state < GST_STATE_PAUSED )
parole_gst_play_file_internal (gst);
else
parole_gst_change_state (gst, GST_STATE_READY);
return FALSE;
}
void parole_gst_play_uri (ParoleGst *gst, const gchar *uri)
{
g_mutex_lock (gst->priv->lock);
......@@ -1689,10 +1704,8 @@ void parole_gst_play_uri (ParoleGst *gst, const gchar *uri)
parole_window_busy_cursor (GTK_WIDGET (gst)->window);
if ( gst->priv->state < GST_STATE_PAUSED )
parole_gst_play_file_internal (gst);
else
parole_gst_change_state (gst, GST_STATE_READY);
g_idle_add ((GSourceFunc) parole_gst_play_idle, gst);
}
void parole_gst_pause (ParoleGst *gst)
......@@ -1821,6 +1834,15 @@ void parole_gst_prev_cdda_track (ParoleGst *gst)
parole_gst_change_cdda_track (gst, -1);
}
void parole_gst_seek_cdda (ParoleGst *gst, guint track_num)
{
gint current_track;
current_track = parole_gst_get_current_cdda_track (gst);
parole_gst_change_cdda_track (gst, (gint) track_num - current_track -1);
}
gint parole_gst_get_current_cdda_track (ParoleGst *gst)
{
GstFormat format;
......
......@@ -116,6 +116,9 @@ void parole_gst_next_cdda_track (ParoleGst *gst);
void parole_gst_prev_cdda_track (ParoleGst *gst);
void parole_gst_seek_cdda (ParoleGst *gst,
guint track_num);
gint parole_gst_get_current_cdda_track (ParoleGst *gst);
ParoleMediaType parole_gst_get_current_stream_type (ParoleGst *gst);
......
......@@ -74,6 +74,14 @@ static struct
static void parole_media_list_dbus_class_init (ParoleMediaListClass *klass);
static void parole_media_list_dbus_init (ParoleMediaList *list);
static GtkTreeRowReference *
parole_media_list_get_row_reference_from_iter (ParoleMediaList *list,
GtkTreeIter *iter,
gboolean select_path);
static void parole_media_list_select_path (ParoleMediaList *list,
GtkTreePath *path);
/*
* Callbacks for GtkBuilder
*/
......@@ -97,9 +105,6 @@ void parole_media_list_row_activated_cb (GtkTreeView *view,
GtkTreeViewColumn *col,
ParoleMediaList *list);
void parole_media_list_cursor_changed_cb (GtkTreeView *view,
ParoleMediaList *list);
gboolean parole_media_list_button_release_event (GtkWidget *widget,
GdkEventButton *ev,
ParoleMediaList *list);
......@@ -133,6 +138,7 @@ struct ParoleMediaListPrivate
GtkWidget *view;
GtkWidget *box;
GtkListStore *store;
GtkTreeSelection *sel;
GtkWidget *remove;
GtkWidget *up;
......@@ -361,7 +367,34 @@ void parole_media_list_close_save_dialog_cb (GtkButton *button, ParolePlaylistSa
gtk_widget_destroy (GTK_WIDGET (data->chooser));