gnome-packagekit r146 - in trunk: help/C help/sv libgbus src



Author: rhughes
Date: Tue Apr  1 02:32:12 2008
New Revision: 146
URL: http://svn.gnome.org/viewvc/gnome-packagekit?rev=146&view=rev

Log:
from git

Added:
   trunk/src/gpk-log.c
Removed:
   trunk/src/gpk-transaction-viewer.c
Modified:
   trunk/help/C/gnome-packagekit.xml
   trunk/help/sv/.gitignore
   trunk/libgbus/libgbus.c
   trunk/libgbus/libgbus.h
   trunk/src/.gitignore
   trunk/src/Makefile.am
   trunk/src/gpk-application-main.c
   trunk/src/gpk-application.c
   trunk/src/gpk-common.c
   trunk/src/gpk-common.h
   trunk/src/gpk-notify.c
   trunk/src/gpk-prefs.c
   trunk/src/gpk-repo.c
   trunk/src/gpk-smart-icon.c
   trunk/src/gpk-update-icon.c
   trunk/src/gpk-update-viewer.c
   trunk/src/gpk-watch.c

Modified: trunk/help/C/gnome-packagekit.xml
==============================================================================
--- trunk/help/C/gnome-packagekit.xml	(original)
+++ trunk/help/C/gnome-packagekit.xml	Tue Apr  1 02:32:12 2008
@@ -25,11 +25,11 @@
     <title>&application; Manual</title>
     <abstract role="description">
       <para>
-        &application; is a suite of tools for interation with the GNOME desktop.
+        &application; is a suite of tools for integration with the GNOME desktop.
       </para>
     </abstract>
     <copyright>
-      <year>2007</year>
+      <year>2008</year>
       <holder>Richard Hughes (richard hughsie com)</holder>
     </copyright>
 
@@ -76,6 +76,15 @@
 
     <revhistory>
       <revision>
+       <revnumber>3.0</revnumber>
+        <date>2008-03-31</date>
+        <revdescription>
+          <para role="author">Rahul Sundaram
+            <email>sundaram fedoraproject org</email>
+          </para>
+          <para role="publisher">Rahul Sundaram</para>
+        </revdescription>
+
         <revnumber>2.0</revnumber>
         <date>2007-08-30</date>
         <revdescription>
@@ -91,7 +100,7 @@
       <title>Feedback</title>
       <para>
         To report a bug or make a suggestion regarding the &app; application or
-        this manual, follow the directions in the 
+        this manual, follow the directions in the
         <ulink url="http://live.gnome.org/PackageKit/";
           type="http">&application; Contact Page</ulink>.
       </para>
@@ -103,7 +112,7 @@
     <primary>&application;</primary>
   </indexterm>
   <indexterm zone="index">
-    <primary>pk-application</primary>
+    <primary>gpk-application</primary>
   </indexterm>
 
 <!-- ============= Document Body ============================= -->
@@ -116,34 +125,132 @@
   <indexterm>
     <primary>&application;</primary>
     <secondary>Manual</secondary>
-    <tertiary>pk-application</tertiary>
+    <tertiary>gpk-application</tertiary>
   </indexterm>
 
   <para>
-  The &app; is a suite of tools for the <systemitem>GNOME desktop</systemitem>
+    &app; is a suite of tools for the <systemitem>GNOME desktop</systemitem>
+  </para>
+  <para>
+    PackageKit is designed to unify all the software graphical tools used in
+    different distributions.
+    It abstracts the various underlying package management technologies like
+    yum, apt, smart etc. and provides unified graphical and command line frontends.
+    It also provides a framework that includes programming interfaces that other
+    software applications can take advantage of.
+    It is not a replacement for existing package managers like yum.
   </para>
 
 </section>
 
-<section id="using">
-  <title>Usage</title>
+<section id="application">
+  <title>Applications</title>
   <para>
-    <application>&app;</application> is usually started in GNOME startup, but
-    you can manually start <application>&app;</application> by doing:
+    <application>packagekitd</application> is started automatically when it is
+    needed.
+  </para>
+  <para>
+    Below is a list containing the names and a short description of the
+    utilities included in the gnome-packagekit pack:
   </para>
   <variablelist>
     <varlistentry>
-      <term>Command line</term>
       <listitem>
         <para>
-          Type <command>pk-application --verbose --no-daemon</command>,
-          then press <keycap>Return</keycap>:
+          <command>gpk-application</command>: Add/Remove Software
+        </para>
+      </listitem>
+      <listitem>
+        <para>
+          <command>gpk-update-viewer</command>: Updating your system.
+          Also can view the history of updates.
+        </para>
+      </listitem>
+      <listitem>
+        <para>
+          <command>gpk-prefs</command>: Configuring software updates preferences
+        </para>
+      </listitem>
+      <listitem>
+        <para>
+          <command>gpk-repo</command>: Enabling or disabling software repositories
+        </para>
+      </listitem>
+      <listitem>
+        <para>
+          <command>gpk-log</command>: History of updates including installing,
+          removing or updating any software
+        </para>
+      </listitem>
+      <listitem>
+        <para>
+          <command>pk-backend-status</command>: Shows technical status of
+          support for the underlying package management backend.
+          Only useful for developers.
         </para>
       </listitem>
     </varlistentry>
   </variablelist>
 </section>
 
+<section id="add-remove">
+  <title>Add/Remove Software</title>
+  <para>
+    Add/Remove software application accessed via <menuchoice><guimenu>System</guimenu><guisubmenu>Administration</guisubmenu><guimenuitem>Add/Remove Software</guimenuitem></menuchoice>
+    allows you to search the software repository easily or browse through the
+    different groups like multimedia or office and select software packages to
+    install or remove from your system.
+    You can find more information about any package such as description and
+    dependencies by just clicking on it.
+    Before installing a package, you also can visit the home page of the software
+    projects easily for getting any additional details
+  </para>
+  <para>
+    Typically, you can find several thousands of software packages under
+    different groups available.
+    Since this can be overwhelming you can choose to filter the lists of
+    packages based on several criteria such as whether the package is already
+    installed, whether it is a development or graphical application and based
+    on the software license.
+  </para>
+  <para>
+    A software source configuration is available in the system menu that allows
+    you to enable or disable a existing software repository.
+    You can also refresh the application lists for displaying the latest information.
+  </para>
+</section>
+
+<section id="software-sources">
+  <title>Software Sources</title>
+  <para>
+    A software repository viewer allows you to enable or disable sources.
+  </para>
+</section>
+
+<section id="update-viewer">
+  <title>Update Viewer</title>
+   <para>
+    You can update your system via <menuchoice><guimenu>System</guimenu><guisubmenu>Administration</guisubmenu><guimenuitem>Update System</guimenuitem></menuchoice>.
+    When you click on this, the application launches and immediately starts
+    checking for updates.
+    If you launched the application a while back, you can choose to manually
+    refresh and verify the presence of updates.
+    There is a option to view the history of updates including
+    previous installations, removal or updates of software.
+  </para>
+</section>
+
+<section id="prefs">
+  <title>Software Updates Preferences</title>
+  <para>
+    Preferences can be configured via <menuchoice><guimenu>System</guimenu><guisubmenu>Preferences</guisubmenu><guisubmenu>System</guisubmenu><guimenuitem>Software Updates</guimenuitem></menuchoice>.
+    You can configure it to check for updates on a daily, hourly or weekly basis
+    or never. The default setting is to check for updates daily.
+    You can also configure it to automatically install all updates or just the
+    ones that fix security issues.
+  </para>
+</section>
+
 <section id="about">
   <title>About</title>
   <para>
