[gnome-software] Start refactoring the 'More' button to match Allans mockups



commit dd3bddc338b8d0d3b1a17ba8e188b8bad406aa89
Author: Richard Hughes <richard hughsie com>
Date:   Wed Aug 14 13:18:53 2013 +0100

    Start refactoring the 'More' button to match Allans mockups
    
    INCOMPLETE, WIP

 src/gnome-software.ui              |  190 ++++++++++++++++++++++++++++++++++++
 src/gs-app-widget.c                |   79 ++-------------
 src/gs-app-widget.h                |    1 +
 src/gs-app.c                       |   25 +++++-
 src/gs-app.h                       |    3 +
 src/gs-main.c                      |  181 ++++++++++++++++++++++++++++++++++
 src/gs-plugin-loader.c             |   28 ++----
 src/plugins/gs-plugin-packagekit.c |    1 +
 8 files changed, 419 insertions(+), 89 deletions(-)
---
diff --git a/src/gnome-software.ui b/src/gnome-software.ui
index dcd1166..b72ca67 100644
--- a/src/gnome-software.ui
+++ b/src/gnome-software.ui
@@ -1,4 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.15.2 on Wed Aug 14 13:18:05 2013 -->
 <interface>
   <!-- interface-requires gtk+ 3.10 -->
   <object class="GtkListStore" id="liststore_popular">
@@ -11,6 +12,16 @@
       <column type="GdkPixbuf"/>
     </columns>
   </object>
+  <object class="GtkListStore" id="liststore_update">
+    <columns>
+      <!-- column-name app -->
+      <column type="GObject"/>
+      <!-- column-name name -->
+      <column type="gchararray"/>
+      <!-- column-name version -->
+      <column type="gchararray"/>
+    </columns>
+  </object>
   <object class="GtkWindow" id="window_software">
     <property name="can_focus">False</property>
     <property name="title" translatable="yes">Software</property>
@@ -832,6 +843,185 @@
       </object>
     </child>
   </object>
+  <object class="GtkDialog" id="dialog_update">
+    <property name="can_focus">False</property>
+    <property name="type_hint">dialog</property>
+    <property name="transient_for">window_software</property>
+    <child internal-child="vbox">
+      <object class="GtkBox" id="dialog-vbox1">
+        <property name="can_focus">False</property>
+        <property name="margin_left">6</property>
+        <property name="margin_right">6</property>
+        <property name="margin_top">6</property>
+        <property name="margin_bottom">6</property>
+        <property name="resize_mode">immediate</property>
+        <property name="orientation">vertical</property>
+        <property name="spacing">2</property>
+        <child internal-child="action_area">
+          <object class="GtkButtonBox" id="dialog-action_area1">
+            <property name="can_focus">False</property>
+            <property name="layout_style">end</property>
+            <child>
+              <object class="GtkButton" id="button_update_back">
+                <property name="label">gtk-go-back</property>
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">True</property>
+                <property name="use_stock">True</property>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">True</property>
+                <property name="position">0</property>
+                <property name="secondary">True</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkButton" id="button_update_close">
+                <property name="label" translatable="yes">Done</property>
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">True</property>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">True</property>
+                <property name="position">1</property>
+              </packing>
+            </child>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">True</property>
+            <property name="pack_type">end</property>
+            <property name="position">0</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkBox" id="box7">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="margin_bottom">3</property>
+            <property name="border_width">3</property>
+            <property name="orientation">vertical</property>
+            <property name="spacing">9</property>
+            <child>
+              <object class="GtkBox" id="box_update_header">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="spacing">9</property>
+                <child>
+                  <object class="GtkImage" id="image_update_icon">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="pixel_size">96</property>
+                    <property name="icon_name">accessories-calculator</property>
+                    <property name="icon_size">0</property>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">True</property>
+                    <property name="position">0</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkBox" id="box9">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="orientation">vertical</property>
+                    <property name="spacing">3</property>
+                    <child>
+                      <object class="GtkLabel" id="label_update_name">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="xalign">0</property>
+                        <property name="label">Inkscape</property>
+                        <property name="angle">0.41999998688697815</property>
+                        <attributes>
+                          <attribute name="weight" value="bold"/>
+                          <attribute name="scale" value="1.3999999999999999"/>
+                        </attributes>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">True</property>
+                        <property name="position">0</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkLabel" id="label_update_summary">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="xalign">0</property>
+                        <property name="label">Vector based drawing program</property>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">True</property>
+                        <property name="position">1</property>
+                      </packing>
+                    </child>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">True</property>
+                    <property name="position">1</property>
+                  </packing>
+                </child>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">True</property>
+                <property name="position">0</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkLabel" id="label_update_details">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="xalign">0</property>
+                <property name="yalign">0</property>
+                <property name="label">New in kmod 14-1
+* Moo
+* bar</property>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">True</property>
+                <property name="position">1</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkTreeView" id="treeview_update">
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="vscroll_policy">natural</property>
+                <property name="model">liststore_update</property>
+                <property name="headers_visible">False</property>
+                <property name="enable_search">False</property>
+                <property name="search_column">1</property>
+                <property name="show_expanders">False</property>
+                <property name="activate_on_single_click">True</property>
+                <child internal-child="selection">
+                  <object class="GtkTreeSelection" id="treeview-selection"/>
+                </child>
+              </object>
+              <packing>
+                <property name="expand">True</property>
+                <property name="fill">True</property>
+                <property name="position">2</property>
+              </packing>
+            </child>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">True</property>
+            <property name="position">1</property>
+          </packing>
+        </child>
+      </object>
+    </child>
+  </object>
   <object class="GtkSizeGroup" id="sizegroup_header_center"/>
   <object class="GtkSizeGroup" id="sizegroup_header_edges">
     <property name="mode">both</property>
