[Xfce4-commits] <parole:master> Cleaned up playlist. Fixed menu positioning. Enhanced DVD detection. Added support for DVD Root, Title, Angle, Audio, and Chapter menus above playlist.

Sean Davis noreply at xfce.org
Thu Dec 6 01:24:01 CET 2012


Updating branch refs/heads/master
         to cde75faaf4b7a5f5f25fbd05fa7515069c1f894e (commit)
       from a4a47a284786bd1ae6658a19d10ceb5a84768ec6 (commit)

commit cde75faaf4b7a5f5f25fbd05fa7515069c1f894e
Author: Sean Davis <smd.seandavis at gmail.com>
Date:   Wed Dec 5 19:23:01 2012 -0500

    Cleaned up playlist. Fixed menu positioning. Enhanced DVD detection. Added support for DVD Root, Title, Angle, Audio, and Chapter menus above playlist.

 data/interfaces/playlist.ui |  350 +++++++++++++++++++++++++++----------------
 src/gst/parole-gst.c        |   43 ++++++
 src/gst/parole-gst.h        |    3 +
 src/parole-disc.c           |  151 +++++++++++++------
 src/parole-disc.h           |    6 +
 src/parole-medialist.c      |  153 ++++++++++++++++++-
 src/parole-medialist.h      |   11 ++
 src/parole-player.c         |   39 +++++
 8 files changed, 573 insertions(+), 183 deletions(-)

diff --git a/data/interfaces/playlist.ui b/data/interfaces/playlist.ui
index d9fc826..3feeec1 100644
--- a/data/interfaces/playlist.ui
+++ b/data/interfaces/playlist.ui
@@ -2,6 +2,56 @@
 <interface>
   <requires lib="gtk+" version="2.24"/>
   <!-- interface-naming-policy project-wide -->
+  <object class="GtkMenu" id="dvd-menu">
+    <property name="visible">True</property>
+    <property name="can_focus">False</property>
+    <property name="ubuntu_local">True</property>
+    <child>
+      <object class="GtkMenuItem" id="dvd-menu-menu">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="use_action_appearance">False</property>
+        <property name="label" translatable="yes">DVD Menu</property>
+        <property name="use_underline">True</property>
+      </object>
+    </child>
+    <child>
+      <object class="GtkMenuItem" id="dvd-menu-title">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="use_action_appearance">False</property>
+        <property name="label" translatable="yes">Title Menu</property>
+        <property name="use_underline">True</property>
+      </object>
+    </child>
+    <child>
+      <object class="GtkMenuItem" id="dvd-menu-audio">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="use_action_appearance">False</property>
+        <property name="label" translatable="yes">Audio Menu</property>
+        <property name="use_underline">True</property>
+      </object>
+    </child>
+    <child>
+      <object class="GtkMenuItem" id="dvd-menu-angle">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="use_action_appearance">False</property>
+        <property name="label" translatable="yes">Angle Menu</property>
+        <property name="use_underline">True</property>
+      </object>
+    </child>
+    <child>
+      <object class="GtkMenuItem" id="dvd-menu-chapter">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="use_action_appearance">False</property>
+        <property name="label" translatable="yes">Chapter Menu</property>
+        <property name="use_underline">True</property>
+      </object>
+    </child>
+  </object>
   <object class="GtkImage" id="image_add">
     <property name="visible">True</property>
     <property name="can_focus">False</property>
@@ -41,164 +91,204 @@
   <object class="GtkVBox" id="playlist-box">
     <property name="visible">True</property>
     <property name="can_focus">False</property>
-    <property name="spacing">5</property>
     <child>
-      <object class="GtkAlignment" id="alignment1">
-        <property name="visible">True</property>
-        <property name="can_focus">False</property>
+      <object class="GtkToggleButton" id="dvd_menu_button">
+        <property name="can_focus">True</property>
+        <property name="receives_default">True</property>
+        <property name="no_show_all">True</property>
+        <property name="use_action_appearance">False</property>
         <child>
-          <object class="GtkVBox" id="vbox1">
+          <object class="GtkHBox" id="hbox1">
             <property name="visible">True</property>
             <property name="can_focus">False</property>
+            <property name="spacing">3</property>
             <child>
-              <object class="GtkScrolledWindow" id="scrolledwindow1">
+              <object class="GtkImage" id="image_disc">
                 <property name="visible">True</property>
-                <property name="can_focus">True</property>
-                <property name="hscrollbar_policy">never</property>
-                <property name="vscrollbar_policy">automatic</property>
-                <property name="window_placement_set">True</property>
-                <property name="shadow_type">in</property>
-                <child>
-                  <object class="GtkTreeView" id="media-list">
-                    <property name="visible">True</property>
-                    <property name="can_focus">True</property>
-                    <property name="has_tooltip">True</property>
-                    <property name="headers_visible">False</property>
-                    <property name="rules_hint">True</property>
-                    <signal name="drag-data-received" handler="parole_media_list_drag_data_received_cb" swapped="no"/>
-                    <signal name="key-press-event" handler="parole_media_list_key_press" swapped="no"/>
-                    <signal name="row-activated" handler="parole_media_list_row_activated_cb" swapped="no"/>
-                    <signal name="button-release-event" handler="parole_media_list_button_release_event" swapped="no"/>
-                    <signal name="query-tooltip" handler="parole_media_list_query_tooltip" swapped="no"/>
-                  </object>
-                </child>
+                <property name="can_focus">False</property>
+                <property name="icon_name">drive-optical</property>
               </object>
               <packing>