@@ -162,9 +269,10 @@
     General Public license as published by the Free Software
     Foundation; either version 2 of the License, or (at your option)
     any later version. A copy of this license can be found at this
-    <ulink url="pk-application:gpl" type="help">link</ulink>, or in the file
+    <ulink url="gpk-application:gpl" type="help">link</ulink>, or in the file
     COPYING included with the source code of this program.
   </para>
 </section>
 
 </article>
+

Modified: trunk/help/sv/.gitignore
==============================================================================
--- trunk/help/sv/.gitignore	(original)
+++ trunk/help/sv/.gitignore	Tue Apr  1 02:32:12 2008
@@ -1,3 +1,4 @@
 .svn
 *.mo
+*.xml
 

Modified: trunk/libgbus/libgbus.c
==============================================================================
--- trunk/libgbus/libgbus.c	(original)
+++ trunk/libgbus/libgbus.c	Tue Apr  1 02:32:12 2008
@@ -42,11 +42,12 @@
 	gchar			*service;
 	DBusGProxy		*proxy;
 	DBusGConnection		*connection;
-	gboolean		 connected;
+	const gchar		*unique_name;
 };
 
 enum {
 	CONNECTION_CHANGED,
+	CONNECTION_REPLACED,
 	LAST_SIGNAL
 };
 
@@ -64,22 +65,43 @@
 		       const gchar    *new,
 		       LibGBus	      *libgbus)
 {
+	guint new_len;
+	guint prev_len;
+
 	g_return_if_fail (IS_LIBGBUS (libgbus));
 	if (libgbus->priv->proxy == NULL) {
 		return;
 	}
 
-	if (strcmp (name, libgbus->priv->service) == 0) {
-		/* ITS4: ignore, not used for allocation */
-		if (strlen (prev) != 0 && strlen (new) == 0 && libgbus->priv->connected == TRUE) {
-			g_signal_emit (libgbus, signals [CONNECTION_CHANGED], 0, FALSE);
-			libgbus->priv->connected = FALSE;
-		}
-		/* ITS4: ignore, not used for allocation */
-		if (strlen (prev) == 0 && strlen (new) != 0 && libgbus->priv->connected == FALSE) {
-			g_signal_emit (libgbus, signals [CONNECTION_CHANGED], 0, TRUE);
-			libgbus->priv->connected = TRUE;
+	/* not us */
+	if (strcmp (name, libgbus->priv->service) != 0) {
+		return;
+	}
+
+	/* ITS4: ignore, not used for allocation */
+	new_len = strlen (new);
+	/* ITS4: ignore, not used for allocation */
+	prev_len = strlen (prev);
+
+	/* something --> nothing */
+	if (prev_len != 0 && new_len == 0) {
+		g_signal_emit (libgbus, signals [CONNECTION_CHANGED], 0, FALSE);
+		return;
+	}
+
+	/* nothing --> something */
+	if (prev_len == 0 && new_len != 0) {
+		g_signal_emit (libgbus, signals [CONNECTION_CHANGED], 0, TRUE);
+		return;
+	}
+
+	/* something --> something (we've replaced the old process) */
+	if (prev_len != 0 && new_len != 0) {
+		/* only send this to the prev client */
+		if (strcmp (libgbus->priv->unique_name, prev) == 0) {
+			g_signal_emit (libgbus, signals [CONNECTION_REPLACED], 0);
 		}
+		return;
 	}
 }
 
@@ -99,6 +121,8 @@
 		const gchar  *service)
 {
 	GError *error = NULL;
+	gboolean connected;
+	DBusConnection *conn;
 
 	g_return_val_if_fail (IS_LIBGBUS (libgbus), FALSE);
 	g_return_val_if_fail (service != NULL, FALSE);
@@ -139,10 +163,14 @@
 				     libgbus, NULL);
 
 	/* coldplug */
-	libgbus->priv->connected = libgbus_is_connected (libgbus);
-	if (libgbus->priv->connected == TRUE) {
+	connected = libgbus_is_connected (libgbus);
+	if (connected == TRUE) {
 		g_signal_emit (libgbus, signals [CONNECTION_CHANGED], 0, TRUE);
 	}
+
+	/* save this for the replaced check */
+	conn = dbus_g_connection_get_connection (libgbus->priv->connection);
+	libgbus->priv->unique_name = dbus_bus_get_unique_name (conn);
 	return TRUE;
 }
 
@@ -184,13 +212,16 @@
 
 	signals [CONNECTION_CHANGED] =
 		g_signal_new ("connection-changed",
-			      G_TYPE_FROM_CLASS (object_class),
-			      G_SIGNAL_RUN_LAST,
+			      G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST,
 			      G_STRUCT_OFFSET (LibGBusClass, connection_changed),
-			      NULL,
-			      NULL,
-			      g_cclosure_marshal_VOID__BOOLEAN,
+			      NULL, NULL, g_cclosure_marshal_VOID__BOOLEAN,
 			      G_TYPE_NONE, 1, G_TYPE_BOOLEAN);
+	signals [CONNECTION_REPLACED] =
+		g_signal_new ("connection-replaced",
+			      G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST,
+			      G_STRUCT_OFFSET (LibGBusClass, connection_replaced),
+			      NULL, NULL, g_cclosure_marshal_VOID__VOID,
+			      G_TYPE_NONE, 0);
 }
 
 /**

Modified: trunk/libgbus/libgbus.h
==============================================================================
--- trunk/libgbus/libgbus.h	(original)
+++ trunk/libgbus/libgbus.h	Tue Apr  1 02:32:12 2008
@@ -47,6 +47,7 @@
 	GObjectClass	parent_class;
 	void		(* connection_changed)	(LibGBus	*watch,
 						 gboolean	 connected);
+	void		(* connection_replaced)	(LibGBus	*watch);
 } LibGBusClass;
 
 typedef enum {

Modified: trunk/src/.gitignore
==============================================================================
--- trunk/src/.gitignore	(original)
+++ trunk/src/.gitignore	Tue Apr  1 02:32:12 2008
@@ -4,6 +4,7 @@
 .deps
 gpk-marshal.c
 gpk-marshal.h
+gpk-interface.h
 gpk-self-test
 gpk-repo
 gpk-application

Modified: trunk/src/Makefile.am
==============================================================================
--- trunk/src/Makefile.am	(original)
+++ trunk/src/Makefile.am	Tue Apr  1 02:32:12 2008
@@ -241,6 +241,7 @@
 BUILT_SOURCES = 					\
 	gpk-marshal.c					\
 	gpk-marshal.h					\
+	gpk-interface.h					\
 	$(NULL)
 
 gpk-marshal.c: gpk-marshal.list
@@ -250,9 +251,16 @@
 gpk-marshal.h: gpk-marshal.list
 	glib-genmarshal $< --prefix=gpk_marshal --header > $@
 
+gpk-interface.h: gpk-interface.xml
+	$(LIBTOOL) --mode=execute dbus-binding-tool	\
+		--prefix=gpk_dbus			\
+		--mode=glib-server			\
+		--output=gpk-interface.h		\
+		$(srcdir)/gpk-interface.xml
 
 EXTRA_DIST =						\
 	gpk-marshal.list				\
+	gpk-interface.xml				\
 	$(NULL)
 
 clean-local:

Modified: trunk/src/gpk-application-main.c
==============================================================================
--- trunk/src/gpk-application-main.c	(original)
+++ trunk/src/gpk-application-main.c	Tue Apr  1 02:32:12 2008
@@ -35,18 +35,6 @@
 #include "gpk-application.h"
 
 /**
- * pk_application_help_cb
- * @application: This application class instance
- *
- * What to do when help is requested
- **/
-static void
-pk_application_help_cb (PkApplication *application)
-{
-	pk_warning ("help application");
-}
-
-/**
  * pk_application_close_cb
  * @application: This application class instance
  *
@@ -107,8 +95,6 @@
 
 	/* create a new application object */
 	application = pk_application_new ();