diff --git a/src/gs-app-widget.c b/src/gs-app-widget.c
index 5fd4256..59ba4da 100644
--- a/src/gs-app-widget.c
+++ b/src/gs-app-widget.c
@@ -30,15 +30,12 @@
 struct _GsAppWidgetPrivate
 {
        ChMarkdown      *markdown;
-       gboolean         expanded;
        gchar           *description;
-       gchar           *description_more;
        GsApp           *app;
        gchar           *status;
        GsAppWidgetKind  kind;
        GtkWidget       *widget_button;
        GtkWidget       *widget_description;
-       GtkWidget       *widget_description_more;
        GtkWidget       *widget_image;
        GtkWidget       *widget_more;
        GtkWidget       *widget_name;
@@ -54,6 +51,7 @@ G_DEFINE_TYPE (GsAppWidget, gs_app_widget, GTK_TYPE_BOX)
 
 enum {
        SIGNAL_BUTTON_CLICKED,
+       SIGNAL_MORE,
        SIGNAL_LAST
 };
 
@@ -73,7 +71,6 @@ gs_app_widget_refresh (GsAppWidget *app_widget)
        gtk_label_set_label (GTK_LABEL (priv->widget_name),
                             gs_app_get_name (priv->app));
        gtk_label_set_markup (GTK_LABEL (priv->widget_description), priv->description);
-       gtk_label_set_markup (GTK_LABEL (priv->widget_description_more), priv->description_more);
        gtk_label_set_label (GTK_LABEL (priv->widget_status), priv->status);
        gtk_label_set_label (GTK_LABEL (priv->widget_version),
                             gs_app_get_version (priv->app));
@@ -81,14 +78,11 @@ gs_app_widget_refresh (GsAppWidget *app_widget)
                                   gs_app_get_pixbuf (priv->app));
        gtk_widget_set_visible (priv->widget_name, TRUE);
        gtk_widget_set_visible (priv->widget_description, TRUE);
-       gtk_widget_set_visible (priv->widget_description_more,
-                               priv->expanded && priv->description_more != NULL);
        gtk_widget_set_visible (priv->widget_status, priv->status != NULL);
        gtk_widget_set_visible (priv->widget_version, TRUE);
        gtk_widget_set_visible (priv->widget_image, TRUE);
        gtk_widget_set_visible (priv->widget_button, TRUE);
