[gnome-software] Deal gracefully with missing AppData



commit 5c6f10db06793e3c1f51e8a86953983702c362aa
Author: Matthias Clasen <mclasen redhat com>
Date:   Wed Sep 18 18:36:20 2013 -0400

    Deal gracefully with missing AppData
    
    Don't abort in the appdata plugin if data is missing.
    In the UI, we hide empty sections of the overview, and if
    the entire overview is empty, we show a placeholder.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=708299

 src/gnome-software.ui             |  286 ++++++++++++++++++++++---------------
 src/gs-shell-overview.c           |   48 ++++++-
 src/plugins/gs-plugin-appstream.c |    8 +-
 3 files changed, 217 insertions(+), 125 deletions(-)
---
diff --git a/src/gnome-software.ui b/src/gnome-software.ui
index 098560c..3a840c8 100644
--- a/src/gnome-software.ui
+++ b/src/gnome-software.ui
@@ -275,134 +275,186 @@
             <property name="show_border">False</property>
             <property name="show_tabs">False</property>
             <child>
-              <object class="GtkScrolledWindow" id="scrolledwindow_overview">
+              <object class="GtkStack" id="stack_overview">
                 <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="shadow_type">none</property>
-                <style>
-                  <class name="main-scrolled-software"/>
-                </style>
                 <child>
-                  <object class="GtkViewport" id="viewport1">
+                  <object class="GtkScrolledWindow" id="scrolledwindow_overview">
                     <property name="visible">True</property>
-                    <property name="can_focus">False</property>
+                    <property name="can_focus">True</property>
+                    <property name="hscrollbar_policy">never</property>
+                    <property name="vscrollbar_policy">automatic</property>
+                    <property name="shadow_type">none</property>
+                    <style>
+                      <class name="main-scrolled-software"/>
+                    </style>
                     <child>
-                      <object class="GtkBox" id="box3">
+                      <object class="GtkViewport" id="viewport_overview">
                         <property name="visible">True</property>
                         <property name="can_focus">False</property>
-                        <property name="orientation">vertical</property>
                         <child>
-                          <object class="GtkLabel" id="label5">
+                          <object class="GtkBox" id="box_overview">
                             <property name="visible">True</property>
                             <property name="can_focus">False</property>