-                <property name="expand">True</property>
+                <property name="expand">False</property>
                 <property name="fill">True</property>
                 <property name="position">0</property>
               </packing>
             </child>
             <child>
-              <object class="GtkHBox" id="hbox3">
+              <object class="GtkLabel" id="dvd_label">
                 <property name="visible">True</property>
                 <property name="can_focus">False</property>
-                <property name="spacing">2</property>
-                <property name="homogeneous">True</property>
-                <child>
-                  <object class="GtkButton" id="add-media">
-                    <property name="visible">True</property>
-                    <property name="can_focus">True</property>
-                    <property name="receives_default">True</property>
-                    <property name="use_action_appearance">False</property>
-                    <property name="image">image_add</property>
-                    <property name="focus_on_click">False</property>
-                    <signal name="clicked" handler="parole_media_list_add_clicked_cb" swapped="no"/>
-                  </object>
-                  <packing>
-                    <property name="expand">False</property>
-                    <property name="fill">True</property>
-                    <property name="position">0</property>
-                  </packing>
-                </child>
-                <child>
-                  <object class="GtkButton" id="remove-media">
-                    <property name="visible">True</property>
-                    <property name="sensitive">False</property>
-                    <property name="can_focus">True</property>
-                    <property name="receives_default">True</property>
-                    <property name="use_action_appearance">False</property>
-                    <property name="image">image_remove</property>
-                    <property name="focus_on_click">False</property>
-                    <signal name="clicked" handler="parole_media_list_remove_clicked_cb" swapped="no"/>
-                  </object>
-                  <packing>
-                    <property name="expand">False</property>
-                    <property name="fill">True</property>
-                    <property name="position">1</property>
-                  </packing>
-                </child>
-                <child>
-                  <object class="GtkButton" id="clear-media">
-                    <property name="visible">True</property>
-                    <property name="sensitive">False</property>
-                    <property name="can_focus">True</property>
-                    <property name="receives_default">True</property>
-                    <property name="use_action_appearance">False</property>
-                    <property name="image">image_clear</property>
-                    <property name="focus_on_click">False</property>
-                    <signal name="clicked" handler="parole_media_list_clear_clicked_cb" swapped="no"/>
-                  </object>
-                  <packing>
-                    <property name="expand">True</property>
-                    <property name="fill">True</property>
-                    <property name="position">2</property>
-                  </packing>
-                </child>
-                <child>
-                  <object class="GtkToggleButton" id="repeat-media">
-                    <property name="visible">True</property>
-                    <property name="can_focus">True</property>
-                    <property name="receives_default">True</property>
-                    <property name="use_action_appearance">False</property>
-                    <property name="image">image_repeat</property>
-                    <property name="focus_on_click">False</property>
-                    <signal name="toggled" handler="parole_media_list_repeat_toggled_cb" swapped="no"/>
-                  </object>
-                  <packing>
-                    <property name="expand">True</property>
-                    <property name="fill">True</property>
-                    <property name="position">3</property>
-                  </packing>
-                </child>
-                <child>
-                  <object class="GtkToggleButton" id="shuffle-media">
-                    <property name="visible">True</property>
-                    <property name="can_focus">True</property>
-                    <property name="receives_default">True</property>
-                    <property name="use_action_appearance">False</property>
-                    <property name="image">image_shuffle</property>
-                    <property name="focus_on_click">False</property>
-                    <signal name="toggled" handler="parole_media_list_shuffle_toggled_cb" swapped="no"/>
-                  </object>
-                  <packing>
-                    <property name="expand">True</property>
-                    <property name="fill">True</property>
-                    <property name="position">4</property>
-                  </packing>
-                </child>
-                <child>
-                  <object class="GtkToggleButton" id="settings">
-                    <property name="visible">True</property>
-                    <property name="can_focus">True</property>
-                    <property name="receives_default">True</property>
-                    <property name="use_action_appearance">False</property>
-                    <property name="image">image_settings</property>
-                    <property name="focus_on_click">False</property>
-                  </object>
-                  <packing>
-                    <property name="expand">True</property>
-                    <property name="fill">True</property>
-                    <property name="position">5</property>
-                  </packing>
-                </child>
+                <property name="xalign">0</property>
+                <property name="label" translatable="yes">DVD Name</property>
+                <property name="ellipsize">end</property>
               </object>
               <packing>
-                <property name="expand">False</property>
-                <property name="fill">False</property>
-                <property name="padding">2</property>
+                <property name="expand">True</property>
+                <property name="fill">True</property>
                 <property name="position">1</property>
               </packing>
             </child>
+            <child>
+              <object class="GtkArrow" id="arrow1">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="arrow_type">down</property>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">True</property>
+                <property name="pack_type">end</property>
+                <property name="position">2</property>
+              </packing>
+            </child>
           </object>
         </child>
       </object>
       <packing>
-        <property name="expand">True</property>
+        <property name="expand">False</property>
         <property name="fill">True</property>
         <property name="position">0</property>
       </packing>
     </child>