-	g_signal_connect (application, "action-help",
-			  G_CALLBACK (pk_application_help_cb), NULL);
 	g_signal_connect (application, "action-close",
 			  G_CALLBACK (pk_application_close_cb), NULL);
 

Modified: trunk/src/gpk-application.c
==============================================================================
--- trunk/src/gpk-application.c	(original)
+++ trunk/src/gpk-application.c	Tue Apr  1 02:32:12 2008
@@ -88,7 +88,6 @@
 };
 
 enum {
-	ACTION_HELP,
 	ACTION_CLOSE,
 	LAST_SIGNAL
 };
@@ -125,15 +124,6 @@
 	object_class->finalize = pk_application_finalize;
 	g_type_class_add_private (klass, sizeof (PkApplicationPrivate));
 
-	signals [ACTION_HELP] =
-		g_signal_new ("action-help",
-			      G_TYPE_FROM_CLASS (object_class),
-			      G_SIGNAL_RUN_LAST,
-			      G_STRUCT_OFFSET (PkApplicationClass, action_help),
-			      NULL,
-			      NULL,
-			      g_cclosure_marshal_VOID__VOID,
-			      G_TYPE_NONE, 0);
 	signals [ACTION_CLOSE] =
 		g_signal_new ("action-close",
 			      G_TYPE_FROM_CLASS (object_class),
@@ -1475,6 +1465,15 @@
 }
 
 /**
+ * pk_application_menu_help_cb:
+ **/
+static void
+pk_application_menu_help_cb (GtkAction *action, PkApplication *application)
+{
+	pk_show_help ("add-remove");
+}
+
+/**
  * pk_application_menu_about_cb:
  **/
 static void
@@ -1991,10 +1990,14 @@
 			  G_CALLBACK (pk_application_homepage_cb), application);
 	gtk_widget_set_tooltip_text (widget, _("Visit homepage for selected package"));
 
-	widget = glade_xml_get_widget (application->priv->glade_xml, "imagemenuitem_about");
+	widget = glade_xml_get_widget (application->priv->glade_xml, "menuitem_about");
 	g_signal_connect (widget, "activate",
 			  G_CALLBACK (pk_application_menu_about_cb), application);
 
+	widget = glade_xml_get_widget (application->priv->glade_xml, "menuitem_help");
+	g_signal_connect (widget, "activate",
+			  G_CALLBACK (pk_application_menu_help_cb), application);
+
 	pk_action = polkit_action_new ();
 	polkit_action_set_action_id (pk_action, "org.freedesktop.packagekit.refresh-cache");
 	application->priv->refresh_action = polkit_gnome_action_new_default ("refresh",

Modified: trunk/src/gpk-common.c
==============================================================================
--- trunk/src/gpk-common.c	(original)
+++ trunk/src/gpk-common.c	Tue Apr  1 02:32:12 2008
@@ -300,6 +300,60 @@
 }
 
 /**
+ * pk_show_help:
+ * @link_id: Subsection of gnome-packagekit help file, or NULL.
+ **/
+gboolean
+pk_show_help (const gchar *link_id)
+{
+	GError *error = NULL;
+	gchar *command;
+	const gchar *lang;
+	gchar *uri = NULL;
+	GdkScreen *gscreen;
+	gint i;
+	gboolean ret = TRUE;
+	const gchar *const *langs = g_get_language_names ();
+
+	for (i = 0; langs[i]; i++) {
+		lang = langs[i];
+		if (strchr (lang, '.')) {
+			continue;
+		}
+		uri = g_build_filename(DATADIR,
+				       "/gnome/help/gnome-packagekit/",
+					lang,
+				       "/gnome-packagekit.xml",
+					NULL);
+		if (g_file_test (uri, G_FILE_TEST_EXISTS)) {
+                    break;
+		}
+	}
+	if (link_id) {
+		command = g_strconcat ("gnome-open ghelp://", uri, "?", link_id, NULL);
+	} else {
+		command = g_strconcat ("gnome-open ghelp://", uri,  NULL);
+	}
+	pk_debug ("using command %s", command);
+
+	gscreen = gdk_screen_get_default();
+	gdk_spawn_command_line_on_screen (gscreen, command, &error);
+	if (error != NULL) {
+		GtkWidget *d;
+		d = gtk_message_dialog_new (NULL, GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
+					    GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, error->message);
+		gtk_dialog_run (GTK_DIALOG(d));
+		gtk_widget_destroy (d);
+		g_error_free (error);
+		ret = FALSE;
+	}
+
+	g_free (command);
+	g_free (uri);
+	return ret;
+}
+
+/**
  * pk_size_to_si_size_text:
  **/
 gchar *
@@ -593,16 +647,18 @@
 			 "Please check your connection settings and try again");
 		break;
 	case PK_ERROR_ENUM_NO_CACHE:
-		text = _("The package list needs to be rebuilt\nThis should have been done by the backend automatically.");
+		text = _("The package list needs to be rebuilt.\n"
+			 "This should have been done by the backend automatically.");
 		break;
 	case PK_ERROR_ENUM_OOM:
-		text = _("The service that is responsible for handling user requests is out of memory.\nPlease restart your computer.");
+		text = _("The service that is responsible for handling user requests is out of memory.\n"
+			 "Please restart your computer.");
 		break;
 	case PK_ERROR_ENUM_CREATE_THREAD_FAILED:
 		text = _("A thread could not be created to service the user request.");
 		break;
 	case PK_ERROR_ENUM_NOT_SUPPORTED:
-		text = _("The action is not supported by this backend\n"
+		text = _("The action is not supported by this backend.\n"
 			 "Please report a bug as this shouldn't have happened.");
 		break;
 	case PK_ERROR_ENUM_INTERNAL_ERROR:
@@ -610,26 +666,28 @@
 			 "Please report this bug with the error description.");
 		break;
 	case PK_ERROR_ENUM_GPG_FAILURE:
-		text = _("A security trust relationship could not be made with the remote software source\n"
+		text = _("A security trust relationship could not be made with software source.\n"
 			 "Please check your security settings.");
 		break;
 	case PK_ERROR_ENUM_PACKAGE_NOT_INSTALLED:
-		text = _("The package that is trying to be removed or updated is not already installed, and hence nothing can be done.");
+		text = _("The package that is trying to be removed or updated is not already installed.");
 		break;
 	case PK_ERROR_ENUM_PACKAGE_NOT_FOUND:
-		text = _("The package that is being modified was not found on your system or in any remote software source.");
+		text = _("The package that is being modified was not found on your system or in any software source.");
 		break;
 	case PK_ERROR_ENUM_PACKAGE_ALREADY_INSTALLED:
 		text = _("The package that is trying to be installed is already installed.");
 		break;
 	case PK_ERROR_ENUM_PACKAGE_DOWNLOAD_FAILED:
-		text = _("The package download failed\nPlease check your network connectivity.");
+		text = _("The package download failed.\n"
+			 "Please check your network connectivity.");
 		break;
 	case PK_ERROR_ENUM_GROUP_NOT_FOUND:
-		text = _("The group type was not found\nPlease check your group list and try again.");
+		text = _("The group type was not found.\n"
+			 "Please check your group list and try again.");
 		break;
 	case PK_ERROR_ENUM_DEP_RESOLUTION_FAILED:
-		text = _("A package could not be found on your system or in a remote software source that allows the transaction to complete\n"
+		text = _("A package could not be found that allows the transaction to complete.\n"
 			 "More information is available in the detailed report.");
 		break;
 	case PK_ERROR_ENUM_FILTER_INVALID:
@@ -644,11 +702,11 @@
 			 "More information is available in the detailed report.");
 		break;
 	case PK_ERROR_ENUM_REPO_NOT_FOUND:
-		text = _("The remote software source name was not found\n"
-			 "You may need to disable an item in Software Sources");
+		text = _("The remote software source name was not found.\n"
+			 "You may need to enable an item in Software Sources");
 		break;
 	case PK_ERROR_ENUM_CANNOT_REMOVE_SYSTEM_PACKAGE:
-		text = _("Removing a protected system package was denied, and thus the whole transaction failed.");
+		text = _("Removing a protected system package is not alloed.");
 		break;
 	case PK_ERROR_ENUM_TRANSACTION_CANCELLED:
 		text = _("The transaction was canceled successfully and no packages were changed.");

Modified: trunk/src/gpk-common.h
==============================================================================
--- trunk/src/gpk-common.h	(original)
+++ trunk/src/gpk-common.h	Tue Apr  1 02:32:12 2008
@@ -65,6 +65,7 @@
 gboolean	 pk_error_modal_dialog			(const gchar	*title,
 							 const gchar	*message);
 gboolean	 pk_execute_url				(const gchar	*url);
+gboolean	 pk_show_help				(const gchar	*link_id);
 gboolean	 pk_restart_system			(void);
 const gchar	*pk_role_enum_to_localised_past		(PkRoleEnum	 role);
 const gchar	*pk_role_enum_to_localised_present	(PkRoleEnum	 role);

Added: trunk/src/gpk-log.c
==============================================================================
--- (empty file)
+++ trunk/src/gpk-log.c	Tue Apr  1 02:32:12 2008
@@ -0,0 +1,523 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2007 Richard Hughes <richard hughsie com>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include <glib.h>
+#include <glib/gi18n.h>
+
+#include <glade/glade.h>
+#include <gtk/gtk.h>
+#include <math.h>
+#include <string.h>
+#include <dbus/dbus-glib.h>
+#include <locale.h>
+
+#include <polkit-gnome/polkit-gnome.h>
+
+#include <pk-debug.h>
+#include <pk-client.h>
+#include <pk-connection.h>
+#include <pk-package-id.h>
+#include <pk-enum-list.h>
+#include <pk-common.h>
+
+#include "gpk-common.h"
+
+static GladeXML *glade_xml = NULL;
+static GtkListStore *list_store_general = NULL;
+static GtkListStore *list_store_details = NULL;
+static PkClient *client = NULL;
+static gchar *transaction_id = NULL;
+static GHashTable *hash = NULL;
+static PolKitGnomeAction *rollback_action = NULL;
+
+enum
+{
+	PACKAGES_COLUMN_GENERAL_ICON,
+	PACKAGES_COLUMN_GENERAL_TEXT,
+	PACKAGES_COLUMN_GENERAL_SUCCEEDED,
+	PACKAGES_COLUMN_GENERAL_ID,
+	PACKAGES_COLUMN_GENERAL_LAST
+};
+
+enum
+{
+	PACKAGES_COLUMN_DETAILS_ICON,
+	PACKAGES_COLUMN_DETAILS_TEXT,
+	PACKAGES_COLUMN_DETAILS_LAST
+};
+
+/**
+ * pk_button_help_cb:
+ **/
+static void
+pk_button_help_cb (GtkWidget *widget,
+		   gboolean  data)
+{
+	pk_show_help ("software-sources");
+}
+
+/**
+ * pk_button_rollback_cb:
+ **/
+static void
+pk_button_rollback_cb (PolKitGnomeAction *action, gpointer data)
+{
+	gboolean ret;
+	GError *error = NULL;
+	GMainLoop *loop = (GMainLoop *) data;
+
+	/* rollback */
+	ret = pk_client_rollback (client, transaction_id, &error);
+	if (!ret) {
+		pk_warning ("failed to reset client: %s", error->message);
+		g_error_free (error);
+	}
+
+	g_main_loop_quit (loop);
+}
+
+/**
+ * pk_button_close_cb:
+ **/
+static void
+pk_button_close_cb (GtkWidget *widget, gpointer data)
+{
+	GMainLoop *loop = (GMainLoop *) data;
+	g_main_loop_quit (loop);
+	pk_debug ("emitting action-close");
+}
+
+/**
+ * pk_transaction_db_get_pretty_date:
+ **/
+static gchar *
+pk_transaction_db_get_pretty_date (const gchar *timespec)
+{
+	GDate *date;
+	GTimeVal timeval;
+	GTimeVal timeval_now;
+	gchar buffer[100];
+	guint hours;
+
+	/* the old date */
+	g_time_val_from_iso8601 (timespec, &timeval);
+
+	/* the new date */
+	g_get_current_time (&timeval_now);
+
+	/* the difference in hours */
+	hours = (timeval_now.tv_sec - timeval.tv_sec) / (60 * 60);
+	pk_debug ("hours is %i", hours);
+
+	/* is this recently? */
+	if (hours < 24) {
+		return g_strdup (_("Today"));
+	} else if (hours < 24*2) {
+		return g_strdup (_("Yesterday"));
+	}
+
+	/* get printed string */
+	date = g_date_new ();
+	g_date_set_time_val (date, &timeval);
+
+	g_date_strftime (buffer, 100, _("%A, %d %B %Y"), date);
+	g_date_free (date);
+	return g_strdup (buffer);
+}
+
+/**
+ * pk_transaction_cb:
+ **/
+static void
+pk_transaction_cb (PkClient *client, const gchar *tid, const gchar *timespec,
+		   gboolean succeeded, PkRoleEnum role, guint duration, const gchar *data, gpointer user_data)
+{
+	GtkTreeIter iter;
+	gchar *text;
+	gchar *pretty;
+	const gchar *icon_name;
+	const gchar *role_text;
+
+	/* we save this */
+	g_hash_table_insert (hash, g_strdup (tid), g_strdup (data));
+
+	pretty = pk_transaction_db_get_pretty_date (timespec);
+	pk_debug ("pretty=%s", pretty);
+	role_text = pk_role_enum_to_localised_past (role);
+	text = g_markup_printf_escaped ("<b>%s</b>\n%s", role_text, pretty);
+	g_free (pretty);
+
+	gtk_list_store_append (list_store_general, &iter);
+	gtk_list_store_set (list_store_general, &iter,
+			    PACKAGES_COLUMN_GENERAL_TEXT, text,
+			    PACKAGES_COLUMN_GENERAL_ID, tid,
+			    -1);
+
+	icon_name = pk_role_enum_to_icon_name (role);
+	gtk_list_store_set (list_store_general, &iter, PACKAGES_COLUMN_GENERAL_ICON, icon_name, -1);
+
+	if (succeeded) {
+		icon_name = "document-new";
+	} else {
+		icon_name = "dialog-error";
+	}
+	gtk_list_store_set (list_store_general, &iter, PACKAGES_COLUMN_GENERAL_SUCCEEDED, icon_name, -1);
+}
+
+/**
+ * pk_window_delete_event_cb:
+ * @event: The event type, unused.
+ **/
+static gboolean
+pk_window_delete_event_cb (GtkWidget	*widget,
+			    GdkEvent	*event,
+			    gpointer data)
+{
+	GMainLoop *loop = (GMainLoop *) data;
+	g_main_loop_quit (loop);
+	return FALSE;
+}
+
+/**
+ * pk_treeview_add_general_columns:
+ **/
+static void
+pk_treeview_add_general_columns (GtkTreeView *treeview)
+{
+	GtkCellRenderer *renderer;
+	GtkTreeViewColumn *column;
+
+	/* image */
+	renderer = gtk_cell_renderer_pixbuf_new ();
+        g_object_set (renderer, "stock-size", GTK_ICON_SIZE_DIALOG, NULL);
+	column = gtk_tree_view_column_new_with_attributes (_("Role"), renderer,
+							   "icon-name", PACKAGES_COLUMN_GENERAL_ICON, NULL);
+	gtk_tree_view_append_column (treeview, column);
+
+	/* column for text */
+	renderer = gtk_cell_renderer_text_new ();
+	column = gtk_tree_view_column_new_with_attributes (_("Transaction"), renderer,
+							   "markup", PACKAGES_COLUMN_GENERAL_TEXT, NULL);
+	gtk_tree_view_column_set_sort_column_id (column, PACKAGES_COLUMN_GENERAL_TEXT);
+	gtk_tree_view_append_column (treeview, column);
+	gtk_tree_view_column_set_expand (column, TRUE);
+
+	/* image */
+	renderer = gtk_cell_renderer_pixbuf_new ();
+        g_object_set (renderer, "stock-size", GTK_ICON_SIZE_BUTTON, NULL);
+	column = gtk_tree_view_column_new_with_attributes (_("Succeeded"), renderer,
+							   "icon-name", PACKAGES_COLUMN_GENERAL_SUCCEEDED, NULL);
+	gtk_tree_view_append_column (treeview, column);
+}
+
+/**
+ * pk_treeview_add_details_columns:
+ **/
+static void
+pk_treeview_add_details_columns (GtkTreeView *treeview)
+{
+	GtkCellRenderer *renderer;
+	GtkTreeViewColumn *column;
+
+	/* image */
+	renderer = gtk_cell_renderer_pixbuf_new ();
+        g_object_set (renderer, "stock-size", GTK_ICON_SIZE_DIALOG, NULL);
+	column = gtk_tree_view_column_new_with_attributes (_("Type"), renderer,
+							   "icon-name", PACKAGES_COLUMN_DETAILS_ICON, NULL);
+	gtk_tree_view_append_column (treeview, column);
+
+	/* column for text */
+	renderer = gtk_cell_renderer_text_new ();
+	column = gtk_tree_view_column_new_with_attributes (_("Details"), renderer,
+							   "markup", PACKAGES_COLUMN_DETAILS_TEXT, NULL);
+	gtk_tree_view_column_set_sort_column_id (column, PACKAGES_COLUMN_DETAILS_TEXT);
+	gtk_tree_view_append_column (treeview, column);
+	gtk_tree_view_column_set_expand (column, TRUE);
+}
+
+
+/**
+ * pk_details_item_add:
+ **/
+static void
+pk_details_item_add (GtkListStore *list_store, PkInfoEnum info, const gchar *package_id, const gchar *summary)
+{
+	GtkTreeIter iter;
+	gchar *text;
+	const gchar *icon_name;
+	const gchar *info_text;
+
+	info_text = pk_info_enum_to_localised_text (info);
+	text = pk_package_id_pretty (package_id, summary);
+	icon_name = pk_info_enum_to_icon_name (info);
+
+	gtk_list_store_append (list_store_details, &iter);
+	gtk_list_store_set (list_store_details, &iter,
+			    PACKAGES_COLUMN_DETAILS_TEXT, text, 
+			    PACKAGES_COLUMN_DETAILS_ICON, icon_name, -1);
+	g_free (text);
+}
+
+/**
+ * pk_treeview_details_populate:
+ **/
+static void
+pk_treeview_details_populate (const gchar *tid)
+{
+	GtkWidget *widget;
+	gchar **array;
+	gchar **sections;
+	guint i;
+	guint size;
+	PkInfoEnum info;
+	gchar *transaction_data;
+
+	/* get from hash */
+	transaction_data = (gchar *) g_hash_table_lookup (hash, tid);
+
+	/* no details? */
+	if (pk_strzero (transaction_data)) {
+		widget = glade_xml_get_widget (glade_xml, "frame_details");
+		gtk_widget_hide (widget);
+		return;
+	}
+
+	widget = glade_xml_get_widget (glade_xml, "treeview_details");
+	gtk_list_store_clear (list_store_details);
+
+	array = g_strsplit (transaction_data, "\n", 0);
+	size = g_strv_length (array);
+	for (i=0; i<size; i++) {
+		sections = g_strsplit (array[i], "\t", 0);
+		info = pk_info_enum_from_text (sections[0]);
+		pk_details_item_add (list_store_details, info, sections[1], sections[2]);
+		g_strfreev (sections);
+	}
+	g_strfreev (array);
+
+	widget = glade_xml_get_widget (glade_xml, "frame_details");
+	gtk_widget_show (widget);
+}
+
+/**
+ * pk_treeview_clicked_cb:
+ **/
+static void
+pk_treeview_clicked_cb (GtkTreeSelection *selection, gboolean data)
+{
+	GtkTreeModel *model;
+	GtkTreeIter iter;
+	gchar *id;
+
+	/* This will only work in single or browse selection mode! */
+	if (gtk_tree_selection_get_selected (selection, &model, &iter)) {
+		g_free (transaction_id);
+		gtk_tree_model_get (model, &iter,
+				    PACKAGES_COLUMN_GENERAL_ID, &id, -1);
+
+		/* make back into transaction_id */
+		transaction_id = g_strdup (id);
+		g_free (id);
+		pk_debug ("selected row is: %s", transaction_id);
+
+		/* get the decription */
+		pk_treeview_details_populate (transaction_id);
+	} else {
+		pk_debug ("no row selected");
+	}
+}
+
+/**
+ * pk_connection_changed_cb:
+ **/
+static void
+pk_connection_changed_cb (PkConnection *pconnection, gboolean connected, gboolean data)
+{
+	pk_debug ("connected=%i", connected);
+}
+
+/**
+ * main:
+ **/
+int
+main (int argc, char *argv[])
+{
+	GMainLoop *loop;
+	gboolean verbose = FALSE;
+	gboolean program_version = FALSE;
+	GOptionContext *context;
+	GtkWidget *main_window;
+	GtkWidget *widget;
+	GtkTreeSelection *selection;
+	PkConnection *pconnection;
+	PkEnumList *role_list;
+	PolKitAction *pk_action;
+	GtkWidget *button;
+
+	const GOptionEntry options[] = {
+		{ "verbose", 'v', 0, G_OPTION_ARG_NONE, &verbose,
+		  N_("Show extra debugging information"), NULL },
+		{ "version", '\0', 0, G_OPTION_ARG_NONE, &program_version,
+		  N_("Show the program version and exit"), NULL },
+		{ NULL}
+	};
+
+	setlocale (LC_ALL, "");
+
+	bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
+	bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
+	textdomain (GETTEXT_PACKAGE);
+
+	if (! g_thread_supported ()) {
+		g_thread_init (NULL);
+	}
+	dbus_g_thread_init ();
+	g_type_init ();
+
+	context = g_option_context_new (NULL);
+	g_option_context_set_summary (context, _("Transaction Viewer"));
+	g_option_context_add_main_entries (context, options, NULL);
+	g_option_context_parse (context, &argc, &argv, NULL);
+	g_option_context_free (context);
+
+	if (program_version) {
+		g_print (VERSION "\n");
+		return 0;
+	}
+
+	pk_debug_init (verbose);
+	gtk_init (&argc, &argv);
+
+	/* add application specific icons to search path */
+	gtk_icon_theme_append_search_path (gtk_icon_theme_get_default (),
+                                           PK_DATA G_DIR_SEPARATOR_S "icons");
+
+	loop = g_main_loop_new (NULL, FALSE);
+
+	client = pk_client_new ();
+	g_signal_connect (client, "transaction",
+			  G_CALLBACK (pk_transaction_cb), NULL);
+
+	/* get actions */
+	role_list = pk_client_get_actions (client);
+
+	/* save the description in a hash */
+	hash = g_hash_table_new (g_str_hash, g_str_equal);
+
+	pconnection = pk_connection_new ();
+	g_signal_connect (pconnection, "connection-changed",
+			  G_CALLBACK (pk_connection_changed_cb), NULL);
+
+	glade_xml = glade_xml_new (PK_DATA "/gpk-log.glade", NULL, NULL);
+	main_window = glade_xml_get_widget (glade_xml, "window_transactions");
+
+	/* 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");
+
+	/* hide the details for now */
+	widget = glade_xml_get_widget (glade_xml, "frame_details");
+	gtk_widget_hide (widget);
+
+	/* Get the main window quit */
+	g_signal_connect (main_window, "delete_event",
+			  G_CALLBACK (pk_window_delete_event_cb), loop);
+
+	widget = glade_xml_get_widget (glade_xml, "button_close");
+	g_signal_connect (widget, "clicked",
+			  G_CALLBACK (pk_button_close_cb), loop);
+	widget = glade_xml_get_widget (glade_xml, "button_help");
+	g_signal_connect (widget, "clicked",
+			  G_CALLBACK (pk_button_help_cb), NULL);
+
+	pk_action = polkit_action_new ();
+	polkit_action_set_action_id (pk_action, "org.freedesktop.packagekit.rollback");
+	rollback_action = polkit_gnome_action_new_default ("rollback",
+							   pk_action,
+							   _("_Rollback"),
+							   NULL);
+	g_object_set (rollback_action,
+		      "no-icon-name", "gtk-go-back-ltr",
+		      "auth-icon-name", "gtk-go-back-ltr",
+		      "yes-icon-name", "gtk-go-back-ltr",
+		      "self-blocked-icon-name", "gtk-go-back-ltr",
+		      NULL);
+	polkit_action_unref (pk_action);
+	g_signal_connect (rollback_action, "activate",
+			  G_CALLBACK (pk_button_rollback_cb), loop);
+	button = polkit_gnome_action_create_button (rollback_action);
+	widget = glade_xml_get_widget (glade_xml, "buttonbox");
+        gtk_box_pack_start (GTK_BOX (widget), button, FALSE, FALSE, 0);
+        gtk_box_reorder_child (GTK_BOX (widget), button, 1);
+	/* hide the rollback button if we can't do the action */
+	if (pk_enum_list_contains (role_list, PK_ROLE_ENUM_ROLLBACK)) {
+		polkit_gnome_action_set_visible (rollback_action, TRUE);
+	} else {
+		polkit_gnome_action_set_visible (rollback_action, FALSE);
+	}
+
+	gtk_widget_set_size_request (main_window, 500, 300);
+
+	/* create list stores */
+	list_store_general = gtk_list_store_new (PACKAGES_COLUMN_GENERAL_LAST, G_TYPE_STRING,
+						 G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING);
+	list_store_details = gtk_list_store_new (PACKAGES_COLUMN_DETAILS_LAST, G_TYPE_STRING, G_TYPE_STRING);
+
+	/* create transaction_id tree view */
+	widget = glade_xml_get_widget (glade_xml, "treeview_transactions");
+	gtk_tree_view_set_model (GTK_TREE_VIEW (widget),
+				 GTK_TREE_MODEL (list_store_general));
+
+	selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (widget));
+	g_signal_connect (selection, "changed",
+			  G_CALLBACK (pk_treeview_clicked_cb), NULL);
+
+	/* add columns to the tree view */
+	pk_treeview_add_general_columns (GTK_TREE_VIEW (widget));
+	gtk_tree_view_columns_autosize (GTK_TREE_VIEW (widget));
+
+	/* create transaction_id tree view */
+	widget = glade_xml_get_widget (glade_xml, "treeview_details");
+	gtk_tree_view_set_model (GTK_TREE_VIEW (widget),
+				 GTK_TREE_MODEL (list_store_details));
+	pk_treeview_add_details_columns (GTK_TREE_VIEW (widget));
+	gtk_tree_view_columns_autosize (GTK_TREE_VIEW (widget));
+
+	/* get the update list */
+	pk_client_get_old_transactions (client, 0, NULL);
+	gtk_widget_show (main_window);
+
+	g_main_loop_run (loop);
+	g_main_loop_unref (loop);
+
+	g_object_unref (glade_xml);
+	g_object_unref (list_store_general);
+	g_object_unref (list_store_details);
+	g_object_unref (client);
+	g_object_unref (pconnection);
+	g_object_unref (role_list);
+	g_free (transaction_id);
+	g_hash_table_unref (hash);
+
+	return 0;
+}