-       gtk_widget_set_visible (priv->widget_more,
-                               !priv->expanded && app_widget->priv->description_more != NULL);
+       gtk_widget_set_visible (priv->widget_more, TRUE);
 
        /* show / hide widgets depending on kind */
        switch (app_widget->priv->kind) {
@@ -187,74 +181,28 @@ gs_app_widget_set_description (GsAppWidget *app_widget, const gchar *description
        gchar **split = NULL;
        GsAppWidgetPrivate *priv = app_widget->priv;
        GString *description2 = NULL;
-       GString *tmp_description_more = NULL;
        GString *tmp_description = NULL;
-       guint i;
 
        g_return_if_fail (GS_IS_APP_WIDGET (app_widget));
 
        g_free (priv->description);
-       g_free (priv->description_more);
 
        /* nothing to set, so use placeholder */
        if (description == NULL) {
                priv->description = g_strdup ("No description");
-               priv->description_more = NULL;
                goto out;
        }
 
        /* force split with bullet */
        description2 = g_string_new (description);
        _g_string_replace (description2, ". ", "\n* ");
-
-       /* common case, no newlines at all */
-       if (g_strstr_len (description, -1, "\n") == NULL) {
-               priv->description = ch_markdown_parse (priv->markdown,
-                                                      description2->str);
-               priv->description_more = NULL;
-               goto out;
-       }
-
-       /* split up description into extra parts */
-       split = g_strsplit (description2->str, "\n", -1);
-       tmp_description = g_string_new ("");
-       tmp_description_more = g_string_new ("");
-       for (i = 0; split[i] != NULL; i++) {
-               if (i <= GS_APP_WIDGET_MAX_LINES_NO_EXPANDER) {
-                       g_string_append_printf (tmp_description,
-                                               "%s\n", split[i]);
-               } else {
-                       g_string_append_printf (tmp_description_more,
-                                               "%s\n", split[i]);
-               }
-       }
-
-       /* remove trailing newline */
-       if (tmp_description->len > 0) {
-               g_string_set_size (tmp_description,
-                                  tmp_description->len - 1);
-       }
-       if (tmp_description_more->len > 0) {
-               g_string_set_size (tmp_description_more,
-                                  tmp_description_more->len - 1);
-       }
-
-       /* parse markdown */
        priv->description = ch_markdown_parse (priv->markdown,
-                                              tmp_description->str);
-       if (tmp_description_more->len > 0) {
-               priv->description_more = ch_markdown_parse (priv->markdown,
-                                                           tmp_description_more->str);
-       } else {
-               priv->description_more = NULL;
-       }
+                                              description2->str);
 out:
        if (description2 != NULL)
                g_string_free (description2, TRUE);
        if (tmp_description != NULL)
                g_string_free (tmp_description, TRUE);
-       if (tmp_description_more != NULL)
-               g_string_free (tmp_description_more, TRUE);
        g_strfreev (split);
 }
 
@@ -314,8 +262,6 @@ gs_app_widget_destroy (GtkWidget *object)
        GsAppWidget *app_widget = GS_APP_WIDGET (object);
        GsAppWidgetPrivate *priv = app_widget->priv;
 
-       g_free (priv->description_more);
-       priv->description_more = NULL;
        g_free (priv->description);
        priv->description = NULL;
        g_free (priv->status);
@@ -341,6 +287,12 @@ gs_app_widget_class_init (GsAppWidgetClass *klass)
                              G_STRUCT_OFFSET (GsAppWidgetClass, button_clicked),
                              NULL, NULL, g_cclosure_marshal_VOID__VOID,
                              G_TYPE_NONE, 0);
+       signals [SIGNAL_MORE] =
+               g_signal_new ("more",
+                             G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST,
+                             G_STRUCT_OFFSET (GsAppWidgetClass, more),
+                             NULL, NULL, g_cclosure_marshal_VOID__VOID,
+                             G_TYPE_NONE, 0);
 
        g_type_class_add_private (klass, sizeof (GsAppWidgetPrivate));
 }
@@ -360,8 +312,7 @@ gs_app_widget_button_clicked_cb (GtkWidget *widget, GsAppWidget *app_widget)
 static void
 gs_app_widget_more_clicked_cb (GtkWidget *widget, GsAppWidget *app_widget)
 {
-       app_widget->priv->expanded = TRUE;
-       gs_app_widget_refresh (app_widget);
+       g_signal_emit (app_widget, signals[SIGNAL_MORE], 0);
 }
 
 /**
@@ -435,7 +386,7 @@ gs_app_widget_init (GsAppWidget *app_widget)
                            TRUE, TRUE, 0);
 
        /* 'More' Expander */
