[gnome-software/wip/templates: 1/6] Use a GtkBuilder template for GsShellUpdates



commit 3555b40d80a0774f921021fe521bc008b5251a39
Author: Kalev Lember <kalevlember gmail com>
Date:   Thu Mar 27 00:12:59 2014 +0100

    Use a GtkBuilder template for GsShellUpdates
    
    Move the UI definition to separate file and use a GtkBuilder template
    for subclassing the widget.

 po/POTFILES.in                   |    1 +
 src/Makefile.am                  |    1 +
 src/gnome-software.gresource.xml |    1 +
 src/gnome-software.ui            |  280 +-------------------------------------
 src/gs-shell-updates.c           |   89 +++++++-----
 src/gs-shell-updates.h           |    4 +-
 src/gs-shell-updates.ui          |  286 ++++++++++++++++++++++++++++++++++++++
 src/gs-shell.c                   |    3 +-
 8 files changed, 345 insertions(+), 320 deletions(-)
---
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 10b376e..d2c8ada 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -24,6 +24,7 @@ src/gs-shell-installed.c
 src/gs-shell-overview.c
 src/gs-shell-search.c
 src/gs-shell-updates.c
+[type: gettext/glade]src/gs-shell-updates.ui
 src/gs-sources-dialog.c
 [type: gettext/glade]src/gs-sources-dialog.ui
 src/gs-update-dialog.c
diff --git a/src/Makefile.am b/src/Makefile.am
index a284e6d..7dfef77 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -33,6 +33,7 @@ UI_FILES =                                            \
        feature-tile.ui                                 \
        gnome-software.ui                               \
        gs-history-dialog.ui                            \
+       gs-shell-updates.ui                             \
        gs-sources-dialog.ui                            \
        gs-star-widget.ui                               \
        gs-update-dialog.ui                             \
diff --git a/src/gnome-software.gresource.xml b/src/gnome-software.gresource.xml
index a851a6d..872a046 100644
--- a/src/gnome-software.gresource.xml
+++ b/src/gnome-software.gresource.xml
@@ -11,6 +11,7 @@
   <file preprocess="xml-stripblanks">app-folder-dialog.ui</file>
   <file preprocess="xml-stripblanks">screenshot-image.ui</file>
   <file preprocess="xml-stripblanks">gs-history-dialog.ui</file>
+  <file preprocess="xml-stripblanks">gs-shell-updates.ui</file>
   <file preprocess="xml-stripblanks">gs-sources-dialog.ui</file>
   <file preprocess="xml-stripblanks">gs-star-widget.ui</file>
   <file preprocess="xml-stripblanks">gs-update-dialog.ui</file>
diff --git a/src/gnome-software.ui b/src/gnome-software.ui
index 5fae66c..9305bd2 100644
--- a/src/gnome-software.ui
+++ b/src/gnome-software.ui
@@ -834,286 +834,8 @@
               </packing>
             </child>
             <child>
-              <object class="GtkStack" id="stack_updates">
+              <object class="GsShellUpdates" id="shell_updates">
                 <property name="visible">True</property>