+    <child>
+      <object class="GtkScrolledWindow" id="scrolledwindow1">
+        <property name="visible">True</property>
+        <property name="can_focus">True</property>
+        <property name="hscrollbar_policy">never</property>
+        <property name="vscrollbar_policy">automatic</property>
+        <property name="window_placement_set">True</property>
+        <property name="shadow_type">in</property>
+        <child>
+          <object class="GtkTreeView" id="media-list">
+            <property name="visible">True</property>
+            <property name="can_focus">True</property>
+            <property name="headers_visible">False</property>
+            <property name="rules_hint">True</property>
+            <signal name="drag-data-received" handler="parole_media_list_drag_data_received_cb" swapped="no"/>
+            <signal name="key-press-event" handler="parole_media_list_key_press" swapped="no"/>
+            <signal name="row-activated" handler="parole_media_list_row_activated_cb" swapped="no"/>
+            <signal name="button-release-event" handler="parole_media_list_button_release_event" swapped="no"/>
+            <signal name="query-tooltip" handler="parole_media_list_query_tooltip" swapped="no"/>
+          </object>
+        </child>
+      </object>
+      <packing>
+        <property name="expand">True</property>
+        <property name="fill">True</property>
+        <property name="position">1</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkHBox" id="hbox3">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="spacing">2</property>
+        <property name="homogeneous">True</property>
+        <child>
+          <object class="GtkButton" id="add-media">
+            <property name="visible">True</property>
+            <property name="can_focus">True</property>
+            <property name="receives_default">True</property>
+            <property name="use_action_appearance">False</property>
+            <property name="image">image_add</property>
+            <property name="focus_on_click">False</property>
+            <signal name="clicked" handler="parole_media_list_add_clicked_cb" swapped="no"/>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">True</property>
+            <property name="position">0</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkButton" id="remove-media">
+            <property name="visible">True</property>
+            <property name="sensitive">False</property>
+            <property name="can_focus">True</property>
+            <property name="receives_default">True</property>
+            <property name="use_action_appearance">False</property>
+            <property name="image">image_remove</property>
+            <property name="focus_on_click">False</property>
+            <signal name="clicked" handler="parole_media_list_remove_clicked_cb" swapped="no"/>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">True</property>
+            <property name="position">1</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkButton" id="clear-media">
+            <property name="visible">True</property>
+            <property name="sensitive">False</property>
+            <property name="can_focus">True</property>
+            <property name="receives_default">True</property>
+            <property name="use_action_appearance">False</property>
+            <property name="image">image_clear</property>
+            <property name="focus_on_click">False</property>
+            <signal name="clicked" handler="parole_media_list_clear_clicked_cb" swapped="no"/>
+          </object>
+          <packing>
+            <property name="expand">True</property>
+            <property name="fill">True</property>
+            <property name="position">2</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkToggleButton" id="repeat-media">
+            <property name="visible">True</property>
+            <property name="can_focus">True</property>
+            <property name="receives_default">True</property>
+            <property name="use_action_appearance">False</property>
+            <property name="image">image_repeat</property>
+            <property name="focus_on_click">False</property>
+            <signal name="toggled" handler="parole_media_list_repeat_toggled_cb" swapped="no"/>
+          </object>
+          <packing>
+            <property name="expand">True</property>
+            <property name="fill">True</property>
+            <property name="position">3</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkToggleButton" id="shuffle-media">
+            <property name="visible">True</property>
+            <property name="can_focus">True</property>
+            <property name="receives_default">True</property>
+            <property name="use_action_appearance">False</property>
+            <property name="image">image_shuffle</property>
+            <property name="focus_on_click">False</property>
+            <signal name="toggled" handler="parole_media_list_shuffle_toggled_cb" swapped="no"/>
+          </object>
+          <packing>
+            <property name="expand">True</property>
+            <property name="fill">True</property>
+            <property name="position">4</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkToggleButton" id="settings">
+            <property name="visible">True</property>
+            <property name="can_focus">True</property>
+            <property name="receives_default">True</property>
+            <property name="use_action_appearance">False</property>
+            <property name="image">image_settings</property>
+            <property name="focus_on_click">False</property>
+          </object>
+          <packing>
+            <property name="expand">True</property>
+            <property name="fill">True</property>
+            <property name="position">5</property>
+          </packing>
+        </child>
+      </object>
+      <packing>
+        <property name="expand">False</property>
+        <property name="fill">False</property>
+        <property name="padding">2</property>
+        <property name="position">2</property>
+      </packing>
+    </child>
   </object>
   <object class="GtkMenu" id="playlist-menu">
     <property name="visible">True</property>
diff --git a/src/gst/parole-gst.c b/src/gst/parole-gst.c
index 346e1fd..a38aad9 100644
--- a/src/gst/parole-gst.c
+++ b/src/gst/parole-gst.c
@@ -83,6 +83,15 @@ typedef enum
 
 } GstPlayFlags;
 
+enum
+{
+    GST_DVD_ROOT_MENU,
+    GST_DVD_TITLE_MENU,
+    GST_DVD_AUDIO_MENU,
+    GST_DVD_ANGLE_MENU,
+    GST_DVD_CHAPTER_MENU
+};
+
 struct ParoleGstPrivate
 {
     GstElement	 *playbin;
@@ -1581,6 +1590,40 @@ parole_gst_play_file_internal (ParoleGst *gst)
     g_free (uri);
 }
 