-       priv->widget_more = gtk_button_new_with_label (_("More  ▾"));
+       priv->widget_more = gtk_button_new_with_label (_("More"));
        context = gtk_widget_get_style_context (priv->widget_more);
        gtk_style_context_add_class (context, "dim-label");
        gtk_button_set_relief (GTK_BUTTON (priv->widget_more), GTK_RELIEF_NONE);
@@ -448,14 +399,6 @@ gs_app_widget_init (GsAppWidget *app_widget)
        g_signal_connect (priv->widget_more, "clicked",
                          G_CALLBACK (gs_app_widget_more_clicked_cb), app_widget);
 
-       /* description - more */
-       priv->widget_description_more = gtk_label_new ("description-more");
-       gtk_misc_set_alignment (GTK_MISC (priv->widget_description_more), 0.0, 0.0);
-       gtk_label_set_line_wrap (GTK_LABEL (priv->widget_description_more), TRUE);
-       gtk_box_pack_start (GTK_BOX (box),
-                           GTK_WIDGET (priv->widget_description_more),
-                           TRUE, TRUE, 0);
-
        /* button */
        priv->widget_button = gtk_button_new_with_label ("button");
        gtk_widget_set_margin_right (GTK_WIDGET (priv->widget_button), 9);
diff --git a/src/gs-app-widget.h b/src/gs-app-widget.h
index e90d626..b98e114 100644
--- a/src/gs-app-widget.h
+++ b/src/gs-app-widget.h
@@ -51,6 +51,7 @@ struct _GsAppWidgetClass
 {
        GtkBoxClass              parent_class;
        void                    (*button_clicked)       (GsAppWidget    *app_widget);
+       void                    (*more)                 (GsAppWidget    *app_widget);
 };
 
 typedef enum {
diff --git a/src/gs-app.c b/src/gs-app.c
index bd54123..ba015a2 100644
--- a/src/gs-app.c
+++ b/src/gs-app.c
@@ -39,6 +39,7 @@ struct GsAppPrivate
        GsAppState               state;
        GHashTable              *metadata;
        GdkPixbuf               *pixbuf;
+       GPtrArray               *related; /* of GsApp */
 };
 
 enum {
@@ -213,7 +214,7 @@ gs_app_get_pretty_version (const gchar *version)
        }
 
        /* then remove any distro suffix */
-       new = g_strdup_printf ("%s %s", "Version", version);
+       new = g_strdup (version);
        f = g_strstr_len (new, -1, ".fc");
        if (f != NULL)
                *f= '\0';
@@ -332,6 +333,26 @@ gs_app_set_metadata (GsApp *app, const gchar *key, const gchar *value)
 }
 
 /**
+ * gs_app_get_related:
+ */
+GPtrArray *
+gs_app_get_related (GsApp *app)
+{
+       g_return_val_if_fail (GS_IS_APP (app), NULL);
+       return app->priv->related;
+}
+
+/**
+ * gs_app_add_related:
+ */
+void
+gs_app_add_related (GsApp *app, GsApp *app2)
+{
+       g_return_if_fail (GS_IS_APP (app));
+       g_ptr_array_add (app->priv->related, g_object_ref (app2));
+}
+
+/**
  * gs_app_get_property:
  */
 static void