-                <child internal-child="accessible">
-                  <object class="AtkObject" id="updates-accessible">
-                    <property name="accessible-name" translatable="yes">Updates page</property>
-                  </object>
-                </child>
-                <child>
-                  <object class="GtkBox" id="updates_spinner_box">
-                    <property name="visible">True</property>
-                    <property name="orientation">vertical</property>
-                    <property name="spacing">12</property>
-                    <property name="halign">center</property>
-                    <property name="valign">center</property>
-                    <property name="hexpand">True</property>
-                    <property name="vexpand">True</property>
-                    <style>
-                      <class name="dim-label"/>
-                    </style>
-                    <child>
-                      <object class="GtkSpinner" id="spinner_updates">
-                        <property name="visible">True</property>
-                        <property name="width_request">128</property>
-                        <property name="height_request">128</property>
-                        <property name="halign">center</property>
-                        <property name="valign">center</property>
-                        <property name="hexpand">True</property>
-                        <property name="vexpand">True</property>
-                      </object>
-                    </child>
-                    <child>
-                      <object class="GtkLabel" id="label_updates_spinner">
-                        <property name="visible">True</property>
-                        <property name="can_focus">False</property>
-                        <property name="label"></property>
-                        <property name="justify">center</property>
-                        <attributes>
-                          <attribute name="scale" value="1.4"/>
-                        </attributes>
-                      </object>
-                    </child>
-                  </object>
-                  <packing>
-                    <property name="name">spinner</property>
-                  </packing>
-                </child>
-                <child>
-                  <object class="GtkScrolledWindow" id="scrolledwindow_updates">
-                    <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="GtkBox" id="list_box_updates_box">
-                        <property name="visible">True</property>
-                        <property name="orientation">vertical</property>
-                        <child>
-                          <object class="GtkListBox" id="list_box_updates">
-                            <property name="visible">True</property>
-                            <property name="can_focus">True</property>
-                            <property name="selection_mode">none</property>
-                          </object>
-                        </child>
-                        <child>
-                          <object class="GtkSeparator" id="list_box_updates_separator">
-                            <property name="visible">True</property>
-                            <property name="orientation">horizontal</property>
-                          </object>
-                        </child>
-                      </object>
-                    </child>
-                  </object>
-                  <packing>
-                    <property name="name">view</property>
-                  </packing>
-                </child>
-                <child>
-                  <object class="GtkBox" id="updates_uptodate_box">
-                    <property name="visible">True</property>
-                    <property name="orientation">vertical</property>
-                    <property name="spacing">48</property>
-                    <property name="hexpand">True</property>
-                    <property name="vexpand">True</property>
-                    <style>
-                      <class name="dim-label"/>
-                    </style>
-                    <child type="center">
-                      <object class="GtkBox" id="updates_uptodate_centerbox">
-                        <property name="visible">True</property>
-                        <property name="orientation">vertical</property>
-                        <property name="spacing">12</property>
-                        <child>
-                          <object class="GtkImage" id="image_updates">
-                            <property name="visible">True</property>
-                            <property name="can_focus">False</property>
-                            <property name="pixel_size">128</property>
-                            <property name="icon_name">object-select-symbolic</property>
-                          </object>
-                        </child>
-                        <child>
-                          <object class="GtkLabel" id="label10">
-                            <property name="visible">True</property>
-                            <property name="can_focus">False</property>
-                            <property name="label" translatable="yes">Software is up to date</property>
-                            <attributes>
-                              <attribute name="scale" value="1.4"/>
-                            </attributes>
-                          </object>
-                        </child>
-                      </object>
-                    </child>
-                    <child>
-                      <object class="GtkLabel" id="label_updates_last_checked">
-                        <property name="visible">True</property>
-                        <property name="can_focus">False</property>
-                        <property name="margin_bottom">32</property>
-                        <property name="label">Last checked: HH:MM</property>
-                      </object>
-                      <packing>
-                        <property name="pack_type">end</property>
-                      </packing>
-                    </child>
-                  </object>
-                  <packing>
-                    <property name="name">uptodate</property>
-                  </packing>
-                </child>
-
-                <child>
-                  <object class="GtkBox" id="updates_mobile_box">
-                    <property name="visible">True</property>
-                    <property name="orientation">vertical</property>
-                    <property name="spacing">12</property>
-                    <property name="halign">center</property>
-                    <property name="valign">center</property>
-                    <property name="hexpand">True</property>
-                    <property name="vexpand">True</property>
-                    <style>
-                      <class name="dim-label"/>
-                    </style>
-                    <child>
-                      <object class="GtkImage" id="image_updates_mobile">
-                        <property name="visible">True</property>
-                        <property name="can_focus">False</property>
-                        <property name="pixel_size">128</property>
-                        <property name="icon_name">dialog-warning-symbolic</property>
-                      </object>
-                    </child>
-                    <child>
-                      <object class="GtkLabel" id="label_updates_mobile">
-                        <property name="visible">True</property>
-                        <property name="can_focus">False</property>
-                        <property name="label" translatable="yes">Checking for updates when using mobile 
broadband could cause you to incur charges</property>
-                        <property name="wrap">True</property>
-                        <property name="halign">center</property>
-                        <property name="max-width-chars">40</property>
-                        <property name="justify">center</property>
-                        <attributes>
-                          <attribute name="scale" value="1.4"/>
-                        </attributes>
-                      </object>
-                    </child>
-                    <child>
-                      <object class="GtkButton" id="button_updates_mobile">
-                        <property name="label" translatable="yes">_Check Anyway</property>
-                        <property name="width_request">150</property>
-                        <property name="visible">True</property>
-                        <property name="can_focus">True</property>
-                        <property name="receives_default">False</property>
-                        <property name="use_underline">True</property>
-                        <property name="hexpand">False</property>
-                        <property name="halign">center</property>
-                      </object>
-                      <packing>
-                        <property name="expand">False</property>
-                        <property name="fill">False</property>
-                      </packing>
-                    </child>
-                  </object>
-                  <packing>
-                    <property name="name">mobile</property>
-                  </packing>
-                </child>
-
-                <child>
-                  <object class="GtkBox" id="updates_offline_box">
-                    <property name="visible">True</property>
-                    <property name="orientation">vertical</property>
-                    <property name="spacing">12</property>
-                    <property name="halign">center</property>
-                    <property name="valign">center</property>
-                    <property name="hexpand">True</property>
-                    <property name="vexpand">True</property>
-                    <style>
-                      <class name="dim-label"/>
-                    </style>
-                    <child>
-                      <object class="GtkImage" id="image_updates_offline">
-                        <property name="visible">True</property>
-                        <property name="can_focus">False</property>
-                        <property name="pixel_size">128</property>
-                        <property name="icon_name">network-offline-symbolic</property>
-                      </object>
-                    </child>
-                    <child>
-                      <object class="GtkLabel" id="label_updates_offline">
-                        <property name="visible">True</property>
-                        <property name="can_focus">False</property>
-                        <property name="label" translatable="yes">Go online to check for updates</property>
-                        <property name="wrap">True</property>
-                        <property name="halign">center</property>
-                        <property name="justify">center</property>
-                        <attributes>
-                          <attribute name="scale" value="1.4"/>
-                        </attributes>
-                      </object>
-                    </child>
-                    <child>
-                      <object class="GtkButton" id="button_updates_offline">
-                        <property name="label" translatable="yes">_Network Settings</property>
-                        <property name="width_request">150</property>
-                        <property name="visible">True</property>
-                        <property name="can_focus">True</property>
-                        <property name="receives_default">False</property>
-                        <property name="use_underline">True</property>
-                        <property name="hexpand">False</property>
-                        <property name="halign">center</property>
-                      </object>
-                      <packing>
-                        <property name="expand">False</property>
-                        <property name="fill">False</property>
-                      </packing>
-                    </child>
-                  </object>
-                  <packing>
-                    <property name="name">offline</property>
-                  </packing>
-                </child>
-
-                <child>
-                  <object class="GtkBox" id="updates_failed_box">
-                    <property name="visible">True</property>
-                    <property name="orientation">vertical</property>
-                    <property name="spacing">12</property>
-                    <property name="halign">center</property>
-                    <property name="valign">center</property>
-                    <property name="hexpand">True</property>
-                    <property name="vexpand">True</property>
-                    <style>
-                      <class name="dim-label"/>
-                    </style>
-                    <child>
-                      <object class="GtkImage" id="image_updates_failed">
-                        <property name="visible">True</property>
-                        <property name="can_focus">False</property>
-                        <property name="pixel_size">128</property>
-                        <property name="icon_name">action-unavailable-symbolic</property>
-                      </object>
-                    </child>
-                    <child>
-                      <object class="GtkLabel" id="label_updates_failed">
-                        <property name="visible">True</property>
-                        <property name="can_focus">False</property>
-                        <property name="wrap">True</property>
-                        <property name="max-width-chars">60</property>
-                        <property name="label" translatable="No">Failed to get updates</property>
-                        <attributes>
-                          <attribute name="scale" value="1.4"/>
-                        </attributes>
-                      </object>
-                    </child>
-                  </object>
-                  <packing>
-                    <property name="name">failed</property>
-                  </packing>
-                </child>
               </object>
               <packing>
                 <property name="name">updates</property>