+void
+parole_gst_send_navigation_command(ParoleGst *gst, gint command)
+{
+    GstNavigation *nav;
+    nav = GST_NAVIGATION (gst->priv->video_sink);
+    
+    switch (command)
+    {
+        case GST_DVD_ROOT_MENU:
+            TRACE("Root Menu");
+            gst_navigation_send_command (nav, GST_NAVIGATION_COMMAND_DVD_MENU);
+            break;
+        case GST_DVD_TITLE_MENU:
+            TRACE("Title Menu");
+            gst_navigation_send_command (nav, GST_NAVIGATION_COMMAND_DVD_TITLE_MENU);
+            break;
+        case GST_DVD_AUDIO_MENU:
+            TRACE("Audio Menu");
+            gst_navigation_send_command (nav, GST_NAVIGATION_COMMAND_DVD_AUDIO_MENU);
+            break;
+        case GST_DVD_ANGLE_MENU:
+            TRACE("Angle Menu");
+            gst_navigation_send_command (nav, GST_NAVIGATION_COMMAND_DVD_ANGLE_MENU);
+            break;
+        case GST_DVD_CHAPTER_MENU:
+            TRACE("Chapter Menu");
+            gst_navigation_send_command (nav, GST_NAVIGATION_COMMAND_DVD_CHAPTER_MENU);
+            break;
+        default:
+            break;
+    }
+
+}
+
 static gboolean
 parole_gst_motion_notify_event (GtkWidget *widget, GdkEventMotion *ev)
 {
diff --git a/src/gst/parole-gst.h b/src/gst/parole-gst.h
index 5530768..84d111d 100644
--- a/src/gst/parole-gst.h
+++ b/src/gst/parole-gst.h
@@ -120,6 +120,9 @@ GstState	        parole_gst_get_gst_state   	(ParoleGst *gst);
 
 GstState	        parole_gst_get_gst_target_state (ParoleGst *gst);
 
+void
+parole_gst_send_navigation_command(ParoleGst *gst, gint command);
+
 void			parole_gst_next_dvd_chapter 	(ParoleGst *gst);
 
 void			parole_gst_prev_dvd_chapter 	(ParoleGst *gst);
diff --git a/src/parole-disc.c b/src/parole-disc.c
index 4f4b4c7..ce22e83 100644
--- a/src/parole-disc.c
+++ b/src/parole-disc.c
@@ -62,6 +62,8 @@ struct ParoleDiscPrivate
 enum
 {
     DISC_SELECTED,
+    DVD_ENABLED,
+    LABEL_CHANGED,
     LAST_SIGNAL
 };
 
@@ -100,6 +102,68 @@ free_mount_data (gpointer data)
     g_free (mount);
 }
 
