gnome-packagekit r121 - trunk/src



Author: rhughes
Date: Thu Mar 20 12:14:40 2008
New Revision: 121
URL: http://svn.gnome.org/viewvc/gnome-packagekit?rev=121&view=rev

Log:
from git

Modified:
   trunk/src/pk-application.c
   trunk/src/pk-backend-status.c
   trunk/src/pk-common-gui.c
   trunk/src/pk-notify.c
   trunk/src/pk-statusbar.c
   trunk/src/pk-update-viewer.c
   trunk/src/pk-watch.c

Modified: trunk/src/pk-application.c
==============================================================================
--- trunk/src/pk-application.c	(original)
+++ trunk/src/pk-application.c	Thu Mar 20 12:14:40 2008
@@ -1422,7 +1422,7 @@
 
 	/* Hide window first so that the dialogue resizes itself without redrawing */
 	gtk_widget_hide (main_window);
-	gtk_window_set_icon_name (GTK_WINDOW (main_window), "system-installer");
+	gtk_window_set_icon_name (GTK_WINDOW (main_window), "system-software-installer");
 
 	/* Get the main window quit */
 	g_signal_connect (main_window, "delete_event",

Modified: trunk/src/pk-backend-status.c
==============================================================================
--- trunk/src/pk-backend-status.c	(original)
+++ trunk/src/pk-backend-status.c	Thu Mar 20 12:14:40 2008
@@ -203,7 +203,7 @@
 		widget = glade_xml_get_widget (glade_xml, "image_file_install");
 		gtk_image_set_from_icon_name (GTK_IMAGE (widget), "gtk-apply", GTK_ICON_SIZE_MENU);
 	}
-	if (pk_enum_list_contains (role_list, PK_ROLE_ENUM_UPDATE_PACKAGE) == TRUE) {
+	if (pk_enum_list_contains (role_list, PK_ROLE_ENUM_UPDATE_PACKAGES) == TRUE) {
 		widget = glade_xml_get_widget (glade_xml, "image_package_update");
 		gtk_image_set_from_icon_name (GTK_IMAGE (widget), "gtk-apply", GTK_ICON_SIZE_MENU);
 	}

Modified: trunk/src/pk-common-gui.c
==============================================================================
--- trunk/src/pk-common-gui.c	(original)
+++ trunk/src/pk-common-gui.c	Thu Mar 20 12:14:40 2008
@@ -95,7 +95,7 @@
 	{PK_ROLE_ENUM_REMOVE_PACKAGE,		"pk-package-delete"},
 	{PK_ROLE_ENUM_INSTALL_PACKAGE,		"pk-package-add"},
 	{PK_ROLE_ENUM_INSTALL_FILE,		"pk-package-add"},
-	{PK_ROLE_ENUM_UPDATE_PACKAGE,		"pk-package-update"},
+	{PK_ROLE_ENUM_UPDATE_PACKAGES,		"pk-package-update"},
 	{PK_ROLE_ENUM_SERVICE_PACK,		"pk-package-update"},
 	{PK_ROLE_ENUM_UPDATE_SYSTEM,		"system-software-update"},
 	{PK_ROLE_ENUM_GET_REPO_LIST,		"emblem-system"},
@@ -392,15 +392,6 @@
 }
 
 /**
- * pk_error_modal_dialog_cb:
- **/
-static void
-pk_error_modal_dialog_cb (GtkWidget *dialog, gint arg1, GMainLoop *loop)
-{
-	g_main_loop_quit (loop);
-}
-
-/**
  * pk_error_modal_dialog:
  *
  * Shows a modal error, and blocks until the user clicks close
@@ -409,16 +400,11 @@
 pk_error_modal_dialog (const gchar *title, const gchar *message)
 {
 	GtkWidget *dialog;
-	GMainLoop *loop;
-
-	loop = g_main_loop_new (NULL, FALSE);
-	dialog = gtk_message_dialog_new_with_markup (NULL, GTK_DIALOG_DESTROY_WITH_PARENT,
-					 	     GTK_MESSAGE_WARNING, GTK_BUTTONS_CLOSE,
-						     "<span size='larger'><b>%s</b></span>", title);
+	dialog = gtk_message_dialog_new (NULL, GTK_DIALOG_DESTROY_WITH_PARENT,
+					 GTK_MESSAGE_WARNING, GTK_BUTTONS_CLOSE, title);
 	gtk_message_dialog_format_secondary_markup (GTK_MESSAGE_DIALOG (dialog), message);
-	g_signal_connect (dialog, "response", G_CALLBACK (pk_error_modal_dialog_cb), loop);
-	gtk_window_present (GTK_WINDOW (dialog));
-	g_main_loop_run (loop);
+	gtk_dialog_run (GTK_DIALOG (dialog));
+	gtk_widget_destroy (dialog);
 	return TRUE;
 }
 
@@ -766,7 +752,7 @@
 		text = g_strdup_printf (ngettext ("%i trivial update", "%i trivial updates", number), number);
 		break;
 	case PK_INFO_ENUM_NORMAL:
-		text = g_strdup_printf (ngettext ("%i normal update", "%i normal updates", number), number);
+		text = g_strdup_printf (ngettext ("%i update", "%i updates", number), number);
 		break;
 	case PK_INFO_ENUM_IMPORTANT:
 		text = g_strdup_printf (ngettext ("%i important update", "%i important updates", number), number);
@@ -799,7 +785,7 @@
 		text = _("Trivial update");
 		break;
 	case PK_INFO_ENUM_NORMAL:
-		text = _("Normal update");
+		text = _("Update");
 		break;
 	case PK_INFO_ENUM_IMPORTANT:
 		text = _("Important update");
@@ -894,7 +880,7 @@
 	case PK_ROLE_ENUM_REFRESH_CACHE:
 		text = _("Refreshing package cache");
 		break;
-	case PK_ROLE_ENUM_UPDATE_PACKAGE:
+	case PK_ROLE_ENUM_UPDATE_PACKAGES:
 		text = _("Updating package");
 		break;
 	case PK_ROLE_ENUM_UPDATE_SYSTEM:
@@ -977,7 +963,7 @@
 	case PK_ROLE_ENUM_REFRESH_CACHE:
 		text = _("Refreshed package cache");
 		break;
-	case PK_ROLE_ENUM_UPDATE_PACKAGE:
+	case PK_ROLE_ENUM_UPDATE_PACKAGES:
 		text = _("Updated package");
 		break;
 	case PK_ROLE_ENUM_UPDATE_SYSTEM:

Modified: trunk/src/pk-notify.c
==============================================================================
--- trunk/src/pk-notify.c	(original)
+++ trunk/src/pk-notify.c	Thu Mar 20 12:14:40 2008
@@ -44,6 +44,7 @@
 #include <pk-task-list.h>
 #include <pk-connection.h>
 #include <pk-package-id.h>
+#include <pk-package-ids.h>
 #include <pk-package-list.h>
 
 #include "pk-smart-icon.h"
@@ -598,6 +599,56 @@
 }
 
 /**
+ * pk_notify_check_on_battery:
+ **/
+static gboolean
+pk_notify_check_on_battery (PkNotify *notify)
+{
+	gboolean on_battery;
+	gboolean conf_update_battery;
+
+	g_return_val_if_fail (notify != NULL, FALSE);
+	g_return_val_if_fail (PK_IS_NOTIFY (notify), FALSE);
+
+	on_battery = pk_auto_refresh_get_on_battery (notify->priv->arefresh);
+	conf_update_battery = gconf_client_get_bool (notify->priv->gconf_client, PK_CONF_UPDATE_BATTERY, NULL);
+	if (!conf_update_battery && on_battery) {
+		pk_smart_icon_notify_new (notify->priv->sicon,
+				      _("Will not install updates"),
+				      _("Automatic updates are not being installed as the computer is on battery power"),
+				      "dialog-information", PK_NOTIFY_URGENCY_LOW, PK_NOTIFY_TIMEOUT_LONG);
+		pk_smart_icon_notify_button (notify->priv->sicon,
+					     PK_NOTIFY_BUTTON_DO_NOT_SHOW_AGAIN,
+					     PK_CONF_NOTIFY_BATTERY_UPDATE);
+		pk_smart_icon_notify_show (notify->priv->sicon);
+		return FALSE;
+	}
+	return TRUE;
+}
+
+/**
+ * pk_notify_get_update_policy:
+ **/
+static PkUpdateEnum
+pk_notify_get_update_policy (PkNotify *notify)
+{
+	PkUpdateEnum update;
+	gchar *updates;
+
+	g_return_val_if_fail (notify != NULL, FALSE);
+	g_return_val_if_fail (PK_IS_NOTIFY (notify), FALSE);
+
+	updates = gconf_client_get_string (notify->priv->gconf_client, PK_CONF_AUTO_UPDATE, NULL);
+	if (updates == NULL) {
+		pk_warning ("'%s' gconf key is null!", PK_CONF_AUTO_UPDATE);
+		return PK_UPDATE_ENUM_UNKNOWN;
+	}
+	update = pk_update_enum_from_text (updates);
+	g_free (updates);
+	return update;
+}
+
+/**
  * pk_notify_query_updates_finished_cb:
  **/
 static void