diff --git a/src/gs-shell-updates.c b/src/gs-shell-updates.c
index a9b5628..4b63bcb 100644
--- a/src/gs-shell-updates.c
+++ b/src/gs-shell-updates.c
@@ -59,7 +59,6 @@ struct GsShellUpdatesPrivate
        GCancellable            *cancellable_refresh;
        GSettings               *settings;
        GSettings               *desktop_settings;
-       GtkListBox              *list_box_updates;
        gboolean                 cache_valid;
        GsShell                 *shell;
        GtkWidget               *update_dialog;
@@ -67,6 +66,16 @@ struct GsShellUpdatesPrivate
        GsShellUpdatesState      state;
        gboolean                 has_agreed_to_mobile_data;
        gboolean                 ampm_available;
+
+       GtkWidget               *button_updates_mobile;
+       GtkWidget               *button_updates_offline;
+       GtkWidget               *label_updates_failed;
+       GtkWidget               *label_updates_last_checked;
+       GtkWidget               *label_updates_spinner;
+       GtkWidget               *list_box_updates;
+       GtkWidget               *scrolledwindow_updates;
+       GtkWidget               *spinner_updates;
+       GtkWidget               *stack_updates;
 };
 
 enum {
@@ -76,7 +85,7 @@ enum {
        COLUMN_UPDATE_LAST
 };
 
-G_DEFINE_TYPE_WITH_PRIVATE (GsShellUpdates, gs_shell_updates, G_TYPE_OBJECT)
+G_DEFINE_TYPE_WITH_PRIVATE (GsShellUpdates, gs_shell_updates, GTK_TYPE_BIN)
 
 /**
  * gs_shell_updates_invalidate:
@@ -201,18 +210,17 @@ gs_shell_updates_update_ui_state (GsShellUpdates *shell_updates)
        }
 
        /* main spinner */
-       widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "spinner_updates"));
        switch (priv->state) {
        case GS_SHELL_UPDATES_STATE_STARTUP:
        case GS_SHELL_UPDATES_STATE_ACTION_REFRESH_NO_UPDATES:
        case GS_SHELL_UPDATES_STATE_ACTION_GET_UPDATES:
-               gs_start_spinner (GTK_SPINNER (widget));
+               gs_start_spinner (GTK_SPINNER (priv->spinner_updates));
                break;
        case GS_SHELL_UPDATES_STATE_ACTION_REFRESH_HAS_UPDATES:
        case GS_SHELL_UPDATES_STATE_NO_UPDATES:
        case GS_SHELL_UPDATES_STATE_HAS_UPDATES:
        case GS_SHELL_UPDATES_STATE_FAILED:
-               gs_stop_spinner (GTK_SPINNER (widget));
+               gs_stop_spinner (GTK_SPINNER (priv->spinner_updates));
                break;
        default:
                g_assert_not_reached ();
@@ -220,26 +228,25 @@ gs_shell_updates_update_ui_state (GsShellUpdates *shell_updates)
        }
 
        /* spinner text */