-                            <property name="xalign">0</property>
-                            <property name="margin-top">24</property>
-                            <property name="margin-bottom">12</property>
-                            <property name="margin-left">24</property>
-                            <property name="margin-right">24</property>
-                            <property name="label" translatable="yes">Featured</property>
-                            <style>
-                              <class name="index-title-alignment-software"/>
-                            </style>
-                          </object>
-                          <packing>
-                            <property name="expand">False</property>
-                            <property name="fill">True</property>
-                            <property name="position">0</property>
-                          </packing>
-                        </child>
-                        <child>
-                          <object class="GtkAlignment" id="feature">
-                            <property name="visible">True</property>
-                            <property name="halign">fill</property>
-                            <property name="margin_left">12</property>
-                            <property name="margin_right">12</property>
+                            <property name="orientation">vertical</property>
+                            <child>
+                              <object class="GtkLabel" id="featured_heading">
+                                <property name="visible">True</property>
+                                <property name="can_focus">False</property>
+                                <property name="xalign">0</property>
+                                <property name="margin-top">24</property>
+                                <property name="margin-bottom">12</property>
+                                <property name="margin-left">24</property>
+                                <property name="margin-right">24</property>
+                                <property name="label" translatable="yes">Featured</property>
+                                <style>
+                                  <class name="index-title-alignment-software"/>
+                                </style>
+                              </object>
+                              <packing>
+                                <property name="expand">False</property>
+                                <property name="fill">True</property>
+                                <property name="position">0</property>
+                              </packing>
+                            </child>
+                            <child>
+                              <object class="GtkAlignment" id="bin_featured">
+                                <property name="visible">True</property>
+                                <property name="halign">fill</property>
+                                <property name="margin_left">12</property>
+                                <property name="margin_right">12</property>
+                              </object>
+                              <packing>
+                                <property name="expand">False</property>
+                                <property name="fill">True</property>
+                                <property name="position">1</property>
+                              </packing>
+                            </child>
+                            <child>
+                              <object class="GtkLabel" id="popular_heading">
+                                <property name="visible">True</property>
+                                <property name="can_focus">False</property>
+                                <property name="xalign">0</property>
+                                <property name="label" translatable="yes" comments="Translators: This is a 
heading for software which has been featured ('picked') by the distribution.">Picks</property>
+                                <property name="margin-top">24</property>
+                                <property name="margin-bottom">12</property>
+                                <property name="margin-left">24</property>
+                                <property name="margin-right">24</property>
+                                <style>
+                                  <class name="index-title-alignment-software"/>
+                                </style>
+                              </object>
+                              <packing>
+                                <property name="expand">False</property>
+                                <property name="fill">True</property>
+                                <property name="position">2</property>
+                              </packing>
+                            </child>
+                            <child>
+                              <object class="GtkBox" id="box_popular">
+                                <property name="visible">True</property>
+                                <property name="can_focus">False</property>
+                                <property name="margin_left">12</property>
+                                <property name="margin_right">12</property>
+                                <property name="spacing">12</property>
+                                <property name="homogeneous">True</property>
+                                <property name="valign">start</property>
+                              </object>
+                              <packing>
+                                <property name="expand">False</property>
+                                <property name="fill">True</property>
+                                <property name="position">3</property>
+                              </packing>
+                            </child>
+                            <child>
+                              <object class="GtkLabel" id="category_heading">
+                                <property name="visible">True</property>
+                                <property name="can_focus">False</property>
+                                <property name="xalign">0</property>
+                                <property name="label" translatable="yes">Categories</property>
+                                <property name="margin-top">24</property>
+                                <property name="margin-bottom">12</property>
+                                <property name="margin-left">24</property>
+                                <property name="margin-right">24</property>
+                                <style>
+                                  <class name="index-title-alignment-software"/>
+                                </style>
+                              </object>
+                              <packing>
+                                <property name="expand">False</property>
+                                <property name="fill">True</property>
+                                <property name="position">4</property>
+                              </packing>
+                            </child>
+                            <child>
+                              <object class="GtkGrid" id="grid_categories">
+                                <property name="visible">True</property>
+                                <property name="can_focus">False</property>
+                                <property name="margin_left">12</property>
+                                <property name="margin_right">12</property>
+                                <property name="margin-bottom">24</property>
+                                <property name="row_spacing">12</property>
+                                <property name="column_spacing">12</property>
+                                <property name="row_homogeneous">True</property>
+                                <property name="column_homogeneous">True</property>
+                              </object>
+                              <packing>
+                                <property name="expand">False</property>
+                                <property name="fill">True</property>
+                                <property name="position">5</property>
+                              </packing>
+                            </child>
                           </object>