@@ -606,102 +657,127 @@
 	PkPackageItem *item;
 	guint length;
 	guint i;
-	gboolean is_security;
 	gboolean ret;
-	const gchar *icon;
-	gchar *updates;
 	GString *status_security;
 	GString *status_tooltip;
 	PkUpdateEnum update;
 	PkPackageId *ident;
+	GPtrArray *security_array;
 
 	g_return_if_fail (notify != NULL);
 	g_return_if_fail (PK_IS_NOTIFY (notify));
 
 	status_security = g_string_new ("");
 	status_tooltip = g_string_new ("");
+	security_array = g_ptr_array_new ();
 
 	/* find packages */
 	length = pk_client_package_buffer_get_size (client);
 	pk_debug ("length=%i", length);
+
+	/* we have no updates */
 	if (length == 0) {
 		pk_debug ("no updates");
 		pk_smart_icon_set_icon_name (notify->priv->sicon, NULL);
-		return;
+		goto out;
 	}
 
-	is_security = FALSE;
+	/* find the security updates */
 	for (i=0; i<length; i++) {
 		item = pk_client_package_buffer_get_item (client, i);
 		pk_debug ("%s, %s, %s", pk_info_enum_to_text (item->info),
 			  item->package_id, item->summary);
 		ident = pk_package_id_new_from_string (item->package_id);
 		if (item->info == PK_INFO_ENUM_SECURITY) {
-			is_security = TRUE;
+			/* add to array */
+			g_ptr_array_add (security_array, g_strdup (item->package_id));
 			g_string_append_printf (status_security, "<b>%s</b> - %s\n",
 						ident->name, item->summary);
 		}
 		pk_package_id_free (ident);
 	}
+
+	/* we are done querying this */
 	g_object_unref (client);
 
 	/* do we do the automatic updates? */