Modified: trunk/src/gpk-notify.c
==============================================================================
--- trunk/src/gpk-notify.c	(original)
+++ trunk/src/gpk-notify.c	Tue Apr  1 02:32:12 2008
@@ -88,8 +88,6 @@
 	g_type_class_add_private (klass, sizeof (GpkNotifyPrivate));
 }
 
-#if 0
-/* No help yet */
 /**
  * gpk_notify_show_help_cb:
  **/
@@ -98,15 +96,8 @@
 {
 	g_return_if_fail (notify != NULL);
 	g_return_if_fail (GPK_IS_NOTIFY (notify));
-	pk_debug ("show help");
-	gpk_smart_icon_notify_new (notify->priv->sicon,
-			      _("Functionality incomplete"),
-			      _("No help yet, sorry..."), "help-browser",
-			      GPK_NOTIFY_URGENCY_LOW, GPK_NOTIFY_TIMEOUT_SHORT);
-	gpk_smart_icon_notify_button (notify->priv->sicon, GPK_NOTIFY_BUTTON_DO_NOT_SHOW_AGAIN, PK_CONF_NOTIFY_ERROR);
-	gpk_smart_icon_notify_show (notify->priv->sicon);
+	pk_show_help (NULL);
 }
-#endif
 
 /**
  * gpk_notify_show_preferences_cb:
@@ -263,7 +254,6 @@
 	item = gtk_separator_menu_item_new ();
 	gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
 
-#if 0
 	/* No help yet */
 	item = gtk_image_menu_item_new_with_mnemonic (_("_Help"));
 	image = gtk_image_new_from_icon_name (GTK_STOCK_HELP, GTK_ICON_SIZE_MENU);