@@ -502,6 +523,7 @@ gs_app_init (GsApp *app)
 {
        app->priv = GS_APP_GET_PRIVATE (app);
        app->priv->rating = -1;
+       app->priv->related = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref);
        app->priv->metadata = g_hash_table_new_full (g_str_hash,
                                                     g_str_equal,
                                                     g_free,
@@ -524,6 +546,7 @@ gs_app_finalize (GObject *object)
        g_free (priv->summary);
        g_free (priv->screenshot);
        g_hash_table_unref (priv->metadata);
+       g_ptr_array_unref (priv->related);
        if (priv->pixbuf != NULL)
                g_object_unref (priv->pixbuf);
 
diff --git a/src/gs-app.h b/src/gs-app.h
index 56e98c3..435d638 100644
--- a/src/gs-app.h
+++ b/src/gs-app.h
@@ -105,5 +105,8 @@ void                 gs_app_set_metadata            (GsApp          *app,
 gint            gs_app_get_rating              (GsApp          *app);
 void            gs_app_set_rating              (GsApp          *app,
                                                 gint            rating);
+GPtrArray      *gs_app_get_related             (GsApp          *app);
+void            gs_app_add_related             (GsApp          *app,
+                                                GsApp          *app2);
 
 #endif /* __GS_APP_H */
diff --git a/src/gs-main.c b/src/gs-main.c
index 1a82118..1618d15 100644
--- a/src/gs-main.c
+++ b/src/gs-main.c
@@ -47,6 +47,13 @@ enum {
        COLUMN_POPULAR_LAST
 };
 
+enum {
+       COLUMN_UPDATE_APP,
+       COLUMN_UPDATE_NAME,
+       COLUMN_UPDATE_VERSION,
+       COLUMN_UPDATE_LAST
+};
+
 typedef struct {
        GCancellable            *cancellable;
        GsMainMode               mode;
@@ -364,6 +371,125 @@ out:
 }
 
 /**
+ * gs_main_app_widget_more_cb:
+ **/
+static void
+gs_main_app_widget_more_cb (GsAppWidget *app_widget, GsMainPrivate *priv)
+{
+       GsAppKind kind;
+       GsApp *app;
+       GsApp *app_related;
+       GtkWidget *widget;
+       gchar *tmp;
+
+       app = gs_app_widget_get_app (app_widget);
+       kind = gs_app_get_kind (app);
+
+       /* set window title */
+       widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "dialog_update"));
+       if (kind == GS_APP_KIND_OS_UPDATE) {
+               gtk_window_set_title (GTK_WINDOW (widget), gs_app_get_name (app));
+       } else {
+               tmp = g_strdup_printf ("%s %s",
+                                      gs_app_get_name (app),
+                                      gs_app_get_version (app));
+               gtk_window_set_title (GTK_WINDOW (widget), tmp);
+               g_free (tmp);
+       }
+
+       /* set update header */
+       widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "box_update_header"));
+//     gtk_widget_set_visible (widget, kind != GS_APP_KIND_OS_UPDATE);
+       widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "label_update_details"));
+       gtk_widget_set_visible (widget, kind != GS_APP_KIND_OS_UPDATE);
+       widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "image_update_icon"));
+       gtk_image_set_from_pixbuf (GTK_IMAGE (widget), gs_app_get_pixbuf (app));
+       widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "label_update_name"));
+       gtk_label_set_label (GTK_LABEL (widget), gs_app_get_name (app));
+       widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "label_update_summary"));
+       gtk_label_set_label (GTK_LABEL (widget), gs_app_get_summary (app));
+
+       /* only OS updates can go back, and only on selection */
+       widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "button_update_back"));
+       gtk_widget_hide (widget);
+
+       /* set update description */
+       if (kind == GS_APP_KIND_OS_UPDATE) {
+               GPtrArray *related;
+               GtkListStore *liststore;
+               GtkTreeIter iter;
+               guint i;
+
+               /* add the related packages to the list view */
+               liststore = GTK_LIST_STORE (gtk_builder_get_object (priv->builder, "liststore_update"));
+               gtk_list_store_clear (liststore);
+               related = gs_app_get_related (app);
+               for (i = 0; i < related->len; i++) {
+                       app_related = g_ptr_array_index (related, i);
+                       gtk_list_store_append (liststore, &iter);
+                       g_warning ("%s", gs_app_get_id (app_related));
+                       gtk_list_store_set (liststore,
+                                           &iter,
+                                           COLUMN_UPDATE_APP, app_related,
+                                           COLUMN_UPDATE_NAME, gs_app_get_name (app_related),
+                                           COLUMN_UPDATE_VERSION, gs_app_get_version (app_related),
+                                           -1);
+               }
+       } else {
+               widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "label_update_details"));
+               gtk_label_set_label (GTK_LABEL (widget), gs_app_get_metadata_item (app, "update-details"));
+       }
+
+       widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "dialog_update"));
+       gtk_window_present (GTK_WINDOW (widget));
+
+       g_warning ("ooo");
+
+#if 0
+       for (l = list; l != NULL; l = l->next) {
+               app = GS_APP (l->data);
+               g_debug ("adding popular %s", gs_app_get_id (app));
+       }
+#endif
+
+//     xxxx
+       
+}
+
+/**
+ * gs_main_update_row_activated_cb:
+ **/
+static void
+gs_main_update_row_activated_cb (GtkTreeView *treeview, GtkTreePath *path,
+                                GtkTreeViewColumn *col, GsMainPrivate *priv)
+{
+       gboolean ret;
+       GsApp *app = NULL;
+       GtkTreeIter iter;
+       GtkTreeModel *model;
+
+       /* get selection */
+       model = gtk_tree_view_get_model (treeview);
+       ret = gtk_tree_model_get_iter (model, &iter, path);
+       if (!ret) {
+               g_warning ("failed to get selection");
+               goto out;
+       }
+
+       /* get data */
+       gtk_tree_model_get (model, &iter,
+                           COLUMN_UPDATE_APP, &app,
+                           -1);
+
+       /* on click, hide listbox, show button_update_back, show label_update_details, set 
label_update_details to the correct one for the click */
+
+       g_error ("moo: %s", gs_app_get_name (app));
+out:
+       if (app != NULL)
+               g_object_unref (app);
+}
+
+/**
  * gs_main_app_widget_button_clicked_cb:
  **/
 static void