-	updates = gconf_client_get_string (notify->priv->gconf_client, PK_CONF_AUTO_UPDATE, NULL);
-	if (updates == NULL) {
-		pk_warning ("'%s' gconf key is null!", PK_CONF_AUTO_UPDATE);
+	update = pk_notify_get_update_policy (notify);
+	if (update == PK_UPDATE_ENUM_UNKNOWN) {
+		pk_warning ("policy unknown");
+		goto out;
 	}
-	update = pk_update_enum_from_text (updates);
-	g_free (updates);
-	if ((update == PK_UPDATE_ENUM_SECURITY && is_security == TRUE) || update == PK_UPDATE_ENUM_ALL) {
-		gboolean on_battery;
-		gboolean conf_update_battery;
-		on_battery = pk_auto_refresh_get_on_battery (notify->priv->arefresh);
-		conf_update_battery = gconf_client_get_bool (notify->priv->gconf_client, PK_CONF_UPDATE_BATTERY, NULL);
-		if (conf_update_battery == FALSE && on_battery == TRUE) {
-			pk_warning ("on battery so not doing update");
-			pk_smart_icon_notify_new (notify->priv->sicon,
-					      _("Will not install updates"),
-					      _("Automatic updates are not being installed as the computer is on battery power"),
-					      "dialog-information", PK_NOTIFY_URGENCY_LOW, PK_NOTIFY_TIMEOUT_LONG);
-			pk_smart_icon_notify_button (notify->priv->sicon,
-						     PK_NOTIFY_BUTTON_DO_NOT_SHOW_AGAIN,
-						     PK_CONF_NOTIFY_BATTERY_UPDATE);
-			pk_smart_icon_notify_show (notify->priv->sicon);
-			return;
+
+	/* is policy none? */
+	if (update == PK_UPDATE_ENUM_NONE) {
+		const gchar *icon;
+		pk_debug ("not updating as policy NONE");
+
+		/* work out icon */
+		icon = pk_notify_get_best_update_icon (notify, client);
+
+		/* trim off extra newlines */
+		if (status_security->len != 0) {
+			g_string_set_size (status_security, status_security->len-1);
 		}
 
-		pk_debug ("we should do the update automatically!");
-		ret = pk_notify_update_system (notify);
-		if (ret == TRUE) {
-			pk_notify_auto_update_message (notify);
-		} else {
-			pk_warning ("update failed");
+		/* make tooltip */
+		g_string_append_printf (status_tooltip, ngettext ("There is %d update pending",
+								  "There are %d updates pending", length), length);
+
+		pk_smart_icon_set_icon_name (notify->priv->sicon, icon);
+		pk_smart_icon_set_tooltip (notify->priv->sicon, status_tooltip->str);
+
+		/* do we warn the user? */
+		if (security_array->len > 0) {
+			pk_notify_critical_updates_warning (notify, status_security->str, length);
 		}
-		return;
+		goto out;
 	}
 
-	/* work out icon */
-	icon = pk_notify_get_best_update_icon (notify, client);
-
-	/* trim off extra newlines */
-	if (status_security->len != 0) {
-		g_string_set_size (status_security, status_security->len-1);
+	/* are we on battery and configured to skip the action */
+	ret = pk_notify_check_on_battery (notify);
+	if (!ret) {
+		pk_debug ("on battery so not doing update");
+		goto out;
 	}
 
-	/* make tooltip */
-	g_string_append_printf (status_tooltip, ngettext ("There is %d update pending",
-							  "There are %d updates pending", length), length);
+	/* just do security updates */
+	if (update == PK_UPDATE_ENUM_SECURITY && security_array->len > 0) {
+		gchar **package_ids;
+		gboolean ret;
+		GError *error = NULL;
 
-	pk_smart_icon_set_icon_name (notify->priv->sicon, icon);
-	pk_smart_icon_set_tooltip (notify->priv->sicon, status_tooltip->str);
+		pk_debug ("just process security updates");
+		package_ids = pk_package_ids_from_array (security_array);
+		ret = pk_client_update_packages_strv (notify->priv->client_update_system, package_ids, &error);
+		if (!ret) {
+			pk_warning ("Individual updates failed: %s", error->message);
+			g_error_free (error);
+		}
+		g_strfreev (package_ids);
+		goto out;
+	}
 
-	/* do we warn the user? */
-	if (is_security == TRUE) {
-		pk_notify_critical_updates_warning (notify, status_security->str, length);
+	/* just do everything */
+	if (update == PK_UPDATE_ENUM_ALL) {
+		pk_debug ("we should do the update automatically!");
+		ret = pk_notify_update_system (notify);
+		if (ret == TRUE) {
+			pk_notify_auto_update_message (notify);
+		} else {
+			pk_warning ("update failed");
+		}
+		goto out;
 	}
 
+	/* shouldn't happen */
+	pk_warning ("unknown update mode");
+out:
 	g_string_free (status_security, TRUE);
 	g_string_free (status_tooltip, TRUE);
+
+	/* get rid of the array, and free the contents */
+	g_ptr_array_free (security_array, TRUE);
 }
 
 /**

Modified: trunk/src/pk-statusbar.c
==============================================================================
--- trunk/src/pk-statusbar.c	(original)
+++ trunk/src/pk-statusbar.c	Thu Mar 20 12:14:40 2008
@@ -201,7 +201,7 @@
 
 	/* don't hide, else the status bar will collapse */
 	if (remaining == 0) {
-		gtk_label_set_label (GTK_LABEL (sbar->priv->statusbar->label), "");
+		gtk_progress_bar_set_text (GTK_PROGRESS_BAR (sbar->priv->statusbar->label), "");
 		return TRUE;
 	}
 
@@ -211,7 +211,7 @@
 	/* print remaining time */
 	time = pk_time_to_localised_string (remaining);
 	text = g_strdup_printf (_("Remaining time: %s"), time);
-	gtk_label_set_label (GTK_LABEL (sbar->priv->statusbar->label), text);
+	gtk_progress_bar_set_text (GTK_PROGRESS_BAR (sbar->priv->statusbar->label), text);
 	g_free (time);
 	g_free (text);
 

Modified: trunk/src/pk-update-viewer.c
==============================================================================
--- trunk/src/pk-update-viewer.c	(original)
+++ trunk/src/pk-update-viewer.c	Thu Mar 20 12:14:40 2008
@@ -38,6 +38,7 @@
 #include <pk-task-list.h>
 #include <pk-connection.h>
 #include <pk-package-id.h>
+#include <pk-package-ids.h>
 #include <pk-enum-list.h>
 #include "pk-common-gui.h"
 #include "pk-statusbar.h"
@@ -45,17 +46,24 @@
 
 static GladeXML *glade_xml = NULL;
 static GtkListStore *list_store_preview = NULL;
-static GtkListStore *list_store_history = NULL;
 static GtkListStore *list_store_details = NULL;
 static GtkListStore *list_store_description = NULL;
 static PkClient *client = NULL;
 static PkTaskList *tlist = NULL;
 static gchar *package = NULL;
-static PkStatusbar *statusbar = NULL;
+
+/* for the preview throbber */
+static void pk_updates_add_preview_item (PkClient *client, const gchar *icon, const gchar *message, gboolean clear);
+static void pk_updates_description_animation_stop (void);
+static int animation_timeout = 0;
+static int frame_counter = 0;
+static int n_frames = 0;
+static GdkPixbuf **frames = NULL;
 
 enum {
 	PREVIEW_COLUMN_ICON,
 	PREVIEW_COLUMN_TEXT,
+	PREVIEW_COLUMN_PROGRESS,
 	PREVIEW_COLUMN_LAST
 };
 
@@ -63,6 +71,7 @@
 	DESC_COLUMN_TITLE,
 	DESC_COLUMN_TEXT,
 	DESC_COLUMN_URI,
+	DESC_COLUMN_PROGRESS,
 	DESC_COLUMN_LAST
 };
 
@@ -100,34 +109,24 @@
 }
 
 /**
- * pk_button_update_cb:
- **/
-static void
-pk_button_update_cb (GtkWidget *widget, gboolean data)
-{
-	gboolean ret;
-	pk_client_reset (client, NULL);
-	ret = pk_client_update_package (client, package, NULL);
-	if (ret == TRUE) {
-		/* make the refresh button non-clickable until we have completed */
-		widget = glade_xml_get_widget (glade_xml, "button_apply");
-		gtk_widget_set_sensitive (widget, FALSE);
-		widget = glade_xml_get_widget (glade_xml, "button_apply2");
-		gtk_widget_set_sensitive (widget, FALSE);
-		widget = glade_xml_get_widget (glade_xml, "button_refresh");
-		gtk_widget_set_sensitive (widget, FALSE);
-	}
-}
-
-/**
  * pk_updates_set_page:
  **/
 static void
 pk_updates_set_page (PkPageEnum page)
 {
+	GList *list, *l;
 	GtkWidget *widget;
-	widget = glade_xml_get_widget (glade_xml, "notebook_hidden");
-	gtk_notebook_set_current_page (GTK_NOTEBOOK (widget), page);
+	guint i;
+
+	widget = glade_xml_get_widget (glade_xml, "hbox_hidden");
+	list = gtk_container_get_children (GTK_CONTAINER (widget));
+	for (l=list, i=0; l; l=l->next, i++) {
+		if (i == page) {
+			gtk_widget_show (l->data);
+		} else {
+			gtk_widget_hide (l->data);
+		}
+	}
 
 	/* some pages are resizeable */
 	widget = glade_xml_get_widget (glade_xml, "window_updates");
@@ -144,13 +143,283 @@
 static void
 pk_updates_apply_cb (GtkWidget *widget, gpointer data)
 {
+	GtkTreeModel *model;
+	GtkTreeIter iter;
+	gboolean valid;
+	gboolean update;
+	gboolean selected_all = TRUE;
+	gboolean selected_any = FALSE;
+	gchar *package_id;
+	GPtrArray *array;
+
 	pk_debug ("Doing the system update");
+	array = g_ptr_array_new ();
 
-	pk_client_reset (client, NULL);
-	pk_client_update_system (client, NULL);
+	widget = glade_xml_get_widget (glade_xml, "treeview_updates");
+	model = gtk_tree_view_get_model (GTK_TREE_VIEW (widget));
+
+	/* get the first iter in the list */
+	valid = gtk_tree_model_get_iter_first (model, &iter);
+
+	/* find out how many we should update */
+	while (valid) {
+		gtk_tree_model_get (model, &iter, PACKAGES_COLUMN_SELECT, &update,
+				    PACKAGES_COLUMN_ID, &package_id, -1);
+
+		if (!update) {
+			selected_all = FALSE;
+		} else {
+			selected_any = TRUE;
+		}
+
+		/* do something with the data */
+		if (update) {
+			pk_debug ("%s", package_id);
+			g_ptr_array_add (array, package_id);
+		} else {
+			/* need to free the one in the array later */
+			g_free (package_id);
+		}
+		valid = gtk_tree_model_iter_next (model, &iter);
+	}
+
+	/* we have no checkboxes selected */
+	if (!selected_any) {
+		pk_error_modal_dialog (_("No updates selected"), _("No updates are selected"));
+		return;
+	}
 
 	/* set correct view */
 	pk_updates_set_page (PAGE_PROGRESS);
+
+	/* send an singular list */
+	if (!selected_all) {
+		gchar **package_ids;
+		gboolean ret;
+		GError *error = NULL;
+
+		package_ids = pk_package_ids_from_array (array);
+		pk_client_reset (client, NULL);
+		ret = pk_client_update_packages_strv (client, package_ids, &error);
+		if (!ret) {
+			pk_error_modal_dialog ("Individual updates failed", error->message);
+			g_error_free (error);
+		}
+		g_strfreev (package_ids);
+	}
+
+	/* get rid of the array, and free the contents */
+	g_ptr_array_free (array, TRUE);
+
+	/* the trivial case */
+	if (selected_all) {
+		pk_client_reset (client, NULL);
+		pk_client_update_system (client, NULL);
+	}
+}
+
+/**
+ * pk_updates_animation_load_frames:
+ **/
+static void
+pk_updates_animation_load_frames (void)
+{
+	GtkWidget *widget;
+	GdkPixbuf *pixbuf;
+	gint w, h;
+	gint rows, cols;
+	gint r, c, i;
+
+	if (frames == NULL) {
+		/* get the process-working animation from the icon theme
+		 * and split it into frames.
+		 * FIXME reset frames on theme changes
+		 */
+		widget = glade_xml_get_widget (glade_xml, "window_updates");
+		gtk_icon_size_lookup (GTK_ICON_SIZE_DIALOG, &w, &h);
+		pixbuf = gtk_icon_theme_load_icon (gtk_icon_theme_get_default (),
+						   "process-working",
+						   w, 0, NULL);
+
+		cols = gdk_pixbuf_get_width (pixbuf) / w;
+		rows = gdk_pixbuf_get_height (pixbuf) / h;
+
+		n_frames = rows * cols;
+		frames = g_new (GdkPixbuf*, n_frames);
+
+		for (i = 0, r = 0; r < rows; r++)
+			for (c = 0; c < cols; c++, i++) {
+			frames[i] = gdk_pixbuf_new_subpixbuf (pixbuf, c * w, r * h, w, h);
+		}
+
+		g_object_unref (pixbuf);
+	}
+}
+
+/**
+ * pk_updates_animation_update:
+ **/
+static gboolean
+pk_updates_animation_update (gpointer data)
+{
+	GtkTreeModel *model = data;
+	GtkTreeIter iter;
+	gint column;
+
+	column = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (model), "progress-column"));
+
+	gtk_tree_model_get_iter_first (model, &iter);
+	gtk_list_store_set (GTK_LIST_STORE (model), &iter,
+			    column, frames[frame_counter],
+			    -1);
+
+	frame_counter = (frame_counter + 1) % n_frames;
+
+	return TRUE;
+}
+
+/**
+ * pk_updates_preview_animation_start:
+ **/
+static void
+pk_updates_preview_animation_start (void)
+{
+	GtkWidget *widget;
+	GtkCellRenderer *renderer;
+	GtkTreeViewColumn *column;
+	GtkTreeModel *model;
+	GList *list;
+
+	/* don't double queue */
+	if (animation_timeout != 0) {
+		pk_debug ("don't double start");
+		return;
+	}
+
+	pk_updates_animation_load_frames ();
+
+	pk_updates_add_preview_item (client, NULL, _("Getting information..."), TRUE);
+
+	widget = glade_xml_get_widget (glade_xml, "treeview_preview");
+	column = gtk_tree_view_get_column (GTK_TREE_VIEW (widget), 0);
+	list = gtk_tree_view_column_get_cell_renderers (column);
+	renderer = list->data;
+	g_list_free (list);
+	gtk_tree_view_column_clear_attributes (column, renderer);
+	gtk_tree_view_column_set_attributes (column, renderer,
+					     "pixbuf", PREVIEW_COLUMN_PROGRESS, NULL);
+
+	model = gtk_tree_view_get_model (GTK_TREE_VIEW (widget));
+	frame_counter = 0;
+
+	g_object_set_data (G_OBJECT (model), "progress-column",
+			   GINT_TO_POINTER (PREVIEW_COLUMN_PROGRESS));
+
+	animation_timeout = g_timeout_add (50, pk_updates_animation_update, model);
+	pk_updates_animation_update (model);
+}
+
+/**
+ * pk_updates_preview_animation_stop:
+ **/
+static void
+pk_updates_preview_animation_stop (void)
+{
+	GtkWidget *widget;
+	GtkCellRenderer *renderer;
+	GtkTreeViewColumn *column;
+	GList *list;
+
+	if (animation_timeout == 0)
+		return;
+
+	g_source_remove (animation_timeout);
+	animation_timeout = 0;
+
+	widget = glade_xml_get_widget (glade_xml, "treeview_preview");
+	column = gtk_tree_view_get_column (GTK_TREE_VIEW (widget), 0);
+	list = gtk_tree_view_column_get_cell_renderers (column);
+	renderer = list->data;
+	g_list_free (list);
+	gtk_tree_view_column_clear_attributes (column, renderer);
+	gtk_tree_view_column_set_attributes (column, renderer,
+					     "icon-name", PREVIEW_COLUMN_ICON, NULL);
+}
+
+/**
+ * pk_updates_description_animation_start:
+ **/
+static void
+pk_updates_description_animation_start (void)
+{
+	GtkWidget *widget;
+	GtkTreeViewColumn *column;
+	GList *list, *l;
+	GtkCellRenderer *renderer;
+	GtkTreeIter iter;
+	gchar *text;
+
+	/* don't double queue */
+	if (animation_timeout != 0) {
+		pk_debug ("don't double start");
+		return;
+	}
+
+	pk_updates_animation_load_frames ();
+
+	widget = glade_xml_get_widget (glade_xml, "treeview_description");
+	column = gtk_tree_view_get_column (GTK_TREE_VIEW (widget), 0);
+	list = gtk_tree_view_column_get_cell_renderers (column);
+	for (l = list; l; l = l->next) {
+		renderer = l->data;
+		if (GTK_IS_CELL_RENDERER_PIXBUF (renderer)) {
+			g_object_set (renderer, "visible", TRUE, NULL);
+		}
+	}
+	g_list_free (list);
+
+	text = g_strdup_printf ("<b>%s</b>", _("Getting Information..."));
+	gtk_list_store_append (list_store_description, &iter);
+	gtk_list_store_set (list_store_description, &iter,
+			    DESC_COLUMN_TITLE, text,
+			    -1);
+	g_free (text);
+
+	frame_counter = 0;
+
+	g_object_set_data (G_OBJECT (list_store_description), "progress-column",
+		           GINT_TO_POINTER (DESC_COLUMN_PROGRESS));
+	animation_timeout = g_timeout_add (50, pk_updates_animation_update, list_store_description);
+	pk_updates_animation_update (list_store_description);
+}
+
+/**
+ * pk_updates_description_animation_stop:
+ **/
+static void
+pk_updates_description_animation_stop (void)
+{
+	GtkWidget *widget;
+	GtkTreeViewColumn *column;
+	GList *list, *l;
+	GtkCellRenderer *renderer;
+
+	if (animation_timeout == 0)
+		return;
+
+	g_source_remove (animation_timeout);
+	animation_timeout = 0;
+
+	widget = glade_xml_get_widget (glade_xml, "treeview_description");
+	column = gtk_tree_view_get_column (GTK_TREE_VIEW (widget), 0);
+	list = gtk_tree_view_column_get_cell_renderers (column);
+	for (l = list; l; l = l->next) {
+		renderer = list->data;
+		if (GTK_IS_CELL_RENDERER_PIXBUF (renderer)) {
+			g_object_set (renderer, "visible", FALSE, NULL);
+		}
+	}
+	g_list_free (list);
 }
 
 /**
@@ -163,6 +432,7 @@
 
 	/* clear existing list */
 	gtk_list_store_clear (list_store_details);
+	pk_updates_preview_animation_start ();
 
 	/* make the refresh button non-clickable */
 	gtk_widget_set_sensitive (widget, FALSE);
@@ -214,6 +484,24 @@
 static void
 pk_button_review_cb (GtkWidget *widget, gpointer data)
 {
+	GtkWidget *treeview;
+	GtkTreeSelection *selection;
+	GtkTreeIter iter;
+
+	treeview = glade_xml_get_widget (glade_xml, "treeview_updates");
+	selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview));
+	if (!gtk_tree_selection_get_selected (selection, NULL, NULL)) {
+		if (gtk_tree_model_get_iter_first (gtk_tree_view_get_model (GTK_TREE_VIEW (treeview)),
+						   &iter))
+			gtk_tree_selection_select_iter (selection, &iter);
+	}
+
+	widget = glade_xml_get_widget (glade_xml, "treeview_updates");
+	gtk_widget_set_size_request (GTK_WIDGET (widget), 500, 200);
+
+	widget = glade_xml_get_widget (glade_xml, "treeview_description");
+	gtk_widget_set_size_request (GTK_WIDGET (widget), 500, 200);
+
 	/* set correct view */
 	pk_updates_set_page (PAGE_DETAILS);
 }