@@ -271,7 +261,6 @@
 	g_signal_connect (G_OBJECT (item), "activate",
 			  G_CALLBACK (gpk_notify_show_help_cb), icon);
 	gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
-#endif
 
 	/* About */
 	item = gtk_image_menu_item_new_with_mnemonic (_("_About"));
@@ -410,8 +399,8 @@
 	if (ret) {
 		gpk_smart_icon_set_icon_name (notify->priv->sicon, NULL);
 	} else {
-		pk_warning ("failed to update system: %s", error->message);
-		message = g_strdup_printf (_("Client action was refused: %s"), error->message);
+		message = g_strdup_printf (_("The error was: %s"), error->message);
+		pk_warning ("%s", message);
 		g_error_free (error);
 		gpk_smart_icon_notify_new (notify->priv->sicon, _("Failed to update system"), message,
 				      "process-stop", GPK_NOTIFY_URGENCY_LOW, GPK_NOTIFY_TIMEOUT_SHORT);
@@ -968,6 +957,31 @@
 }
 
 /**
+ * gpk_notify_restart_schedule_cb:
+ **/
+static void
+gpk_notify_restart_schedule_cb (PkClient *client, GpkNotify *notify)
+{
+	gboolean ret;
+	GError *error = NULL;
+	const gchar *file;
+
+	g_return_if_fail (notify != NULL);
+	g_return_if_fail (GPK_IS_NOTIFY (notify));
+
+	/* wait for the daemon to quit */
+	g_usleep (2*G_USEC_PER_SEC);
+
+	file = BINDIR "/gpk-update-icon";
+	pk_debug ("trying to spawn: %s", file);
+	ret = g_spawn_command_line_async (file, &error);
+	if (!ret) {
+		pk_warning ("failed to spawn new instance: %s", error->message);
+		g_error_free (error);
+	}
+}
+
+/**
  * gpk_notify_task_list_changed_cb:
  **/
 static void