-       widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "label_updates_spinner"));
        switch (priv->state) {
        case GS_SHELL_UPDATES_STATE_STARTUP:
                tmp = g_strdup_printf ("%s\n%s",
                                       /* TRANSLATORS: the updates panel is starting up */
                                       _("Setting up updates…"),
                                       _("(This could take a while)"));
-               gtk_label_set_label (GTK_LABEL (widget), tmp);
+               gtk_label_set_label (GTK_LABEL (priv->label_updates_spinner), tmp);
                g_free (tmp);
        case GS_SHELL_UPDATES_STATE_ACTION_REFRESH_NO_UPDATES:
                tmp = g_strdup_printf ("%s\n%s",
                                       /* TRANSLATORS: the updates panel is starting up */
                                       _("Looking for new updates…"),
                                       _("(This could take a while)"));
-               gtk_label_set_label (GTK_LABEL (widget), tmp);
+               gtk_label_set_label (GTK_LABEL (priv->label_updates_spinner), tmp);
                g_free (tmp);
                break;
        case GS_SHELL_UPDATES_STATE_ACTION_GET_UPDATES:
                /* TRANSLATORS: this is when the updates panel is starting up */
-               gtk_label_set_label (GTK_LABEL (widget), _("Checking for updates…"));
+               gtk_label_set_label (GTK_LABEL (priv->label_updates_spinner), _("Checking for updates…"));
                break;
        case GS_SHELL_UPDATES_STATE_ACTION_REFRESH_HAS_UPDATES:
        case GS_SHELL_UPDATES_STATE_NO_UPDATES:
@@ -308,12 +315,11 @@ gs_shell_updates_update_ui_state (GsShellUpdates *shell_updates)
        }
 
        /* stack */