@@ -240,10 +528,10 @@
 	PkRoleEnum role;
 	const gchar *icon_name;
 	GtkWidget *widget;
-	GtkTreePath *path;
 
 	pk_client_get_role (client, &role, NULL, NULL);
-	pk_debug ("package = %s:%s:%s", pk_info_enum_to_text (info), package_id, summary);
+	pk_debug ("role = %s, package = %s:%s:%s", pk_role_enum_to_text (role),
+		  pk_info_enum_to_text (info), package_id, summary);
 
 	if (role == PK_ROLE_ENUM_GET_UPDATES) {
 		text = pk_package_id_pretty (package_id, summary);
@@ -260,19 +548,11 @@
 		return;
 	}
 
-	if (role == PK_ROLE_ENUM_UPDATE_SYSTEM) {
-		text = pk_package_id_pretty (package_id, summary);
-		icon_name = pk_info_enum_to_icon_name (info);
-		gtk_list_store_prepend (list_store_history, &iter);
-		gtk_list_store_set (list_store_history, &iter,
-				    HISTORY_COLUMN_TEXT, text,
-				    HISTORY_COLUMN_ICON, icon_name,
-				    -1);
-
-		/* move focus to top entry */
-		widget = glade_xml_get_widget (glade_xml, "treeview_history");
-		path = gtk_tree_path_new_from_indices (0, -1);
-		gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW (widget), path, NULL, FALSE, 0.0, 0.0);
+	if (role == PK_ROLE_ENUM_UPDATE_SYSTEM ||
+	    role == PK_ROLE_ENUM_UPDATE_PACKAGES) {
+		text = pk_package_id_pretty_oneline (package_id, summary);
+		widget = glade_xml_get_widget (glade_xml, "progress_package_label");
+		gtk_label_set_markup (GTK_LABEL (widget), text);
 
 		g_free (text);
 		return;
@@ -363,18 +643,13 @@
 	PkInfoEnum info;
 
 	/* clear existing list */
+	pk_updates_description_animation_stop ();
 	gtk_list_store_clear (list_store_description);
 
 	/* initially we are hidden */
 	widget = glade_xml_get_widget (glade_xml, "scrolledwindow_description");
 	gtk_widget_show (widget);
 
-	widget = glade_xml_get_widget (glade_xml, "treeview_updates");
-	gtk_widget_set_size_request (GTK_WIDGET (widget), 500, 200);
-
-	widget = glade_xml_get_widget (glade_xml, "treeview_description");
-	gtk_widget_set_size_request (GTK_WIDGET (widget), 500, 200);
-
 	/* get info  */
 	widget = glade_xml_get_widget (glade_xml, "treeview_updates");
 	selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (widget));