@@ -522,6 +648,9 @@ gs_main_get_updates_cb (GsPluginLoader *plugin_loader,
                g_signal_connect (widget, "button-clicked",
                                  G_CALLBACK (gs_main_app_widget_button_clicked_cb),
                                  priv);
+               g_signal_connect (widget, "more",
+                                 G_CALLBACK (gs_main_app_widget_more_cb),
+                                 priv);
                gs_app_widget_set_kind (GS_APP_WIDGET (widget),
                                        GS_APP_WIDGET_KIND_UPDATE);
                gs_app_widget_set_app (GS_APP_WIDGET (widget), app);
@@ -895,6 +1024,16 @@ gs_main_overview_button_cb (GtkWidget *widget, GsMainPrivate *priv)
 }
 
 /**
+ * gs_main_button_updates_close_cb:
+ **/
+static void
+gs_main_button_updates_close_cb (GtkWidget *widget, GsMainPrivate *priv)
+{
+       widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "dialog_update"));
+       gtk_widget_hide (widget);
+}
+
+/**
  * gs_main_back_button_cb:
  **/
 static void
@@ -1220,6 +1359,48 @@ gs_main_startup_cb (GApplication *application, GsMainPrivate *priv)
        g_signal_connect (widget, "clicked",
                          G_CALLBACK (gs_main_overview_button_cb), priv);
 
