[gtk+] Modernize the app chooser dialog



commit 6578c9d876b6a40003696f773acd801fbfa73921
Author: Matthias Clasen <mclasen redhat com>
Date:   Thu Feb 13 00:14:42 2014 -0500

    Modernize the app chooser dialog
    
    This is according to suggestions in
    https://bugzilla.gnome.org/show_bug.cgi?id=724218

 gtk/gtkappchooserdialog.c                 |  119 +++++++++++++--------------
 gtk/gtkappchooserwidget.c                 |   29 ++++---
 gtk/resources/ui/gtkappchooserdialog.ui   |   19 +++--
 gtk/resources/ui/gtkappchooserdialog.ui.h |    3 +-
 gtk/resources/ui/gtkappchooserwidget.ui   |  125 +++++++++++++++++++----------
 gtk/resources/ui/gtkappchooserwidget.ui.h |    1 +
 6 files changed, 170 insertions(+), 126 deletions(-)
---
diff --git a/gtk/gtkappchooserdialog.c b/gtk/gtkappchooserdialog.c
index d100e30..57be9cf 100644
--- a/gtk/gtkappchooserdialog.c
+++ b/gtk/gtkappchooserdialog.c
@@ -66,13 +66,13 @@ struct _GtkAppChooserDialogPrivate {
   char *heading;
 
   GtkWidget *label;
-  GtkWidget *software_button;
   GtkWidget *inner_box;
 
   GtkWidget *open_label;
 
   GtkWidget *app_chooser_widget;
   GtkWidget *show_more_button;
+  GtkWidget *software_button;
 
   gboolean show_more_clicked;
   gboolean dismissed;
@@ -165,18 +165,18 @@ get_extension (const char *basename)
 static void
 set_dialog_properties (GtkAppChooserDialog *self)
 {
-  gchar *label;
   gchar *name;
   gchar *extension;
   gchar *description;
-  gchar *default_text;
   gchar *string;
   gboolean unknown;
-  PangoFontDescription *font_desc;
+  gchar *title;
+  gchar *subtitle;
+  gboolean use_header;
+  GtkWidget *header;
 
   name = NULL;
   extension = NULL;
-  label = NULL;
   description = NULL;
   unknown = TRUE;
 
@@ -192,48 +192,54 @@ set_dialog_properties (GtkAppChooserDialog *self)
       unknown = g_content_type_is_unknown (self->priv->content_type);
     }
 
-  gtk_window_set_title (GTK_WINDOW (self), "");
-
   if (name != NULL)
     {
+      title = g_strdup (_("Select Application"));
       /* Translators: %s is a filename */
-      label = g_strdup_printf (_("Select an application to open “%s”"), name);
-      string = g_strdup_printf (_("No applications available to open “%s”"),
-                                name);
+      subtitle = g_strdup_printf (_("Opening “%s”."), name);
+      string = g_strdup_printf (_("No applications found for “%s”"), name);
     }
   else
     {
+      title = g_strdup (_("Select Application"));
       /* Translators: %s is a file type description */
-      label = g_strdup_printf (_("Select an application for “%s” files"),
-                               unknown ? self->priv->content_type : description);
-      string = g_strdup_printf (_("No applications available to open “%s” files"),
-                               unknown ? self->priv->content_type : description);
+      subtitle = g_strdup_printf (_("Opening “%s” files."), 
+                                  unknown ? self->priv->content_type : description);
+      string = g_strdup_printf (_("No applications found for “%s” files"),
+                                unknown ? self->priv->content_type : description);
     }
 
-  font_desc = pango_font_description_new ();
-  pango_font_description_set_weight (font_desc, PANGO_WEIGHT_BOLD);
-  gtk_widget_override_font (self->priv->label, font_desc);
-  pango_font_description_free (font_desc);
+  g_object_get (self, "use-header-bar", &use_header, NULL); 
+  if (use_header)
+    {
+      header = gtk_dialog_get_header_bar (GTK_DIALOG (self));
+      gtk_header_bar_set_title (GTK_HEADER_BAR (header), title);
+      gtk_header_bar_set_subtitle (GTK_HEADER_BAR (header), subtitle);
+    }
+  else
+    {
+      gtk_window_set_title (GTK_WINDOW (self), _("Select Application"));
+    }
 
   if (self->priv->heading != NULL)
-    gtk_label_set_markup (GTK_LABEL (self->priv->label), self->priv->heading);
+    {
+      gtk_label_set_markup (GTK_LABEL (self->priv->label), self->priv->heading);
+      gtk_widget_show (self->priv->label);
+    }
   else
-    gtk_label_set_markup (GTK_LABEL (self->priv->label), label);
-
-  default_text = g_strdup_printf ("<big><b>%s</b></big>\n%s",
-                                  string,
-                                  _("Click \"Show other applications\", for more options, or "
-                                    "\"Software\" to install a new application"));
+    {
+      gtk_widget_hide (self->priv->label);
+    }
 
   gtk_app_chooser_widget_set_default_text (GTK_APP_CHOOSER_WIDGET (self->priv->app_chooser_widget),
-                                           default_text);
+                                           string);
 