-                          <packing>
-                            <property name="expand">False</property>
-                            <property name="fill">True</property>
-                            <property name="position">1</property>
-                          </packing>
-                        </child>
-                        <child>
-                          <object class="GtkLabel" id="label1">
-                            <property name="visible">True</property>
-                            <property name="can_focus">False</property>
-                            <property name="xalign">0</property>
-                            <property name="label" translatable="yes" comments="Translators: This is a 
heading for software which has been featured ('picked') by the distribution.">Picks</property>
-                            <property name="margin-top">24</property>
-                            <property name="margin-bottom">12</property>
-                            <property name="margin-left">24</property>
-                            <property name="margin-right">24</property>
-                            <style>
-                              <class name="index-title-alignment-software"/>
-                            </style>
-                          </object>
-                          <packing>
-                            <property name="expand">False</property>
-                            <property name="fill">True</property>
-                            <property name="position">2</property>
-                          </packing>
-                        </child>
-                        <child>
-                          <object class="GtkBox" id="box_popular">
-                            <property name="visible">True</property>
-                            <property name="can_focus">False</property>
-                            <property name="margin_left">12</property>
-                            <property name="margin_right">12</property>
-                            <property name="spacing">12</property>
-                            <property name="homogeneous">True</property>
-                            <property name="valign">start</property>
-                          </object>
-                          <packing>
-                            <property name="expand">False</property>
-                            <property name="fill">True</property>
-                            <property name="position">3</property>
-                          </packing>
-                        </child>
-                        <child>
-                          <object class="GtkLabel" id="label6">
-                            <property name="visible">True</property>
-                            <property name="can_focus">False</property>
-                            <property name="xalign">0</property>
-                            <property name="label" translatable="yes">Categories</property>
-                            <property name="margin-top">24</property>
-                            <property name="margin-bottom">12</property>
-                            <property name="margin-left">24</property>
-                            <property name="margin-right">24</property>
-                            <style>
-                              <class name="index-title-alignment-software"/>
-                            </style>
-                          </object>
-                          <packing>
-                            <property name="expand">False</property>
-                            <property name="fill">True</property>
-                            <property name="position">4</property>
-                          </packing>
-                        </child>
-                        <child>
-                          <object class="GtkGrid" id="grid_categories">
-                            <property name="visible">True</property>
-                            <property name="can_focus">False</property>
-                            <property name="margin_left">12</property>
-                            <property name="margin_right">12</property>
-                            <property name="margin-bottom">24</property>
-                            <property name="row_spacing">12</property>
-                            <property name="column_spacing">12</property>
-                            <property name="row_homogeneous">True</property>
-                            <property name="column_homogeneous">True</property>
-                          </object>
-                          <packing>
-                            <property name="expand">False</property>
-                            <property name="fill">True</property>
-                            <property name="position">5</property>
-                          </packing>
                         </child>
                       </object>
                     </child>
                   </object>
+                  <packing>
+                    <property name="name">overview</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkGrid" id="noresults_grid_overview">
+                    <property name="visible">True</property>
+                    <property name="hexpand">True</property>
+                    <property name="vexpand">True</property>
+                    <property name="halign">center</property>
+                    <property name="valign">center</property>
+                    <property name="row-spacing">12</property>
+                    <property name="column-spacing">12</property>
+                    <style>
+                      <class name="dim-label"/>
+                    </style>
+                    <child>
+                      <object class="GtkImage" id="noappdata_icon">
+                        <property name="visible">True</property>
+                        <property name="icon_name">gnome-software-symbolic</property>
+                        <property name="pixel-size">64</property>
+                        <property name="opacity">0.55</property>
+                      </object>
+                      <packing>
+                        <property name="left-attach">0</property>
+                        <property name="top-attach">0</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkLabel" id="noappdata_label">
+                        <property name="visible">True</property>
+                        <property name="label" translatable="yes">No Application Data Found</property>
+                        <property name="halign">start</property>
+                        <property name="valign">center</property>
+                        <attributes>
+                          <attribute name="scale" value="1.4"/>
+                        </attributes>
+                      </object>
+                      <packing>
+                        <property name="left-attach">1</property>
+                        <property name="top-attach">0</property>
+                      </packing>
+                    </child>
+                  </object>
+                  <packing>
+                    <property name="name">no-results</property>
+                  </packing>
                 </child>
               </object>
             </child>
@@ -681,7 +733,7 @@
                         <property name="margin_bottom">10</property>
                         <property name="hexpand">True</property>
                         <property name="xalign">0</property>
-                        <property name="label"></property>
+                        <property name="label"/>
                         <attributes>
                           <attribute name="weight" value="bold"/>
                           <attribute name="scale" value="1"/>
@@ -737,7 +789,7 @@
                         <property name="halign">start</property>
                         <property name="valign">start</property>
                         <property name="hexpand">True</property>
-                        <property name="label"></property>
+                        <property name="label"/>
                         <property name="margin_bottom">20</property>
                       </object>
                       <packing>
@@ -752,7 +804,7 @@
                         <property name="visible">True</property>
                         <property name="can_focus">False</property>
                         <property name="xalign">0</property>