@@ -1102,6 +1116,8 @@
 	notify->priv->notify = pk_notify_new ();
 	g_signal_connect (notify->priv->notify, "updates-changed",
 			  G_CALLBACK (gpk_notify_updates_changed_cb), notify);
+	g_signal_connect (notify->priv->notify, "restart-schedule",
+			  G_CALLBACK (gpk_notify_restart_schedule_cb), notify);
 
 	/* we need the task list so we can hide the update icon when we are doing the update */
 	notify->priv->tlist = pk_task_list_new ();

Modified: trunk/src/gpk-prefs.c
==============================================================================
--- trunk/src/gpk-prefs.c	(original)
+++ trunk/src/gpk-prefs.c	Tue Apr  1 02:32:12 2008
@@ -52,10 +52,9 @@
  * pk_button_help_cb:
  **/
 static void
-pk_button_help_cb (GtkWidget *widget,
-		   gboolean  data)
+pk_button_help_cb (GtkWidget *widget, gboolean  data)
 {
-	pk_debug ("emitting action-help");
+	pk_show_help ("prefs");
 }
 
 /**
@@ -359,8 +358,6 @@
 	widget = glade_xml_get_widget (glade_xml, "button_help");
 	g_signal_connect (widget, "clicked",
 			  G_CALLBACK (pk_button_help_cb), NULL);
-	/* no help yet */
-	gtk_widget_hide (widget);
 
 	/* update the combo boxes */
 	pk_prefs_freq_combo_setup ();

Modified: trunk/src/gpk-repo.c
==============================================================================
--- trunk/src/gpk-repo.c	(original)
+++ trunk/src/gpk-repo.c	Tue Apr  1 02:32:12 2008
@@ -57,10 +57,9 @@
  * pk_button_help_cb:
  **/
 static void
-pk_button_help_cb (GtkWidget *widget,
-		   gboolean  data)
+pk_button_help_cb (GtkWidget *widget, gboolean  data)
 {
-	pk_debug ("emitting action-help");
+	pk_show_help ("software-sources");
 }
 
 /**
@@ -346,8 +345,6 @@
 	widget = glade_xml_get_widget (glade_xml, "button_help");
 	g_signal_connect (widget, "clicked",
 			  G_CALLBACK (pk_button_help_cb), NULL);
-	/* no help yet */
-	gtk_widget_hide (widget);
 
 	gtk_widget_set_size_request (main_window, 500, 300);
 

Modified: trunk/src/gpk-smart-icon.c
==============================================================================
--- trunk/src/gpk-smart-icon.c	(original)
+++ trunk/src/gpk-smart-icon.c	Tue Apr  1 02:32:12 2008
@@ -353,9 +353,11 @@
 
 	sicon = PK_SMART_ICON (object);
 	g_return_if_fail (sicon->priv != NULL);
+
+	g_free (sicon->priv->new);
+	g_free (sicon->priv->current);
+
 	g_object_unref (sicon->priv->status_icon);