-  g_free (label);
+  g_free (title);
+  g_free (subtitle);
   g_free (name);
   g_free (extension);
   g_free (description);
   g_free (string);
-  g_free (default_text);
 }
 
 static void
@@ -323,8 +329,7 @@ construct_appchooser_widget (GtkAppChooserDialog *self)
   GAppInfo *info;
 
   /* Need to build the appchooser widget after, because of the content-type construct-only property */
-  self->priv->app_chooser_widget =
-    gtk_app_chooser_widget_new (self->priv->content_type);
+  self->priv->app_chooser_widget = gtk_app_chooser_widget_new (self->priv->content_type);
   gtk_box_pack_start (GTK_BOX (self->priv->inner_box), self->priv->app_chooser_widget, TRUE, TRUE, 0);
   gtk_widget_show (self->priv->app_chooser_widget);
 
@@ -338,8 +343,11 @@ construct_appchooser_widget (GtkAppChooserDialog *self)
                     G_CALLBACK (widget_populate_popup_cb), self);
 
   /* Add the custom button to the new appchooser */
-  gtk_box_pack_start (GTK_BOX (self->priv->app_chooser_widget),
-                     self->priv->show_more_button, FALSE, FALSE, 6);
+  gtk_box_pack_start (GTK_BOX (self->priv->inner_box),
+                     self->priv->show_more_button, FALSE, FALSE, 0);
+
+  gtk_box_pack_start (GTK_BOX (self->priv->inner_box),
+                     self->priv->software_button, FALSE, FALSE, 0);
 
   info = gtk_app_chooser_get_app_info (GTK_APP_CHOOSER (self->priv->app_chooser_widget));
   gtk_dialog_set_response_sensitive (GTK_DIALOG (self), GTK_RESPONSE_OK, info != NULL);
@@ -434,34 +442,9 @@ static void
 ensure_software_button (GtkAppChooserDialog *self)
 {
   if (g_find_program_in_path ("gnome-software"))
-    {
-      GtkWidget *parent;
-      gboolean use_header;
-
-      self->priv->software_button = gtk_button_new_with_label (_("Software"));
-
-      gtk_button_set_always_show_image (GTK_BUTTON (self->priv->software_button), TRUE);
-      gtk_button_set_image (GTK_BUTTON (self->priv->software_button), gtk_image_new_from_icon_name 
("gnome-software", GTK_ICON_SIZE_BUTTON));
-      gtk_widget_set_valign (self->priv->software_button, GTK_ALIGN_CENTER);
-      g_signal_connect (self->priv->software_button, "clicked",
-                        G_CALLBACK (software_button_clicked_cb), self);
-      gtk_widget_show (self->priv->software_button);
-      
-      g_object_get (self, "use-header-bar", &use_header, NULL);
-      if (use_header)
-        {
-          parent = gtk_dialog_get_header_bar (GTK_DIALOG (self));
-          gtk_header_bar_pack_end (GTK_HEADER_BAR (parent), self->priv->software_button);
-        }
-      else
-        {
-G_GNUC_BEGIN_IGNORE_DEPRECATIONS
-          parent = gtk_dialog_get_action_area (GTK_DIALOG (self));
-          gtk_container_add (GTK_CONTAINER (parent), self->priv->software_button);
-          gtk_button_box_set_child_secondary (GTK_BUTTON_BOX (parent), self->priv->software_button, TRUE);
-G_GNUC_END_IGNORE_DEPRECATIONS
-        }
-    }
+    gtk_widget_show (self->priv->software_button);
+  else
+    gtk_widget_hide (self->priv->software_button);
 }
 
 static void
@@ -611,8 +594,10 @@ gtk_app_chooser_dialog_class_init (GtkAppChooserDialogClass *klass)
                                               "/org/gtk/libgtk/ui/gtkappchooserdialog.ui");
   gtk_widget_class_bind_template_child_private (widget_class, GtkAppChooserDialog, label);
   gtk_widget_class_bind_template_child_private (widget_class, GtkAppChooserDialog, show_more_button);
