From 44e1257d761438849aa17e46c88bcc17f0f204f6 Mon Sep 17 00:00:00 2001
From: Rafal Luzynski <digitalfreak@lingonborough.com>
Date: Wed, 6 May 2015 02:51:17 +0200
Subject: [PATCH] offline updates: GtkExpander in the error message dialog

The previous patch turned out to be not so perfect because
the detailed error message can be too wide, not only too high.
This patch introduces: GtkExpander, wrapped label inside it,
and few other minor improvements.

This is not the final solution of the problem but is backward
compatible and can be backported to the old branches.

https://bugzilla.gnome.org/show_bug.cgi?id=748936
---
 src/gs-offline-updates.c | 95 +++++++++++++++++++++++++++++++++++-------------
 1 file changed, 70 insertions(+), 25 deletions(-)

diff --git a/src/gs-offline-updates.c b/src/gs-offline-updates.c
index c2c20a5..81773fd 100644
--- a/src/gs-offline-updates.c
+++ b/src/gs-offline-updates.c
@@ -23,18 +23,23 @@
 
 #include <glib/gi18n.h>
 #include <packagekit-glib2/packagekit.h>
+#include <pango/pango-font.h>
 
 #include "gs-cleanup.h"
 #include "gs-offline-updates.h"
 #include "gs-utils.h"
 
 static void
-gs_offline_updates_label_allocate_cb (GtkWidget *label,
-				      GdkRectangle *allocation, gpointer data)
+expander_cb (GtkExpander *expander, GParamSpec *pspec, GtkWindow *dialog)
 {
-	GtkScrolledWindow *sw = GTK_SCROLLED_WINDOW (data);
-	gtk_scrolled_window_set_min_content_height (
-			sw, MIN (allocation->height, 300));
+	gtk_window_set_resizable (dialog, gtk_expander_get_expanded (expander));
+}
+
+static void
+do_not_expand (GtkWidget *child, gpointer data)
+{
+	gtk_container_child_set (GTK_CONTAINER (gtk_widget_get_parent (child)),
+				 child, "expand", FALSE, "fill", FALSE, NULL);
 }
 
 void
@@ -43,6 +48,9 @@ gs_offline_updates_show_error (void)
 	const gchar *title;
 	gboolean show_geeky = FALSE;
 	GtkWidget *dialog, *message_area, *sw, *label;
+	GtkWidget *box, *expander;
+	PangoFontMetrics *metrics;
+	int lineheight;
 	_cleanup_error_free_ GError *error = NULL;
 	_cleanup_object_unref_ PkError *pk_error = NULL;
 	_cleanup_object_unref_ PkResults *results = NULL;
@@ -127,33 +135,70 @@ gs_offline_updates_show_error (void)
 		show_geeky = TRUE;
 		break;
 	}
+
+	dialog = gtk_message_dialog_new_with_markup (NULL,
+					 0,
+					 GTK_MESSAGE_INFO,
+					 GTK_BUTTONS_CLOSE,
+					 "<big><b>%s</b></big>", title);
+	gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
+						  "%s", msg->str);
+
 	if (show_geeky) {
-		g_string_append_printf (msg, "\n%s\n\n%s",
+		g_string_assign (msg, "");
+		g_string_append_printf (msg, "%s\n\n%s",
 					/* TRANSLATORS: these are geeky messages from the
 					 * package manager no mortal is supposed to understand,
 					 * but google might know what they mean */
 					_("Detailed errors from the package manager follow:"),
 					pk_error_get_details (pk_error));
+
+		message_area = gtk_message_dialog_get_message_area (GTK_MESSAGE_DIALOG (dialog));
+		g_assert (GTK_IS_BOX (message_area));
+		/* make the hbox expand */
+		box = gtk_widget_get_parent (message_area);
+		gtk_container_child_set (GTK_CONTAINER (gtk_widget_get_parent (box)), box,
+					 "expand", TRUE, "fill", TRUE, NULL);
+		/* make the labels not expand */
+		gtk_container_foreach (GTK_CONTAINER (message_area), do_not_expand, NULL);
+
+		/* TODO: In 3.18 the label will be "Details:" (":" appended) */
+		expander = gtk_expander_new (_("Details"));
+		gtk_widget_set_visible (expander, TRUE);
+		sw = gtk_scrolled_window_new (NULL, NULL);
+		gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (sw),
+						     GTK_SHADOW_IN);
+		gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
+						GTK_POLICY_NEVER,
+						GTK_POLICY_AUTOMATIC);
+		gtk_widget_set_visible (sw, TRUE);
+
+		label = gtk_label_new (msg->str);
+		gtk_label_set_selectable (GTK_LABEL (label), TRUE);
+		gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
+		gtk_label_set_line_wrap_mode (GTK_LABEL (label), GTK_WRAP_WORD);
+		gtk_widget_set_halign (label, GTK_ALIGN_START);
+		gtk_widget_set_valign (label, GTK_ALIGN_START);
+		gtk_label_set_xalign (GTK_LABEL (label), 0.0);
+		gtk_widget_set_visible (label, TRUE);
+
+		/* Setup the minimum size of the text label */
+		gtk_label_set_width_chars (GTK_LABEL (label), 50);
+		metrics = pango_context_get_metrics (
+				gtk_widget_get_pango_context (label), NULL, NULL);
+		lineheight = PANGO_PIXELS_CEIL(
+				pango_font_metrics_get_ascent (metrics)
+				+ pango_font_metrics_get_descent (metrics));
+		pango_font_metrics_unref (metrics);
+		gtk_scrolled_window_set_min_content_height(GTK_SCROLLED_WINDOW (sw),
+							   5 * lineheight);
+
+		gtk_container_add (GTK_CONTAINER (sw), label);
+		gtk_container_add (GTK_CONTAINER (expander), sw);
+		gtk_box_pack_end (GTK_BOX (message_area), expander, TRUE, TRUE, 0);
+		g_signal_connect (expander, "notify::expanded",
+				  G_CALLBACK (expander_cb), dialog);
 	}
-	dialog = gtk_message_dialog_new (NULL,
-					 0,
-					 GTK_MESSAGE_INFO,
-					 GTK_BUTTONS_CLOSE,
-					 "%s", title);
-
-	message_area = gtk_message_dialog_get_message_area (GTK_MESSAGE_DIALOG (dialog));
-	g_assert (GTK_IS_BOX (message_area));
-	sw = gtk_scrolled_window_new (NULL, NULL);
-	gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
-					GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
-	gtk_widget_set_visible (sw, TRUE);
-
-	label = gtk_label_new (msg->str);
-	gtk_widget_set_visible (label, TRUE);
-	g_signal_connect (label, "size-allocate",
-			G_CALLBACK (gs_offline_updates_label_allocate_cb), sw);
-	gtk_container_add (GTK_CONTAINER (sw), label);
-	gtk_container_add (GTK_CONTAINER (message_area), sw);
 
 	g_signal_connect_swapped (dialog, "response",
 				  G_CALLBACK (gtk_widget_destroy),
-- 
2.1.0

