[rygel] ui: Improve preferences dialog, bug 663631



commit f68fdfe1fed2af11f4ef01b221afb044cc1065a5
Author: David King <amigadave amigadave com>
Date:   Tue Nov 8 15:34:10 2011 +0100

    ui: Improve preferences dialog, bug 663631
    
    Add tooltips to the widgets in the preferences dialog. Add +/-
    ToolButtons for adding and removing shared directories. Update the
    sensitivity of the remove toolbutton, based on whether a row in the URI
    model is selected, or if the model is empty. Remove the GtkAlignments
    and use padding on containers. Set the correct response ID on the close
    button. Set the entry text column in the GtkBuilder file.

 TODO                                   |    1 -
 data/rygel-preferences.ui              |  341 +++++++++++++++-----------------
 src/ui/rygel-media-pref-section.vala   |   47 +++--
 src/ui/rygel-network-pref-section.vala |    7 +-
 4 files changed, 193 insertions(+), 203 deletions(-)
---
diff --git a/TODO b/TODO
index 992c026..07e15b5 100644
--- a/TODO
+++ b/TODO
@@ -54,7 +54,6 @@
 
   * UI
     * Make sure we restart rygel when configuration changes.
-    * Fix tooltips.
     * Get interfaces directly from NM.
     * Show available APs for Wifi interface.
 
diff --git a/data/rygel-preferences.ui b/data/rygel-preferences.ui
index 7a2780d..3a2aaac 100644
--- a/data/rygel-preferences.ui
+++ b/data/rygel-preferences.ui
@@ -1,11 +1,14 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <interface>
-  <requires lib="gtk+" version="2.16"/>
+  <!-- interface-requires gtk+ 3.0 -->
   <object class="GtkAdjustment" id="adjustment1">
     <property name="upper">65525</property>
     <property name="step_increment">1</property>
     <property name="page_increment">10</property>
   </object>
+  <object class="GtkSizeGroup" id="general-labels-sizegroup">
+    <property name="mode">both</property>
+  </object>
   <object class="GtkListStore" id="iface-liststore">
     <columns>
       <!-- column-name interface -->
@@ -18,7 +21,7 @@
     <property name="can_focus">False</property>
     <property name="hexpand">True</property>
     <property name="vexpand">True</property>
-    <property name="border_width">5</property>
+    <property name="border_width">6</property>
     <property name="title" translatable="yes">Rygel Preferences</property>
     <property name="default_height">400</property>
     <property name="type_hint">dialog</property>
@@ -28,219 +31,156 @@
         <property name="can_focus">False</property>
         <property name="orientation">vertical</property>
         <property name="spacing">12</property>
-        <child internal-child="action_area">
-          <object class="GtkButtonBox" id="dialog-action_area1">
+        <child>
+          <object class="GtkGrid" id="grid1">
             <property name="visible">True</property>
             <property name="can_focus">False</property>
-            <property name="layout_style">end</property>
+            <property name="row_spacing">12</property>
+            <property name="column_spacing">12</property>
             <child>
-              <object class="GtkButton" id="button3">
-                <property name="label">gtk-close</property>
+              <object class="GtkCheckButton" id="upnp-checkbutton">
+                <property name="label" translatable="yes">_Share media through DLNA</property>
+                <property name="use_action_appearance">False</property>
                 <property name="visible">True</property>
                 <property name="can_focus">True</property>
-                <property name="has_focus">True</property>
-                <property name="can_default">True</property>
-                <property name="has_default">True</property>
-                <property name="receives_default">True</property>
+                <property name="receives_default">False</property>
+                <property name="has_tooltip">True</property>
+                <property name="tooltip_markup" translatable="yes">Enable sharing of media, such as photos, videos and music, with DLNA</property>
+                <property name="tooltip_text" translatable="yes">Enable sharing of media, such as photos, videos and music, with DLNA</property>
                 <property name="use_action_appearance">False</property>
-                <property name="use_stock">True</property>
+                <property name="use_underline">True</property>
+                <property name="xalign">0</property>
+                <property name="draw_indicator">True</property>
               </object>
               <packing>
-                <property name="expand">False</property>
-                <property name="fill">False</property>
-                <property name="position">0</property>
+                <property name="left_attach">0</property>
+                <property name="top_attach">0</property>
+                <property name="width">2</property>
+                <property name="height">1</property>
               </packing>
             </child>