-       widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "stack_updates"));
        switch (priv->state) {
        case GS_SHELL_UPDATES_STATE_STARTUP:
        case GS_SHELL_UPDATES_STATE_ACTION_REFRESH_NO_UPDATES:
        case GS_SHELL_UPDATES_STATE_ACTION_GET_UPDATES:
-               gtk_stack_set_visible_child_name (GTK_STACK (widget), "spinner");
+               gtk_stack_set_visible_child_name (GTK_STACK (priv->stack_updates), "spinner");
                break;
        case GS_SHELL_UPDATES_STATE_NO_UPDATES:
                /* check we have a "free" network connection */
@@ -321,16 +327,16 @@ gs_shell_updates_update_ui_state (GsShellUpdates *shell_updates)
                case PK_NETWORK_ENUM_ONLINE:
                case PK_NETWORK_ENUM_WIFI:
                case PK_NETWORK_ENUM_WIRED:
-                       gtk_stack_set_visible_child_name (GTK_STACK (widget), "uptodate");
+                       gtk_stack_set_visible_child_name (GTK_STACK (priv->stack_updates), "uptodate");
                        break;
                case PK_NETWORK_ENUM_OFFLINE:
-                       gtk_stack_set_visible_child_name (GTK_STACK (widget), "offline");
+                       gtk_stack_set_visible_child_name (GTK_STACK (priv->stack_updates), "offline");
                        break;
                case PK_NETWORK_ENUM_MOBILE:
                        if (priv->has_agreed_to_mobile_data) {
-                               gtk_stack_set_visible_child_name (GTK_STACK (widget), "uptodate");
+                               gtk_stack_set_visible_child_name (GTK_STACK (priv->stack_updates), 
"uptodate");
                        } else {
-                               gtk_stack_set_visible_child_name (GTK_STACK (widget), "mobile");
+                               gtk_stack_set_visible_child_name (GTK_STACK (priv->stack_updates), "mobile");
                        }
                        break;
                default:
@@ -339,10 +345,10 @@ gs_shell_updates_update_ui_state (GsShellUpdates *shell_updates)
                break;
        case GS_SHELL_UPDATES_STATE_HAS_UPDATES:
        case GS_SHELL_UPDATES_STATE_ACTION_REFRESH_HAS_UPDATES:
-               gtk_stack_set_visible_child_name (GTK_STACK (widget), "view");
+               gtk_stack_set_visible_child_name (GTK_STACK (priv->stack_updates), "view");
                break;
        case GS_SHELL_UPDATES_STATE_FAILED:
-               gtk_stack_set_visible_child_name (GTK_STACK (widget), "failed");
+               gtk_stack_set_visible_child_name (GTK_STACK (priv->stack_updates), "failed");
                break;
        default:
                g_assert_not_reached ();
@@ -350,18 +356,18 @@ gs_shell_updates_update_ui_state (GsShellUpdates *shell_updates)
        }
 
        /* last checked label */
-       if (g_strcmp0 (gtk_stack_get_visible_child_name (GTK_STACK (widget)), "uptodate") == 0) {
-               widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "label_updates_last_checked"));
+       if (g_strcmp0 (gtk_stack_get_visible_child_name (GTK_STACK (priv->stack_updates)), "uptodate") == 0) {
                tmp = gs_shell_updates_last_checked_time_string (shell_updates);
                if (tmp != NULL) {
                        gchar *last_checked;
 
                        /* TRANSLATORS: This is the time when we last checked for updates */
                        last_checked = g_strdup_printf (_("Last checked: %s"), tmp);
-                       gtk_label_set_label (GTK_LABEL (widget), last_checked);
+                       gtk_label_set_label (GTK_LABEL (priv->label_updates_last_checked),
+                                            last_checked);
                        g_free (last_checked);
                }
-               gtk_widget_set_visible (widget, tmp != NULL);
+               gtk_widget_set_visible (priv->label_updates_last_checked, tmp != NULL);
                g_free (tmp);
        }
 }
@@ -443,9 +449,8 @@ gs_shell_updates_get_updates_cb (GsPluginLoader *plugin_loader,
                                                    GS_SHELL_UPDATES_STATE_NO_UPDATES);
                } else {
                        g_warning ("failed to get updates: %s", error->message);
-                       widget = GTK_WIDGET (gtk_builder_get_object (priv->builder,
-                                                                    "label_updates_failed"));
-                       gtk_label_set_label (GTK_LABEL (widget), error->message);
+                       gtk_label_set_label (GTK_LABEL (priv->label_updates_failed),
+                                            error->message);
                        gs_shell_updates_set_state (shell_updates,
                                                    GS_SHELL_UPDATES_STATE_FAILED);
                }
@@ -502,10 +507,9 @@ gs_shell_updates_refresh (GsShellUpdates *shell_updates,
                gtk_widget_set_visible (widget, TRUE);
        }
 
-       widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "scrolledwindow_updates"));
        if (scroll_up) {
                GtkAdjustment *adj;
-               adj = gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (widget));
+               adj = gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW 
(priv->scrolledwindow_updates));
                gtk_adjustment_set_value (adj, gtk_adjustment_get_lower (adj));
        }
 