@@ -448,7 +723,13 @@
 static void
 pk_updates_status_changed_cb (PkClient *client, PkStatusEnum status, gpointer data)
 {
-	pk_statusbar_set_status (statusbar, status);
+	GtkWidget *widget;
+	gchar *text;
+
+	widget = glade_xml_get_widget (glade_xml, "progress_part_label");
+	text = g_strdup_printf ("<b>%s</b>", pk_status_enum_to_localised_text (status));
+	gtk_label_set_markup (GTK_LABEL (widget), text);
+	g_free (text);
 }
 
 /**
@@ -487,7 +768,7 @@
 			    PACKAGES_COLUMN_ID, &package_id, -1);
 
 	/* unstage */
-//	update ^= 1;
+	update ^= 1;
 
 	pk_debug ("update %s[%i]", package_id, update);
 	g_free (package_id);
@@ -544,9 +825,15 @@
 	GtkTreeViewColumn *column;
 
 	/* image */
+	column = gtk_tree_view_column_new ();
+	renderer = gtk_cell_renderer_pixbuf_new ();
+	g_object_set (renderer, "visible", FALSE, NULL);
+	gtk_tree_view_column_pack_start (column, renderer, FALSE);
+	gtk_tree_view_column_add_attribute (column, renderer, "pixbuf", DESC_COLUMN_PROGRESS);
+
 	renderer = gtk_cell_renderer_text_new ();