-          </object>
-        </child>
-        <child>
-          <object class="GtkAlignment" id="alignment1">
-            <property name="visible">True</property>
-            <property name="can_focus">False</property>
-            <property name="top_padding">12</property>
-            <property name="bottom_padding">12</property>
-            <property name="left_padding">12</property>
-            <property name="right_padding">12</property>
             <child>
-              <object class="GtkVBox" id="vbox1">
+              <object class="GtkGrid" id="grid2">
                 <property name="visible">True</property>
                 <property name="can_focus">False</property>
-                <property name="spacing">12</property>
+                <property name="margin_left">12</property>
                 <child>
-                  <object class="GtkCheckButton" id="upnp-checkbutton">
-                    <property name="label" translatable="yes">_Share media through DLNA</property>
+                  <object class="GtkScrolledWindow" id="scrolledwindow1">
                     <property name="visible">True</property>
                     <property name="can_focus">True</property>
-                    <property name="receives_default">False</property>
-                    <property name="use_action_appearance">False</property>
-                    <property name="use_underline">True</property>
-                    <property name="xalign">0</property>
-                    <property name="draw_indicator">True</property>
-                  </object>
-                  <packing>
-                    <property name="expand">False</property>
-                    <property name="fill">False</property>
-                    <property name="position">0</property>
-                  </packing>
-                </child>
-                <child>
-                  <object class="GtkAlignment" id="alignment2">
-                    <property name="visible">True</property>
-                    <property name="can_focus">False</property>
-                    <property name="xalign">0</property>
-                    <property name="left_padding">12</property>
+                    <property name="hexpand">True</property>
+                    <property name="vexpand">True</property>
+                    <property name="shadow_type">in</property>
                     <child>
-                      <object class="GtkHBox" id="hbox2">
+                      <object class="GtkTreeView" id="uris-treeview">
                         <property name="visible">True</property>
-                        <property name="can_focus">False</property>
-                        <property name="spacing">12</property>
-                        <child>
-                          <object class="GtkScrolledWindow" id="scrolledwindow1">
-                            <property name="visible">True</property>
-                            <property name="can_focus">True</property>
-                            <property name="hexpand">True</property>
-                            <property name="vexpand">True</property>
-                            <property name="shadow_type">in</property>
-                            <child>
-                              <object class="GtkTreeView" id="uris-treeview">
-                                <property name="visible">True</property>
-                                <property name="can_focus">True</property>
-                                <property name="hexpand">True</property>
-                                <property name="vexpand">True</property>
-                                <property name="model">uris-liststore</property>
-                                <property name="headers_visible">False</property>
-                                <property name="search_column">0</property>
-                                <property name="fixed_height_mode">True</property>
-                                <child internal-child="selection">
-                                  <object class="GtkTreeSelection" id="treeview-selection"/>
-                                </child>
-                              </object>
-                            </child>
-                          </object>
-                          <packing>
-                            <property name="expand">True</property>
-                            <property name="fill">True</property>
-                            <property name="position">0</property>
-                          </packing>
-                        </child>
-                        <child>
-                          <object class="GtkVButtonBox" id="vbuttonbox1">
-                            <property name="visible">True</property>
-                            <property name="can_focus">False</property>
-                            <property name="spacing">5</property>
-                            <property name="layout_style">start</property>
-                            <child>
-                              <object class="GtkButton" id="add-button">
-                                <property name="label">gtk-add</property>
-                                <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="use_underline">True</property>
-                                <property name="use_stock">True</property>
-                              </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-button">
-                                <property name="label">gtk-remove</property>
-                                <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="use_stock">True</property>
-                              </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-button">
-                                <property name="label">gtk-clear</property>
-                                <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="use_underline">True</property>
-                                <property name="use_stock">True</property>
-                              </object>
-                              <packing>
-                                <property name="expand">False</property>
-                                <property name="fill">True</property>
-                                <property name="position">2</property>
-                              </packing>
-                            </child>
-                          </object>
-                          <packing>
-                            <property name="expand">False</property>
-                            <property name="fill">True</property>
-                            <property name="position">1</property>
-                          </packing>
+                        <property name="can_focus">True</property>
+                        <property name="hexpand">True</property>
+                        <property name="vexpand">True</property>
+                        <property name="model">uris-liststore</property>
+                        <property name="headers_visible">False</property>
+                        <property name="search_column">0</property>
+                        <property name="fixed_height_mode">True</property>
+                        <child internal-child="selection">
+                          <object class="GtkTreeSelection" id="treeview-selection"/>
                         </child>
                       </object>
                     </child>
                   </object>
                   <packing>