+
+static void
+parole_disc_set_label(ParoleDisc *disc, const gchar *label)
+{
+    gchar *menu_label;
+    
+    if ( g_strcmp0(label, _("Insert Disc")) != 0 )
+    {
+    menu_label = g_strdup_printf ("%s '%s'", _("Play Disc"), label);
+    g_signal_emit (G_OBJECT (disc), signals [LABEL_CHANGED], 0, label);
+    }
+    else
+    {
+    menu_label = g_strdup(label);
+    g_signal_emit (G_OBJECT (disc), signals [LABEL_CHANGED], 0, label);
+    }
+    
+    gtk_menu_item_set_label( GTK_MENU_ITEM (disc->priv->disc_menu_item), menu_label );
+    g_free(menu_label);
+}
+
+static void
+parole_disc_set_enabled(ParoleDisc *disc, gboolean enabled)
+{
+    gtk_widget_set_sensitive( GTK_WIDGET(disc->priv->disc_menu_item), enabled);
+    //g_signal_emit (G_OBJECT (disc), signals [DVD_ENABLED], 0, enabled);
+}
+
+static gboolean
+parole_disc_get_enabled(ParoleDisc *disc)
+{
+    return gtk_widget_get_sensitive( GTK_WIDGET(disc->priv->disc_menu_item) );
+}
+
+static void
+parole_disc_set_kind(ParoleDisc *disc, ParoleDiscKind kind)
+{
+    GtkWidget *img;
+    gboolean enabled = TRUE;
+    
+    switch (kind)
+	{
+		case PAROLE_DISC_CDDA:
+			img = gtk_image_new_from_icon_name("media-cdrom-audio", GTK_ICON_SIZE_MENU);
+			break;
+		case PAROLE_DISC_SVCD:
+		case PAROLE_DISC_VCD:
+		case PAROLE_DISC_DVD:
+			img = gtk_image_new_from_stock("gtk-cdrom", GTK_ICON_SIZE_MENU);
+			break;
+		default:
+		    img = gtk_image_new_from_stock("gtk-cdrom", GTK_ICON_SIZE_MENU);
+		    parole_disc_set_label(disc, _("Insert Disc") );
+		    enabled = FALSE;
+		    break;
+	}
+	
+	gtk_image_menu_item_set_image( GTK_IMAGE_MENU_ITEM (disc->priv->disc_menu_item), img);
+	parole_disc_set_enabled(disc, enabled);
+}
+
+
 /**
  * parole_disc_media_activate_cb:
  * @widget : the #GtkWidget activated for this callback function.
@@ -129,45 +193,19 @@ parole_disc_media_activate_cb (GtkWidget *widget, ParoleDisc *disc)
 static void
 parole_disc_show_menu_item (ParoleDisc *disc, MountData *data, const gchar *label)
 {
-	GtkWidget *img;
-	
-	switch (data->kind)
-	{
-		case PAROLE_DISC_CDDA:
-			img = gtk_image_new_from_icon_name("media-cdrom-audio", GTK_ICON_SIZE_MENU);
-			break;
-		case PAROLE_DISC_SVCD:
-		case PAROLE_DISC_VCD:
-		case PAROLE_DISC_DVD:
-			img = gtk_image_new_from_stock("gtk-cdrom", GTK_ICON_SIZE_MENU);
-			break;
-		default:
-		    img = gtk_image_new_from_stock("gtk-cdrom", GTK_ICON_SIZE_MENU);
-		    gtk_image_menu_item_set_image( GTK_IMAGE_MENU_ITEM (disc->priv->disc_menu_item), img);
-		    gtk_menu_item_set_label( GTK_MENU_ITEM (disc->priv->disc_menu_item), _("Insert Disc") );
-		    gtk_widget_set_sensitive( GTK_WIDGET (disc->priv->disc_menu_item), FALSE );
-		    data->mi = disc->priv->disc_menu_item;
-	        gtk_widget_show (data->mi);
-            gtk_widget_show (img);
-		    return;
-		    break;
-	}
-	
-	gtk_image_menu_item_set_image( GTK_IMAGE_MENU_ITEM (disc->priv->disc_menu_item), img);
-	gtk_menu_item_set_label( GTK_MENU_ITEM (disc->priv->disc_menu_item), label );
-	
-	gtk_widget_set_sensitive( GTK_WIDGET (disc->priv->disc_menu_item), TRUE );
+	parole_disc_set_kind (disc, data->kind);
+	parole_disc_set_label(disc, label);
 
-	data->mi = disc->priv->disc_menu_item;
-	
-	gtk_widget_show (data->mi);
-    gtk_widget_show (img);
-	
-    g_object_set_data (G_OBJECT (data->mi),
-		      "mount-data", data);
-		      
-	g_signal_connect (data->mi, "activate",
-		      G_CALLBACK (parole_disc_media_activate_cb), disc);
+	if (parole_disc_get_enabled(disc))
+	{
+	    data->mi = disc->priv->disc_menu_item;
+	    
+        g_object_set_data (G_OBJECT (data->mi),
+		          "mount-data", data);
+		          
+	    g_signal_connect (data->mi, "activate",
+		          G_CALLBACK (parole_disc_media_activate_cb), disc);
+    }
 }
 
 /**
@@ -222,6 +260,13 @@ parole_disc_add_mount_to_menu (ParoleDisc *disc, GMount *mount, const gchar *dev
 	uri = g_strdup ("cdda://");
 	goto got_cdda;
     }
+    
+    if ( g_file_has_uri_scheme (file, "dvd") )
+    {
+	kind = PAROLE_DISC_DVD;
+	uri = g_strdup ("dvd:/");
+	goto got_cdda;
+    }
 	
     content_type = g_content_type_guess_for_tree (file);
 
@@ -264,19 +309,16 @@ got_cdda:
     {
 	MountData *data;
 	gchar *name;
-	gchar *label;
 	
 	name = g_mount_get_name (mount);
-	label = g_strdup_printf ("%s '%s'", _("Play Disc"), name);
 	
 	data = parole_disc_get_mount_data (disc, uri, device, kind);
-	parole_disc_show_menu_item (disc, data, label);
+	parole_disc_show_menu_item (disc, data, name);
 	
 	if ( uri )
 	    g_free (uri);
 	
 	g_ptr_array_add (disc->priv->array, data);
-	g_free (label);
 	g_free (name);
     }
     
@@ -458,12 +500,7 @@ parole_disc_select_cb (GtkItem *item, ParoleDisc *disc)
 static void
 parole_disc_monitor_changed_cb (GVolumeMonitor *monitor, gpointer *device, ParoleDisc *disc)
 {
-    GtkWidget *img;
-	
-	img = gtk_image_new_from_stock("gtk-cdrom", GTK_ICON_SIZE_MENU);
-    gtk_image_menu_item_set_image( GTK_IMAGE_MENU_ITEM (disc->priv->disc_menu_item), img);
-    gtk_menu_item_set_label( GTK_MENU_ITEM (disc->priv->disc_menu_item), _("Insert Disc") );
-    gtk_widget_set_sensitive( GTK_WIDGET (disc->priv->disc_menu_item), FALSE );
+    parole_disc_set_kind(disc, PAROLE_DISC_UNKNOWN);
     
     disc->priv->needs_update = TRUE;
 }
@@ -489,6 +526,24 @@ parole_disc_class_init (ParoleDiscClass *klass)
                       G_TYPE_NONE, 2, 
 		      G_TYPE_STRING, G_TYPE_STRING);
 		      
+    signals[DVD_ENABLED] = 
+        g_signal_new ("dvd-enabled",
+                      PAROLE_TYPE_DISC,
+                      G_SIGNAL_RUN_LAST,
+                      G_STRUCT_OFFSET (ParoleDiscClass, dvd_enabled),
+                      NULL, NULL,
+                      g_cclosure_marshal_VOID__BOOLEAN,
+                      G_TYPE_NONE, 1, G_TYPE_BOOLEAN);
+
+    signals[LABEL_CHANGED] = 
+        g_signal_new ("label-changed",
+                      PAROLE_TYPE_DISC,
+                      G_SIGNAL_RUN_LAST,
+                      G_STRUCT_OFFSET (ParoleDiscClass, label_changed),
+                      NULL, NULL,
+                      g_cclosure_marshal_VOID__STRING,
+                      G_TYPE_NONE, 1, G_TYPE_STRING);
+		      
     object_class->finalize = parole_disc_finalize;
 
     g_type_class_add_private (klass, sizeof (ParoleDiscPrivate));
diff --git a/src/parole-disc.h b/src/parole-disc.h
index c7bccbe..267a0db 100644
--- a/src/parole-disc.h
+++ b/src/parole-disc.h
@@ -55,6 +55,12 @@ typedef struct
     void		   (*disc_selected)	       (ParoleDisc *disc,
 							const gchar *uri,
 							const gchar *device);
+							
+    void			(*label_changed)			    (ParoleDisc *disc,
+								     const gchar *label_changed);
+								     
+	void			(*dvd_enabled)		    (ParoleDisc *disc,
+								     gboolean dvd_enabled);
     
 } ParoleDiscClass;
 
diff --git a/src/parole-medialist.c b/src/parole-medialist.c
index 655d068..b3c4fc8 100644
--- a/src/parole-medialist.c
+++ b/src/parole-medialist.c
@@ -96,8 +96,6 @@ static GtkTreeRowReference *
 static void 	parole_media_list_select_path 	  (ParoleMediaList *list, 
 						   GtkTreePath *path);
 
-static void	parole_media_list_clear_list 	  (ParoleMediaList *list);
-
 /*
  * Callbacks for GtkBuilder
  */