-                        <property name="label"></property>
+                        <property name="label"/>
                         <property name="wrap">True</property>
                         <property name="margin_bottom">20</property>
                       </object>
diff --git a/src/gs-shell-overview.c b/src/gs-shell-overview.c
index cdd319d..a95da72 100644
--- a/src/gs-shell-overview.c
+++ b/src/gs-shell-overview.c
@@ -40,6 +40,7 @@ struct GsShellOverviewPrivate
        gboolean                 cache_valid;
        GsShell                 *shell;
        gint                     refresh_count;
+       gboolean                 empty;
 };
 
 G_DEFINE_TYPE_WITH_PRIVATE (GsShellOverview, gs_shell_overview, G_TYPE_OBJECT)
@@ -75,8 +76,8 @@ popular_tile_clicked (GsPopularTile *tile, gpointer data)
  **/
 static void
 gs_shell_overview_get_popular_cb (GObject *source_object,
-                       GAsyncResult *res,
-                       gpointer user_data)
+                                 GAsyncResult *res,
+                                 gpointer user_data)
 {
        GsShellOverview *shell = GS_SHELL_OVERVIEW (user_data);
        GsShellOverviewPrivate *priv = shell->priv;
@@ -93,6 +94,7 @@ gs_shell_overview_get_popular_cb (GObject *source_object,
        list = gs_plugin_loader_get_popular_finish (plugin_loader, res, &error);
        if (list == NULL) {
                g_warning ("failed to get popular apps: %s", error->message);
+               gtk_widget_hide (GTK_WIDGET (gtk_builder_get_object (priv->builder, "popular_heading")));
                g_error_free (error);
                goto out;
        }
@@ -105,6 +107,9 @@ gs_shell_overview_get_popular_cb (GObject *source_object,
                          G_CALLBACK (popular_tile_clicked), shell);
                gtk_box_pack_start (GTK_BOX (grid), tile, TRUE, TRUE, 0);
        }
+
+       priv->empty = FALSE;
+
 out:
        priv->refresh_count--;
        if (priv->refresh_count == 0)
@@ -138,20 +143,22 @@ gs_shell_overview_get_featured_cb (GObject *source_object,
        list = gs_plugin_loader_get_featured_finish (plugin_loader, res, &error);
        if (list == NULL) {
                g_warning ("failed to get featured apps: %s", error->message);
+               gtk_widget_hide (GTK_WIDGET (gtk_builder_get_object (priv->builder, "featured_heading")));
                g_error_free (error);
                goto out;
        }
 
        /* at the moment, we only care about the first app */
        app = GS_APP (list->data);
-       box = GTK_WIDGET (gtk_builder_get_object (priv->builder, "feature"));
        tile = gs_feature_tile_new (app);
        g_signal_connect (tile, "clicked",
                          G_CALLBACK (feature_tile_clicked), shell);
 
-       gs_container_remove_all (GTK_CONTAINER (box));
+       box = GTK_WIDGET (gtk_builder_get_object (priv->builder, "bin_featured"));
        gtk_container_add (GTK_CONTAINER (box), tile);
 
+       priv->empty = FALSE;
+
 out:
        g_list_free (list);
 
@@ -188,6 +195,7 @@ gs_shell_overview_get_categories_cb (GObject *source_object,
        GsCategory *cat;
        GtkWidget *grid;
        GtkWidget *tile;
+       gboolean has_category = FALSE;
 
        list = gs_plugin_loader_get_categories_finish (plugin_loader, res, &error);
        if (list == NULL) {
@@ -205,9 +213,15 @@ gs_shell_overview_get_categories_cb (GObject *source_object,
                                  G_CALLBACK (category_tile_clicked), shell);
                gtk_grid_attach (GTK_GRID (grid), tile, i % 3, i / 3, 1, 1);
                i++;
+               has_category = TRUE;
        }
        g_list_free_full (list, g_object_unref);
 out:
+       if (has_category) {
+               priv->empty = FALSE;
+       } else {
+               gtk_widget_hide (GTK_WIDGET (gtk_builder_get_object (priv->builder, "category_heading")));
+       }
        priv->cache_valid = TRUE;
        priv->refresh_count--;
        if (priv->refresh_count == 0)
@@ -247,9 +261,17 @@ gs_shell_overview_refresh (GsShellOverview *shell, gboolean scroll_up)
        if (priv->cache_valid)
                return;
 
+       grid = GTK_WIDGET (gtk_builder_get_object (priv->builder, "bin_featured"));
+       gs_container_remove_all (GTK_CONTAINER (grid));
+
        grid = GTK_WIDGET (gtk_builder_get_object (priv->builder, "box_popular"));
        gs_container_remove_all (GTK_CONTAINER (grid));
 
+       grid = GTK_WIDGET (gtk_builder_get_object (priv->builder, "grid_categories"));
+       gs_container_remove_all (GTK_CONTAINER (grid));
+
+
+       priv->empty = TRUE;
        priv->refresh_count = 3;
 
        gs_plugin_loader_get_featured_async (priv->plugin_loader,
@@ -264,9 +286,6 @@ gs_shell_overview_refresh (GsShellOverview *shell, gboolean scroll_up)
                                            gs_shell_overview_get_popular_cb,
                                            shell);
 
-       grid = GTK_WIDGET (gtk_builder_get_object (priv->builder, "grid_categories"));
-       gs_container_remove_all (GTK_CONTAINER (grid));
-
        gs_plugin_loader_get_categories_async (priv->plugin_loader,
                                               GS_PLUGIN_LOADER_FLAGS_NONE,
                                               priv->cancellable,
@@ -319,6 +338,20 @@ gs_shell_overview_finalize (GObject *object)
        G_OBJECT_CLASS (gs_shell_overview_parent_class)->finalize (object);
 }
 
+static void
+gs_shell_overview_refreshed (GsShellOverview *shell)
+{
+       GsShellOverviewPrivate *priv = shell->priv;
+       GtkWidget *stack;
+
+       stack = GTK_WIDGET (gtk_builder_get_object (priv->builder, "stack_overview"));
+       if (priv->empty) {
+               gtk_stack_set_visible_child_name (GTK_STACK (stack), "no-results");
+       } else {
+               gtk_stack_set_visible_child_name (GTK_STACK (stack), "overview");
+       }
+}
+
 /**
  * gs_shell_overview_class_init:
  **/
@@ -327,6 +360,7 @@ gs_shell_overview_class_init (GsShellOverviewClass *klass)
 {
        GObjectClass *object_class = G_OBJECT_CLASS (klass);
        object_class->finalize = gs_shell_overview_finalize;
+       klass->refreshed = gs_shell_overview_refreshed;
 
        signals [SIGNAL_REFRESHED] =
                g_signal_new ("refreshed",
diff --git a/src/plugins/gs-plugin-appstream.c b/src/plugins/gs-plugin-appstream.c
index 37e7e7a..81857a1 100644
--- a/src/plugins/gs-plugin-appstream.c
+++ b/src/plugins/gs-plugin-appstream.c
@@ -20,8 +20,10 @@
  */
 
 #include <config.h>
+#include <glib/gi18n.h>
 
 #include <gs-plugin.h>
+#include <gs-plugin-loader.h>
 
 #include "appstream-app.h"
 #include "appstream-cache.h"
@@ -190,7 +192,11 @@ gs_plugin_startup (GsPlugin *plugin, GError **error)
        size = appstream_cache_get_size (plugin->priv->cache);
        if (size == 0) {
                g_warning ("No AppStream data, try 'make install-sample-data' in data/");
-               g_assert_not_reached ();
+                g_set_error (error,
+                             gs_plugin_loader_error_quark (),
+                             GS_PLUGIN_LOADER_ERROR_FAILED,
+                             _("No AppStream data found"));
+               //g_assert_not_reached ();
                goto out;
        }
        g_debug ("Parsed %i entries of XML\t:%.1fms", size,



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