-                    <property name="expand">True</property>
-                    <property name="fill">True</property>
-                    <property name="position">1</property>
+                    <property name="left_attach">0</property>
+                    <property name="top_attach">0</property>
+                    <property name="width">1</property>
+                    <property name="height">1</property>
                   </packing>
                 </child>
                 <child>
-                  <object class="GtkAlignment" id="alignment3">
+                  <object class="GtkToolbar" id="toolbar1">
                     <property name="visible">True</property>
                     <property name="can_focus">False</property>
-                    <property name="xalign">0</property>
-                    <property name="left_padding">12</property>
                     <child>
-                      <object class="GtkHBox" id="hbox1">
+                      <object class="GtkToolButton" id="add-button">
+                        <property name="use_action_appearance">False</property>
                         <property name="visible">True</property>
                         <property name="can_focus">False</property>
-                        <property name="spacing">6</property>
-                        <child>
-                          <object class="GtkLabel" id="iface-label">
-                            <property name="visible">True</property>
-                            <property name="can_focus">False</property>
-                            <property name="xalign">0</property>
-                            <property name="label" translatable="yes" comments="Network Interface">_Network</property>
-                            <property name="use_underline">True</property>
-                          </object>
-                          <packing>
-                            <property name="expand">False</property>
-                            <property name="fill">True</property>
-                            <property name="position">0</property>
-                          </packing>
-                        </child>
-                        <child>
-                          <object class="GtkComboBoxText" id="iface-entry">
-                            <property name="visible">True</property>
-                            <property name="can_focus">False</property>
-                            <items>
-                              <item translatable="yes">Any</item>
-                            </items>
-                          </object>
-                          <packing>
-                            <property name="expand">True</property>
-                            <property name="fill">True</property>
-                            <property name="position">1</property>
-                          </packing>
-                        </child>
+                        <property name="tooltip_text" translatable="yes">Add a directory to the list of shared directories</property>
+                        <property name="use_action_appearance">False</property>
+                        <property name="label" translatable="yes">Add shared directory</property>
+                        <property name="icon_name">list-add-symbolic</property>
                       </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="homogeneous">True</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkToolButton" id="remove-button">
+                        <property name="use_action_appearance">False</property>
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="tooltip_text" translatable="yes">Remove a directory from the list of shared directories</property>
+                        <property name="use_action_appearance">False</property>
+                        <property name="label" translatable="yes">Remove shared directory</property>
+                        <property name="icon_name">list-add-symbolic</property>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="homogeneous">True</property>
+                      </packing>
                     </child>
                   </object>
                   <packing>
-                    <property name="expand">False</property>
-                    <property name="fill">False</property>
-                    <property name="position">2</property>
+                    <property name="left_attach">0</property>
+                    <property name="top_attach">1</property>
+                    <property name="width">1</property>
+                    <property name="height">1</property>
                   </packing>
                 </child>
               </object>
+              <packing>
+                <property name="left_attach">0</property>
+                <property name="top_attach">1</property>
+                <property name="width">2</property>
+                <property name="height">1</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkLabel" id="iface-label">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="margin_left">12</property>
+                <property name="xalign">0</property>
+                <property name="label" translatable="yes" comments="Network Interface">_Network:</property>
+                <property name="use_underline">True</property>
+                <property name="mnemonic_widget">iface-entry</property>
+              </object>
+              <packing>
+                <property name="left_attach">0</property>
+                <property name="top_attach">2</property>
+                <property name="width">1</property>
+                <property name="height">1</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkComboBoxText" id="iface-entry">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="has_tooltip">True</property>
+                <property name="tooltip_markup" translatable="yes">Select the network interface that DLNA media will be shared on, or share media on all interfaces</property>
+                <property name="tooltip_text" translatable="yes">Select the network interface that DLNA media will be shared on, or share media on all interfaces</property>
+                <property name="hexpand">True</property>
+                <property name="entry_text_column">0</property>
+                <property name="id_column">1</property>
+                <items>
+                  <item translatable="yes">Any</item>
+                </items>
+              </object>
+              <packing>
+                <property name="left_attach">1</property>
+                <property name="top_attach">2</property>
+                <property name="width">1</property>
+                <property name="height">1</property>
+              </packing>
             </child>
           </object>
           <packing>