-	column = gtk_tree_view_column_new_with_attributes (_("Title"), renderer,
-							   "markup", DESC_COLUMN_TITLE, NULL);
+	gtk_tree_view_column_pack_start (column, renderer, FALSE);
+	gtk_tree_view_column_add_attribute (column, renderer, "markup", DESC_COLUMN_TITLE);
 	gtk_tree_view_append_column (treeview, column);
 
 	/* column for uris */
@@ -596,7 +883,10 @@
 
 	/* hide the widgets until we have data */
 	widget = glade_xml_get_widget (glade_xml, "scrolledwindow_description");
-	gtk_widget_hide (widget);
+
+	gtk_list_store_clear (list_store_description);
+	pk_updates_description_animation_start ();
+
 	widget = glade_xml_get_widget (glade_xml, "hbox_reboot");
 	gtk_widget_hide (widget);
 
@@ -613,13 +903,8 @@
 		/* get the decription */
 		pk_client_reset (client, NULL);
 		pk_client_get_update_detail (client, package, NULL);
-
-		widget = glade_xml_get_widget (glade_xml, "button_update");
-		gtk_widget_set_sensitive (widget, TRUE);
 	} else {
 		pk_debug ("no row selected");
-		widget = glade_xml_get_widget (glade_xml, "button_update");
-		gtk_widget_set_sensitive (widget, FALSE);
 	}
 }
 