+       /* setup update details window */
+       widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "button_update_close"));
+       g_signal_connect (widget, "clicked",
+                         G_CALLBACK (gs_main_button_updates_close_cb), priv);
+       //FIXME: connect to dialog_update and just hide widget if user closes modal
+//     button_update_back
+
+
+{
+       GtkCellRenderer *renderer;
+       GtkTreeViewColumn *column;
+       GtkTreeView *treeview;
+
+       treeview = GTK_TREE_VIEW (gtk_builder_get_object (priv->builder, "treeview_update"));
+
+       /* column for name */
+       renderer = gtk_cell_renderer_text_new ();
+       g_object_set (renderer,
+                     "xpad", 6,
+                     "ypad", 6,
+                     NULL);
+       column = gtk_tree_view_column_new_with_attributes ("name", renderer,
+                                                          "markup", COLUMN_UPDATE_NAME, NULL);
+       gtk_tree_view_column_set_sort_column_id (column, COLUMN_UPDATE_NAME);
+       gtk_tree_view_column_set_expand (column, TRUE);
+       gtk_tree_view_append_column (treeview, column);
+
+       renderer = gtk_cell_renderer_text_new ();
+       g_object_set (renderer,
+                     "xpad", 6,
+                     "ypad", 6,
+                     NULL);
+       column = gtk_tree_view_column_new_with_attributes ("version", renderer,
+                                                          "markup", COLUMN_UPDATE_VERSION, NULL);
+       gtk_tree_view_append_column (treeview, column);
+       g_signal_connect (treeview, "row-activated",
+                         G_CALLBACK (gs_main_update_row_activated_cb), priv);
+
+}
+
+
+
        /* refilter on search box changing */
        widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "entry_search"));
        g_signal_connect (GTK_EDITABLE (widget), "changed",
diff --git a/src/gs-plugin-loader.c b/src/gs-plugin-loader.c
index 6fe4b1f..231b9b8 100644
--- a/src/gs-plugin-loader.c
+++ b/src/gs-plugin-loader.c
@@ -296,7 +296,6 @@ cd_plugin_loader_get_updates_thread_cb (GSimpleAsyncResult *res,
        GsApp *app_tmp;
        GsPluginLoaderAsyncState *state = (GsPluginLoaderAsyncState *) g_object_get_data (G_OBJECT 
(cancellable), "state");
        GsPluginLoader *plugin_loader = GS_PLUGIN_LOADER (object);
-       GString *str_id = NULL;
        GString *str_summary = NULL;
 
        /* do things that would block */
@@ -325,21 +324,19 @@ cd_plugin_loader_get_updates_thread_cb (GSimpleAsyncResult *res,
 
        /* smush them all together */
        if (has_os_update) {
-               str_summary = g_string_new (_("Includes performance, stability and security improvements for 
all users"));
-               g_string_append (str_summary, "\n\n\n");
-               str_id = g_string_new ("os-update:");
+
+               /* create new meta object */
+               app = gs_app_new ("os-update");
+               gs_app_set_kind (app, GS_APP_KIND_OS_UPDATE);
+               gs_app_set_name (app, _("OS Updates"));
+               gs_app_set_summary (app, _("Includes performance, stability and security improvements for all 
users."));
+               gs_app_set_version (app, "3.10.1");
                for (l = state->list; l != NULL; l = l->next) {
                        app_tmp = GS_APP (l->data);
                        if (gs_app_get_kind (app_tmp) != GS_APP_KIND_PACKAGE)
                                continue;
-                       g_string_append_printf (str_id, "%s,",
-                                               gs_app_get_id (app_tmp));
-                       g_string_append_printf (str_summary, "%s:\n\n%s\n\n",
-                                               gs_app_get_metadata_item (app_tmp, "update-name"),
-                                               gs_app_get_metadata_item (app_tmp, "update-details"));
+                       gs_app_add_related (app, app_tmp);
                }
-               g_string_truncate (str_id, str_id->len - 1);
-               g_string_truncate (str_summary, str_summary->len - 1);
 
                /* load icon */
                pixbuf = gtk_icon_theme_load_icon (gtk_icon_theme_get_default (),
@@ -353,13 +350,6 @@ cd_plugin_loader_get_updates_thread_cb (GSimpleAsyncResult *res,
                                   error->message);
                        g_error_free (error);
                }
-
-               /* create new meta object */
-               app = gs_app_new (str_id->str);
-               gs_app_set_kind (app, GS_APP_KIND_OS_UPDATE);
-               gs_app_set_name (app, _("OS Updates"));
-               gs_app_set_summary (app, str_summary->str);
-               gs_app_set_version (app, "3.6.3");
                gs_app_set_pixbuf (app, pixbuf);
                gs_plugin_add_app (&state->list, app);
 
@@ -383,8 +373,6 @@ cd_plugin_loader_get_updates_thread_cb (GSimpleAsyncResult *res,
 out:
        if (pixbuf != NULL)
                g_object_unref (pixbuf);
-       if (str_id != NULL)
-               g_string_free (str_id, TRUE);
        if (str_summary != NULL)
                g_string_free (str_summary, TRUE);
 }
diff --git a/src/plugins/gs-plugin-packagekit.c b/src/plugins/gs-plugin-packagekit.c
index c6b2176..ca65c16 100644
--- a/src/plugins/gs-plugin-packagekit.c
+++ b/src/plugins/gs-plugin-packagekit.c
@@ -292,6 +292,7 @@ gs_plugin_packagekit_add_updates_results (GsPlugin *plugin,
                gs_app_set_metadata (app, "package-name", split[PK_PACKAGE_ID_NAME]);
                gs_app_set_metadata (app, "update-name", split[PK_PACKAGE_ID_NAME]);
                gs_app_set_metadata (app, "update-details", update_text);
+               gs_app_set_name (app, split[PK_PACKAGE_ID_NAME]);
                gs_app_set_version (app, split[PK_PACKAGE_ID_VERSION]);
                gs_app_set_state (app, GS_APP_STATE_INSTALLED);
                gs_app_set_kind (app, GS_APP_KIND_PACKAGE);


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