@@ -634,7 +638,6 @@ gs_shell_updates_refresh_cb (GsPluginLoader *plugin_loader,
        gboolean ret;
        GDateTime *now;
        GsShellUpdatesPrivate *priv = shell_updates->priv;
-       GtkWidget *widget;
 
        /* get the results */
        ret = gs_plugin_loader_refresh_finish (plugin_loader, res, &error);
@@ -659,9 +662,8 @@ gs_shell_updates_refresh_cb (GsPluginLoader *plugin_loader,
                        return;
                }
                g_warning ("failed to refresh: %s", error->message);
-               widget = GTK_WIDGET (gtk_builder_get_object (priv->builder,
-                                                            "label_updates_failed"));
-               gtk_label_set_label (GTK_LABEL (widget), error->message);
+               gtk_label_set_label (GTK_LABEL (priv->label_updates_failed),
+                                    error->message);
                gs_shell_updates_set_state (shell_updates,
                                            GS_SHELL_UPDATES_STATE_FAILED);
                g_error_free (error);
@@ -990,14 +992,13 @@ gs_shell_updates_setup (GsShellUpdates *shell_updates,
        priv->cancellable = g_object_ref (cancellable);
 
        /* setup updates */
-       priv->list_box_updates = GTK_LIST_BOX (gtk_builder_get_object (priv->builder, "list_box_updates"));
        g_signal_connect (priv->list_box_updates, "row-activated",
                          G_CALLBACK (gs_shell_updates_activated_cb), shell_updates);
-       gtk_list_box_set_header_func (priv->list_box_updates,
+       gtk_list_box_set_header_func (GTK_LIST_BOX (priv->list_box_updates),
                                      gs_shell_updates_list_header_func,
                                      shell_updates,
                                      NULL);
-       gtk_list_box_set_sort_func (priv->list_box_updates,
+       gtk_list_box_set_sort_func (GTK_LIST_BOX (priv->list_box_updates),
                                    gs_shell_updates_sort_func,
                                    shell_updates, NULL);
 
@@ -1009,12 +1010,10 @@ gs_shell_updates_setup (GsShellUpdates *shell_updates,
        g_signal_connect (widget, "clicked",
                          G_CALLBACK (gs_shell_updates_button_refresh_cb),
                          shell_updates);
-       widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "button_updates_mobile"));
-       g_signal_connect (widget, "clicked",
+       g_signal_connect (priv->button_updates_mobile, "clicked",
                          G_CALLBACK (gs_shell_updates_button_mobile_refresh_cb),
                          shell_updates);
-       widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "button_updates_offline"));
-       g_signal_connect (widget, "clicked",
+       g_signal_connect (priv->button_updates_offline, "clicked",
                          G_CALLBACK (gs_shell_updates_button_network_settings_cb),
                          shell_updates);
        priv->update_dialog = gs_update_dialog_new ();
@@ -1038,7 +1037,21 @@ static void
 gs_shell_updates_class_init (GsShellUpdatesClass *klass)
 {
        GObjectClass *object_class = G_OBJECT_CLASS (klass);
+       GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+
        object_class->finalize = gs_shell_updates_finalize;
+
+       gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/software/gs-shell-updates.ui");
+
+       gtk_widget_class_bind_template_child_private (widget_class, GsShellUpdates, button_updates_mobile);
+       gtk_widget_class_bind_template_child_private (widget_class, GsShellUpdates, button_updates_offline);
+       gtk_widget_class_bind_template_child_private (widget_class, GsShellUpdates, label_updates_failed);
+       gtk_widget_class_bind_template_child_private (widget_class, GsShellUpdates, 
label_updates_last_checked);
+       gtk_widget_class_bind_template_child_private (widget_class, GsShellUpdates, label_updates_spinner);
+       gtk_widget_class_bind_template_child_private (widget_class, GsShellUpdates, list_box_updates);
+       gtk_widget_class_bind_template_child_private (widget_class, GsShellUpdates, scrolledwindow_updates);
+       gtk_widget_class_bind_template_child_private (widget_class, GsShellUpdates, spinner_updates);
+       gtk_widget_class_bind_template_child_private (widget_class, GsShellUpdates, stack_updates);
 }
 
 /**
@@ -1049,6 +1062,8 @@ gs_shell_updates_init (GsShellUpdates *shell_updates)
 {
        const char *ampm;
 
+       gtk_widget_init_template (GTK_WIDGET (shell_updates));
+
        shell_updates->priv = gs_shell_updates_get_instance_private (shell_updates);
        shell_updates->priv->control = pk_control_new ();
        shell_updates->priv->cancellable_refresh = g_cancellable_new ();
diff --git a/src/gs-shell-updates.h b/src/gs-shell-updates.h
index c408649..fe3a654 100644
--- a/src/gs-shell-updates.h
+++ b/src/gs-shell-updates.h
@@ -41,13 +41,13 @@ typedef struct GsShellUpdatesPrivate GsShellUpdatesPrivate;
 
 typedef struct
 {
-        GObject                 parent;
+        GtkBin                  parent;
         GsShellUpdatesPrivate  *priv;
 } GsShellUpdates;
 
 typedef struct
 {
-       GObjectClass             parent_class;
+       GtkBinClass              parent_class;
 } GsShellUpdatesClass;
 
 GType           gs_shell_updates_get_type      (void);
diff --git a/src/gs-shell-updates.ui b/src/gs-shell-updates.ui
new file mode 100644
index 0000000..684b348
--- /dev/null
+++ b/src/gs-shell-updates.ui
@@ -0,0 +1,286 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+  <requires lib="gtk+" version="3.10"/>
+  <template class="GsShellUpdates" parent="GtkBin">
+    <child internal-child="accessible">
+      <object class="AtkObject" id="updates-accessible">
+        <property name="accessible-name" translatable="yes">Updates page</property>
+      </object>
+    </child>
+    <child>
+      <object class="GtkStack" id="stack_updates">
+        <property name="visible">True</property>
+        <child>
+          <object class="GtkBox" id="updates_spinner_box">
+            <property name="visible">True</property>
+            <property name="orientation">vertical</property>
+            <property name="spacing">12</property>
+            <property name="halign">center</property>
+            <property name="valign">center</property>
+            <property name="hexpand">True</property>
+            <property name="vexpand">True</property>
+            <style>
+              <class name="dim-label"/>
+            </style>
+            <child>
+              <object class="GtkSpinner" id="spinner_updates">
+                <property name="visible">True</property>
+                <property name="width_request">128</property>
+                <property name="height_request">128</property>
+                <property name="halign">center</property>
+                <property name="valign">center</property>
+                <property name="hexpand">True</property>
+                <property name="vexpand">True</property>
+              </object>
+            </child>
+            <child>
+              <object class="GtkLabel" id="label_updates_spinner">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="label"/>
+                <property name="justify">center</property>
+                <attributes>
+                  <attribute name="scale" value="1.4"/>
+                </attributes>
+              </object>
+            </child>
+          </object>
+          <packing>
+            <property name="name">spinner</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkScrolledWindow" id="scrolledwindow_updates">
+            <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="GtkBox" id="list_box_updates_box">
+                <property name="visible">True</property>
+                <property name="orientation">vertical</property>
+                <child>
+                  <object class="GtkListBox" id="list_box_updates">
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="selection_mode">none</property>
+                  </object>
+                </child>
+                <child>
+                  <object class="GtkSeparator" id="list_box_updates_separator">
+                    <property name="visible">True</property>
+                    <property name="orientation">horizontal</property>
+                  </object>
+                </child>
+              </object>
+            </child>
+          </object>
+          <packing>
+            <property name="name">view</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkBox" id="updates_uptodate_box">
+            <property name="visible">True</property>
+            <property name="orientation">vertical</property>
+            <property name="spacing">48</property>
+            <property name="hexpand">True</property>
+            <property name="vexpand">True</property>
+            <style>
+              <class name="dim-label"/>
+            </style>
+            <child type="center">
+              <object class="GtkBox" id="updates_uptodate_centerbox">
+                <property name="visible">True</property>
+                <property name="orientation">vertical</property>
+                <property name="spacing">12</property>
+                <child>
+                  <object class="GtkImage" id="image_updates">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="pixel_size">128</property>
+                    <property name="icon_name">object-select-symbolic</property>
+                  </object>
+                </child>
+                <child>
+                  <object class="GtkLabel" id="label10">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="label" translatable="yes">Software is up to date</property>
+                    <attributes>
+                      <attribute name="scale" value="1.4"/>
+                    </attributes>
+                  </object>
+                </child>
+              </object>
+            </child>
+            <child>
+              <object class="GtkLabel" id="label_updates_last_checked">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="margin_bottom">32</property>
+                <property name="label">Last checked: HH:MM</property>
+              </object>
+              <packing>
+                <property name="pack_type">end</property>
+              </packing>
+            </child>
+          </object>
+          <packing>
+            <property name="name">uptodate</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkBox" id="updates_mobile_box">
+            <property name="visible">True</property>
+            <property name="orientation">vertical</property>
+            <property name="spacing">12</property>
+            <property name="halign">center</property>
+            <property name="valign">center</property>
+            <property name="hexpand">True</property>
+            <property name="vexpand">True</property>
+            <style>
+              <class name="dim-label"/>
+            </style>
+            <child>
+              <object class="GtkImage" id="image_updates_mobile">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="pixel_size">128</property>
+                <property name="icon_name">dialog-warning-symbolic</property>
+              </object>
+            </child>
+            <child>
+              <object class="GtkLabel" id="label_updates_mobile">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="label" translatable="yes">Checking for updates when using mobile broadband 
could cause you to incur charges</property>
+                <property name="wrap">True</property>
+                <property name="halign">center</property>
+                <property name="max-width-chars">40</property>
+                <property name="justify">center</property>
+                <attributes>
+                  <attribute name="scale" value="1.4"/>
+                </attributes>
+              </object>
+            </child>
+            <child>
+              <object class="GtkButton" id="button_updates_mobile">
+                <property name="label" translatable="yes">_Check Anyway</property>
+                <property name="width_request">150</property>
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">False</property>
+                <property name="use_underline">True</property>
+                <property name="hexpand">False</property>
+                <property name="halign">center</property>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">False</property>
+              </packing>
+            </child>
+          </object>
+          <packing>
+            <property name="name">mobile</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkBox" id="updates_offline_box">
+            <property name="visible">True</property>
+            <property name="orientation">vertical</property>
+            <property name="spacing">12</property>
+            <property name="halign">center</property>
+            <property name="valign">center</property>
+            <property name="hexpand">True</property>
+            <property name="vexpand">True</property>
+            <style>
+              <class name="dim-label"/>
+            </style>
+            <child>
+              <object class="GtkImage" id="image_updates_offline">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="pixel_size">128</property>
+                <property name="icon_name">network-offline-symbolic</property>
+              </object>
+            </child>
+            <child>
+              <object class="GtkLabel" id="label_updates_offline">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="label" translatable="yes">Go online to check for updates</property>
+                <property name="wrap">True</property>
+                <property name="halign">center</property>
+                <property name="justify">center</property>
+                <attributes>
+                  <attribute name="scale" value="1.4"/>
+                </attributes>
+              </object>
+            </child>
+            <child>
+              <object class="GtkButton" id="button_updates_offline">
+                <property name="label" translatable="yes">_Network Settings</property>
+                <property name="width_request">150</property>
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">False</property>
+                <property name="use_underline">True</property>
+                <property name="hexpand">False</property>
+                <property name="halign">center</property>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">False</property>
+              </packing>
+            </child>
+          </object>
+          <packing>
+            <property name="name">offline</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkBox" id="updates_failed_box">
+            <property name="visible">True</property>
+            <property name="orientation">vertical</property>
+            <property name="spacing">12</property>
+            <property name="halign">center</property>
+            <property name="valign">center</property>
+            <property name="hexpand">True</property>
+            <property name="vexpand">True</property>
+            <style>
+              <class name="dim-label"/>
+            </style>
+            <child>
+              <object class="GtkImage" id="image_updates_failed">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="pixel_size">128</property>
+                <property name="icon_name">action-unavailable-symbolic</property>
+              </object>
+            </child>
+            <child>
+              <object class="GtkLabel" id="label_updates_failed">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="wrap">True</property>
+                <property name="max-width-chars">60</property>
+                <property name="label" translatable="No">Failed to get updates</property>
+                <attributes>
+                  <attribute name="scale" value="1.4"/>
+                </attributes>
+              </object>
+            </child>
+          </object>
+          <packing>
+            <property name="name">failed</property>
+          </packing>
+        </child>
+      </object>
+    </child>
+  </template>
+</interface>
diff --git a/src/gs-shell.c b/src/gs-shell.c
index a02122b..7e5fbe5 100644
--- a/src/gs-shell.c
+++ b/src/gs-shell.c
@@ -525,6 +525,7 @@ gs_shell_setup (GsShell *shell, GsPluginLoader *plugin_loader, GCancellable *can
                                 priv->plugin_loader,
                                 priv->builder,
                                 priv->cancellable);
+       priv->shell_updates = GS_SHELL_UPDATES (gtk_builder_get_object (priv->builder, "shell_updates"));
        gs_shell_updates_setup (priv->shell_updates,
                                shell,
                                priv->plugin_loader,
@@ -731,7 +732,6 @@ gs_shell_init (GsShell *shell)
 {
        shell->priv = gs_shell_get_instance_private (shell);
        shell->priv->shell_overview = gs_shell_overview_new ();
-       shell->priv->shell_updates = gs_shell_updates_new ();
        shell->priv->shell_installed = gs_shell_installed_new ();
        shell->priv->shell_details = gs_shell_details_new ();
        shell->priv->shell_category = gs_shell_category_new ();
@@ -754,7 +754,6 @@ gs_shell_finalize (GObject *object)
        g_object_unref (priv->plugin_loader);
        g_object_unref (priv->shell_overview);
        g_object_unref (priv->shell_installed);
-       g_object_unref (priv->shell_updates);
        g_object_unref (priv->shell_details);
        g_object_unref (priv->shell_category);
        g_object_unref (priv->shell_search);



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