@@ -249,12 +189,45 @@
             <property name="position">0</property>
           </packing>
         </child>
+        <child internal-child="action_area">
+          <object class="GtkButtonBox" id="dialog-action_area1">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="layout_style">end</property>
+            <child>
+              <object class="GtkButton" id="button3">
+                <property name="label">gtk-close</property>
+                <property name="use_action_appearance">False</property>
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="has_focus">True</property>
+                <property name="can_default">True</property>
+                <property name="has_default">True</property>
+                <property name="receives_default">True</property>
+                <property name="use_action_appearance">False</property>
+                <property name="use_stock">True</property>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">False</property>
+                <property name="position">0</property>
+              </packing>
+            </child>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">True</property>
+            <property name="pack_type">end</property>
+            <property name="position">0</property>
+          </packing>
+        </child>
       </object>
     </child>
     <action-widgets>
-      <action-widget response="0">button3</action-widget>
+      <action-widget response="-7">button3</action-widget>
     </action-widgets>
   </object>
+  <object class="GtkSizeGroup" id="plugin-labels-sizegroup"/>
   <object class="GtkFileChooserDialog" id="uris-dialog">
     <property name="can_focus">False</property>
     <property name="can_default">True</property>
@@ -282,6 +255,7 @@
             <child>
               <object class="GtkButton" id="button4">
                 <property name="label">gtk-cancel</property>
+                <property name="use_action_appearance">False</property>
                 <property name="visible">True</property>
                 <property name="can_focus">True</property>
                 <property name="can_default">True</property>
@@ -298,6 +272,7 @@
             <child>
               <object class="GtkButton" id="button5">
                 <property name="label">gtk-open</property>
+                <property name="use_action_appearance">False</property>
                 <property name="visible">True</property>
                 <property name="can_focus">True</property>
                 <property name="can_default">True</property>
@@ -313,6 +288,12 @@
               </packing>
             </child>
           </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">True</property>
+            <property name="pack_type">end</property>
+            <property name="position">0</property>
+          </packing>
         </child>
         <child>
           <placeholder/>
@@ -324,10 +305,6 @@
       <action-widget response="-5">button5</action-widget>
     </action-widgets>
   </object>
-  <object class="GtkSizeGroup" id="general-labels-sizegroup">
-    <property name="mode">both</property>
-  </object>
-  <object class="GtkSizeGroup" id="plugin-labels-sizegroup"/>
   <object class="GtkListStore" id="uris-liststore">
     <columns>
       <!-- column-name path -->