-	g_object_unref (sicon->priv->new);
-	g_object_unref (sicon->priv->current);
 	if (sicon->priv->dialog != NULL) {
 		notify_notification_close (sicon->priv->dialog, NULL);
 		g_object_unref (sicon->priv->dialog);

Modified: trunk/src/gpk-update-icon.c
==============================================================================
--- trunk/src/gpk-update-icon.c	(original)
+++ trunk/src/gpk-update-icon.c	Tue Apr  1 02:32:12 2008
@@ -31,10 +31,74 @@
 #include <gtk/gtk.h>
 #include <locale.h>
 
+#include <libgbus.h>
+
 #include <pk-debug.h>
+#include <pk-common.h>
 
 #include "gpk-notify.h"
 #include "gpk-watch.h"
+#include "gpk-interface.h"
+
+/**
+ * gpk_object_register:
+ * @connection: What we want to register to
+ * @object: The GObject we want to register
+ *
+ * Return value: success
+ **/
+static gboolean
+gpk_object_register (DBusGConnection *connection, GObject *object)
+{
+	DBusGProxy *bus_proxy = NULL;
+	GError *error = NULL;
+	guint request_name_result;
+	gboolean ret;
+
+	/* connect to the bus */
+	bus_proxy = dbus_g_proxy_new_for_name (connection, DBUS_SERVICE_DBUS,
+					       DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS);
+
+	/* get our name */
+	ret = dbus_g_proxy_call (bus_proxy, "RequestName", &error,
+				 G_TYPE_STRING, PK_DBUS_SERVICE,
+				 G_TYPE_UINT, DBUS_NAME_FLAG_ALLOW_REPLACEMENT |
+					      DBUS_NAME_FLAG_REPLACE_EXISTING |
+					      DBUS_NAME_FLAG_DO_NOT_QUEUE,
+				 G_TYPE_INVALID,
+				 G_TYPE_UINT, &request_name_result,
+				 G_TYPE_INVALID);
+	if (ret == FALSE) {
+		/* abort as the DBUS method failed */
+		pk_warning ("RequestName failed: %s", error->message);
+		g_error_free (error);
+		return FALSE;
+	}
+
+	/* free the bus_proxy */
+	g_object_unref (G_OBJECT (bus_proxy));
+
+	/* already running */
+	if (request_name_result != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) {
+		return FALSE;
+	}
+
+	dbus_g_object_type_install_info (GPK_TYPE_NOTIFY, &dbus_glib_gpk_dbus_object_info);
+	dbus_g_connection_register_g_object (connection, PK_DBUS_PATH, object);
+
+	return TRUE;
+}
+
+/**
+ * pk_dbus_connection_replaced_cb:
+ **/
+static void
+pk_dbus_connection_replaced_cb (LibGBus *libgbus, gpointer data)
+{
+	GMainLoop *loop = (GMainLoop *) data;
+	pk_warning ("exiting the mainloop as we have been replaced");
+	g_main_loop_quit (loop);
+}
 
 /**
  * main:
@@ -48,6 +112,10 @@
 	GpkNotify *notify = NULL;
 	GpkWatch *watch = NULL;
 	GOptionContext *context;
+	GError *error = NULL;
+	gboolean ret;
+	DBusGConnection *connection;
+	LibGBus *libgbus;
 
 	const GOptionEntry options[] = {
 		{ "verbose", 'v', 0, G_OPTION_ARG_NONE, &verbose,
@@ -88,14 +156,40 @@
 	gtk_icon_theme_append_search_path (gtk_icon_theme_get_default (),
                                            PK_DATA G_DIR_SEPARATOR_S "icons");
 
-	/* create a new notify object */
+	/* create new objects */
 	notify = gpk_notify_new ();
 	watch = gpk_watch_new ();
 	loop = g_main_loop_new (NULL, FALSE);
+
+	/* find out when we are replaced */
+	libgbus = libgbus_new ();
+	libgbus_assign (libgbus, LIBGBUS_SESSION, PK_DBUS_SERVICE);
+	g_signal_connect (libgbus, "connection-replaced",
+			  G_CALLBACK (pk_dbus_connection_replaced_cb), loop);
+
+	/* get the bus */
+	connection = dbus_g_bus_get (DBUS_BUS_SESSION, &error);
+	if (error) {
+		pk_warning ("%s", error->message);
+		g_error_free (error);
+		goto out;
+	}
+
+	/* try to register */
+	ret = gpk_object_register (connection, G_OBJECT (notify));
+	if (!ret) {
+		pk_warning ("failed to replace running instance.");
+		goto out;
+	}
+
+	/* wait until loop killed */
 	g_main_loop_run (loop);
+
+out:
 	g_main_loop_unref (loop);
 	g_object_unref (notify);
 	g_object_unref (watch);
+	g_object_unref (libgbus);
 
 	return 0;
 }

Modified: trunk/src/gpk-update-viewer.c
==============================================================================
--- trunk/src/gpk-update-viewer.c	(original)
+++ trunk/src/gpk-update-viewer.c	Tue Apr  1 02:32:12 2008
@@ -114,7 +114,7 @@
 static void
 pk_button_help_cb (GtkWidget *widget, gboolean data)
 {
-	pk_debug ("emitting action-help");
+	pk_show_help ("update-viewer");
 }
 
 /**
@@ -617,8 +617,30 @@
 static void
 pk_button_overview_cb (GtkWidget *widget, gpointer data)
 {
+	gboolean ret;
+	GError *error = NULL;
+
+	/* clear existing list */
+	gtk_list_store_clear (list_store_details);
+
 	/* set correct view */
 	pk_updates_set_page (PAGE_PREVIEW);
+
+	/* get the new update list */
+	ret = pk_client_reset (client_query, &error);
+	if (!ret) {
+		pk_warning ("failed to reset client: %s", error->message);
+		g_error_free (error);
+		return;
+	}
+	/* TODO: we don't actually need to re-request the data, but we've
+	 * nuked the preview window with the spinner */
+	ret = pk_client_get_updates (client_query, "basename", &error);
+	if (!ret) {
+		pk_warning ("failed to get updates: %s", error->message);
+		g_error_free (error);
+		return;
+	}
 }
 
 /**
@@ -842,6 +864,12 @@
 	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);
+
+	/* when we are testing the transaction, no package should be displayed */
+	if (status == PK_STATUS_ENUM_TEST_COMMIT) {
+		widget = glade_xml_get_widget (glade_xml, "progress_package_label");
+		gtk_label_set_label (GTK_LABEL (widget), "");
+	}
 }
 
 /**
@@ -1762,8 +1790,6 @@
 	widget = glade_xml_get_widget (glade_xml, "button_help");
 	g_signal_connect (widget, "clicked",
 			  G_CALLBACK (pk_button_help_cb), NULL);
-	/* we have no yelp file yet */
-	gtk_widget_hide (widget);
 
 	/* create list stores */
 	list_store_details = gtk_list_store_new (PACKAGES_COLUMN_LAST, G_TYPE_STRING,

Modified: trunk/src/gpk-watch.c
==============================================================================
--- trunk/src/gpk-watch.c	(original)
+++ trunk/src/gpk-watch.c	Tue Apr  1 02:32:12 2008
@@ -614,8 +614,8 @@
 	ret = pk_client_refresh_cache (client, TRUE, NULL);
 	if (ret == FALSE) {
 		g_object_unref (client);
-		pk_warning ("failed to refresh cache: %s", error->message);
-		message = g_strdup_printf (_("Client action was refused: %s"), error->message);
+		message = g_strdup_printf (_("The error was: %s"), error->message);
+		pk_warning ("%s", message);
 		g_error_free (error);
 		gpk_smart_icon_notify_new (watch->priv->sicon, _("Failed to refresh cache"), message,
 				      "process-stop", GPK_NOTIFY_URGENCY_LOW, GPK_NOTIFY_TIMEOUT_SHORT);



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