@@ -662,6 +947,67 @@
 }
 
 /**
+ * pk_update_get_approx_time:
+ **/
+static const gchar *
+pk_update_get_approx_time (guint time)
+{
+	if (time < 60) {
+		return _("Less than a minute");
+	} else if (time < 60*60) {
+		return _("Less than an hour");
+	} else if (time < 24*60*60) {
+		return _("A few hours");
+	} else if (time < 7*24*60*60) {
+		return _("A few days");
+	}
+	return _("Over a week");
+}
+
+/**
+ * pk_update_update_last_refreshed_time:
+ **/
+static gboolean
+pk_update_update_last_refreshed_time (PkClient *client)
+{
+	GtkWidget *widget;
+	guint time;
+	const gchar *time_text;
+
+	/* get times from the daemon */
+	pk_client_get_time_since_action (client, PK_ROLE_ENUM_REFRESH_CACHE, &time, NULL);
+	time_text = pk_update_get_approx_time (time);
+	widget = glade_xml_get_widget (glade_xml, "label_last_refresh");
+	gtk_label_set_label (GTK_LABEL (widget), time_text);
+	return TRUE;
+}
+
+/**
+ * pk_update_update_last_updated_time:
+ **/
+static gboolean
+pk_update_update_last_updated_time (PkClient *client)
+{
+	GtkWidget *widget;
+	guint time;
+	guint time_new;
+	const gchar *time_text;
+
+	/* get times from the daemon */
+	pk_client_get_time_since_action (client, PK_ROLE_ENUM_UPDATE_SYSTEM, &time, NULL);
+	pk_client_get_time_since_action (client, PK_ROLE_ENUM_UPDATE_PACKAGES, &time_new, NULL);
+
+	/* always use the shortest time */
+	if (time_new < time) {
+		time = time_new;
+	}
+	time_text = pk_update_get_approx_time (time);
+	widget = glade_xml_get_widget (glade_xml, "label_last_update");
+	gtk_label_set_label (GTK_LABEL (widget), time_text);
+	return TRUE;
+}
+
+/**
  * pk_updates_finished_cb:
  **/
 static void
@@ -674,21 +1020,23 @@
 
 	pk_client_get_role (client, &role, NULL, NULL);
 
-	/* hide widget */
-	pk_statusbar_hide (statusbar);
-
+	/* just update the preview page */
 	if (role == PK_ROLE_ENUM_REFRESH_CACHE) {
-		pk_client_reset (client, NULL);
-		pk_client_set_use_buffer (client, TRUE, NULL);
-		pk_client_get_updates (client, "basename", NULL);
-		return;
+		/* update last time in the UI */
+		pk_update_update_last_refreshed_time (client);
+	} else if (role == PK_ROLE_ENUM_UPDATE_SYSTEM || role == PK_ROLE_ENUM_UPDATE_PACKAGES) {
+		pk_update_update_last_updated_time (client);
 	}
 
 	/* we don't need to do anything here */
-	if (role == PK_ROLE_ENUM_GET_UPDATE_DETAIL) {
+	if (role == PK_ROLE_ENUM_REFRESH_CACHE ||
+	    role == PK_ROLE_ENUM_GET_UPDATE_DETAIL) {
 		return;
 	}
 
+	/* stop the throbber */
+	pk_updates_preview_animation_stop ();
+
 	/* make the refresh button clickable now we have completed */
 	widget = glade_xml_get_widget (glade_xml, "button_apply");
 	gtk_widget_set_sensitive (widget, TRUE);
@@ -724,7 +1072,7 @@
 	}
 
 	/* we don't need to do anything here */
-	if (role == PK_ROLE_ENUM_UPDATE_PACKAGE) {
+	if (role == PK_ROLE_ENUM_UPDATE_PACKAGES) {
 		/* clear existing list */
 		gtk_list_store_clear (list_store_details);
 
@@ -835,17 +1183,11 @@
 				guint elapsed, guint remaining, gpointer data)
 {
 	GtkWidget *widget;
-	widget = glade_xml_get_widget (glade_xml, "progressbar_subpercent");
+	widget = glade_xml_get_widget (glade_xml, "progressbar_percent");
 
-	if (subpercentage == PK_CLIENT_PERCENTAGE_INVALID) {
-		gtk_widget_hide (widget);
-	} else {
+	if (subpercentage != PK_CLIENT_PERCENTAGE_INVALID) {
 		gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (widget), (gfloat) subpercentage / 100.0);
-		gtk_widget_show (widget);
 	}
-
-	pk_statusbar_set_percentage (statusbar, percentage);
-	pk_statusbar_set_remaining (statusbar, remaining);
 }
 
 /**
@@ -913,6 +1255,28 @@
 }
 
 /**
+ * pk_updates_changed_cb:
+ **/
+static void
+pk_updates_changed_cb (PkClient *client, gpointer data)
+{
+	gboolean ret;
+	GError *error = NULL;
+
+	/* get the update list */
+	pk_client_reset (client, NULL);
+	pk_client_set_use_buffer (client, TRUE, NULL);
+	ret = pk_client_get_updates (client, "basename", &error);
+	if (!ret) {
+		pk_warning ("failed to get new list: %s", error->message);
+		g_error_free (error);
+	} else {
+		/* only show this if we succeeded */
+		pk_updates_preview_animation_start ();
+	}
+}
+
+/**
  * main:
  **/
 int
@@ -928,6 +1292,7 @@
 	PkConnection *pconnection;
 	PkEnumList *role_list;
 	PkRoleEnum role;
+	gboolean ret;
 
 	const GOptionEntry options[] = {
 		{ "verbose", 'v', 0, G_OPTION_ARG_NONE, &verbose,
@@ -985,6 +1350,8 @@
 			  G_CALLBACK (pk_updates_error_code_cb), NULL);
 	g_signal_connect (client, "allow-cancel",
 			  G_CALLBACK (pk_updates_allow_cancel_cb), NULL);
+	g_signal_connect (client, "updates-changed",
+			  G_CALLBACK (pk_updates_changed_cb), NULL);
 
 	/* get actions */
 	role_list = pk_client_get_actions (client);
@@ -1005,11 +1372,6 @@
 	/* Hide window first so that the dialogue resizes itself without redrawing */
 	gtk_widget_hide (main_window);
 
-	/* hide the tabs */
-	widget = glade_xml_get_widget (glade_xml, "notebook_hidden");
-	gtk_notebook_set_show_tabs (GTK_NOTEBOOK (widget), FALSE);
-	gtk_notebook_set_show_border (GTK_NOTEBOOK (widget), FALSE);
-
 	/* hide until we have updates */
 	widget = glade_xml_get_widget (glade_xml, "hbox_reboot");
 	gtk_widget_hide (widget);
@@ -1086,17 +1448,11 @@
 	/* we have no yelp file yet */
 	gtk_widget_hide (widget);
 
-	widget = glade_xml_get_widget (glade_xml, "button_update");
-	g_signal_connect (widget, "clicked",
-			  G_CALLBACK (pk_button_update_cb), NULL);
-	gtk_widget_set_tooltip_text(widget, _("Update selected package"));
-
 	/* create list stores */
 	list_store_details = gtk_list_store_new (PACKAGES_COLUMN_LAST, G_TYPE_STRING,
 						 G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INT, G_TYPE_BOOLEAN);
-	list_store_preview = gtk_list_store_new (PREVIEW_COLUMN_LAST, G_TYPE_STRING, G_TYPE_STRING);
-	list_store_history = gtk_list_store_new (PREVIEW_COLUMN_LAST, G_TYPE_STRING, G_TYPE_STRING);
-	list_store_description = gtk_list_store_new (DESC_COLUMN_LAST, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING);
+	list_store_preview = gtk_list_store_new (PREVIEW_COLUMN_LAST, G_TYPE_STRING, G_TYPE_STRING, GDK_TYPE_PIXBUF);
+	list_store_description = gtk_list_store_new (DESC_COLUMN_LAST, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, GDK_TYPE_PIXBUF);
 
 	/* sorted */
 	gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (list_store_details),
@@ -1111,12 +1467,7 @@
 	pk_treeview_add_columns (GTK_TREE_VIEW (widget));
 	gtk_tree_view_columns_autosize (GTK_TREE_VIEW (widget));
 
-	/* create history tree view */
-	widget = glade_xml_get_widget (glade_xml, "treeview_history");
-	gtk_tree_view_set_model (GTK_TREE_VIEW (widget),
-				 GTK_TREE_MODEL (list_store_history));
-
-	/* create history tree view */
+	/* create description tree view */
 	widget = glade_xml_get_widget (glade_xml, "treeview_description");
 	gtk_tree_view_set_model (GTK_TREE_VIEW (widget),
 				 GTK_TREE_MODEL (list_store_description));
@@ -1131,6 +1482,7 @@
 				 GTK_TREE_MODEL (list_store_details));
 
 	selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (widget));