diff --git a/src/ui/rygel-media-pref-section.vala b/src/ui/rygel-media-pref-section.vala
index a3d1a9e..e05234b 100644
--- a/src/ui/rygel-media-pref-section.vala
+++ b/src/ui/rygel-media-pref-section.vala
@@ -31,13 +31,15 @@ public class Rygel.MediaPrefSection : PreferencesSection {
     const string URIS_DIALOG = URIS_KEY + "-dialog";
     const string ADD_BUTTON = "add-button";
     const string REMOVE_BUTTON = "remove-button";
-    const string CLEAR_BUTTON = "clear-button";
+    const string TREE_SELECTION = "treeview-selection";
 
     private ArrayList<Widget> widgets; // All widgets in this section
 
     private TreeView treeview;
     private ListStore liststore;
+    private TreeSelection tree_selection;
     private FileChooserDialog dialog;
+    private ToolButton remove_button;
 
     public MediaPrefSection (Builder            builder,
                              WritableUserConfig config) {
@@ -49,6 +51,9 @@ public class Rygel.MediaPrefSection : PreferencesSection {
         assert (this.treeview != null);
         this.liststore = (ListStore) builder.get_object (URIS_LISTSTORE);
         assert (this.liststore != null);
+        this.tree_selection = builder.get_object (TREE_SELECTION)
+                                                  as TreeSelection;
+        assert (this.tree_selection != null);
         this.dialog = (FileChooserDialog) builder.get_object (URIS_DIALOG);
         assert (this.dialog != null);
 
@@ -74,17 +79,17 @@ public class Rygel.MediaPrefSection : PreferencesSection {
         this.dialog.set_current_folder (Environment.get_home_dir ());
         this.dialog.show_hidden = false;
 
-        var button = (Button) builder.get_object (ADD_BUTTON);
-        button.clicked.connect (this.on_add_button_clicked);
-        this.widgets.add (button);
+        var add_button = builder.get_object (ADD_BUTTON) as ToolButton;
+        add_button.clicked.connect (this.on_add_button_clicked);
+        this.widgets.add (add_button);
 
-        button = (Button) builder.get_object (REMOVE_BUTTON);
-        button.clicked.connect (this.on_remove_button_clicked);
-        this.widgets.add (button);
+        remove_button = builder.get_object (REMOVE_BUTTON) as ToolButton;
+        remove_button.clicked.connect (this.on_remove_button_clicked);
+        this.widgets.add (remove_button);
 
-        button = (Button) builder.get_object (CLEAR_BUTTON);
-        button.clicked.connect (this.on_clear_button_clicked);
-        this.widgets.add (button);
+        // Update the sensitivity of the remove button
+        this.on_tree_selection_changed ();
+        this.tree_selection.changed.connect (this.on_tree_selection_changed);
     }
 
     public override void save () {
@@ -108,9 +113,14 @@ public class Rygel.MediaPrefSection : PreferencesSection {
         foreach (var widget in this.widgets) {
             widget.sensitive = sensitivity;
         }
+
+        // Force an update of the remove button.
+        if (sensitivity) {
+            this.on_tree_selection_changed ();
+        }
     }
 
-    private void on_add_button_clicked (Button button) {
+    private void on_add_button_clicked (ToolButton button) {
         if (this.dialog.run () == ResponseType.OK) {
             TreeIter iter;
 
@@ -131,7 +141,7 @@ public class Rygel.MediaPrefSection : PreferencesSection {
         this.dialog.hide ();
     }
 
-    private void on_remove_button_clicked (Button button) {
+    private void on_remove_button_clicked (ToolButton button) {
         var selection = this.treeview.get_selection ();
         var rows = selection.get_selected_rows (null);
 
@@ -152,10 +162,6 @@ public class Rygel.MediaPrefSection : PreferencesSection {
         }
     }
 
-    private void on_clear_button_clicked (Button button) {
-        this.liststore.clear ();
-    }
-
     private string get_real_uri (string uri) {
         switch (uri) {
         case "@MUSIC@":
@@ -182,4 +188,13 @@ public class Rygel.MediaPrefSection : PreferencesSection {
             return uri;
         }
     }
+
+    private void on_tree_selection_changed () {
+        // Remove button cannot be sensitive if no row is selected
+        if (tree_selection.get_selected (null, null)) {
+            remove_button.set_sensitive (true);
+        } else {
+            remove_button.set_sensitive (false);
+        }
+    }
 }
diff --git a/src/ui/rygel-network-pref-section.vala b/src/ui/rygel-network-pref-section.vala
index 4997f14..0e6c8bc 100644
--- a/src/ui/rygel-network-pref-section.vala
+++ b/src/ui/rygel-network-pref-section.vala
@@ -25,7 +25,6 @@ using GUPnP;
 
 public class Rygel.NetworkPrefSection : PreferencesSection {
     const string IFACE_ENTRY = "iface-entry";
-    const string ANY_NETWORK = "Any";
 
     private ComboBoxText iface_entry;
 
@@ -40,10 +39,9 @@ public class Rygel.NetworkPrefSection : PreferencesSection {
 
         this.context_manager = new ContextManager (null, 0);
 
-        // Apparently glade/GtkBuilder is unable to do this for us
-        this.iface_entry.set_entry_text_column (0);
         try {
             this.iface_entry.append_text (config.get_interface ());
+            // TODO: Set the current interface to be active.
             this.iface_entry.set_active (0);
         } catch (GLib.Error err) {
             // No problem if we fail to read the config, the default values
@@ -59,7 +57,8 @@ public class Rygel.NetworkPrefSection : PreferencesSection {
     public override void save () {
         var iface = this.iface_entry.get_active_text ();
 
-        if (iface == ANY_NETWORK) {
+        // The zeroth item is "Any" network. -1 represents no active item.
+        if (this.iface_entry.active <= 0 ) {
             iface = "";
         }
 



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