+  gtk_widget_class_bind_template_child_private (widget_class, GtkAppChooserDialog, software_button);
   gtk_widget_class_bind_template_child_private (widget_class, GtkAppChooserDialog, inner_box);
   gtk_widget_class_bind_template_callback (widget_class, show_more_button_clicked_cb);
+  gtk_widget_class_bind_template_callback (widget_class, software_button_clicked_cb);
 }
 
 static void
@@ -754,8 +739,18 @@ gtk_app_chooser_dialog_set_heading (GtkAppChooserDialog *self,
   g_free (self->priv->heading);
   self->priv->heading = g_strdup (heading);
 
-  if (self->priv->label && self->priv->heading)
-    gtk_label_set_markup (GTK_LABEL (self->priv->label), self->priv->heading);
+  if (self->priv->label)
+    {
+      if (self->priv->heading)
+        {
+          gtk_label_set_markup (GTK_LABEL (self->priv->label), self->priv->heading);
+          gtk_widget_show (self->priv->label);
+        }
+      else
+        {
+          gtk_widget_hide (self->priv->label);
+        }
+    }
 
   g_object_notify (G_OBJECT (self), "heading");
 }
diff --git a/gtk/gtkappchooserwidget.c b/gtk/gtkappchooserwidget.c
index 213a8b2..652f934 100644
--- a/gtk/gtkappchooserwidget.c
+++ b/gtk/gtkappchooserwidget.c
@@ -38,6 +38,7 @@
 #include "gtktreemodelsort.h"
 #include "gtkorientable.h"
 #include "gtkscrolledwindow.h"
+#include "gtklabel.h"
 
 #include <string.h>
 #include <glib/gi18n-lib.h>