@@ -159,6 +157,18 @@ gboolean	parole_media_list_query_tooltip		(GtkWidget *widget,
 							 
 void		parole_media_list_menu_pos (GtkMenu *menu, 
 							gint *px, gint *py, gpointer data);
+
+void parole_media_list_send_dvd_menu_navigation (ParoleMediaList *list, gint msg_id);
+
+void parole_media_list_dvd_menu_activated (GtkMenuItem *widget, ParoleMediaList *list);
+
+void parole_media_list_dvd_title_activated (GtkMenuItem *widget, ParoleMediaList *list);
+
+void parole_media_list_dvd_audio_activated (GtkMenuItem *widget, ParoleMediaList *list);
+
+void parole_media_list_dvd_angle_activated (GtkMenuItem *widget, ParoleMediaList *list);
+
+void parole_media_list_dvd_chapter_activated (GtkMenuItem *widget, ParoleMediaList *list);
 							 
 /*
  * End of GtkBuilder callbacks
@@ -175,6 +185,10 @@ struct ParoleMediaListPrivate
     GtkWidget		*box;
     GtkListStore	*store;
     GtkTreeSelection    *sel;
+    
+    GtkWidget *dvd_menu;
+    GtkWidget *dvd_menu_button;
+    GtkWidget *dvd_label;
 
     GtkWidget *remove_button;
     GtkWidget *clear_button;
@@ -191,9 +205,19 @@ enum
     SHUFFLE_TOGGLED,
     REPEAT_TOGGLED,
     SHOW_PLAYLIST,
+    GST_DVD_NAV_MESSAGE,
     LAST_SIGNAL
 };
 
+enum
+{
+    GST_DVD_ROOT_MENU,
+    GST_DVD_TITLE_MENU,
+    GST_DVD_AUDIO_MENU,
+    GST_DVD_ANGLE_MENU,
+    GST_DVD_CHAPTER_MENU
+};
+
 static guint signals [LAST_SIGNAL] = { 0 };
 
 G_DEFINE_TYPE (ParoleMediaList, parole_media_list, GTK_TYPE_VBOX)
@@ -1031,7 +1055,7 @@ parole_media_list_add_open_containing_folder (ParoleMediaList *list, GtkWidget *
 }
 
 
-static void
+void
 parole_media_list_clear_list (ParoleMediaList *list)
 {
     gtk_list_store_clear (GTK_LIST_STORE (list->priv->store));
@@ -1091,8 +1115,11 @@ parole_media_list_menu_pos (GtkMenu *menu, gint *px, gint *py, gpointer data)
 	window = gtk_widget_get_window( widget );
 	gdk_window_get_position( window, &x, &y );
 	
-	px += x + widget_allocation.x - menu_allocation.width + widget_allocation.width;
-	py += y + widget_allocation.y + widget_allocation.height;
+	if (widget_allocation.width > 100)
+	gtk_widget_set_size_request(GTK_WIDGET(menu), widget_allocation.width, -1);
+	
+	*px = x + widget_allocation.x;
+	*py = y + widget_allocation.y + widget_allocation.height;
 }
 
 static void
@@ -1122,6 +1149,106 @@ menu_detach( GtkMenu *menu )
 	//gtk_menu_detach (menu);
 }
 
+void
+parole_media_list_set_dvd_menu_visible(ParoleMediaList *list, gboolean visible)
+{
+    gtk_widget_set_visible(list->priv->dvd_menu_button, visible);
+}
+
+void
+parole_media_list_add_dvd (ParoleMediaList *list, gchar *dvd_name)
+{
+    //parole_media_list_set_dvd_menu_visible(list, TRUE);
+    
+    gtk_label_set_label(GTK_LABEL(list->priv->dvd_label), dvd_name);
+}
+
+void
+parole_media_list_send_dvd_menu_navigation (ParoleMediaList *list, gint msg_id)
+{
+    g_signal_emit (G_OBJECT (list), signals [GST_DVD_NAV_MESSAGE], 0, msg_id);
+}
+
+void
+parole_media_list_dvd_menu_activated (GtkMenuItem *widget, ParoleMediaList *list)
+{
+    parole_media_list_send_dvd_menu_navigation(list, GST_DVD_ROOT_MENU);
+}
+
+void
+parole_media_list_dvd_title_activated (GtkMenuItem *widget, ParoleMediaList *list)
+{
+    parole_media_list_send_dvd_menu_navigation(list, GST_DVD_TITLE_MENU);
+}
+
+void
+parole_media_list_dvd_audio_activated (GtkMenuItem *widget, ParoleMediaList *list)
+{
+    parole_media_list_send_dvd_menu_navigation(list, GST_DVD_AUDIO_MENU);
+}
+
+void
+parole_media_list_dvd_angle_activated (GtkMenuItem *widget, ParoleMediaList *list)
+{
+    parole_media_list_send_dvd_menu_navigation(list, GST_DVD_ANGLE_MENU);
+}
+
+void
+parole_media_list_dvd_chapter_activated (GtkMenuItem *widget, ParoleMediaList *list)
+{
+    parole_media_list_send_dvd_menu_navigation(list, GST_DVD_CHAPTER_MENU);
+}
+
+
+static void
+parole_media_list_show_dvd_menu (GtkToggleButton *button, ParoleMediaList *list)
+{
+    gboolean toggled = gtk_toggle_button_get_active( button );
+    GtkBuilder *builder;
+	GtkMenu *menu;
+	GtkMenuItem *dvd_menu, *title_menu, *audio_menu, *angle_menu, *chapter_menu;
+	
+	if (!toggled)
+	return;
+	
+	builder = parole_builder_new_from_string (playlist_ui, playlist_ui_length);
+    
+    menu = GTK_MENU (gtk_builder_get_object (builder, "dvd-menu"));
+    
+    dvd_menu =   GTK_MENU_ITEM (gtk_builder_get_object (builder, "dvd-menu-menu"));
+    g_signal_connect (dvd_menu, "activate",
+                      G_CALLBACK (parole_media_list_dvd_menu_activated), list);
+                      
+    title_menu = GTK_MENU_ITEM (gtk_builder_get_object (builder, "dvd-menu-title"));
+    g_signal_connect (title_menu, "activate",
+                      G_CALLBACK (parole_media_list_dvd_title_activated), list);
+                      
+    audio_menu = GTK_MENU_ITEM (gtk_builder_get_object (builder, "dvd-menu-audio"));
+    g_signal_connect (audio_menu, "activate",
+                      G_CALLBACK (parole_media_list_dvd_audio_activated), list);
+                      
+    angle_menu = GTK_MENU_ITEM (gtk_builder_get_object (builder, "dvd-menu-angle"));
+    g_signal_connect (angle_menu, "activate",
+                      G_CALLBACK (parole_media_list_dvd_angle_activated), list);
+                      
+    chapter_menu = GTK_MENU_ITEM (gtk_builder_get_object (builder, "dvd-menu-chapter"));
+    g_signal_connect (chapter_menu, "activate",
+                      G_CALLBACK (parole_media_list_dvd_chapter_activated), list);
+    
+    gtk_menu_attach_to_widget( GTK_MENU(menu), list->priv->dvd_menu_button, (GtkMenuDetachFunc) menu_detach );
+    
+    g_signal_connect_swapped (menu, "selection-done",
+                              G_CALLBACK (parole_media_list_destroy_menu), menu);
+                              
+	g_signal_connect_swapped (menu, "destroy",
+                              G_CALLBACK (parole_media_list_hide_menu), list->priv->dvd_menu_button);
+    
+    gtk_menu_popup (GTK_MENU (menu), 
+                    NULL, NULL,
+                    (GtkMenuPositionFunc) parole_media_list_menu_pos, NULL,
+                    3, gtk_get_current_event_time ());
+}
+
 static void
 parole_media_list_show_button_menu (GtkToggleButton *button, ParoleMediaList *list)
 {
@@ -1383,6 +1510,15 @@ parole_media_list_class_init (ParoleMediaListClass *klass)
                       NULL, NULL,
                       g_cclosure_marshal_VOID__BOOLEAN,
                       G_TYPE_NONE, 1, G_TYPE_BOOLEAN);
+                      
+    signals[GST_DVD_NAV_MESSAGE] = 
+        g_signal_new ("gst-dvd-nav-message",
+                      PAROLE_TYPE_MEDIA_LIST,
+                      G_SIGNAL_RUN_LAST,
+                      G_STRUCT_OFFSET (ParoleMediaListClass, gst_dvd_nav_message),
+                      NULL, NULL,
+                      g_cclosure_marshal_VOID__INT,
+                      G_TYPE_NONE, 1, G_TYPE_INT);
 
     g_type_class_add_private (klass, sizeof (ParoleMediaListPrivate));
     
@@ -1462,6 +1598,13 @@ parole_media_list_init (ParoleMediaList *list)
     
     builder = parole_builder_new_from_string (playlist_ui, playlist_ui_length);
     
+    list->priv->dvd_menu_button = GTK_WIDGET (gtk_builder_get_object(builder, "dvd_menu_button"));
+    list->priv->dvd_menu = GTK_WIDGET (gtk_builder_get_object(builder, "dvd-menu"));
+    list->priv->dvd_label = GTK_WIDGET (gtk_builder_get_object(builder, "dvd_label"));
+    
+    g_signal_connect (GTK_TOGGLE_BUTTON(list->priv->dvd_menu_button), "toggled",
+		      G_CALLBACK (parole_media_list_show_dvd_menu), list);
+    
     list->priv->view = GTK_WIDGET (gtk_builder_get_object (builder, "media-list"));
     
     box = GTK_WIDGET (gtk_builder_get_object (builder, "playlist-box"));
diff --git a/src/parole-medialist.h b/src/parole-medialist.h
index 249008d..8ca04f0 100644
--- a/src/parole-medialist.h
+++ b/src/parole-medialist.h
@@ -70,6 +70,9 @@ typedef struct
 								     
     void			(*show_playlist)		    (ParoleMediaList *list,
 								     gboolean show_playlist);
+								     
+    void			(*gst_dvd_nav_message)		    (ParoleMediaList *list,
+								     gint gst_dvd_nav_message);
     
 } ParoleMediaListClass;
 
@@ -80,6 +83,9 @@ GtkWidget       		*parole_media_list_get              (void);
 void				 parole_media_list_load             (ParoleMediaList *list);
 
 
+void	parole_media_list_clear_list 	  (ParoleMediaList *list);
+
+
 gboolean			 parole_media_list_add_by_path      (ParoleMediaList *list, 
 								     const gchar *path, 
 								     gboolean emit);
@@ -137,6 +143,11 @@ void				 parole_media_list_set_repeat_toggled		(ParoleMediaList *list,
 																
 void 				 parole_media_list_set_shuffle_toggled		(ParoleMediaList *list,
 																gboolean shuffle_toggled);
+																
+void parole_media_list_add_dvd (ParoleMediaList *list, gchar *dvd_name);
+
+							
+void parole_media_list_set_dvd_menu_visible(ParoleMediaList *list, gboolean visible);
 
 G_END_DECLS
 
diff --git a/src/parole-player.c b/src/parole-player.c
index 54c32c6..cbb1fb1 100644
--- a/src/parole-player.c
+++ b/src/parole-player.c
@@ -573,6 +573,8 @@ parole_player_reset (ParolePlayer *player)
 	gtk_tree_row_reference_free (player->priv->row);
 	player->priv->row = NULL;
     }
+    
+    parole_media_list_set_dvd_menu_visible(player->priv->list, FALSE);
 }
 
 
@@ -1004,7 +1006,29 @@ parole_player_disc_selected_cb (ParoleDisc *disc, const gchar *uri, const gchar
     player->priv->current_media_type = parole_gst_get_current_stream_type (PAROLE_GST (player->priv->gst));
     
     if ( player->priv->current_media_type == PAROLE_MEDIA_TYPE_CDDA )
+    {
         player->priv->wait_for_gst_disc_info = TRUE;
+        parole_media_list_set_dvd_menu_visible(player->priv->list, FALSE);
+    }
+    else if (player->priv->current_media_type == PAROLE_MEDIA_TYPE_DVD )
+        parole_media_list_set_dvd_menu_visible(player->priv->list, TRUE);
+    else
+        parole_media_list_set_dvd_menu_visible(player->priv->list, FALSE);
+        
+    
+    parole_media_list_clear_list (player->priv->list);
+}
+
+static void
+parole_player_disc_label_changed_cb (ParoleDisc *disc, const gchar *label, ParolePlayer *player)
+{
+    parole_media_list_add_dvd(player->priv->list, g_strdup(label));
+}
+
+static void
+parole_player_disc_dvd_enabled_cb (ParoleDisc *disc, gboolean enabled, ParolePlayer *player)
+{
+    parole_media_list_set_dvd_menu_visible(player->priv->list, enabled);
 }
 
 static void
@@ -1121,6 +1145,12 @@ parole_player_media_list_show_playlist_cb (ParoleMediaList *list, gboolean show_
 }
 
 static void
+parole_player_media_list_gst_nav_message_cb (ParoleMediaList *list, gint msg_id, ParolePlayer *player)
+{
+    parole_gst_send_navigation_command (PAROLE_GST(player->priv->gst), msg_id);
+}
+
+static void
 parole_player_media_progressed_cb (ParoleGst *gst, const ParoleStream *stream, gint64 value, ParolePlayer *player)
 {
 #ifdef DEBUG
@@ -2680,6 +2710,12 @@ parole_player_init (ParolePlayer *player)
     player->priv->disc = parole_disc_new ();
     g_signal_connect (player->priv->disc, "disc-selected",
 		      G_CALLBACK (parole_player_disc_selected_cb), player);
+		      
+    g_signal_connect (player->priv->disc, "label-changed",
+		      G_CALLBACK (parole_player_disc_label_changed_cb), player);
+		      
+    g_signal_connect (player->priv->disc, "dvd-enabled",
+		      G_CALLBACK (parole_player_disc_dvd_enabled_cb), player);
 	    
     player->priv->screen_saver = parole_screen_saver_new ();
     player->priv->list = PAROLE_MEDIA_LIST (parole_media_list_get ());
@@ -2912,6 +2948,9 @@ parole_player_init (ParolePlayer *player)
 		      
     g_signal_connect (player->priv->list, "show-playlist",
 		      G_CALLBACK (parole_player_media_list_show_playlist_cb), player);
+		      
+    g_signal_connect (player->priv->list, "gst-dvd-nav-message",
+		      G_CALLBACK (parole_player_media_list_gst_nav_message_cb), player);
     
     /*
      * Load auto saved media list.


More information about the Xfce4-commits mailing list