+	gtk_tree_selection_set_mode (selection, GTK_SELECTION_BROWSE);
 	g_signal_connect (selection, "changed",
 			  G_CALLBACK (pk_packages_treeview_clicked_cb), NULL);
 
@@ -1138,24 +1490,20 @@
 	pk_treeview_add_columns_update (GTK_TREE_VIEW (widget));
 	gtk_tree_view_columns_autosize (GTK_TREE_VIEW (widget));
 
-	/* use the in-statusbar for progress */
-	statusbar = pk_statusbar_new ();
-	widget = glade_xml_get_widget (glade_xml, "statusbar_status");
-	pk_statusbar_set_widget (statusbar, widget);
-
 	/* make the refresh button non-clickable until we get completion */
 	widget = glade_xml_get_widget (glade_xml, "button_refresh");
 	gtk_widget_set_sensitive (widget, FALSE);
 
-	widget = glade_xml_get_widget (glade_xml, "button_update");
-	gtk_widget_set_sensitive (widget, FALSE);
-
-	/* assume we don't get this yet */
-	widget = glade_xml_get_widget (glade_xml, "progressbar_subpercent");
-	gtk_widget_hide (widget);
+	/* set the last updated text */
+	pk_update_update_last_refreshed_time (client);
+	pk_update_update_last_updated_time (client);
 
 	/* get the update list */
-	pk_client_get_updates (client, "basename", NULL);
+	ret = pk_client_get_updates (client, "basename", NULL);
+	if (ret) {
+		/* only show this if we succeeded */
+		pk_updates_preview_animation_start ();
+	}
 	gtk_widget_show (main_window);
 
 	g_main_loop_run (loop);
@@ -1170,13 +1518,11 @@
 
 	g_object_unref (glade_xml);
 	g_object_unref (list_store_preview);
-	g_object_unref (list_store_history);
 	g_object_unref (list_store_description);
 	g_object_unref (list_store_details);
 	g_object_unref (client);
 	g_object_unref (pconnection);
 	g_object_unref (role_list);
-	g_object_unref (statusbar);
 	g_free (package);
 
 	return 0;

Modified: trunk/src/pk-watch.c
==============================================================================
--- trunk/src/pk-watch.c	(original)
+++ trunk/src/pk-watch.c	Thu Mar 20 12:14:40 2008
@@ -740,6 +740,21 @@
 }
 
 /**
+ * pk_watch_hide_restart_cb:
+ **/
+static void
+pk_watch_hide_restart_cb (GtkMenuItem *item, gpointer data)
+{
+	PkWatch *watch = PK_WATCH (data);
+
+	g_return_if_fail (watch != NULL);
+	g_return_if_fail (PK_IS_WATCH (watch));
+
+	/* just hide it */
+	pk_smart_icon_set_icon_name (watch->priv->sicon_restart, NULL);
+}
+
+/**
  * pk_watch_activate_status_restart_cb:
  * @button: Which buttons are pressed
  *
@@ -765,6 +780,14 @@
 			  G_CALLBACK (pk_watch_restart_cb), watch);
 	gtk_menu_shell_append (GTK_MENU_SHELL (menu), widget);
 
+	/* hide this option */
+	widget = gtk_image_menu_item_new_with_mnemonic (_("_Hide this icon"));
+	image = gtk_image_new_from_icon_name ("dialog-information", GTK_ICON_SIZE_MENU);
+	gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (widget), image);
+	g_signal_connect (G_OBJECT (widget), "activate",
+			  G_CALLBACK (pk_watch_hide_restart_cb), watch);
+	gtk_menu_shell_append (GTK_MENU_SHELL (menu), widget);
+
 	/* show the menu */
 	gtk_widget_show_all (GTK_WIDGET (menu));
 	gtk_menu_popup (GTK_MENU (menu), NULL, NULL,



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