@@ -81,6 +82,8 @@ struct _GtkAppChooserWidgetPrivate {
 
   GtkWidget *program_list;
   GtkListStore *program_list_store;
+  GtkWidget *no_apps_label;
+  GtkWidget *no_apps;
 
   GtkTreeViewColumn *column;
   GtkCellRenderer *padding_renderer;
@@ -438,7 +441,7 @@ gtk_app_chooser_sort_func (GtkTreeModel *model,
       goto out;
     }
 
-  /* they're both recommended/falback or not, so if one is a heading, wins */
+  /* they're both recommended/fallback or not, so if one is a heading, wins */
   if (a_heading)
     {
       retval = -1;
@@ -660,15 +663,13 @@ add_no_applications_label (GtkAppChooserWidget *self)
 {
   gchar *text = NULL, *desc = NULL;
   const gchar *string;
-  GtkTreeIter iter;
 
   if (self->priv->default_text == NULL)
     {
       if (self->priv->content_type)
        desc = g_content_type_get_description (self->priv->content_type);
 
-      string = text = g_strdup_printf (_("No applications available to open “%s”"),
-                                       desc);
+      string = text = g_strdup_printf (_("No applications found for “%s”."), desc);
       g_free (desc);
     }
   else
@@ -676,11 +677,7 @@ add_no_applications_label (GtkAppChooserWidget *self)
       string = self->priv->default_text;
     }
 
-  gtk_list_store_append (self->priv->program_list_store, &iter);
-  gtk_list_store_set (self->priv->program_list_store, &iter,
-                      COLUMN_HEADING_TEXT, string,
-                      COLUMN_HEADING, TRUE,
-                      -1);
+  gtk_label_set_text (GTK_LABEL (self->priv->no_apps_label), string);
 
   g_free (text);
 }
@@ -693,7 +690,8 @@ gtk_app_chooser_widget_select_first (GtkAppChooserWidget *self)
   GtkTreeModel *model;
 
   model = gtk_tree_view_get_model (GTK_TREE_VIEW (self->priv->program_list));
-  gtk_tree_model_get_iter_first (model, &iter);
+  if (!gtk_tree_model_get_iter_first (model, &iter))
+    return;
 
   while (info == NULL)
     {
@@ -791,7 +789,14 @@ gtk_app_chooser_widget_real_add_items (GtkAppChooserWidget *self)
     }
 
   if (!apps_added)
-    add_no_applications_label (self);
+    {
+      add_no_applications_label (self);
+      gtk_widget_show (self->priv->no_apps);
+    }
+  else
+    {
+      gtk_widget_hide (self->priv->no_apps);
+    }
 
   gtk_app_chooser_widget_select_first (self);
 
@@ -1110,6 +1115,8 @@ gtk_app_chooser_widget_class_init (GtkAppChooserWidgetClass *klass)
   gtk_widget_class_bind_template_child_private (widget_class, GtkAppChooserWidget, column);
   gtk_widget_class_bind_template_child_private (widget_class, GtkAppChooserWidget, padding_renderer);
   gtk_widget_class_bind_template_child_private (widget_class, GtkAppChooserWidget, secondary_padding);
+  gtk_widget_class_bind_template_child_private (widget_class, GtkAppChooserWidget, no_apps_label);
+  gtk_widget_class_bind_template_child_private (widget_class, GtkAppChooserWidget, no_apps);
   gtk_widget_class_bind_template_callback (widget_class, refresh_and_emit_app_selected);
   gtk_widget_class_bind_template_callback (widget_class, program_list_selection_activated);
   gtk_widget_class_bind_template_callback (widget_class, widget_button_press_event_cb);
diff --git a/gtk/resources/ui/gtkappchooserdialog.ui b/gtk/resources/ui/gtkappchooserdialog.ui
index 791379c..07e40bf 100644
--- a/gtk/resources/ui/gtkappchooserdialog.ui
+++ b/gtk/resources/ui/gtkappchooserdialog.ui
@@ -40,7 +40,7 @@
                   <object class="GtkLabel" id="label">
                     <property name="visible">True</property>
                     <property name="can_focus">False</property>
-                    <property name="halign">start</property>
+                    <property name="halign">center</property>
                     <property name="valign">center</property>
                     <property name="label" translatable="yes">label</property>
                     <property name="wrap">True</property>
@@ -74,17 +74,20 @@
       </object>
     </child>
   </template>
-  <object class="GtkImage" id="show_more_image">
-    <property name="visible">True</property>
-    <property name="can_focus">False</property>
-    <property name="icon_name">list-add-symbolic</property>
-  </object>
   <object class="GtkButton" id="show_more_button">
-    <property name="label" translatable="yes">Show Other Applications</property>
+    <property name="label" translatable="yes">_View All Application</property>
     <property name="visible">True</property>
+    <property name="use_underline">True</property>
     <property name="can_focus">True</property>
     <property name="receives_default">True</property>
-    <property name="image">show_more_image</property>
     <signal name="clicked" handler="show_more_button_clicked_cb" swapped="no"/>
   </object>
+  <object class="GtkButton" id="software_button">
+    <property name="label" translatable="yes">_Find Applications in Software </property>
+    <property name="visible">True</property>
+    <property name="use_underline">True</property>
+    <property name="can_focus">True</property>
+    <property name="receives_default">True</property>
+    <signal name="clicked" handler="software_button_clicked_cb" swapped="no"/>
+  </object>
 </interface>
diff --git a/gtk/resources/ui/gtkappchooserdialog.ui.h b/gtk/resources/ui/gtkappchooserdialog.ui.h
index ee8dd3e..c0e9306 100644
--- a/gtk/resources/ui/gtkappchooserdialog.ui.h
+++ b/gtk/resources/ui/gtkappchooserdialog.ui.h
@@ -1,3 +1,4 @@
 N_("Select Application");
 N_("label");
-N_("Show Other Applications");
+N_("_View All Application");
+N_("_Find Applications in Software ");
diff --git a/gtk/resources/ui/gtkappchooserwidget.ui b/gtk/resources/ui/gtkappchooserwidget.ui
index 5cf807c..4b23628 100644
--- a/gtk/resources/ui/gtkappchooserwidget.ui
+++ b/gtk/resources/ui/gtkappchooserwidget.ui
@@ -32,64 +32,101 @@
     <property name="can_focus">False</property>
     <property name="orientation">vertical</property>
     <child>
-      <object class="GtkScrolledWindow" id="scrolled_window">
-        <property name="width_request">400</property>
-        <property name="height_request">300</property>
+      <object class="GtkOverlay" id="overlay">
         <property name="visible">True</property>
-        <property name="can_focus">True</property>
-        <property name="hscrollbar_policy">never</property>
-        <property name="shadow_type">in</property>
         <child>
-          <object class="GtkTreeView" id="program_list">
+          <object class="GtkScrolledWindow" id="scrolled_window">
+            <property name="width_request">400</property>
+            <property name="height_request">300</property>
             <property name="visible">True</property>
             <property name="can_focus">True</property>
-            <property name="model">program_list_sort</property>
-            <property name="headers_visible">False</property>
-            <signal name="button-press-event" handler="widget_button_press_event_cb" swapped="no"/>
-            <signal name="row-activated" handler="program_list_selection_activated" swapped="no"/>
-            <child internal-child="selection">
-              <object class="GtkTreeSelection" id="treeview-selection2">
-                <property name="mode">browse</property>
-                <signal name="changed" handler="refresh_and_emit_app_selected" object="GtkAppChooserWidget" 
swapped="yes"/>
-              </object>
-            </child>
+            <property name="hscrollbar_policy">never</property>
+            <property name="shadow_type">in</property>
             <child>
-              <object class="GtkTreeViewColumn" id="column">
-                <child>
-                  <object class="GtkCellRendererText" id="padding_renderer"/>
-                </child>
-                <child>
-                  <object class="GtkCellRendererText" id="heading">
-                    <property name="ypad">6</property>
-                    <property name="wrap_mode">word</property>
-                    <property name="wrap_width">350</property>
+              <object class="GtkTreeView" id="program_list">
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="model">program_list_sort</property>
+                <property name="headers_visible">False</property>
+                <signal name="button-press-event" handler="widget_button_press_event_cb" swapped="no"/>
+                <signal name="row-activated" handler="program_list_selection_activated" swapped="no"/>
+                <child internal-child="selection">
+                  <object class="GtkTreeSelection" id="treeview-selection2">
+                    <property name="mode">browse</property>
+                    <signal name="changed" handler="refresh_and_emit_app_selected" 
object="GtkAppChooserWidget" swapped="yes"/>
                   </object>
-                  <attributes>
-                    <attribute name="visible">6</attribute>
-                    <attribute name="markup">7</attribute>
-                  </attributes>
-                </child>
-                <child>
-                  <object class="GtkCellRendererText" id="secondary_padding"/>
-                </child>
-                <child>
-                  <object class="GtkCellRendererPixbuf" id="app_icon"/>
-                  <attributes>
-                    <attribute name="gicon">1</attribute>
-                  </attributes>
                 </child>
                 <child>
-                  <object class="GtkCellRendererText" id="app_name">
-                    <property name="ellipsize">end</property>
+                  <object class="GtkTreeViewColumn" id="column">
+                    <child>
+                      <object class="GtkCellRendererText" id="padding_renderer"/>
+                    </child>
+                    <child>
+                      <object class="GtkCellRendererText" id="heading">
+                        <property name="ypad">6</property>
+                        <property name="wrap_mode">word</property>
+                        <property name="wrap_width">350</property>
+                      </object>
+                      <attributes>
+                        <attribute name="visible">6</attribute>
+                        <attribute name="markup">7</attribute>
+                      </attributes>
+                    </child>
+                    <child>
+                      <object class="GtkCellRendererText" id="secondary_padding"/>
+                    </child>
+                    <child>
+                      <object class="GtkCellRendererPixbuf" id="app_icon"/>
+                      <attributes>
+                        <attribute name="gicon">1</attribute>
+                      </attributes>
+                    </child>
+                    <child>
+                      <object class="GtkCellRendererText" id="app_name">
+                        <property name="ellipsize">end</property>
+                      </object>
+                      <attributes>
+                        <attribute name="markup">3</attribute>
+                      </attributes>
+                    </child>
                   </object>
-                  <attributes>
-                    <attribute name="markup">3</attribute>
-                  </attributes>
                 </child>
               </object>
             </child>
           </object>
         </child>
+        <child type="overlay">
+          <object class="GtkBox" id="no_apps">
+            <property name="orientation">vertical</property>
+            <property name="halign">center</property>
+            <property name="valign">center</property>
+            <child>
+              <object class="GtkImage">
+                <property name="visible">True</property>
+                <property name="icon-name">gnome-software-symbolic</property>
+                <property name="pixel-size">48</property>
+                <property name="margin">12</property>
+                <style>
+                  <class name="dim-label"/>
+                </style>
+              </object>
+            </child>
+            <child>
+              <object class="GtkLabel" id="no_apps_label">
+                <property name="visible">True</property>
+                <property name="label" translatable="yes">No applications found.</property>
+                <property name="halign">center</property>
+                <property name="valign">center</property>
+                <attributes>
+                  <attribute name="scale" value="1.2"/>
+                </attributes>
+                <style>
+                  <class name="dim-label"/>
+                </style>
+              </object>
+            </child>
+          </object>
+        </child>
       </object>
       <packing>
         <property name="expand">True</property>
diff --git a/gtk/resources/ui/gtkappchooserwidget.ui.h b/gtk/resources/ui/gtkappchooserwidget.ui.h
index e69de29..35d9fd3 100644
--- a/gtk/resources/ui/gtkappchooserwidget.ui.h
+++ b/gtk/resources/ui/gtkappchooserwidget.ui.h
@@ -0,0 +1 @@
+N_("No applications found.");


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