File gnome-packagekit-fix-logout-button-not-working.patch of Package gnome-packagekit.6609
From ecb2afe33e70b66af8e95d79afc6470e5ad3ce16 Mon Sep 17 00:00:00 2001
From: Jonathan Kang <jonathan121537@gmail.com>
Date: Wed, 3 Aug 2016 15:17:18 +0800
Subject: [PATCH] Revert "Move the D-Bus interface to gnome-software" and "Remove unused functionality"
This reverts commit 0780f7987f0dc9a0021207ea22e9b032be6b27e1 and 52b1ece4d58f407436bd74aceeca9da607c701eb
---
configure.ac | 5 +
data/Makefile.am | 9 +
data/gpk-dbus-service.desktop.in | 10 +
data/org.freedesktop.PackageKit.service.in | 4 +
docs/Makefile.am | 1 +
docs/dbus/.gitignore | 3 +
docs/dbus/Makefile.am | 17 +
docs/dbus/dbus-introspect-docs.dtd | 32 +
docs/dbus/spec-to-docbook.xsl | 436 ++++
man/Makefile.am | 4 +
man/gpk-dbus-service.sgml | 77 +
man/gpk-install-local-file.sgml | 77 +
po/POTFILES.in | 7 +
src/Makefile.am | 97 +
src/gpk-animated-icon.c | 307 +++
src/gpk-animated-icon.h | 72 +
src/gpk-application.c | 6 +-
src/gpk-common.c | 47 +
src/gpk-common.h | 5 +
src/gpk-dbus-service.c | 184 ++
src/gpk-dbus-task.c | 3273 ++++++++++++++++++++++++++++
src/gpk-dbus-task.h | 161 ++
src/gpk-dbus.c | 590 +++++
src/gpk-dbus.h | 124 ++
src/gpk-enum.c | 139 +-
src/gpk-enum.h | 8 +
src/gpk-error.c | 2 +-
src/gpk-error.h | 5 +
src/gpk-gnome.c | 49 +
src/gpk-gnome.h | 33 +
src/gpk-helper-chooser.c | 348 +++
src/gpk-helper-chooser.h | 65 +
src/gpk-helper-run.c | 392 ++++
src/gpk-helper-run.h | 61 +
src/gpk-install-local-file.c | 139 ++
src/gpk-language.c | 196 ++
src/gpk-language.h | 60 +
src/gpk-log.c | 1 +
src/gpk-marshal.list | 3 +
src/gpk-modal-dialog.c | 861 ++++++++
src/gpk-modal-dialog.h | 127 ++
src/gpk-prefs.c | 1 +
src/gpk-self-test.c | 219 ++
src/gpk-session.c | 361 +++
src/gpk-session.h | 69 +
src/gpk-task.c | 1 +
src/gpk-update-viewer.c | 12 +-
src/gpk-vendor.c | 159 ++
src/gpk-vendor.h | 70 +
src/gpk-x11.c | 250 +++
src/gpk-x11.h | 63 +
src/org.freedesktop.PackageKit.xml | 506 +++++
53 files changed, 9754 insertions(+), 4 deletions(-)
create mode 100644 data/gpk-dbus-service.desktop.in
create mode 100644 data/org.freedesktop.PackageKit.service.in
create mode 100644 docs/dbus/.gitignore
create mode 100644 docs/dbus/Makefile.am
create mode 100644 docs/dbus/dbus-introspect-docs.dtd
create mode 100644 docs/dbus/spec-to-docbook.xsl
create mode 100644 man/gpk-dbus-service.sgml
create mode 100644 man/gpk-install-local-file.sgml
create mode 100644 src/gpk-animated-icon.c
create mode 100644 src/gpk-animated-icon.h
create mode 100644 src/gpk-dbus-service.c
create mode 100644 src/gpk-dbus-task.c
create mode 100644 src/gpk-dbus-task.h
create mode 100644 src/gpk-dbus.c
create mode 100644 src/gpk-dbus.h
create mode 100644 src/gpk-gnome.c
create mode 100644 src/gpk-gnome.h
create mode 100644 src/gpk-helper-chooser.c
create mode 100644 src/gpk-helper-chooser.h
create mode 100644 src/gpk-helper-run.c
create mode 100644 src/gpk-helper-run.h
create mode 100644 src/gpk-install-local-file.c
create mode 100644 src/gpk-language.c
create mode 100644 src/gpk-language.h
create mode 100644 src/gpk-marshal.list
create mode 100644 src/gpk-modal-dialog.c
create mode 100644 src/gpk-modal-dialog.h
create mode 100644 src/gpk-session.c
create mode 100644 src/gpk-session.h
create mode 100644 src/gpk-vendor.c
create mode 100644 src/gpk-vendor.h
create mode 100644 src/gpk-x11.c
create mode 100644 src/gpk-x11.h
create mode 100644 src/org.freedesktop.PackageKit.xml
Index: gnome-packagekit-3.20.0/configure.ac
===================================================================
--- gnome-packagekit-3.20.0.orig/configure.ac
+++ gnome-packagekit-3.20.0/configure.ac
@@ -92,6 +92,10 @@ PKG_CHECK_MODULES(GLIB, \
gobject-2.0
gio-2.0 >= 2.25.9
gio-unix-2.0)
+PKG_CHECK_MODULES(DBUS, \
+ dbus-glib-1 >= 0.73 \
+ dbus-1 >= 1.1.2 \
+ gthread-2.0)
PKG_CHECK_MODULES(GTK, \
gtk+-3.0 >= 3.15.3 gdk-3.0 fontconfig)
PKG_CHECK_MODULES(CANBERRA, libcanberra-gtk3 >= 0.10)
@@ -203,6 +207,7 @@ po/Makefile.in
data/Makefile
data/appdata/Makefile
docs/Makefile
+docs/dbus/Makefile
data/icons/Makefile
data/icons/16x16/Makefile
data/icons/22x22/Makefile
Index: gnome-packagekit-3.20.0/data/Makefile.am
===================================================================
--- gnome-packagekit-3.20.0.orig/data/Makefile.am
+++ gnome-packagekit-3.20.0/data/Makefile.am
@@ -9,6 +9,7 @@ dist_migration_DATA = org.gnome.packagek
desktopdir = $(datadir)/applications
desktop_in_files = \
gpk-install-local-file.desktop.in \
+ gpk-dbus-service.desktop.in \
gpk-prefs.desktop.in \
gpk-application.desktop.in \
gpk-update-viewer.desktop.in \
@@ -30,6 +31,13 @@ pkgdata_DATA = \
gpk-client.ui \
$(NULL)
+servicedir = $(datadir)/dbus-1/services
+service_in_files = org.freedesktop.PackageKit.service.in
+service_DATA = $(service_in_files:.service.in=.service)
+
+$(service_DATA): $(service_in_files) Makefile
+ @sed -e "s|\@servicedir\@|$(bindir)|" $< > $@
+
@GSETTINGS_RULES@
gsettings_SCHEMAS = org.gnome.packagekit.gschema.xml
@@ -48,6 +56,7 @@ DISTCLEANFILES = \
gpk-prefs.desktop \
gpk-update-viewer.desktop \
gpk-install-local-file.desktop \
+ gpk-dbus-service.desktop \
gpk-log.desktop \
gpk-application.desktop \
org.freedesktop.PackageKit.service \
Index: gnome-packagekit-3.20.0/data/gpk-dbus-service.desktop.in
===================================================================
--- /dev/null
+++ gnome-packagekit-3.20.0/data/gpk-dbus-service.desktop.in
@@ -0,0 +1,10 @@
+[Desktop Entry]
+_Name=Software Install
+_Comment=Install selected software on the system
+Categories=System;
+Exec=gpk-dbus-service
+Terminal=false
+Type=Application
+Icon=system-software-install
+StartupNotify=true
+NoDisplay=true
Index: gnome-packagekit-3.20.0/data/org.freedesktop.PackageKit.service.in
===================================================================
--- /dev/null
+++ gnome-packagekit-3.20.0/data/org.freedesktop.PackageKit.service.in
@@ -0,0 +1,4 @@
+[D-BUS Service]
+Name=org.freedesktop.PackageKit
+Exec=@servicedir@/gpk-dbus-service
+
Index: gnome-packagekit-3.20.0/docs/Makefile.am
===================================================================
--- gnome-packagekit-3.20.0.orig/docs/Makefile.am
+++ gnome-packagekit-3.20.0/docs/Makefile.am
@@ -1 +1,2 @@
+SUBDIRS = dbus
Index: gnome-packagekit-3.20.0/docs/dbus/.gitignore
===================================================================
--- /dev/null
+++ gnome-packagekit-3.20.0/docs/dbus/.gitignore
@@ -0,0 +1,3 @@
+*.ref.xml
+*.html
+
Index: gnome-packagekit-3.20.0/docs/dbus/Makefile.am
===================================================================
--- /dev/null
+++ gnome-packagekit-3.20.0/docs/dbus/Makefile.am
@@ -0,0 +1,17 @@
+
+if ENABLE_GTK_DOC
+
+all : org.freedesktop.PackageKit.ref.xml
+
+org.freedesktop.PackageKit.ref.xml : $(top_srcdir)/src/org.freedesktop.PackageKit.xml $(top_srcdir)/docs/dbus/spec-to-docbook.xsl
+ echo "<?xml version=\"1.0\"?>""<!DOCTYPE refentry PUBLIC \"-//OASIS//DTD DocBook XML V4.1.2//EN\" \"http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd\">" > $@
+ $(XSLTPROC) $(top_srcdir)/docs/dbus/spec-to-docbook.xsl $< | tail -n +2 >> $@
+
+#$(top_srcdir)/docs/dbus/spec-to-docbook $(top_srcdir)/src/org.freedesktop.PackageKit.xml
+
+endif
+
+EXTRA_DIST = spec-to-docbook.xsl dbus-introspect-docs.dtd
+
+clean-local :
+ rm -f *~ *.ref.xml
Index: gnome-packagekit-3.20.0/docs/dbus/dbus-introspect-docs.dtd
===================================================================
--- /dev/null
+++ gnome-packagekit-3.20.0/docs/dbus/dbus-introspect-docs.dtd
@@ -0,0 +1,32 @@
+<!-- DTD for D-Bus Introspection Documentation -->
+
+<!ELEMENT doc (summary?,description?,errors?,permission?,since?,deprecated,seealso?)>
+
+<!ELEMENT summary (#PCDATA|ref)*>
+<!ELEMENT description (#PCDATA|para|example)*>
+<!ELEMENT errors (error)*>
+<!ELEMENT permission (#PCDATA|ref|para)*>
+<!ELEMENT since EMPTY>
+<!ATTLIST since version CDATA #REQUIRED>
+<!ELEMENT deprecated (#PCDATA|ref)>
+<!ATTLIST deprecated version CDATA #REQUIRED>
+<!ATTLIST deprecated instead CDATA #REQUIRED>
+<!ELEMENT seealso (ref+)>
+
+<!ELEMENT error (#PCDATA|para)*>
+<!ATTLIST error name CDATA #REQUIRED>
+<!ELEMENT para (#PCDATA|example|code|list|ref)*>
+<!ELEMENT example (#PCDATA|para|code|ref)*>
+<!ATTLIST language (c|glib|python|shell) #REQUIRED>
+<!ATTLIST title CDATA #IMPLIED>
+<!ELEMENT list (listheader?, item*)>
+<!ATTLIST list type (bullet|number|table) #REQUIRED>
+<!ELEMENT item (term|definition)*>
+<!ELEMENT term (#PCDATA|ref)*>
+<!ELEMENT definition (#PCDATA|para)*>
+
+<!ELEMENT code (#PCDATA)>
+<!ATTLIST code lang CDATA #IMPLIED>
+<!ELEMENT ref CDATA>
+<!ATTLIST ref type (parameter|arg|signal|method|interface) #REQUIRED>
+<!ATTLIST ref to CDATA #REQUIRED>
Index: gnome-packagekit-3.20.0/docs/dbus/spec-to-docbook.xsl
===================================================================
--- /dev/null
+++ gnome-packagekit-3.20.0/docs/dbus/spec-to-docbook.xsl
@@ -0,0 +1,436 @@
+<?xml version='1.0'?>
+<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns:doc="http://www.freedesktop.org/dbus/1.0/doc.dtd"
+ exclude-result-prefixes="doc">
+<!--
+ Convert D-Bus Glib xml into DocBook refentries
+ Copyright (C) 2007 William Jon McCann
+ License: GPL
+-->
+<xsl:output method="xml" indent="yes" encoding="UTF-8"/>
+
+<xsl:template match="/">
+
+<xsl:variable name="interface" select="//interface/@name"/>
+<xsl:variable name="basename">
+ <xsl:call-template name="interface-basename">
+ <xsl:with-param name="str" select="$interface"/>
+ </xsl:call-template>
+</xsl:variable>
+
+<refentry><xsl:attribute name="id"><xsl:value-of select="$basename"/></xsl:attribute>
+ <refmeta>
+ <refentrytitle role="top_of_page"><xsl:value-of select="//interface/@name"/></refentrytitle>
+ </refmeta>
+
+ <refnamediv>
+ <refname><xsl:value-of select="//interface/@name"/></refname>
+ <refpurpose><xsl:value-of select="$basename"/> interface</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv role="synopsis">
+ <title role="synopsis.title">Methods</title>
+ <synopsis>
+ <xsl:call-template name="methods-synopsis">
+ <xsl:with-param name="basename" select="$basename"/>
+ </xsl:call-template>
+ </synopsis>
+ </refsynopsisdiv>
+
+ <refsect1 role="signal_proto">
+ <title role="signal_proto.title">Signals</title>
+ <synopsis>
+ <xsl:call-template name="signals-synopsis">
+ <xsl:with-param name="basename" select="$basename"/>
+ </xsl:call-template>
+ </synopsis>
+ </refsect1>
+
+ <refsect1 role="impl_interfaces">
+ <title role="impl_interfaces.title">Implemented Interfaces</title>
+ <para>
+ <xsl:value-of select="$interface"/> implements
+ org.freedesktop.DBus.Introspectable,
+ org.freedesktop.DBus.Properties
+ </para>
+ </refsect1>
+
+ <refsect1 role="properties">
+ <title role="properties.title">Properties</title>
+ <synopsis>
+ <xsl:call-template name="properties-synopsis">
+ <xsl:with-param name="basename" select="$basename"/>
+ </xsl:call-template>
+ </synopsis>
+ </refsect1>
+
+ <refsect1 role="desc">
+ <title role="desc.title">Description</title>
+ <para>
+ <xsl:apply-templates select="//interface/doc:doc"/>
+ </para>
+ </refsect1>
+
+ <refsect1 role="details">
+ <title role="details.title">Details</title>
+ <xsl:call-template name="method-details">
+ <xsl:with-param name="basename" select="$basename"/>
+ </xsl:call-template>
+ </refsect1>
+
+ <refsect1 role="signals">
+ <title role="signals.title">Signal Details</title>
+ <xsl:call-template name="signal-details">
+ <xsl:with-param name="basename" select="$basename"/>
+ </xsl:call-template>
+ </refsect1>
+
+ <refsect1 role="property_details">
+ <title role="property_details.title">Property Details</title>
+ <xsl:call-template name="property-details">
+ <xsl:with-param name="basename" select="$basename"/>
+ </xsl:call-template>
+ </refsect1>
+
+</refentry>
+</xsl:template>
+
+
+<xsl:template name="property-doc">
+ <xsl:apply-templates select="doc:doc/doc:description"/>
+
+ <variablelist role="params">
+ <xsl:for-each select="arg">
+<varlistentry><term><parameter><xsl:value-of select="@name"/></parameter>:</term>
+<listitem><simpara><xsl:value-of select="doc:doc/doc:summary"/></simpara></listitem>
+</varlistentry>
+ </xsl:for-each>
+ </variablelist>
+
+ <xsl:apply-templates select="doc:doc/doc:since"/>
+ <xsl:apply-templates select="doc:doc/doc:deprecated"/>
+ <xsl:apply-templates select="doc:doc/doc:permission"/>
+ <xsl:apply-templates select="doc:doc/doc:seealso"/>
+</xsl:template>
+
+
+<xsl:template name="property-details">
+ <xsl:param name="basename"/>
+ <xsl:variable name="longest">
+ <xsl:call-template name="find-longest">
+ <xsl:with-param name="set" select="@name"/>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:for-each select="///property">
+ <refsect2>
+ <title><anchor role="function"><xsl:attribute name="id"><xsl:value-of select="$basename"/>:<xsl:value-of select="@name"/></xsl:attribute></anchor>The "<xsl:value-of select="@name"/>" property</title>
+<indexterm><primary><xsl:value-of select="@name"/></primary><secondary><xsl:value-of select="$basename"/></secondary></indexterm>
+<programlisting>'<xsl:value-of select="@name"/>'<xsl:call-template name="pad-spaces"><xsl:with-param name="width" select="2"/></xsl:call-template>
+<xsl:call-template name="property-args"><xsl:with-param name="indent" select="string-length(@name) + 2"/></xsl:call-template></programlisting>
+ </refsect2>
+
+ <xsl:call-template name="property-doc"/>
+
+ </xsl:for-each>
+</xsl:template>
+
+<xsl:template name="signal-doc">
+ <xsl:apply-templates select="doc:doc/doc:description"/>
+
+ <variablelist role="params">
+ <xsl:for-each select="arg">
+<varlistentry><term><parameter><xsl:value-of select="@name"/></parameter>:</term>
+<listitem><simpara><xsl:value-of select="doc:doc/doc:summary"/></simpara></listitem>
+</varlistentry>
+ </xsl:for-each>
+ </variablelist>
+
+ <xsl:apply-templates select="doc:doc/doc:since"/>
+ <xsl:apply-templates select="doc:doc/doc:deprecated"/>
+ <xsl:apply-templates select="doc:doc/doc:permission"/>
+ <xsl:apply-templates select="doc:doc/doc:seealso"/>
+</xsl:template>
+
+<xsl:template name="signal-details">
+ <xsl:param name="basename"/>
+ <xsl:variable name="longest">
+ <xsl:call-template name="find-longest">
+ <xsl:with-param name="set" select="@name"/>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:for-each select="///signal">
+ <refsect2>
+ <title><anchor role="function"><xsl:attribute name="id"><xsl:value-of select="$basename"/>::<xsl:value-of select="@name"/></xsl:attribute></anchor>The <xsl:value-of select="@name"/> signal</title>
+<indexterm><primary><xsl:value-of select="@name"/></primary><secondary><xsl:value-of select="$basename"/></secondary></indexterm>
+<programlisting><xsl:value-of select="@name"/> (<xsl:call-template name="signal-args"><xsl:with-param name="indent" select="string-length(@name) + 2"/><xsl:with-param name="prefix" select="."/></xsl:call-template>)</programlisting>
+ </refsect2>
+
+ <xsl:call-template name="signal-doc"/>
+
+ </xsl:for-each>
+</xsl:template>
+
+<xsl:template match="doc:code">
+<programlisting>
+<xsl:apply-templates />
+</programlisting>
+</xsl:template>
+
+<xsl:template match="doc:summary">
+<!-- by default don't display -->
+</xsl:template>
+
+<xsl:template match="doc:example">
+<informalexample>
+<xsl:apply-templates />
+</informalexample>
+</xsl:template>
+
+<xsl:template match="doc:para">
+<para>
+<xsl:apply-templates />
+</para>
+</xsl:template>
+
+<xsl:template match="doc:description">
+<xsl:apply-templates />
+</xsl:template>
+
+<xsl:template match="doc:since">
+<para role="since">Since <xsl:value-of select="@version"/>
+</para>
+</xsl:template>
+
+<xsl:template match="doc:deprecated">
+ <xsl:variable name="name" select="../../@name"/>
+ <xsl:variable name="parent">
+ <xsl:call-template name="interface-basename">
+ <xsl:with-param name="str" select="../../../@name"/>/>
+ </xsl:call-template>
+ </xsl:variable>
+
+ <xsl:variable name="type" select="name(../..)"/>
+
+ <para role="deprecated">
+ <warning><para><literal><xsl:value-of select="$name"/></literal> is deprecated since version <xsl:value-of select="@version"/> and should not be used in newly-written code. Use
+
+ <xsl:variable name="to">
+ <xsl:choose>
+ <xsl:when test="contains($type,'property')">
+ <xsl:value-of select="$parent"/>:<xsl:value-of select="@instead"/>
+ </xsl:when>
+ <xsl:when test="contains($type,'signal')">
+ <xsl:value-of select="$parent"/>::<xsl:value-of select="@instead"/>
+ </xsl:when>
+ <xsl:when test="contains($type,'method')">
+ <xsl:value-of select="$parent"/>.<xsl:value-of select="@instead"/>
+ </xsl:when>
+ <xsl:when test="contains($type,'interface')">
+ <xsl:value-of select="@instead"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="@instead"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+
+ <xsl:call-template name="create-link">
+ <xsl:with-param name="type" select="$type"/>
+ <xsl:with-param name="to" select="$to"/>
+ <xsl:with-param name="val" select="@instead"/>
+ </xsl:call-template>
+instead.</para></warning>
+</para>
+</xsl:template>
+
+<xsl:template match="doc:permission">
+<para role="permission">
+<xsl:apply-templates />
+</para>
+</xsl:template>
+
+<xsl:template match="doc:seealso">
+<para>
+See also:
+<xsl:apply-templates />
+
+</para>
+</xsl:template>
+
+<xsl:template name="create-link">
+ <xsl:param name="type"/>
+ <xsl:param name="to"/>
+ <xsl:param name="val"/>
+
+ <xsl:choose>
+ <xsl:when test="contains($type,'property')">
+ <link><xsl:attribute name="linkend"><xsl:value-of select="$to"/></xsl:attribute><literal><xsl:value-of select="$val"/></literal></link>
+ </xsl:when>
+ <xsl:when test="contains($type,'signal')">
+ <link><xsl:attribute name="linkend"><xsl:value-of select="$to"/></xsl:attribute><literal><xsl:value-of select="$val"/></literal></link>
+ </xsl:when>
+ <xsl:when test="contains($type,'method')">
+ <link><xsl:attribute name="linkend"><xsl:value-of select="$to"/></xsl:attribute><function><xsl:value-of select="$val"/></function></link>
+ </xsl:when>
+ <xsl:when test="contains($type,'interface')">
+ <link><xsl:attribute name="linkend"><xsl:value-of select="$to"/></xsl:attribute><xsl:value-of select="$val"/></link>
+ </xsl:when>
+ </xsl:choose>
+</xsl:template>
+
+<xsl:template match="doc:ref">
+ <xsl:call-template name="create-link">
+ <xsl:with-param name="type" select="@type"/>
+ <xsl:with-param name="to" select="@to"/>
+ <xsl:with-param name="val" select="."/>
+ </xsl:call-template>
+</xsl:template>
+
+<xsl:template name="method-doc">
+ <xsl:apply-templates select="doc:doc/doc:description"/>
+
+ <variablelist role="params">
+ <xsl:for-each select="arg">
+<varlistentry><term><parameter><xsl:value-of select="@name"/></parameter>:</term>
+<listitem><simpara><xsl:value-of select="doc:doc/doc:summary"/></simpara></listitem>
+</varlistentry>
+ </xsl:for-each>
+ </variablelist>
+
+ <xsl:apply-templates select="doc:doc/doc:since"/>
+ <xsl:apply-templates select="doc:doc/doc:deprecated"/>
+ <xsl:apply-templates select="doc:doc/doc:permission"/>
+ <xsl:apply-templates select="doc:doc/doc:seealso"/>
+</xsl:template>
+
+<xsl:template name="method-details">
+ <xsl:param name="basename"/>
+ <xsl:variable name="longest">
+ <xsl:call-template name="find-longest">
+ <xsl:with-param name="set" select="@name"/>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:for-each select="///method">
+ <refsect2>
+ <title><anchor role="function"><xsl:attribute name="id"><xsl:value-of select="$basename"/>.<xsl:value-of select="@name"/></xsl:attribute></anchor><xsl:value-of select="@name"/> ()</title>
+<indexterm><primary><xsl:value-of select="@name"/></primary><secondary><xsl:value-of select="$basename"/></secondary></indexterm>
+<programlisting><xsl:value-of select="@name"/> (<xsl:call-template name="method-args"><xsl:with-param name="indent" select="string-length(@name) + 2"/><xsl:with-param name="prefix" select="."/></xsl:call-template>)</programlisting>
+ </refsect2>
+
+ <xsl:call-template name="method-doc"/>
+
+ </xsl:for-each>
+</xsl:template>
+
+
+<xsl:template name="properties-synopsis">
+ <xsl:param name="basename"/>
+ <xsl:variable name="longest">
+ <xsl:call-template name="find-longest">
+ <xsl:with-param name="set" select="///property/@name"/>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:for-each select="///property">
+<link><xsl:attribute name="linkend"><xsl:value-of select="$basename"/>:<xsl:value-of select="@name"/></xsl:attribute>'<xsl:value-of select="@name"/>'</link><xsl:call-template name="pad-spaces"><xsl:with-param name="width" select="$longest - string-length(@name) + 1"/></xsl:call-template> <xsl:call-template name="property-args"><xsl:with-param name="indent" select="$longest + 2"/></xsl:call-template>
+</xsl:for-each>
+</xsl:template>
+
+
+<xsl:template name="signals-synopsis">
+ <xsl:param name="basename"/>
+ <xsl:variable name="longest">
+ <xsl:call-template name="find-longest">
+ <xsl:with-param name="set" select="///signal/@name"/>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:for-each select="///signal">
+<link><xsl:attribute name="linkend"><xsl:value-of select="$basename"/>::<xsl:value-of select="@name"/></xsl:attribute><xsl:value-of select="@name"/></link><xsl:call-template name="pad-spaces"><xsl:with-param name="width" select="$longest - string-length(@name) + 1"/></xsl:call-template>(<xsl:call-template name="signal-args"><xsl:with-param name="indent" select="$longest + 2"/><xsl:with-param name="prefix" select="///signal"/></xsl:call-template>)
+</xsl:for-each>
+</xsl:template>
+
+
+<xsl:template name="methods-synopsis">
+ <xsl:param name="basename"/>
+ <xsl:variable name="longest">
+ <xsl:call-template name="find-longest">
+ <xsl:with-param name="set" select="///method/@name"/>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:for-each select="///method">
+<link><xsl:attribute name="linkend"><xsl:value-of select="$basename"/>.<xsl:value-of select="@name"/></xsl:attribute><xsl:value-of select="@name"/></link><xsl:call-template name="pad-spaces"><xsl:with-param name="width" select="$longest - string-length(@name) + 1"/></xsl:call-template>(<xsl:call-template name="method-args"><xsl:with-param name="indent" select="$longest + 2"/><xsl:with-param name="prefix" select="///method"/></xsl:call-template>)
+</xsl:for-each>
+</xsl:template>
+
+
+<xsl:template name="method-args"><xsl:param name="indent"/><xsl:param name="prefix"/><xsl:variable name="longest"><xsl:call-template name="find-longest"><xsl:with-param name="set" select="$prefix/arg/@type"/></xsl:call-template></xsl:variable><xsl:for-each select="arg"><xsl:value-of select="@direction"/>
+<xsl:call-template name="pad-spaces"><xsl:with-param name="width" select="4 - string-length(@direction)"/></xsl:call-template>'<xsl:value-of select="@type"/>'<xsl:call-template name="pad-spaces"><xsl:with-param name="width" select="$longest - string-length(@type) + 1"/></xsl:call-template>
+<xsl:value-of select="@name"/><xsl:if test="not(position() = last())">,
+<xsl:call-template name="pad-spaces"><xsl:with-param name="width" select="$indent"/></xsl:call-template></xsl:if>
+</xsl:for-each>
+</xsl:template>
+
+
+<xsl:template name="signal-args"><xsl:param name="indent"/><xsl:param name="prefix"/><xsl:variable name="longest"><xsl:call-template name="find-longest"><xsl:with-param name="set" select="$prefix/arg/@type"/></xsl:call-template></xsl:variable><xsl:for-each select="arg">'<xsl:value-of select="@type"/>'<xsl:call-template name="pad-spaces"><xsl:with-param name="width" select="$longest - string-length(@type) + 1"/></xsl:call-template>
+<xsl:value-of select="@name"/><xsl:if test="not(position() = last())">,
+<xsl:call-template name="pad-spaces"><xsl:with-param name="width" select="$indent"/></xsl:call-template></xsl:if>
+</xsl:for-each>
+</xsl:template>
+
+
+<xsl:template name="property-args"><xsl:param name="indent"/>
+<xsl:value-of select="@access"/><xsl:call-template name="pad-spaces"><xsl:with-param name="width" select="9 - string-length(@access) + 1"/></xsl:call-template>'<xsl:value-of select="@type"/>'
+</xsl:template>
+
+
+<xsl:template name="pad-spaces">
+ <xsl:param name="width"/>
+ <xsl:variable name="spaces" xml:space="preserve"> </xsl:variable>
+ <xsl:value-of select="substring($spaces,1,$width)"/>
+</xsl:template>
+
+
+<xsl:template name="find-longest">
+ <xsl:param name="set"/>
+ <xsl:param name="index" select="1"/>
+ <xsl:param name="longest" select="0"/>
+
+ <xsl:choose>
+ <xsl:when test="$index > count($set)">
+ <!--finished looking-->
+ <xsl:value-of select="$longest"/>
+ </xsl:when>
+ <xsl:when test="string-length($set[$index])>$longest">
+ <!--found new longest-->
+ <xsl:call-template name="find-longest">
+ <xsl:with-param name="set" select="$set"/>
+ <xsl:with-param name="index" select="$index + 1"/>
+ <xsl:with-param name="longest" select="string-length($set[$index])"/>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:otherwise>
+ <!--this isn't any longer-->
+ <xsl:call-template name="find-longest">
+ <xsl:with-param name="set" select="$set"/>
+ <xsl:with-param name="index" select="$index + 1"/>
+ <xsl:with-param name="longest" select="$longest"/>
+ </xsl:call-template>
+ </xsl:otherwise>
+ </xsl:choose>
+</xsl:template>
+
+
+<xsl:template name="interface-basename">
+ <xsl:param name="str"/>
+ <xsl:choose>
+ <xsl:when test="contains($str,'.')">
+ <xsl:call-template name="interface-basename">
+ <xsl:with-param name="str" select="substring-after($str,'.')"/>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="$str"/>
+ </xsl:otherwise>
+ </xsl:choose>
+</xsl:template>
+
+</xsl:stylesheet>
Index: gnome-packagekit-3.20.0/man/Makefile.am
===================================================================
--- gnome-packagekit-3.20.0.orig/man/Makefile.am
+++ gnome-packagekit-3.20.0/man/Makefile.am
@@ -1,5 +1,7 @@
EXTRA_DIST = \
gpk-application.sgml \
+ gpk-dbus-service.sgml \
+ gpk-install-local-file.sgml \
gpk-log.sgml \
gpk-prefs.sgml \
gpk-update-viewer.sgml
@@ -7,6 +9,8 @@ EXTRA_DIST = \
if HAVE_DOCBOOK2MAN
man_MANS = \
gpk-application.1 \
+ gpk-dbus-service.1 \
+ gpk-install-local-file.1 \
gpk-log.1 \
gpk-prefs.1 \
gpk-update-viewer.1
Index: gnome-packagekit-3.20.0/man/gpk-dbus-service.sgml
===================================================================
--- /dev/null
+++ gnome-packagekit-3.20.0/man/gpk-dbus-service.sgml
@@ -0,0 +1,77 @@
+<!doctype refentry PUBLIC "-//OASIS//DTD DocBook V4.1//EN" [
+ <!-- Please adjust the date whenever revising the manpage. -->
+ <!ENTITY date "<date>11 April,2008</date>">
+ <!ENTITY package "gpk-dbus-service">
+ <!ENTITY gnu "<acronym>GNU</acronym>">
+ <!ENTITY gpl "&gnu; <acronym>GPL</acronym>">
+]>
+
+<refentry>
+ <refentryinfo>
+ <address>
+ <email>richard@hughsie.com</email>;
+ </address>
+ <author>
+ <firstname>Richard</firstname>
+ <surname>Hughes</surname>
+ </author>
+ <copyright>
+ <year>2008-2013</year>
+ <holder>Richard Hughes</holder>
+ </copyright>
+ &date;
+ </refentryinfo>
+ <refmeta>
+ <refentrytitle>gpk-dbus-service</refentrytitle>
+ <manvolnum>1</manvolnum>
+ </refmeta>
+ <refnamediv>
+ <refname>&package;</refname>
+ <refpurpose>GNOME PackageKit Session Service</refpurpose>
+ </refnamediv>
+ <refsynopsisdiv>
+ <cmdsynopsis>
+ <command>&package;</command>
+ <arg><option>--verbose</option></arg>
+ </cmdsynopsis>
+ </refsynopsisdiv>
+ <refsect1>
+ <title>DESCRIPTION</title>
+ <para>
+ This manual page documents briefly the <command>&package;</command> command.
+ </para>
+ <para>
+ <command>&package;</command> provides the PackageKit D-Bus session API in GNOME.
+ </para>
+ </refsect1>
+ <refsect1>
+ <title>SEE ALSO</title>
+ <para>gpk-update-viewer (1).</para>
+ <para>gpk-application (2).</para>
+ <para>gpk-log (3).</para>
+ <para>gpk-install-catalog (4).</para>
+ </refsect1>
+ <refsect1>
+ <title>AUTHOR</title>
+ <para>This manual page was written by Richard Hughes <email>richard@hughsie.com</email>.
+ </para>
+ </refsect1>
+</refentry>
+
+<!-- Keep this comment at the end of the file
+Local variables:
+mode: sgml
+sgml-omittag:t
+sgml-shorttag:t
+sgml-minimize-attributes:nil
+sgml-always-quote-attributes:t
+sgml-indent-step:2
+sgml-indent-data:t
+sgml-parent-document:nil
+sgml-default-dtd-file:nil
+sgml-exposed-tags:nil
+sgml-local-catalogs:nil
+sgml-local-ecat-files:nil
+End:
+-->
+
Index: gnome-packagekit-3.20.0/man/gpk-install-local-file.sgml
===================================================================
--- /dev/null
+++ gnome-packagekit-3.20.0/man/gpk-install-local-file.sgml
@@ -0,0 +1,77 @@
+<!doctype refentry PUBLIC "-//OASIS//DTD DocBook V4.1//EN" [
+ <!-- Please adjust the date whenever revising the manpage. -->
+ <!ENTITY date "<date>11 April,2008</date>">
+ <!ENTITY package "gpk-install-local-file">
+ <!ENTITY gnu "<acronym>GNU</acronym>">
+ <!ENTITY gpl "&gnu; <acronym>GPL</acronym>">
+]>
+
+<refentry>
+ <refentryinfo>
+ <address>
+ <email>richard@hughsie.com</email>;
+ </address>
+ <author>
+ <firstname>Richard</firstname>
+ <surname>Hughes</surname>
+ </author>
+ <copyright>
+ <year>2008-2013</year>
+ <holder>Richard Hughes</holder>
+ </copyright>
+ &date;
+ </refentryinfo>
+ <refmeta>
+ <refentrytitle>gpk-install-local-file</refentrytitle>
+ <manvolnum>1</manvolnum>
+ </refmeta>
+ <refnamediv>
+ <refname>&package;</refname>
+ <refpurpose>GNOME PackageKit Local File Helper</refpurpose>
+ </refnamediv>
+ <refsynopsisdiv>
+ <cmdsynopsis>
+ <command>&package;</command>
+ <arg><option>--verbose</option></arg>
+ <arg><option>filename</option></arg>
+ </cmdsynopsis>
+ </refsynopsisdiv>
+ <refsect1>
+ <title>DESCRIPTION</title>
+ <para>
+ This manual page documents briefly the <command>&package;</command> command.
+ </para>
+ <para>
+ <command>&package;</command> allows you to install a local package file such as an
+ rpm or deb file.
+ </para>
+ </refsect1>
+ <refsect1>
+ <title>SEE ALSO</title>
+ <para>gpk-install-package-name (1).</para>
+ <para>gpk-install-provide-file (2).</para>
+ </refsect1>
+ <refsect1>
+ <title>AUTHOR</title>
+ <para>This manual page was written by Richard Hughes <email>richard@hughsie.com</email>.
+ </para>
+ </refsect1>
+</refentry>
+
+<!-- Keep this comment at the end of the file
+Local variables:
+mode: sgml
+sgml-omittag:t
+sgml-shorttag:t
+sgml-minimize-attributes:nil
+sgml-always-quote-attributes:t
+sgml-indent-step:2
+sgml-indent-data:t
+sgml-parent-document:nil
+sgml-default-dtd-file:nil
+sgml-exposed-tags:nil
+sgml-local-catalogs:nil
+sgml-local-ecat-files:nil
+End:
+-->
+
Index: gnome-packagekit-3.20.0/po/POTFILES.in
===================================================================
--- gnome-packagekit-3.20.0.orig/po/POTFILES.in
+++ gnome-packagekit-3.20.0/po/POTFILES.in
@@ -6,6 +6,7 @@ data/appdata/gpk-update-viewer.appdata.x
data/gpk-application.desktop.in
[type: gettext/glade]data/gpk-application.ui
[type: gettext/glade]data/gpk-client.ui
+data/gpk-dbus-service.desktop.in
[type: gettext/glade]data/gpk-error.ui
[type: gettext/glade]data/gpk-eula.ui
data/gpk-install-local-file.desktop.in
@@ -19,11 +20,17 @@ data/gpk-update-viewer.desktop.in
data/org.gnome.packagekit.gschema.xml
src/gpk-application.c
src/gpk-common.c
+src/gpk-dbus-service.c
+src/gpk-dbus-task.c
src/gpk-debug.c
src/gpk-dialog.c
src/gpk-enum.c
src/gpk-error.c
+src/gpk-helper-chooser.c
+src/gpk-helper-run.c
+src/gpk-install-local-file.c
src/gpk-log.c
+src/gpk-modal-dialog.c
src/gpk-prefs.c
src/gpk-task.c
src/gpk-update-viewer.c
Index: gnome-packagekit-3.20.0/src/Makefile.am
===================================================================
--- gnome-packagekit-3.20.0.orig/src/Makefile.am
+++ gnome-packagekit-3.20.0/src/Makefile.am
@@ -7,6 +7,7 @@ AM_CPPFLAGS = \
$(GLIB_CFLAGS) \
$(GIO_CFLAGS) \
$(GTK_CFLAGS) \
+ $(DBUS_CFLAGS) \
$(NOTIFY_CFLAGS) \
$(PACKAGEKIT_CFLAGS) \
$(GUDEV_CFLAGS) \
@@ -30,8 +31,10 @@ AM_CPPFLAGS = \
bin_PROGRAMS = \
gpk-application \
gpk-prefs \
+ gpk-install-local-file \
gpk-update-viewer \
gpk-log \
+ gpk-dbus-service \
$(NULL)
noinst_LIBRARIES = libgpkshared.a
@@ -44,8 +47,28 @@ libgpkshared_a_SOURCES = \
gpk-debug.h \
gpk-enum.c \
gpk-enum.h \
+ gpk-x11.c \
+ gpk-x11.h \
+ gpk-session.c \
+ gpk-session.h \
gpk-dialog.c \
gpk-dialog.h \
+ gpk-marshal.c \
+ gpk-marshal.h \
+ gpk-animated-icon.c \
+ gpk-animated-icon.h \
+ gpk-vendor.c \
+ gpk-vendor.h \
+ gpk-language.c \
+ gpk-language.h \
+ gpk-modal-dialog.c \
+ gpk-modal-dialog.h \
+ gpk-helper-run.c \
+ gpk-helper-run.h \
+ gpk-helper-chooser.c \
+ gpk-helper-chooser.h \
+ gpk-gnome.c \
+ gpk-gnome.h \
gpk-common.c \
gpk-common.h \
gpk-task.c \
@@ -63,6 +86,7 @@ endif
shared_LIBS = \
$(GLIB_LIBS) \
$(GIO_LIBS) \
+ $(DBUS_LIBS) \
$(GTK_LIBS) \
$(GUDEV_LIBS) \
$(NOTIFY_LIBS) \
@@ -70,6 +94,29 @@ shared_LIBS = \
$(PACKAGEKIT_LIBS) \
$(GNOME_MENUS_LIBS) \
$(CANBERRA_LIBS) \
+ $(X11_LIBS) \
+ $(NULL)
+
+gpk_install_local_file_SOURCES = \
+ gpk-install-local-file.c \
+ $(NULL)
+
+gpk_install_local_file_LDADD = \
+ libgpkshared.a \
+ $(shared_LIBS) \
+ $(NULL)
+
+gpk_dbus_service_SOURCES = \
+ gpk-dbus-service.c \
+ gpk-dbus.c \
+ gpk-dbus.h \
+ gpk-dbus-task.c \
+ gpk-dbus-task.h \
+ $(NULL)
+
+gpk_dbus_service_LDADD = \
+ libgpkshared.a \
+ $(shared_LIBS) \
$(NULL)
gpk_application_SOURCES = \
@@ -84,6 +131,8 @@ gpk_application_LDADD = \
gpk_prefs_SOURCES = \
gpk-debug.h \
gpk-debug.c \
+ gpk-animated-icon.c \
+ gpk-animated-icon.h \
gpk-enum.c \
gpk-enum.h \
gpk-common.c \
@@ -122,6 +171,26 @@ gpk_log_LDADD = \
$(shared_LIBS) \
$(NULL)
+BUILT_SOURCES = \
+ gpk-marshal.c \
+ gpk-marshal.h \
+ org.freedesktop.PackageKit.h \
+ $(NULL)
+
+gpk-marshal.c: gpk-marshal.list
+ echo "#include \"gpk-marshal.h\"" > $@ && \
+ glib-genmarshal $< --prefix=gpk_marshal --body >> $@
+
+gpk-marshal.h: gpk-marshal.list
+ glib-genmarshal $< --prefix=gpk_marshal --header > $@
+
+org.freedesktop.PackageKit.h: org.freedesktop.PackageKit.xml
+ $(LIBTOOL) --mode=execute dbus-binding-tool \
+ --prefix=gpk_dbus \
+ --mode=glib-server \
+ --output=org.freedesktop.PackageKit.h \
+ $(srcdir)/org.freedesktop.PackageKit.xml
+
if EGG_BUILD_TESTS
check_PROGRAMS = \
@@ -144,8 +213,30 @@ gpk_self_test_SOURCES = \
gpk-common.h \
gpk-error.c \
gpk-error.h \
+ gpk-dbus.c \
+ gpk-dbus.h \
+ gpk-dbus-task.c \
+ gpk-dbus-task.h \
+ gpk-x11.c \
+ gpk-x11.h \
gpk-task.c \
gpk-task.h \
+ gpk-language.c \
+ gpk-language.h \
+ gpk-modal-dialog.c \
+ gpk-modal-dialog.h \
+ gpk-animated-icon.c \
+ gpk-animated-icon.h \
+ gpk-gnome.c \
+ gpk-gnome.h \
+ gpk-vendor.c \
+ gpk-vendor.h \
+ gpk-helper-run.c \
+ gpk-helper-run.h \
+ gpk-helper-chooser.c \
+ gpk-helper-chooser.h \
+ gpk-marshal.c \
+ gpk-marshal.h \
gpk-dialog.c \
gpk-dialog.h \
$(NULL)
@@ -160,8 +251,14 @@ gpk_self_test_CFLAGS = $(AM_CFLAGS)
TESTS = gpk-self-test
endif
+EXTRA_DIST = \
+ gpk-marshal.list \
+ org.freedesktop.PackageKit.xml \
+ $(NULL)
+
clean-local:
rm -f *~
+ rm -f gpk-marshal.c gpk-marshal.h
rm -f *.out
rm -f *.gcda
rm -f *.gcno
Index: gnome-packagekit-3.20.0/src/gpk-animated-icon.c
===================================================================
--- /dev/null
+++ gnome-packagekit-3.20.0/src/gpk-animated-icon.c
@@ -0,0 +1,307 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2008 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include "config.h"
+
+#include <glib.h>
+#include <glib/gi18n.h>
+#include <gtk/gtk.h>
+#include <packagekit-glib2/packagekit.h>
+
+#include "egg-string.h"
+
+#include "gpk-animated-icon.h"
+
+G_DEFINE_TYPE (GpkAnimatedIcon, gpk_animated_icon, GTK_TYPE_IMAGE)
+
+static gpointer parent_class = NULL;
+
+/**
+ * gpk_animated_icon_free_pixbufs:
+ **/
+static gboolean
+gpk_animated_icon_free_pixbufs (GpkAnimatedIcon *icon)
+{
+ guint i;
+
+ g_return_val_if_fail (GPK_IS_ANIMATED_ICON (icon), FALSE);
+
+ /* none loaded */
+ if (icon->frames == NULL) {
+ g_debug ("nothing to free");
+ return FALSE;
+ }
+
+ /* free each frame */
+ for (i=0; i<icon->number_frames; i++)
+ g_object_unref (icon->frames[i]);
+ g_free (icon->frames);
+ icon->frames = NULL;
+ return TRUE;
+}
+
+/**
+ * gpk_animated_icon_set_icon_name:
+ **/
+gboolean
+gpk_animated_icon_set_icon_name (GpkAnimatedIcon *icon, GtkIconSize size, const gchar *name)
+{
+ g_return_val_if_fail (GPK_IS_ANIMATED_ICON (icon), FALSE);
+ g_return_val_if_fail (name != NULL, FALSE);
+
+ /* stop existing animation */
+ gpk_animated_icon_enable_animation (icon, FALSE);
+
+ /* set static image */
+ gtk_image_set_from_icon_name (GTK_IMAGE (icon), name, size);
+ return TRUE;
+}
+
+/**
+ * gpk_animated_icon_set_filename_tile:
+ **/
+gboolean
+gpk_animated_icon_set_filename_tile (GpkAnimatedIcon *icon, GtkIconSize size, const gchar *name)
+{
+ gboolean ret;
+ gint w, h;
+ gint rows, cols;
+ gint r, c, i;
+ GdkPixbuf *pixbuf;
+
+ g_return_val_if_fail (GPK_IS_ANIMATED_ICON (icon), FALSE);
+ g_return_val_if_fail (name != NULL, FALSE);
+
+ /* have we already set the same icon */
+ if (g_strcmp0 (icon->filename, name) == 0) {
+ g_debug ("already set the same icon name %s, ignoring", name);
+ return FALSE;
+ }
+
+ /* stop existing animation */
+ gpk_animated_icon_enable_animation (icon, FALSE);
+
+ /* save new value */
+ g_free (icon->filename);
+ icon->filename = g_strdup (name);
+
+ /* do we need to unload */
+ if (icon->frames != NULL) {
+ gpk_animated_icon_free_pixbufs (icon);
+ }
+
+ g_debug ("loading from %s", name);
+ ret = gtk_icon_size_lookup (size, &w, &h);
+ if (!ret) {
+ g_warning ("Can't get icon size info");
+ return FALSE;
+ }
+
+ pixbuf = gtk_icon_theme_load_icon (gtk_icon_theme_get_default (), name, w, 0, NULL);
+ /* can't load from gnome-icon-theme */
+ if (pixbuf == NULL) {
+ g_debug ("can't load animation %s", name);
+ return FALSE;
+ }
+
+ /* silly hack until we get some metadata */
+ if (g_strcmp0 (name, "process-working") == 0) {
+ w = gdk_pixbuf_get_width (pixbuf) / 8;
+ h = gdk_pixbuf_get_height (pixbuf) / 4;
+ }
+
+ /* we failed to get a valid pixbuf */
+ if (w == 0 || h == 0) {
+ g_object_unref (pixbuf);
+ return FALSE;
+ }
+
+ cols = gdk_pixbuf_get_width (pixbuf) / w;
+ rows = gdk_pixbuf_get_height (pixbuf) / h;
+
+ icon->frame_counter = 0;
+ icon->number_frames = rows * cols;
+ icon->frames = g_new (GdkPixbuf*, icon->number_frames);
+
+ for (i = 0, r = 0; r < rows; r++)
+ for (c = 0; c < cols; c++, i++) {
+ icon->frames[i] = gdk_pixbuf_new_subpixbuf (pixbuf, c * w, r * h, w, h);
+ }
+
+ g_object_unref (pixbuf);
+
+ /* enable new animation */
+ gpk_animated_icon_enable_animation (icon, TRUE);
+
+ return TRUE;
+}
+
+/**
+ * gpk_animated_icon_visible_notify_cb:
+ **/
+static void
+gpk_animated_icon_visible_notify_cb (GObject *object, GParamSpec *param, GpkAnimatedIcon *icon)
+{
+ gboolean ret;
+ g_object_get (object, "visible", &ret, NULL);
+ if (!ret && icon->animation_id != 0) {
+ g_debug ("disabling animation as hidden");
+ gpk_animated_icon_enable_animation (icon, FALSE);
+ }
+}
+
+/**
+ * gpk_animated_icon_update:
+ **/
+static gboolean
+gpk_animated_icon_update (GpkAnimatedIcon *icon)
+{
+ static guint rate_limit = 0;
+
+ /* debug so we can catch polling */
+ if (rate_limit++ % 20 == 0)
+ g_debug ("polling check");
+
+ /* have we loaded a file */
+ if (icon->frames == NULL) {
+ g_warning ("no frames to process");
+ icon->animation_id = 0;
+ return FALSE;
+ }
+
+ /* set new */
+ gtk_image_set_from_pixbuf (GTK_IMAGE (icon), icon->frames[icon->frame_counter]);
+
+ /* advance counter, wrapping around */
+ icon->frame_counter = (icon->frame_counter + 1) % icon->number_frames;
+
+ return TRUE;
+}
+
+/**
+ * gpk_animated_icon_set_frame_delay:
+ **/
+gboolean
+gpk_animated_icon_set_frame_delay (GpkAnimatedIcon *icon, guint delay_ms)
+{
+ g_return_val_if_fail (GPK_IS_ANIMATED_ICON (icon), FALSE);
+
+ g_debug ("frame delay set to %ims", delay_ms);
+ icon->frame_delay = delay_ms;
+
+ /* do we have to change a running icon? */
+ if (icon->animation_id != 0) {
+ g_source_remove (icon->animation_id);
+ icon->animation_id = g_timeout_add (icon->frame_delay, (GSourceFunc) gpk_animated_icon_update, icon);
+ g_source_set_name_by_id (icon->animation_id, "[GpkAnimatedIcon] update from delay change");
+ }
+
+ return TRUE;
+}
+
+/**
+ * gpk_animated_icon_enable_animation:
+ **/
+gboolean
+gpk_animated_icon_enable_animation (GpkAnimatedIcon *icon, gboolean enabled)
+{
+ g_return_val_if_fail (GPK_IS_ANIMATED_ICON (icon), FALSE);
+
+ if (!enabled) {
+ if (icon->animation_id == 0) {
+ g_debug ("ignoring stop on stopped icon");
+ return FALSE;
+ }
+
+ g_source_remove (icon->animation_id);
+ icon->animation_id = 0;
+ return TRUE;
+ }
+
+ /* don't double queue */
+ if (icon->animation_id != 0) {
+ g_debug ("ignoring start on started icon");
+ return FALSE;
+ }
+
+ /* start */
+ icon->frame_counter = 0;
+ icon->animation_id = g_timeout_add (icon->frame_delay, (GSourceFunc) gpk_animated_icon_update, icon);
+ g_source_set_name_by_id (icon->animation_id, "[GpkAnimatedIcon] start update");
+ gpk_animated_icon_update (icon);
+ return TRUE;
+}
+
+/**
+ * gpk_animated_icon_destroy:
+ * @object: The object to destroy
+ **/
+static void
+gpk_animated_icon_destroy (GtkWidget *object)
+{
+ GpkAnimatedIcon *icon;
+ icon = GPK_ANIMATED_ICON (object);
+
+ /* avoid going pop after unref when spinning */
+ if (icon->animation_id != 0) {
+ g_source_remove (icon->animation_id);
+ }
+ g_free (icon->filename);
+ icon->filename = NULL;
+ gpk_animated_icon_free_pixbufs (icon);
+
+ GTK_WIDGET_CLASS (parent_class)->destroy (object);
+}
+
+static void
+gpk_animated_icon_class_init (GpkAnimatedIconClass *class)
+{
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
+ widget_class->destroy = gpk_animated_icon_destroy;
+ parent_class = g_type_class_peek_parent (class);
+}
+
+/**
+ * gpk_animated_icon_init:
+ **/
+static void
+gpk_animated_icon_init (GpkAnimatedIcon *icon)
+{
+ g_return_if_fail (GPK_IS_ANIMATED_ICON (icon));
+ icon->frames = NULL;
+ icon->filename = NULL;
+ icon->animation_id = 0;
+ icon->frame_counter = 0;
+ icon->number_frames = 0;
+ icon->frame_delay = 200;
+
+ /* disable polling if we are hidden */
+ g_signal_connect (GTK_WIDGET (icon), "notify::visible", G_CALLBACK (gpk_animated_icon_visible_notify_cb), icon);
+}
+
+/**
+ * gpk_animated_icon_new:
+ **/
+GtkWidget *
+gpk_animated_icon_new (void)
+{
+ return g_object_new (GPK_TYPE_ANIMATED_ICON, NULL);
+}
Index: gnome-packagekit-3.20.0/src/gpk-animated-icon.h
===================================================================
--- /dev/null
+++ gnome-packagekit-3.20.0/src/gpk-animated-icon.h
@@ -0,0 +1,72 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2008 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef GPK_ANIMATED_ICON_H
+#define GPK_ANIMATED_ICON_H
+
+#include <glib-object.h>
+#include <gtk/gtk.h>
+
+#define GPK_TYPE_ANIMATED_ICON (gpk_animated_icon_get_type())
+#define GPK_ANIMATED_ICON(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GPK_TYPE_ANIMATED_ICON, GpkAnimatedIcon))
+#define GPK_ANIMATED_ICON_CLASS(cls) (G_TYPE_CHECK_CLASS_CAST((cls), GPK_TYPE_ANIMATED_ICON, GpkAnimatedIconClass))
+#define GPK_IS_ANIMATED_ICON(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), GPK_TYPE_ANIMATED_ICON))
+#define GPK_IS_ANIMATED_ICON_CLASS(cls) (G_TYPE_CHECK_CLASS_TYPE((cls), GPK_TYPE_ANIMATED_ICON))
+#define GPK_ANIMATED_ICON_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GPK_TYPE_ANIMATED_ICON, GpkAnimatedIconClass))
+
+G_BEGIN_DECLS
+
+typedef struct _GpkAnimatedIcon GpkAnimatedIcon;
+typedef struct _GpkAnimatedIconClass GpkAnimatedIconClass;
+
+struct _GpkAnimatedIcon
+{
+ GtkImage parent;
+ gchar *filename;
+ guint animation_id;
+ guint frame_counter;
+ guint number_frames;
+ guint frame_delay;
+ GdkPixbuf **frames;
+};
+
+struct _GpkAnimatedIconClass
+{
+ GtkImageClass parent_class;
+};
+
+GType gpk_animated_icon_get_type (void);
+GtkWidget *gpk_animated_icon_new (void);
+gboolean gpk_animated_icon_set_filename_tile (GpkAnimatedIcon *icon,
+ GtkIconSize size,
+ const gchar *name);
+gboolean gpk_animated_icon_set_icon_name (GpkAnimatedIcon *icon,
+ GtkIconSize size,
+ const gchar *name);
+gboolean gpk_animated_icon_set_frame_delay (GpkAnimatedIcon *icon,
+ guint delay_ms);
+gboolean gpk_animated_icon_enable_animation (GpkAnimatedIcon *icon,
+ gboolean enabled);
+
+G_END_DECLS
+
+#endif /* GPK_ANIMATED_ICON_H */
+
Index: gnome-packagekit-3.20.0/src/gpk-application.c
===================================================================
--- gnome-packagekit-3.20.0.orig/src/gpk-application.c
+++ gnome-packagekit-3.20.0/src/gpk-application.c
@@ -21,6 +21,7 @@
#include "config.h"
+#include <dbus/dbus-glib.h>
#include <errno.h>
#include <gdk/gdkkeysyms.h>
#include <gdk/gdkx.h>
@@ -42,6 +43,8 @@
#include "gpk-dialog.h"
#include "gpk-enum.h"
#include "gpk-error.h"
+#include "gpk-gnome.h"
+#include "gpk-helper-run.h"
#include "gpk-task.h"
#include "gpk-debug.h"
@@ -505,7 +508,7 @@ out:
static void
gpk_application_menu_homepage_cb (GtkAction *action, GpkApplicationPrivate *priv)
{
- gtk_show_uri (NULL, priv->homepage_url, GDK_CURRENT_TIME, NULL);
+ gpk_gnome_open (priv->homepage_url);
}
/**
@@ -3433,6 +3436,7 @@ main (int argc, char *argv[])
bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
textdomain (GETTEXT_PACKAGE);
+ dbus_g_thread_init ();
gtk_init (&argc, &argv);
context = g_option_context_new (NULL);
Index: gnome-packagekit-3.20.0/src/gpk-common.c
===================================================================
--- gnome-packagekit-3.20.0.orig/src/gpk-common.c
+++ gnome-packagekit-3.20.0/src/gpk-common.c
@@ -49,6 +49,21 @@
/* static, so local to process */
static gboolean small_form_factor_mode = FALSE;
+gchar **
+pk_package_array_to_strv (GPtrArray *array)
+{
+ PkPackage *item;
+ gchar **results;
+ guint i;
+
+ results = g_new0 (gchar *, array->len+1);
+ for (i=0; i<array->len; i++) {
+ item = g_ptr_array_index (array, i);
+ results[i] = g_strdup (pk_package_get_id (item));
+ }
+ return results;
+}
+
/**
* pk_strv_to_ptr_array:
* @array: the gchar** array of strings
@@ -320,6 +335,38 @@ out:
}
/**
+ * gpk_set_animated_icon_from_status:
+ **/
+gboolean
+gpk_set_animated_icon_from_status (GpkAnimatedIcon *icon, PkStatusEnum status, GtkIconSize size)
+{
+ const gchar *name = NULL;
+ guint delay = 0;
+
+ /* see if there is an animation */
+ name = gpk_status_enum_to_animation (status);
+
+ /* get the timing */
+ if (g_str_has_prefix (name, "pk-action-"))
+ delay = 150;
+ else if (g_str_has_prefix (name, "process-working"))
+ delay = 50;
+
+ /* animate or set static */
+ if (delay != 0) {
+ gpk_animated_icon_set_frame_delay (icon, delay);
+ gpk_animated_icon_set_filename_tile (icon, size, name);
+ } else {
+ gpk_animated_icon_set_icon_name (icon, size, name);
+ }
+
+ /* stop spinning */
+ if (status == PK_STATUS_ENUM_FINISHED)
+ gpk_animated_icon_enable_animation (icon, FALSE);
+ return TRUE;
+}
+
+/**
* gpk_time_to_imprecise_string:
* @time_secs: The time value to convert in seconds
*
Index: gnome-packagekit-3.20.0/src/gpk-common.h
===================================================================
--- gnome-packagekit-3.20.0.orig/src/gpk-common.h
+++ gnome-packagekit-3.20.0/src/gpk-common.h
@@ -26,6 +26,7 @@
#include <gtk/gtk.h>
#include <packagekit-glib2/packagekit.h>
+#include "gpk-animated-icon.h"
#include "gpk-enum.h"
G_BEGIN_DECLS
@@ -69,6 +70,9 @@ gchar *gpk_time_to_localised_string (g
gchar *gpk_time_to_imprecise_string (guint time_secs);
gboolean gpk_check_privileged_user (const gchar *application_name,
gboolean show_ui);
+gboolean gpk_set_animated_icon_from_status (GpkAnimatedIcon *icon,
+ PkStatusEnum status,
+ GtkIconSize size);
gchar *gpk_strv_join_locale (gchar **array);
GtkEntryCompletion *gpk_package_entry_completion_new (void);
gboolean gpk_window_set_size_request (GtkWindow *window,
@@ -78,6 +82,7 @@ gboolean gpk_window_set_parent_xid (Gt
guint32 xid);
GPtrArray *pk_strv_to_ptr_array (gchar **array)
G_GNUC_WARN_UNUSED_RESULT;
+gchar **pk_package_array_to_strv (GPtrArray *array);
G_END_DECLS
Index: gnome-packagekit-3.20.0/src/gpk-dbus-service.c
===================================================================
--- /dev/null
+++ gnome-packagekit-3.20.0/src/gpk-dbus-service.c
@@ -0,0 +1,184 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2007-2009 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include "config.h"
+
+#include <glib/gi18n.h>
+#include <dbus/dbus-glib.h>
+#include <gtk/gtk.h>
+#include <locale.h>
+#include <libnotify/notify.h>
+#include <packagekit-glib2/packagekit.h>
+
+#include "gpk-common.h"
+#include "gpk-dbus.h"
+#include "gpk-debug.h"
+
+#include "org.freedesktop.PackageKit.h"
+
+static GMainLoop *loop = NULL;
+
+#define GPK_SESSION_IDLE_EXIT 60 /* seconds */
+
+/**
+ * gpk_dbus_service_object_register:
+ * @connection: What we want to register to
+ * @object: The GObject we want to register
+ *
+ * Return value: success
+ **/
+static gboolean
+gpk_dbus_service_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) {
+ /* abort as the D-Bus method failed */
+ g_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_DBUS, &dbus_glib_gpk_dbus_object_info);
+ dbus_g_error_domain_register (GPK_DBUS_ERROR, NULL, GPK_DBUS_TYPE_ERROR);
+ dbus_g_connection_register_g_object (connection, PK_DBUS_PATH, object);
+
+ return TRUE;
+}
+
+/**
+ * gpk_dbus_service_check_idle_cb:
+ **/
+static gboolean
+gpk_dbus_service_check_idle_cb (GpkDbus *dbus)
+{
+ guint idle;
+
+ /* get the idle time */
+ idle = gpk_dbus_get_idle_time (dbus);
+ if (idle > GPK_SESSION_IDLE_EXIT) {
+ g_debug ("exiting loop as idle");
+ g_main_loop_quit (loop);
+ return FALSE;
+ }
+ /* continue to poll */
+ return TRUE;
+}
+
+/**
+ * main:
+ **/
+int
+main (int argc, char *argv[])
+{
+ gboolean no_timed_exit = FALSE;
+ GpkDbus *dbus = NULL;
+ GOptionContext *context;
+ GError *error = NULL;
+ gboolean ret;
+ guint retval = 0;
+ DBusGConnection *connection;
+ guint timer_id = 0;
+
+ const GOptionEntry options[] = {
+ { "no-timed-exit", '\0', 0, G_OPTION_ARG_NONE, &no_timed_exit,
+ _("Do not exit after the request has been processed"), NULL },
+ { NULL}
+ };
+
+ setlocale (LC_ALL, "");
+
+ bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
+ bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
+ textdomain (GETTEXT_PACKAGE);
+
+ dbus_g_thread_init ();
+ notify_init (_("Software Install"));
+
+ /* TRANSLATORS: program name, a session wide daemon to watch for updates and changing system state */
+ g_set_application_name (_("Software Install"));
+ context = g_option_context_new (NULL);
+ g_option_context_set_summary (context, _("Session D-Bus service for PackageKit"));
+ g_option_context_add_main_entries (context, options, NULL);
+ g_option_context_add_group (context, gpk_debug_get_option_group ());
+ g_option_context_add_group (context, gtk_get_option_group (TRUE));
+ g_option_context_parse (context, &argc, &argv, NULL);
+ g_option_context_free (context);
+
+ gtk_init (&argc, &argv);
+
+ /* create new objects */
+ dbus = gpk_dbus_new ();
+ loop = g_main_loop_new (NULL, FALSE);
+
+ /* get the bus */
+ connection = dbus_g_bus_get (DBUS_BUS_SESSION, &error);
+ if (error) {
+ g_warning ("%s", error->message);
+ g_error_free (error);
+ retval = 1;
+ goto out;
+ }
+
+ /* try to register */
+ ret = gpk_dbus_service_object_register (connection, G_OBJECT (dbus));
+ if (!ret) {
+ g_warning ("failed to replace running instance.");
+ retval = 1;
+ goto out;
+ }
+
+ /* only timeout if we have specified iton the command line */
+ if (!no_timed_exit) {
+ timer_id = g_timeout_add_seconds (5, (GSourceFunc) gpk_dbus_service_check_idle_cb, dbus);
+ g_source_set_name_by_id (timer_id, "[GpkDbusService] timed exit");
+ }
+
+ /* wait */
+ g_main_loop_run (loop);
+out:
+ g_main_loop_unref (loop);
+ g_object_unref (dbus);
+ return retval;
+}
Index: gnome-packagekit-3.20.0/src/gpk-dbus-task.c
===================================================================
--- /dev/null
+++ gnome-packagekit-3.20.0/src/gpk-dbus-task.c
@@ -0,0 +1,3273 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2009 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include "config.h"
+
+#include <unistd.h>
+#include <string.h>
+#include <glib/gi18n.h>
+#include <glib/gprintf.h>
+#include <glib/gstdio.h>
+#include <gio/gio.h>
+
+#include <fontconfig/fontconfig.h>
+#include <gdk/gdkx.h>
+#include <gtk/gtk.h>
+#include <libnotify/notify.h>
+#include <packagekit-glib2/packagekit.h>
+
+#include "egg-string.h"
+
+#include "gpk-common.h"
+#include "gpk-dbus.h"
+#include "gpk-dbus-task.h"
+#include "gpk-dialog.h"
+#include "gpk-enum.h"
+#include "gpk-error.h"
+#include "gpk-gnome.h"
+#include "gpk-helper-chooser.h"
+#include "gpk-helper-run.h"
+#include "gpk-language.h"
+#include "gpk-modal-dialog.h"
+#include "gpk-task.h"
+#include "gpk-vendor.h"
+#include "gpk-x11.h"
+
+static void gpk_dbus_task_finalize (GObject *object);
+static void gpk_dbus_task_progress_cb (PkProgress *progress, PkProgressType type, GpkDbusTask *dtask);
+
+#define GPK_DBUS_TASK_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GPK_TYPE_DBUS_TASK, GpkDbusTaskPrivate))
+#define GPK_DBUS_TASK_FINISHED_AUTOCLOSE_DELAY 10 /* seconds */
+
+/**
+ * GpkDbusTaskPrivate:
+ *
+ * Private #GpkDbusTask data
+ **/
+struct _GpkDbusTaskPrivate
+{
+ GdkWindow *parent_window;
+ GSettings *settings;
+ PkTask *task;
+ PkControl *control;
+ PkExitEnum exit;
+ PkBitfield roles;
+ GpkLanguage *language;
+ GpkModalDialog *dialog;
+ GpkVendor *vendor;
+ gboolean show_confirm_search;
+ gboolean show_confirm_deps;
+ gboolean show_confirm_install;
+ gboolean show_progress;
+ gboolean show_finished;
+ gboolean show_warning;
+ guint timestamp;
+ gchar *parent_title;
+ gchar *parent_icon_name;
+ gchar *exec;
+ PkError *cached_error_code;
+ gint timeout;
+ GpkHelperRun *helper_run;
+ GpkHelperChooser *helper_chooser;
+ DBusGMethodInvocation *context;
+ gchar **package_ids;
+ gchar **files;
+ GCancellable *cancellable;
+ GpkDbusTaskFinishedCb finished_cb;
+ gpointer finished_userdata;
+};
+
+G_DEFINE_TYPE (GpkDbusTask, gpk_dbus_task, G_TYPE_OBJECT)
+
+/**
+ * gpk_dbus_task_set_interaction:
+ **/
+gboolean
+gpk_dbus_task_set_interaction (GpkDbusTask *dtask, PkBitfield interact)
+{
+ g_return_val_if_fail (GPK_IS_DBUS_TASK (dtask), FALSE);
+
+ dtask->priv->show_confirm_search = pk_bitfield_contain (interact, GPK_CLIENT_INTERACT_CONFIRM_SEARCH);
+ dtask->priv->show_confirm_deps = pk_bitfield_contain (interact, GPK_CLIENT_INTERACT_CONFIRM_DEPS);
+ dtask->priv->show_confirm_install = pk_bitfield_contain (interact, GPK_CLIENT_INTERACT_CONFIRM_INSTALL);
+ dtask->priv->show_progress = pk_bitfield_contain (interact, GPK_CLIENT_INTERACT_PROGRESS);
+ dtask->priv->show_finished = pk_bitfield_contain (interact, GPK_CLIENT_INTERACT_FINISHED);
+ dtask->priv->show_warning = pk_bitfield_contain (interact, GPK_CLIENT_INTERACT_WARNING);
+
+ /* debug */
+ g_debug ("confirm_search:%i, confirm_deps:%i, confirm_install:%i, progress:%i, finished:%i, warning:%i",
+ dtask->priv->show_confirm_search, dtask->priv->show_confirm_deps,
+ dtask->priv->show_confirm_install, dtask->priv->show_progress,
+ dtask->priv->show_finished, dtask->priv->show_warning);
+
+ return TRUE;
+}
+
+/**
+ * gpk_dbus_task_set_context:
+ **/
+gboolean
+gpk_dbus_task_set_context (GpkDbusTask *dtask, DBusGMethodInvocation *context)
+{
+ g_return_val_if_fail (GPK_IS_DBUS_TASK (dtask), FALSE);
+ g_return_val_if_fail (context != NULL, FALSE);
+
+ dtask->priv->context = context;
+ return TRUE;
+}
+
+/**
+ * gpk_dbus_task_set_xid:
+ **/
+gboolean
+gpk_dbus_task_set_xid (GpkDbusTask *dtask, guint32 xid)
+{
+ GdkDisplay *display;
+ g_return_val_if_fail (GPK_IS_DBUS_TASK (dtask), FALSE);
+
+ display = gdk_display_get_default ();
+ dtask->priv->parent_window = gdk_x11_window_foreign_new_for_display (display, xid);
+ g_debug ("parent_window=%p", dtask->priv->parent_window);
+ gpk_modal_dialog_set_parent (dtask->priv->dialog, dtask->priv->parent_window);
+ return TRUE;
+}
+
+/**
+ * gpk_dbus_task_set_timestamp:
+ **/
+gboolean
+gpk_dbus_task_set_timestamp (GpkDbusTask *dtask, guint32 timestamp)
+{
+ g_return_val_if_fail (GPK_IS_DBUS_TASK (dtask), FALSE);
+ dtask->priv->timestamp = timestamp;
+ return TRUE;
+}
+
+static void gpk_dbus_task_install_package_ids (GpkDbusTask *dtask);
+
+/**
+ * gpk_dbus_task_dbus_return_error:
+ **/
+static void
+gpk_dbus_task_dbus_return_error (GpkDbusTask *dtask, const GError *error)
+{
+ g_return_if_fail (error != NULL);
+
+ /* already sent or never setup */
+ if (dtask->priv->context == NULL) {
+ g_error ("context does not exist, cannot return: %s", error->message);
+ goto out;
+ }
+
+ /* send error */
+ g_debug ("sending async return error in response to %p: %s", dtask->priv->context, error->message);
+ dbus_g_method_return_error (dtask->priv->context, error);
+
+ /* set context NULL just in case we try to repeat */
+ dtask->priv->context = NULL;
+
+ /* do the finish callback */
+ if (dtask->priv->finished_cb)
+ dtask->priv->finished_cb (dtask, dtask->priv->finished_userdata);
+out:
+ /* we can't touch dtask now, as it might have been unreffed in the finished callback */
+ return;
+}
+
+/**
+ * gpk_dbus_task_dbus_return_value:
+ **/
+static void
+gpk_dbus_task_dbus_return_value (GpkDbusTask *dtask, gboolean ret)
+{
+ /* already sent or never setup */
+ if (dtask->priv->context == NULL) {
+ g_error ("context does not exist, cannot return %i", ret);
+ goto out;
+ }
+
+ /* send error */
+ g_debug ("sending async return in response to %p: %i", dtask->priv->context, ret);
+ dbus_g_method_return (dtask->priv->context, ret);
+
+ /* set context NULL just in case we try to repeat */
+ dtask->priv->context = NULL;
+
+ /* do the finish callback */
+ if (dtask->priv->finished_cb)
+ dtask->priv->finished_cb (dtask, dtask->priv->finished_userdata);
+out:
+ /* we can't touch dtask now, as it might have been unreffed in the finished callback */
+ return;
+}
+
+/**
+ * gpk_dbus_task_chooser_event_cb:
+ **/
+static void
+gpk_dbus_task_chooser_event_cb (GpkHelperChooser *helper_chooser, GtkResponseType type, const gchar *package_id, GpkDbusTask *dtask)
+{
+ GError *error_dbus = NULL;
+
+ /* selected nothing */
+ if (type != GTK_RESPONSE_YES || package_id == NULL) {
+
+ /* failed */
+ error_dbus = g_error_new (GPK_DBUS_ERROR, PK_ERROR_ENUM_TRANSACTION_CANCELLED, "did not choose anything to install");
+ gpk_dbus_task_dbus_return_error (dtask, error_dbus);
+ g_error_free (error_dbus);
+
+ if (dtask->priv->show_warning) {
+ gpk_modal_dialog_setup (dtask->priv->dialog, GPK_MODAL_DIALOG_PAGE_WARNING, 0);
+ /* TRANSLATORS: we failed to install */
+ gpk_modal_dialog_set_title (dtask->priv->dialog, _("Failed to install software"));
+ /* TRANSLATORS: we didn't select any applications that were returned */
+ gpk_modal_dialog_set_message (dtask->priv->dialog, _("No applications were chosen to be installed"));
+ gpk_modal_dialog_present (dtask->priv->dialog);
+ gpk_modal_dialog_run (dtask->priv->dialog);
+ }
+ goto out;
+ }
+
+ /* install this specific package */
+ dtask->priv->package_ids = pk_package_ids_from_id (package_id);
+
+ /* install these packages with deps */
+ gpk_dbus_task_install_package_ids (dtask);
+out:
+ return;
+}
+
+/**
+ * gpk_dbus_task_libnotify_cb:
+ **/
+static void
+gpk_dbus_task_libnotify_cb (NotifyNotification *notification, gchar *action, gpointer data)
+{
+ GpkDbusTask *task = GPK_DBUS_TASK (data);
+ gchar *details;
+
+ if (task->priv->cached_error_code == NULL) {
+ g_warning ("called show error with no error!");
+ return;
+ }
+ if (g_strcmp0 (action, "show-error-details") == 0) {
+ details = g_markup_escape_text (pk_error_get_details (task->priv->cached_error_code), -1);
+ /* TRANSLATORS: detailed text about the error */
+ gpk_error_dialog (_("Error details"), _("Package Manager error details"), details);
+ g_free (details);
+ } else {
+ g_warning ("unknown action id: %s", action);
+ }
+}
+
+/**
+ * gpk_dbus_task_error_msg:
+ **/
+static void
+gpk_dbus_task_error_msg (GpkDbusTask *dtask, const gchar *title, GError *error)
+{
+ GtkWindow *window;
+ /* TRANSLATORS: default fallback error -- this should never happen */
+ const gchar *message = _("Unknown error. Please refer to the detailed report and report in your distribution bug tracker.");
+ const gchar *details = NULL;
+
+ if (!dtask->priv->show_warning)
+ return;
+
+ /* setup UI */
+ gpk_modal_dialog_setup (dtask->priv->dialog, GPK_MODAL_DIALOG_PAGE_WARNING, 0);
+
+ /* print a proper error if we have it */
+ if (error != NULL) {
+ if (error->domain == GPK_DBUS_ERROR) {
+ message = gpk_error_enum_to_localised_message (error->code);
+ }
+ }
+
+ /* it's a normal UI, not a backtrace so keep in the UI */
+ if (details == NULL) {
+ gpk_modal_dialog_set_title (dtask->priv->dialog, title);
+ gpk_modal_dialog_set_message (dtask->priv->dialog, message);
+ gpk_modal_dialog_present_with_time (dtask->priv->dialog, dtask->priv->timestamp);
+ gpk_modal_dialog_run (dtask->priv->dialog);
+ return;
+ }
+
+ /* hide the main window */
+ window = gpk_modal_dialog_get_window (dtask->priv->dialog);
+ gpk_error_dialog_modal_with_time (window, title, message, details, dtask->priv->timestamp);
+}
+
+/**
+ * gpk_dbus_task_handle_error:
+ **/
+static void
+gpk_dbus_task_handle_error (GpkDbusTask *dtask, PkError *error_code)
+{
+ gboolean ret;
+ GError *error = NULL;
+ const gchar *title;
+ const gchar *message;
+ NotifyNotification *notification;
+ GtkWidget *widget;
+
+ /* ignore some errors */
+ if (pk_error_get_code (error_code) == PK_ERROR_ENUM_NO_LICENSE_AGREEMENT ||
+ pk_error_get_code (error_code) == PK_ERROR_ENUM_PROCESS_KILL ||
+ pk_error_get_code (error_code) == PK_ERROR_ENUM_TRANSACTION_CANCELLED) {
+ g_warning ("ignoring %s", pk_error_enum_to_string (pk_error_get_code (error_code)));
+ }
+
+ g_debug ("code was %s", pk_error_enum_to_string (pk_error_get_code (error_code)));
+
+ /* use a modal dialog if showing progress, else use libnotify */
+ title = gpk_error_enum_to_localised_text (pk_error_get_code (error_code));
+ message = gpk_error_enum_to_localised_message (pk_error_get_code (error_code));
+ if (dtask->priv->show_progress) {
+ widget = GTK_WIDGET (gpk_modal_dialog_get_window (dtask->priv->dialog));
+ gpk_error_dialog_modal (GTK_WINDOW (widget), title, message, pk_error_get_details (error_code));
+ return;
+ }
+
+ /* save this globally */
+ if (dtask->priv->cached_error_code != NULL)
+ g_object_unref (dtask->priv->cached_error_code);
+ dtask->priv->cached_error_code = g_object_ref (error_code);
+
+ /* do the bubble */
+ notification = notify_notification_new (title, message, NULL);
+ notify_notification_set_hint_string (notification, "desktop-entry", "gpk-application");
+ notify_notification_set_timeout (notification, 15000);
+ notify_notification_set_urgency (notification, NOTIFY_URGENCY_LOW);
+ notify_notification_add_action (notification, "show-error-details",
+ /* TRANSLATORS: button: show details about the error */
+ _("Show details"), gpk_dbus_task_libnotify_cb, dtask, NULL);
+ ret = notify_notification_show (notification, &error);
+ if (!ret) {
+ g_warning ("error: %s", error->message);
+ g_error_free (error);
+ }
+}
+
+/**
+ * gpk_dbus_task_get_code_from_gerror:
+ **/
+static gint
+gpk_dbus_task_get_code_from_gerror (const GError *error)
+{
+ gint code = PK_ERROR_ENUM_INTERNAL_ERROR;
+
+ /* already correct */
+ if (error->domain == GPK_DBUS_ERROR) {
+ code = error->code;
+ goto out;
+ }
+
+ /* not recognized */
+ if (error->domain != PK_CLIENT_ERROR) {
+ g_warning ("Not a PkClientError error code");
+ goto out;
+ }
+
+ /* PkError codes */
+ if (error->code > 0xff) {
+ code = error->code - 0xff;
+ goto out;
+ }
+
+ /* map return codes to PkError codes */
+ switch (error->code) {
+ case PK_CLIENT_ERROR_NO_TID:
+ case PK_CLIENT_ERROR_ALREADY_TID:
+ case PK_CLIENT_ERROR_ROLE_UNKNOWN:
+ case PK_CLIENT_ERROR_CANNOT_START_DAEMON:
+ case PK_CLIENT_ERROR_NOT_SUPPORTED:
+ code = PK_ERROR_ENUM_INTERNAL_ERROR;
+ break;
+ case PK_CLIENT_ERROR_INVALID_INPUT:
+ case PK_CLIENT_ERROR_INVALID_FILE:
+ case PK_CLIENT_ERROR_FAILED:
+ code = PK_ERROR_ENUM_UNKNOWN;
+ break;
+ case PK_CLIENT_ERROR_DECLINED_SIMULATION:
+ code = PK_ERROR_ENUM_TRANSACTION_CANCELLED;
+ break;
+ case PK_CLIENT_ERROR_FAILED_AUTH:
+ code = PK_ERROR_ENUM_NOT_AUTHORIZED;
+ break;
+ default:
+ break;
+ }
+out:
+ return code;
+}
+
+/**
+ * gpk_dbus_task_get_code_from_pkerror:
+ **/
+static gint
+gpk_dbus_task_get_code_from_pkerror (PkError *error_code)
+{
+ gint code = PK_ERROR_ENUM_UNKNOWN;
+
+ switch (pk_error_get_code (error_code)) {
+ case PK_ERROR_ENUM_TRANSACTION_CANCELLED:
+ code = PK_ERROR_ENUM_TRANSACTION_CANCELLED;
+ break;
+ default:
+ break;
+ }
+ return code;
+}
+
+/**
+ * gpk_dbus_task_install_packages_cb:
+ **/
+static void
+gpk_dbus_task_install_packages_cb (PkTask *task, GAsyncResult *res, GpkDbusTask *dtask)
+{
+ GError *error = NULL;
+ GError *error_dbus = NULL;
+ PkResults *results = NULL;
+ PkError *error_code = NULL;
+
+ /* get the results */
+ results = pk_task_generic_finish (task, res, &error);
+ if (results == NULL) {
+ /* TRANSLATORS: error: failed to install, detailed error follows */
+ error_dbus = g_error_new (GPK_DBUS_ERROR, gpk_dbus_task_get_code_from_gerror (error), "%s", error->message);
+ gpk_dbus_task_error_msg (dtask, _("Failed to install software"), error_dbus);
+ gpk_dbus_task_dbus_return_error (dtask, error_dbus);
+ g_error_free (error);
+ g_error_free (error_dbus);
+ goto out;
+ }
+
+ /* check error code */
+ error_code = pk_results_get_error_code (results);
+ if (error_code != NULL) {
+ g_warning ("failed to install package: %s, %s", pk_error_enum_to_string (pk_error_get_code (error_code)), pk_error_get_details (error_code));
+ error_dbus = g_error_new (GPK_DBUS_ERROR, gpk_dbus_task_get_code_from_pkerror (error_code), "%s", pk_error_get_details (error_code));
+ gpk_dbus_task_handle_error (dtask, error_code);
+ gpk_dbus_task_dbus_return_error (dtask, error_dbus);
+ g_error_free (error_dbus);
+ goto out;
+ }
+
+ /* we're done */
+ gpk_dbus_task_dbus_return_value (dtask, TRUE);
+out:
+ if (error_code != NULL)
+ g_object_unref (error_code);
+ if (results != NULL)
+ g_object_unref (results);
+}
+
+/**
+ * gpk_dbus_task_install_package_ids:
+ * @task: a valid #GpkDbusTask instance
+ **/
+static void
+gpk_dbus_task_install_package_ids (GpkDbusTask *dtask)
+{
+ GtkWindow *window;
+ gpk_modal_dialog_setup (dtask->priv->dialog, GPK_MODAL_DIALOG_PAGE_PROGRESS, GPK_MODAL_DIALOG_PACKAGE_PADDING);
+ /* TRANSLATORS: title: installing packages */
+ gpk_modal_dialog_set_title (dtask->priv->dialog, _("Installing packages"));
+ if (dtask->priv->show_progress)
+ gpk_modal_dialog_present (dtask->priv->dialog);
+
+ /* ensure parent is set */
+ window = gpk_modal_dialog_get_window (dtask->priv->dialog);
+ gpk_task_set_parent_window (GPK_TASK (dtask->priv->task), window);
+
+ /* install async */
+ pk_task_install_packages_async (dtask->priv->task, dtask->priv->package_ids, NULL,
+ (PkProgressCallback) gpk_dbus_task_progress_cb, dtask,
+ (GAsyncReadyCallback) gpk_dbus_task_install_packages_cb, dtask);
+}
+
+/**
+ * gpk_dbus_task_set_status:
+ **/
+static gboolean
+gpk_dbus_task_set_status (GpkDbusTask *dtask, PkStatusEnum status)
+{
+ g_return_val_if_fail (GPK_IS_DBUS_TASK (dtask), FALSE);
+
+ /* do we force progress? */
+ if (!dtask->priv->show_progress) {
+ if (status == PK_STATUS_ENUM_DOWNLOAD_REPOSITORY ||
+ status == PK_STATUS_ENUM_DOWNLOAD_PACKAGELIST ||
+ status == PK_STATUS_ENUM_DOWNLOAD_FILELIST ||
+ status == PK_STATUS_ENUM_DOWNLOAD_CHANGELOG ||
+ status == PK_STATUS_ENUM_DOWNLOAD_GROUP ||
+ status == PK_STATUS_ENUM_DOWNLOAD_UPDATEINFO ||
+ status == PK_STATUS_ENUM_REFRESH_CACHE) {
+ gpk_modal_dialog_setup (dtask->priv->dialog, GPK_MODAL_DIALOG_PAGE_PROGRESS, 0);
+ gpk_modal_dialog_present_with_time (dtask->priv->dialog, 0);
+ }
+ }
+
+ /* ignore */
+ if (!dtask->priv->show_progress) {
+ g_warning ("not showing progress");
+ return FALSE;
+ }
+
+ /* set icon */
+ gpk_modal_dialog_set_image_status (dtask->priv->dialog, status);
+
+ /* set label */
+ gpk_modal_dialog_set_title (dtask->priv->dialog, gpk_status_enum_to_localised_text (status));
+
+ /* spin */
+ if (status == PK_STATUS_ENUM_WAIT)
+ gpk_modal_dialog_set_percentage (dtask->priv->dialog, -1);
+
+ /* do visual stuff when finished */
+ if (status == PK_STATUS_ENUM_FINISHED) {
+ /* make insensitive */
+ gpk_modal_dialog_set_allow_cancel (dtask->priv->dialog, FALSE);
+
+ /* stop spinning */
+ gpk_modal_dialog_set_percentage (dtask->priv->dialog, 100);
+ }
+ return TRUE;
+}
+
+/**
+ * gpk_dbus_task_button_close_cb:
+ **/
+static void
+gpk_dbus_task_button_close_cb (GtkWidget *widget, GpkDbusTask *dtask)
+{
+ /* close, don't abort */
+ gpk_modal_dialog_close (dtask->priv->dialog);
+}
+
+/**
+ * gpk_dbus_task_button_cancel_cb:
+ **/
+static void
+gpk_dbus_task_button_cancel_cb (GtkWidget *widget, GpkDbusTask *dtask)
+{
+ /* we might have a transaction running */
+ g_cancellable_cancel (dtask->priv->cancellable);
+}
+
+/**
+ * gpk_dbus_task_install_files_cb:
+ **/
+static void
+gpk_dbus_task_install_files_cb (PkTask *task, GAsyncResult *res, GpkDbusTask *dtask)
+{
+ GError *error = NULL;
+ GError *error_dbus = NULL;
+ PkResults *results = NULL;
+ guint length;
+ const gchar *title;
+ PkError *error_code = NULL;
+
+ /* get the results */
+ results = pk_task_generic_finish (task, res, &error);
+ if (results == NULL) {
+ /* TRANSLATORS: error: failed to install, detailed error follows */
+ length = g_strv_length (dtask->priv->files);
+ title = ngettext ("Failed to install file", "Failed to install files", length);
+ error_dbus = g_error_new (GPK_DBUS_ERROR, gpk_dbus_task_get_code_from_gerror (error), "%s", error->message);
+ gpk_dbus_task_error_msg (dtask, title, error_dbus);
+ gpk_dbus_task_dbus_return_error (dtask, error_dbus);
+ g_error_free (error);
+ g_error_free (error_dbus);
+ goto out;
+ }
+
+ /* check error code */
+ error_code = pk_results_get_error_code (results);
+ if (error_code != NULL) {
+ g_warning ("failed to install file: %s, %s",
+ pk_error_enum_to_string (pk_error_get_code (error_code)),
+ pk_error_get_details (error_code));
+ gpk_dbus_task_handle_error (dtask, error_code);
+ error_dbus = g_error_new (GPK_DBUS_ERROR,
+ gpk_dbus_task_get_code_from_pkerror (error_code),
+ "failed to install file: %s",
+ pk_error_get_details (error_code));
+ gpk_dbus_task_dbus_return_error (dtask, error_dbus);
+ g_error_free (error_dbus);
+ goto out;
+ }
+
+ /* we're done */
+ gpk_dbus_task_dbus_return_value (dtask, TRUE);
+out:
+ if (error_code != NULL)
+ g_object_unref (error_code);
+ if (results != NULL)
+ g_object_unref (results);
+}
+
+/**
+ * gpk_dbus_task_ptr_array_to_bullets:
+ *
+ * splits the strings up nicely
+ *
+ * Return value: a newly allocated string
+ **/
+static gchar *
+gpk_dbus_task_ptr_array_to_bullets (GPtrArray *array, const gchar *prefix)
+{
+ GString *string;
+ guint i;
+ gchar *text;
+
+ /* don't use a bullet for one item */
+ if (array->len == 1) {
+ if (prefix != NULL)
+ return g_strdup_printf ("%s\n\n%s", prefix, (const gchar *) g_ptr_array_index (array, 0));
+ else
+ return g_strdup (g_ptr_array_index (array, 0));
+ }
+
+ string = g_string_new (prefix);
+ if (prefix != NULL)
+ g_string_append (string, "\n\n");
+
+ /* prefix with bullet and suffix with newline */
+ for (i=0; i<array->len; i++) {
+ text = (gchar *) g_ptr_array_index (array, i);
+ g_string_append_printf (string, "• %s\n", text);
+ }
+
+ /* remove last \n */
+ g_string_set_size (string, string->len - 1);
+
+ text = g_string_free (string, FALSE);
+ return text;
+}
+
+/**
+ * gpk_dbus_task_install_package_files_verify:
+ *
+ * Allow the user to confirm the action
+ *
+ * Return value: %TRUE if the method succeeded
+ **/
+static gboolean
+gpk_dbus_task_install_package_files_verify (GpkDbusTask *dtask, GPtrArray *array, GError **error)
+{
+ GtkResponseType button;
+ const gchar *title;
+ gchar *message;
+ gboolean ret = TRUE;
+
+ /* TRANSLATORS: title: confirm the user want's to install a local file */
+ title = ngettext ("Do you want to install this file?",
+ "Do you want to install these files?", array->len);
+ message = gpk_dbus_task_ptr_array_to_bullets (array, NULL);
+
+ /* show UI */
+ gpk_modal_dialog_setup (dtask->priv->dialog, GPK_MODAL_DIALOG_PAGE_CONFIRM, 0);
+ gpk_modal_dialog_set_title (dtask->priv->dialog, title);
+ gpk_modal_dialog_set_message (dtask->priv->dialog, message);
+ /* TRANSLATORS: title: installing local files */
+ gpk_modal_dialog_set_action (dtask->priv->dialog, _("Install"));
+ gpk_modal_dialog_present_with_time (dtask->priv->dialog, dtask->priv->timestamp);
+ button = gpk_modal_dialog_run (dtask->priv->dialog);
+ g_free (message);
+
+ /* did we click no or exit the window? */
+ if (button != GTK_RESPONSE_OK) {
+ g_set_error_literal (error, GPK_DBUS_ERROR, PK_ERROR_ENUM_TRANSACTION_CANCELLED, "Aborted");
+ ret = FALSE;
+ goto out;
+ }
+out:
+ return ret;
+}
+
+/**
+ * gpk_dbus_task_confirm_action:
+ * @task: a valid #GpkDbusTask instance
+ **/
+static gboolean
+gpk_dbus_task_confirm_action (GpkDbusTask *dtask, const gchar *title, const gchar *message, const gchar *action)
+{
+ GtkResponseType button;
+
+ /* check the user wanted to call this method */
+ if (!dtask->priv->show_confirm_search)
+ return TRUE;
+
+ /* setup UI */
+ gpk_modal_dialog_setup (dtask->priv->dialog, GPK_MODAL_DIALOG_PAGE_CONFIRM, 0);
+ gpk_modal_dialog_set_action (dtask->priv->dialog, action);
+
+ /* set icon */
+ if (dtask->priv->parent_icon_name != NULL)
+ gpk_modal_dialog_set_image (dtask->priv->dialog, dtask->priv->parent_icon_name);
+ else
+ gpk_modal_dialog_set_image (dtask->priv->dialog, "emblem-system");
+
+ gpk_modal_dialog_set_title (dtask->priv->dialog, title);
+ gpk_modal_dialog_set_message (dtask->priv->dialog, message);
+ gpk_modal_dialog_present_with_time (dtask->priv->dialog, dtask->priv->timestamp);
+ button = gpk_modal_dialog_run (dtask->priv->dialog);
+
+ /* close, we're going to fail the method */
+ if (button != GTK_RESPONSE_OK) {
+ gpk_modal_dialog_close (dtask->priv->dialog);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/**
+ * gpk_dbus_task_progress_cb:
+ **/
+static void
+gpk_dbus_task_progress_cb (PkProgress *progress, PkProgressType type, GpkDbusTask *dtask)
+{
+ gboolean allow_cancel;
+ gint percentage;
+ guint remaining_time;
+ PkStatusEnum status;
+ gchar *package_id = NULL;
+ gchar *text;
+
+ /* optimise */
+ if (!dtask->priv->show_progress)
+ goto out;
+
+ g_object_get (progress,
+ "allow-cancel", &allow_cancel,
+ "percentage", &percentage,
+ "remaining-time", &remaining_time,
+ "status", &status,
+ "package-id", &package_id,
+ NULL);
+
+ if (type == PK_PROGRESS_TYPE_PACKAGE_ID) {
+ g_debug ("_package");
+ } else if (type == PK_PROGRESS_TYPE_PERCENTAGE) {
+ gpk_modal_dialog_set_percentage (dtask->priv->dialog, percentage);
+ } else if (type == PK_PROGRESS_TYPE_ALLOW_CANCEL) {
+ gpk_modal_dialog_set_allow_cancel (dtask->priv->dialog, allow_cancel);
+ } else if (type == PK_PROGRESS_TYPE_STATUS) {
+ gpk_dbus_task_set_status (dtask, status);
+
+ if (status == PK_STATUS_ENUM_FINISHED) {
+ /* stop spinning */
+ gpk_modal_dialog_set_percentage (dtask->priv->dialog, 100);
+ }
+ } else if (type == PK_PROGRESS_TYPE_REMAINING_TIME) {
+ gpk_modal_dialog_set_remaining (dtask->priv->dialog, remaining_time);
+ } else if (type == PK_PROGRESS_TYPE_PACKAGE_ID) {
+ text = gpk_package_id_format_twoline (NULL, package_id, NULL); //TODO: need summary
+ gpk_modal_dialog_set_message (dtask->priv->dialog, text);
+ g_free (text);
+ }
+out:
+ g_free (package_id);
+}
+
+/**
+ * gpk_dbus_task_is_installed_resolve_cb:
+ **/
+static void
+gpk_dbus_task_is_installed_resolve_cb (PkClient *client, GAsyncResult *res, GpkDbusTask *dtask)
+{
+ GError *error = NULL;
+ GError *error_dbus = NULL;
+ PkResults *results = NULL;
+ GPtrArray *array = NULL;
+ gboolean ret;
+ PkError *error_code = NULL;
+
+ /* get the results */
+ results = pk_client_generic_finish (client, res, &error);
+ if (results == NULL) {
+ error_dbus = g_error_new (GPK_DBUS_ERROR, gpk_dbus_task_get_code_from_gerror (error), "failed to resolve: %s", error->message);
+ gpk_dbus_task_dbus_return_error (dtask, error_dbus);
+ g_warning ("failed to resolve: %s", error->message);
+ g_error_free (error);
+ goto out;
+ }
+
+ /* check error code */
+ error_code = pk_results_get_error_code (results);
+ if (error_code != NULL) {
+ g_warning ("failed to resolve: %s, %s", pk_error_enum_to_string (pk_error_get_code (error_code)), pk_error_get_details (error_code));
+ error_dbus = g_error_new (GPK_DBUS_ERROR, gpk_dbus_task_get_code_from_pkerror (error_code), "failed to resolve: %s", pk_error_get_details (error_code));
+ gpk_dbus_task_dbus_return_error (dtask, error_dbus);
+ g_error_free (error_dbus);
+ goto out;
+ }
+
+ /* get results */
+ array = pk_results_get_package_array (results);
+ ret = (array->len > 0);
+ gpk_dbus_task_dbus_return_value (dtask, ret);
+out:
+ if (error_code != NULL)
+ g_object_unref (error_code);
+ if (array != NULL)
+ g_ptr_array_unref (array);
+ if (results != NULL)
+ g_object_unref (results);
+}
+
+/**
+ * gpk_dbus_task_is_installed:
+ **/
+void
+gpk_dbus_task_is_installed (GpkDbusTask *dtask, const gchar *package_name, GpkDbusTaskFinishedCb finished_cb, gpointer userdata)
+{
+ gchar **package_names = NULL;
+
+ g_return_if_fail (GPK_IS_DBUS_TASK (dtask));
+ g_return_if_fail (package_name != NULL);
+
+ /* save callback information */
+ dtask->priv->finished_cb = finished_cb;
+ dtask->priv->finished_userdata = userdata;
+
+ /* get the package list for the installed packages */
+ package_names = g_strsplit (package_name, "|", 1);
+ pk_client_resolve_async (PK_CLIENT(dtask->priv->task), pk_bitfield_value (PK_FILTER_ENUM_INSTALLED), package_names, NULL,
+ (PkProgressCallback) gpk_dbus_task_progress_cb, dtask,
+ (GAsyncReadyCallback) gpk_dbus_task_is_installed_resolve_cb, dtask);
+ g_strfreev (package_names);
+}
+
+/**
+ * gpk_dbus_task_search_file_search_file_cb:
+ **/
+static void
+gpk_dbus_task_search_file_search_file_cb (PkClient *client, GAsyncResult *res, GpkDbusTask *dtask)
+{
+ GError *error = NULL;
+ GError *error_dbus = NULL;
+ PkResults *results = NULL;
+ GPtrArray *array = NULL;
+ PkError *error_code = NULL;
+ gchar **split = NULL;
+ PkPackage *item;
+ PkInfoEnum info;
+ gchar *package_id = NULL;
+
+ /* get the results */
+ results = pk_client_generic_finish (client, res, &error);
+ if (results == NULL) {
+ error_dbus = g_error_new (GPK_DBUS_ERROR, gpk_dbus_task_get_code_from_gerror (error), "failed to search file: %s", error->message);
+ gpk_dbus_task_dbus_return_error (dtask, error_dbus);
+ g_warning ("failed to resolve: %s", error->message);
+ g_error_free (error);
+ g_error_free (error_dbus);
+ goto out;
+ }
+
+ /* check error code */
+ error_code = pk_results_get_error_code (results);
+ if (error_code != NULL) {
+ g_warning ("failed to resolve: %s, %s", pk_error_enum_to_string (pk_error_get_code (error_code)), pk_error_get_details (error_code));
+ error_dbus = g_error_new (GPK_DBUS_ERROR, gpk_dbus_task_get_code_from_pkerror (error_code), "failed to search file: %s", pk_error_get_details (error_code));
+ gpk_dbus_task_dbus_return_error (dtask, error_dbus);
+ g_error_free (error_dbus);
+ goto out;
+ }
+
+ /* get results */
+ array = pk_results_get_package_array (results);
+ if (array->len == 0) {
+ g_warning ("no packages");
+ error_dbus = g_error_new (GPK_DBUS_ERROR, PK_ERROR_ENUM_UNKNOWN, "failed to find any packages");
+ gpk_dbus_task_dbus_return_error (dtask, error_dbus);
+ g_error_free (error_dbus);
+ goto out;
+ }
+
+ /* get first item */
+ item = g_ptr_array_index (array, 0);
+ g_object_get (item,
+ "info", &info,
+ "package-id", &package_id,
+ NULL);
+ split = pk_package_id_split (package_id);
+
+ /* send error */
+ g_debug ("sending async return in response to %p", dtask->priv->context);
+ dbus_g_method_return (dtask->priv->context, (info == PK_INFO_ENUM_INSTALLED), split[PK_PACKAGE_ID_NAME]);
+
+ /* set context NULL just in case we try to repeat */
+ dtask->priv->context = NULL;
+out:
+ g_free (package_id);
+ g_strfreev (split);
+ if (error_code != NULL)
+ g_object_unref (error_code);
+ if (array != NULL)
+ g_ptr_array_unref (array);
+ if (results != NULL)
+ g_object_unref (results);
+}
+
+/**
+ * gpk_dbus_task_search_file:
+ **/
+void
+gpk_dbus_task_search_file (GpkDbusTask *dtask, const gchar *search_file, GpkDbusTaskFinishedCb finished_cb, gpointer userdata)
+{
+ gchar **values = NULL;
+
+ g_return_if_fail (GPK_IS_DBUS_TASK (dtask));
+ g_return_if_fail (search_file != NULL);
+
+ /* save callback information */
+ dtask->priv->finished_cb = finished_cb;
+ dtask->priv->finished_userdata = userdata;
+
+ /* get the package list for the installed packages */
+ g_debug ("package_name=%s", search_file);
+ values = g_strsplit (search_file, "&", -1);
+ pk_client_search_files_async (PK_CLIENT(dtask->priv->task), pk_bitfield_value (PK_FILTER_ENUM_NEWEST), values, NULL,
+ (PkProgressCallback) gpk_dbus_task_progress_cb, dtask,
+ (GAsyncReadyCallback) gpk_dbus_task_search_file_search_file_cb, dtask);
+ g_strfreev (values);
+}
+
+/**
+ * gpk_dbus_task_install_package_files:
+ * @task: a valid #GpkDbusTask instance
+ * @file_rel: a file such as <literal>./hal-devel-0.10.0.rpm</literal>
+ * @error: a %GError to put the error code and message in, or %NULL
+ *
+ * Install a file locally, and get the deps from the repositories.
+ * This is useful for double clicking on a .rpm or .deb file.
+ *
+ * Return value: %TRUE if the method succeeded
+ **/
+void
+gpk_dbus_task_install_package_files (GpkDbusTask *dtask, gchar **files_rel, GpkDbusTaskFinishedCb finished_cb, gpointer userdata)
+{
+ GError *error = NULL;
+ GError *error_dbus = NULL;
+ gboolean ret;
+ GPtrArray *array_basename;
+ GPtrArray *array;
+ guint len;
+ guint i;
+
+ g_return_if_fail (GPK_IS_DBUS_TASK (dtask));
+ g_return_if_fail (files_rel != NULL);
+
+ /* save callback information */
+ dtask->priv->finished_cb = finished_cb;
+ dtask->priv->finished_userdata = userdata;
+
+ /* only show the basenames */
+ array = g_ptr_array_new_with_free_func (g_free);
+ array_basename = g_ptr_array_new_with_free_func (g_free);
+ for (i = 0; files_rel[i] != NULL; i++) {
+ g_ptr_array_add (array, g_strdup (files_rel[i]));
+ g_ptr_array_add (array_basename, g_path_get_basename (files_rel[i]));
+ }
+
+ /* check the user wanted to call this method */
+ if (dtask->priv->show_confirm_search) {
+ ret = gpk_dbus_task_install_package_files_verify (dtask, array_basename, &error);
+ if (!ret) {
+ error_dbus = g_error_new (GPK_DBUS_ERROR, gpk_dbus_task_get_code_from_gerror (error), "failed to verify files: %s", error->message);
+ gpk_dbus_task_dbus_return_error (dtask, error_dbus);
+ g_error_free (error);
+ g_error_free (error_dbus);
+ goto out;
+ }
+ }
+
+ /* check for deps */
+ dtask->priv->files = pk_ptr_array_to_strv (array);
+
+ gpk_modal_dialog_setup (dtask->priv->dialog, GPK_MODAL_DIALOG_PAGE_PROGRESS, 0);
+ len = g_strv_length (dtask->priv->files);
+ /* TRANSLATORS: title: installing a local file */
+ gpk_modal_dialog_set_title (dtask->priv->dialog, ngettext ("Install local file", "Install local files", len));
+ if (dtask->priv->show_progress)
+ gpk_modal_dialog_present_with_time (dtask->priv->dialog, dtask->priv->timestamp);
+
+ /* install async */
+ pk_task_install_files_async (dtask->priv->task, dtask->priv->files, NULL,
+ (PkProgressCallback) gpk_dbus_task_progress_cb, dtask,
+ (GAsyncReadyCallback) gpk_dbus_task_install_files_cb, dtask);
+
+ /* wait for async reply */
+out:
+ g_ptr_array_unref (array);
+ g_ptr_array_unref (array_basename);
+}
+
+/**
+ * gpk_dbus_task_install_package_names_resolve_cb:
+ **/
+static void
+gpk_dbus_task_install_package_names_resolve_cb (PkTask *task, GAsyncResult *res, GpkDbusTask *dtask, GpkDbusTaskFinishedCb finished_cb, gpointer userdata)
+{
+ GError *error = NULL;
+ GError *error_dbus = NULL;
+ PkResults *results = NULL;
+ GPtrArray *array = NULL;
+ PkError *error_code = NULL;
+ gchar *package_id = NULL;
+ gchar *title;
+ gchar *info_url;
+ PkPackage *item;
+ GtkResponseType button;
+ guint i;
+ gboolean already_installed = FALSE;
+ PkInfoEnum info;
+ gchar *package_id_tmp = NULL;
+
+ /* get the results */
+ results = pk_task_generic_finish (task, res, &error);
+ if (results == NULL) {
+ error_dbus = g_error_new (GPK_DBUS_ERROR, gpk_dbus_task_get_code_from_gerror (error), "failed to resolve: %s", error->message);
+ gpk_dbus_task_dbus_return_error (dtask, error_dbus);
+ g_error_free (error);
+ g_error_free (error_dbus);
+ goto out;
+ }
+
+ /* check error code */
+ error_code = pk_results_get_error_code (results);
+ if (error_code != NULL) {
+ error_dbus = g_error_new (GPK_DBUS_ERROR, gpk_dbus_task_get_code_from_pkerror (error_code), "failed to resolve: %s", pk_error_get_details (error_code));
+ gpk_dbus_task_dbus_return_error (dtask, error_dbus);
+ g_error_free (error_dbus);
+ goto out;
+ }
+
+ /* found nothing? */
+ array = pk_results_get_package_array (results);
+ if (array->len == 0) {
+ if (!dtask->priv->show_warning) {
+ /* TRANSLATORS: couldn't resolve name to package */
+ title = g_strdup_printf (_("Could not find packages"));
+ info_url = gpk_vendor_get_not_found_url (dtask->priv->vendor, GPK_VENDOR_URL_TYPE_DEFAULT);
+ /* only show the "more info" button if there is a valid link */
+ if (info_url != NULL)
+ gpk_modal_dialog_setup (dtask->priv->dialog, GPK_MODAL_DIALOG_PAGE_WARNING, GPK_MODAL_DIALOG_BUTTON_ACTION);
+ else
+ gpk_modal_dialog_setup (dtask->priv->dialog, GPK_MODAL_DIALOG_PAGE_WARNING, 0);
+ gpk_modal_dialog_set_title (dtask->priv->dialog, title);
+ /* TRANSLATORS: message: could not find */
+ gpk_modal_dialog_set_message (dtask->priv->dialog, _("The packages could not be found in any package source"));
+ /* TRANSLATORS: button: a link to the help file */
+ gpk_modal_dialog_set_action (dtask->priv->dialog, _("More information"));
+ gpk_modal_dialog_present (dtask->priv->dialog);
+ button = gpk_modal_dialog_run (dtask->priv->dialog);
+ if (button == GTK_RESPONSE_OK)
+ gpk_gnome_open (info_url);
+ g_free (info_url);
+ g_free (title);
+ }
+ error_dbus = g_error_new (GPK_DBUS_ERROR, PK_ERROR_ENUM_PACKAGE_NOT_FOUND, "no package found");
+ gpk_dbus_task_dbus_return_error (dtask, error_dbus);
+ g_error_free (error_dbus);
+ goto out;
+ }
+
+ /* see what we've got already */
+ for (i=0; i<array->len; i++) {
+ item = g_ptr_array_index (array, i);
+ g_object_get (item,
+ "info", &info,
+ "package-id", &package_id_tmp,
+ NULL);
+ if (info == PK_INFO_ENUM_INSTALLED) {
+ already_installed = TRUE;
+ } else if (info == PK_INFO_ENUM_AVAILABLE) {
+ g_debug ("package '%s' resolved", package_id_tmp);
+ package_id = g_strdup (package_id_tmp);
+ //TODO: we need to list these in a gpk-dbus_task-chooser
+ }
+ g_free (package_id_tmp);
+ }
+
+ /* already installed? */
+ if (already_installed) {
+ if (dtask->priv->show_warning) {
+ gpk_modal_dialog_setup (dtask->priv->dialog, GPK_MODAL_DIALOG_PAGE_FINISHED, 0);
+ /* TRANSLATORS: title: package is already installed */
+ gpk_modal_dialog_set_title (dtask->priv->dialog,
+ ngettext ("The package is already installed",
+ "The packages are already installed",
+ g_strv_length (dtask->priv->package_ids)));
+ /* TRANSLATORS: message: package is already installed */
+ gpk_modal_dialog_set_message (dtask->priv->dialog, _("Nothing to do."));
+ gpk_modal_dialog_present (dtask->priv->dialog);
+ gpk_modal_dialog_run (dtask->priv->dialog);
+ }
+ error_dbus = g_error_new (GPK_DBUS_ERROR, PK_ERROR_ENUM_UNKNOWN, "package already found");
+ gpk_dbus_task_dbus_return_error (dtask, error_dbus);
+ g_error_free (error_dbus);
+ goto out;
+ }
+
+ /* got junk? */
+ if (package_id == NULL) {
+ if (dtask->priv->show_warning) {
+ gpk_modal_dialog_setup (dtask->priv->dialog, GPK_MODAL_DIALOG_PAGE_WARNING, 0);
+ /* TRANSLATORS: failed to install, shouldn't be shown */
+ gpk_modal_dialog_set_title (dtask->priv->dialog, _("Failed to install package"));
+ /* TRANSLATORS: the search gave us the wrong result. internal error. barf. */
+ gpk_modal_dialog_set_message (dtask->priv->dialog, _("Incorrect response from search"));
+ gpk_modal_dialog_present (dtask->priv->dialog);
+ gpk_modal_dialog_run (dtask->priv->dialog);
+ }
+ error_dbus = g_error_new (GPK_DBUS_ERROR, PK_ERROR_ENUM_UNKNOWN, "incorrect response from search");
+ gpk_dbus_task_dbus_return_error (dtask, error_dbus);
+ g_error_free (error_dbus);
+ goto out;
+ }
+
+ /* convert to data */
+ dtask->priv->package_ids = pk_package_array_to_strv (array);
+
+ /* install these packages with deps */
+ gpk_dbus_task_install_package_ids (dtask);
+out:
+ g_free (package_id);
+ if (error_code != NULL)
+ g_object_unref (error_code);
+ if (array != NULL)
+ g_ptr_array_unref (array);
+ if (results != NULL)
+ g_object_unref (results);
+}
+
+/**
+ * gpk_dbus_task_install_package_names:
+ * @task: a valid #GpkDbusTask instance
+ * @package: a pakage name such as <literal>hal-info</literal>
+ * @error: a %GError to put the error code and message in, or %NULL
+ *
+ * Install a package of the newest and most correct version.
+ *
+ * Return value: %TRUE if the method succeeded
+ **/
+void
+gpk_dbus_task_install_package_names (GpkDbusTask *dtask, gchar **packages, GpkDbusTaskFinishedCb finished_cb, gpointer userdata)
+{
+ gboolean ret;
+ GError *error_dbus = NULL;
+ gchar *message;
+ gchar *text;
+ guint len;
+ guint i;
+ GString *string;
+
+ g_return_if_fail (GPK_IS_DBUS_TASK (dtask));
+ g_return_if_fail (packages != NULL);
+
+ /* save callback information */
+ dtask->priv->finished_cb = finished_cb;
+ dtask->priv->finished_userdata = userdata;
+
+ /* optional */
+ if (!dtask->priv->show_confirm_install) {
+ g_debug ("skip confirm as not allowed to interact with user");
+ goto skip_checks;
+ }
+
+ string = g_string_new ("");
+ len = g_strv_length (packages);
+ if (len == 0) {
+ gpk_dbus_task_dbus_return_value (dtask, TRUE);
+ goto out;
+ }
+
+ /* don't use a bullet for one item */
+ if (len == 1) {
+ g_string_append_printf (string, "%s\n", packages[0]);
+ } else {
+ for (i=0; i<len; i++)
+ g_string_append_printf (string, "• %s\n", packages[i]);
+ }
+ /* display messagebox */
+ text = g_string_free (string, FALSE);
+
+ /* check user wanted operation */
+ message = g_strdup_printf ("%s\n\n%s\n%s",
+ /* TRANSLATORS: a program needs a package, for instance openoffice-clipart */
+ ngettext ("An additional package is required:", "Additional packages are required:", len),
+ text,
+ /* TRANSLATORS: ask the user if it's okay to search */
+ ngettext ("Do you want to search for and install this package now?", "Do you want to search for and install these packages now?", len));
+ g_free (text);
+
+ /* make title using application name */
+ if (dtask->priv->parent_title != NULL) {
+ /* TRANSLATORS: string is a program name, e.g. "Movie Player" */
+ text = g_strdup_printf (ngettext ("%s wants to install a package", "%s wants to install packages", len), dtask->priv->parent_title);
+ } else {
+ /* TRANSLATORS: a random program which we can't get the name wants to do something */
+ text = g_strdup (ngettext ("A program wants to install a package", "A program wants to install packages", len));
+ }
+
+ /* TRANSLATORS: button: confirm to search for packages */
+ ret = gpk_dbus_task_confirm_action (dtask, text, message, _("Install"));
+ g_free (text);
+ g_free (message);
+ if (!ret) {
+ error_dbus = g_error_new (GPK_DBUS_ERROR, PK_ERROR_ENUM_TRANSACTION_CANCELLED, "did not agree to search");
+ gpk_dbus_task_dbus_return_error (dtask, error_dbus);
+ g_error_free (error_dbus);
+ goto out;
+ }
+
+skip_checks:
+ gpk_modal_dialog_setup (dtask->priv->dialog, GPK_MODAL_DIALOG_PAGE_PROGRESS, 0);
+ /* TRANSLATORS: title, searching */
+ gpk_modal_dialog_set_title (dtask->priv->dialog, _("Searching for packages"));
+ gpk_modal_dialog_set_image_status (dtask->priv->dialog, PK_STATUS_ENUM_WAIT);
+ if (dtask->priv->show_progress)
+ gpk_modal_dialog_present (dtask->priv->dialog);
+
+ /* find out if we can find a package */
+ pk_client_resolve_async (PK_CLIENT(dtask->priv->task), pk_bitfield_from_enums (PK_FILTER_ENUM_ARCH, PK_FILTER_ENUM_NEWEST, -1), packages, NULL,
+ (PkProgressCallback) gpk_dbus_task_progress_cb, dtask,
+ (GAsyncReadyCallback) gpk_dbus_task_install_package_names_resolve_cb, dtask);
+
+ /* wait for async reply */
+out:
+ return;
+}
+
+/**
+ * gpk_dbus_task_install_provide_files_search_file_cb:
+ **/
+static void
+gpk_dbus_task_install_provide_files_search_file_cb (PkClient *client, GAsyncResult *res, GpkDbusTask *dtask)
+{
+ GError *error = NULL;
+ GError *error_dbus = NULL;
+ PkResults *results = NULL;
+ GPtrArray *array = NULL;
+ PkError *error_code = NULL;
+ gchar *info_url;
+ PkPackage *item;
+ GtkResponseType button;
+ guint i;
+ gboolean already_installed = FALSE;
+ gchar *text;
+ gchar **split;
+ PkInfoEnum info;
+ gchar *package_id = NULL;
+ gchar *package_id_tmp = NULL;
+
+ /* get the results */
+ results = pk_client_generic_finish (client, res, &error);
+ if (results == NULL) {
+ error_dbus = g_error_new (GPK_DBUS_ERROR, gpk_dbus_task_get_code_from_gerror (error), "failed to resolve: %s", error->message);
+ gpk_dbus_task_dbus_return_error (dtask, error_dbus);
+ g_error_free (error);
+ g_error_free (error_dbus);
+ goto out;
+ }
+
+ /* check error code */
+ error_code = pk_results_get_error_code (results);
+ if (error_code != NULL) {
+ error_dbus = g_error_new (GPK_DBUS_ERROR, gpk_dbus_task_get_code_from_pkerror (error_code), "failed to resolve: %s", pk_error_get_details (error_code));
+ gpk_dbus_task_dbus_return_error (dtask, error_dbus);
+ g_error_free (error_dbus);
+ goto out;
+ }
+
+ /* get results */
+ array = pk_results_get_package_array (results);
+
+ /* found nothing? */
+ if (array->len == 0) {
+ if (dtask->priv->show_warning) {
+ info_url = gpk_vendor_get_not_found_url (dtask->priv->vendor, GPK_VENDOR_URL_TYPE_DEFAULT);
+ /* only show the "more info" button if there is a valid link */
+ if (info_url != NULL)
+ gpk_modal_dialog_setup (dtask->priv->dialog, GPK_MODAL_DIALOG_PAGE_WARNING, GPK_MODAL_DIALOG_BUTTON_ACTION);
+ else
+ gpk_modal_dialog_setup (dtask->priv->dialog, GPK_MODAL_DIALOG_PAGE_WARNING, 0);
+ /* TRANSLATORS: failed to fild the package for thefile */
+ gpk_modal_dialog_set_title (dtask->priv->dialog, _("Failed to find package"));
+ /* TRANSLATORS: nothing found */
+ gpk_modal_dialog_set_message (dtask->priv->dialog, _("The file could not be found in any packages"));
+ /* TRANSLATORS: button: show the user a button to get more help finding stuff */
+ gpk_modal_dialog_set_action (dtask->priv->dialog, _("More information"));
+ gpk_modal_dialog_present (dtask->priv->dialog);
+ button = gpk_modal_dialog_run (dtask->priv->dialog);
+ if (button == GTK_RESPONSE_OK)
+ gpk_gnome_open (info_url);
+ g_free (info_url);
+ }
+ error_dbus = g_error_new (GPK_DBUS_ERROR, PK_ERROR_ENUM_PACKAGE_NOT_FOUND, "no files found");
+ gpk_dbus_task_dbus_return_error (dtask, error_dbus);
+ g_error_free (error_dbus);
+ goto out;
+ }
+
+ /* see what we've got already */
+ for (i=0; i<array->len; i++) {
+ item = g_ptr_array_index (array, i);
+ g_object_get (item,
+ "info", &info,
+ "package-id", &package_id_tmp,
+ NULL);
+ if (info == PK_INFO_ENUM_INSTALLED) {
+ already_installed = TRUE;
+ package_id = g_strdup (package_id_tmp);
+ } else if (info == PK_INFO_ENUM_AVAILABLE) {
+ g_debug ("package '%s' resolved to:", package_id_tmp);
+ package_id = g_strdup (package_id_tmp);
+ }
+ g_free (package_id_tmp);
+ }
+
+ /* already installed? */
+ if (already_installed) {
+ if (dtask->priv->show_warning) {
+ split = pk_package_id_split (package_id);
+ /* TRANSLATORS: we've already got a package that provides this file */
+ text = g_strdup_printf (_("The %s package already provides this file"), split[PK_PACKAGE_ID_NAME]);
+ gpk_modal_dialog_setup (dtask->priv->dialog, GPK_MODAL_DIALOG_PAGE_WARNING, 0);
+ /* TRANSLATORS: title */
+ gpk_modal_dialog_set_title (dtask->priv->dialog, _("Failed to install file"));
+ gpk_modal_dialog_set_message (dtask->priv->dialog, text);
+ gpk_modal_dialog_present (dtask->priv->dialog);
+ gpk_modal_dialog_run (dtask->priv->dialog);
+ g_free (text);
+ g_strfreev (split);
+ }
+ error_dbus = g_error_new (GPK_DBUS_ERROR, PK_ERROR_ENUM_UNKNOWN, "already provided");
+ gpk_dbus_task_dbus_return_error (dtask, error_dbus);
+ g_error_free (error_dbus);
+ goto out;
+ }
+
+ /* convert to data */
+ dtask->priv->package_ids = pk_package_ids_from_id (package_id);
+
+ /* install these packages with deps */
+ gpk_dbus_task_install_package_ids (dtask);
+out:
+ g_free (package_id);
+ if (error_code != NULL)
+ g_object_unref (error_code);
+ if (array != NULL)
+ g_ptr_array_unref (array);
+ if (results != NULL)
+ g_object_unref (results);
+}
+
+/**
+ * gpk_dbus_task_install_provide_files:
+ * @task: a valid #GpkDbusTask instance
+ * @full_path: a file path name such as <literal>/usr/sbin/packagekitd</literal>
+ * @error: a %GError to put the error code and message in, or %NULL
+ *
+ * Install a package which provides a file on the system.
+ *
+ * Return value: %TRUE if the method succeeded
+ **/
+void
+gpk_dbus_task_install_provide_files (GpkDbusTask *dtask, gchar **full_paths, GpkDbusTaskFinishedCb finished_cb, gpointer userdata)
+{
+ gboolean ret;
+ GError *error_dbus = NULL;
+ guint len;
+ guint i;
+ gchar *text;
+ gchar *message;
+ GString *string;
+
+ g_return_if_fail (GPK_IS_DBUS_TASK (dtask));
+ g_return_if_fail (full_paths != NULL);
+
+ /* save callback information */
+ dtask->priv->finished_cb = finished_cb;
+ dtask->priv->finished_userdata = userdata;
+
+ /* optional */
+ if (!dtask->priv->show_confirm_search) {
+ g_debug ("skip confirm as not allowed to interact with user");
+ goto skip_checks;
+ }
+
+ string = g_string_new ("");
+ len = g_strv_length (full_paths);
+
+ /* don't use a bullet for one item */
+ if (len == 1) {
+ g_string_append_printf (string, "%s\n", full_paths[0]);
+ } else {
+ for (i=0; i<len; i++)
+ g_string_append_printf (string, "• %s\n", full_paths[i]);
+ }
+ /* display messagebox */
+ text = g_string_free (string, FALSE);
+
+ /* check user wanted operation */
+ message = g_strdup_printf ("%s\n\n%s\n\n%s",
+ /* TRANSLATORS: a program wants to install a file, e.g. /lib/moo.so */
+ ngettext ("The following file is required:", "The following files are required:", len),
+ text,
+ /* TRANSLATORS: confirm with the user */
+ ngettext ("Do you want to search for this file now?", "Do you want to search for these files now?", len));
+
+ /* make title using application name */
+ if (dtask->priv->parent_title != NULL) {
+ /* TRANSLATORS: string is a program name, e.g. "Movie Player" */
+ text = g_strdup_printf (ngettext ("%s wants to install a file", "%s wants to install files", len), dtask->priv->parent_title);
+ } else {
+ /* TRANSLATORS: a random program which we can't get the name wants to do something */
+ text = g_strdup (ngettext ("A program wants to install a file", "A program wants to install files", len));
+ }
+
+ /* TRANSLATORS: button: confirm to search for packages */
+ ret = gpk_dbus_task_confirm_action (dtask, text, message, _("Install"));
+ g_free (text);
+ g_free (message);
+ if (!ret) {
+ error_dbus = g_error_new (GPK_DBUS_ERROR, PK_ERROR_ENUM_TRANSACTION_CANCELLED, "did not agree to search");
+ gpk_dbus_task_dbus_return_error (dtask, error_dbus);
+ g_error_free (error_dbus);
+ goto out;
+ }
+
+skip_checks:
+ /* TRANSLATORS: searching for the package that provides the file */
+ gpk_modal_dialog_set_title (dtask->priv->dialog, _("Searching for file"));
+ gpk_modal_dialog_set_image_status (dtask->priv->dialog, PK_STATUS_ENUM_WAIT);
+
+ /* do search */
+ pk_client_search_files_async (PK_CLIENT(dtask->priv->task), pk_bitfield_from_enums (PK_FILTER_ENUM_ARCH, PK_FILTER_ENUM_NEWEST, -1), full_paths, NULL,
+ (PkProgressCallback) gpk_dbus_task_progress_cb, dtask,
+ (GAsyncReadyCallback) gpk_dbus_task_install_provide_files_search_file_cb, dtask);
+
+ /* wait for async reply */
+out:
+ return;
+}
+
+/**
+ * gpk_dbus_task_install_gstreamer_resources_confirm:
+ **/
+static gboolean
+gpk_dbus_task_install_gstreamer_resources_confirm (GpkDbusTask *dtask, gchar **codec_names)
+{
+ guint i;
+ guint len;
+ const gchar *text;
+ gchar **parts;
+ gboolean ret;
+ GString *string;
+ gchar *title;
+ gchar *message;
+ gboolean is_decoder = FALSE;
+ gboolean is_encoder = FALSE;
+
+ len = g_strv_length (codec_names);
+
+ /* find out what type of request this is */
+ for (i=0; i<len; i++) {
+ parts = g_strsplit (codec_names[i], "|", 2);
+ if (g_strstr_len (parts[1], -1, "(decoder") != NULL)
+ is_decoder = TRUE;
+ if (g_strstr_len (parts[1], -1, "(encoder") != NULL)
+ is_encoder = TRUE;
+ g_strfreev (parts);
+ }
+
+ /* TRANSLATORS: we are listing the plugins in a box */
+ text = ngettext ("The following plugin is required:", "The following plugins are required:", len);
+ string = g_string_new ("");
+ g_string_append_printf (string, "%s\n\n", text);
+
+ /* don't use a bullet for one item */
+ if (len == 1) {
+ parts = g_strsplit (codec_names[0], "|", 2);
+ g_string_append_printf (string, "%s\n", parts[0]);
+ g_strfreev (parts);
+ } else {
+ for (i=0; i<len; i++) {
+ parts = g_strsplit (codec_names[i], "|", 2);
+ g_string_append_printf (string, "• %s\n", parts[0]);
+ g_strfreev (parts);
+ }
+ }
+
+ /* TRANSLATORS: ask for confirmation */
+ message = ngettext ("Do you want to search for this now?", "Do you want to search for these now?", len);
+ g_string_append_printf (string, "\n%s\n", message);
+
+ /* remove last \n */
+ g_string_set_size (string, string->len - 1);
+
+ /* display messagebox */
+ message = g_string_free (string, FALSE);
+
+ /* make title using application name */
+ if (dtask->priv->parent_title != NULL) {
+ if (is_decoder && !is_encoder) {
+ /* TRANSLATORS: a program wants to decode something (unknown) -- string is a program name, e.g. "Movie Player" */
+ title = g_strdup_printf (ngettext ("%s requires an additional plugin to decode this file",
+ "%s requires additional plugins to decode this file", len), dtask->priv->parent_title);
+ } else if (!is_decoder && is_encoder) {
+ /* TRANSLATORS: a program wants to encode something (unknown) -- string is a program name, e.g. "Movie Player" */
+ title = g_strdup_printf (ngettext ("%s requires an additional plugin to encode this file",
+ "%s requires additional plugins to encode this file", len), dtask->priv->parent_title);
+ } else {
+ /* TRANSLATORS: a program wants to do something (unknown) -- string is a program name, e.g. "Movie Player" */
+ title = g_strdup_printf (ngettext ("%s requires an additional plugin for this operation",
+ "%s requires additional plugins for this operation", len), dtask->priv->parent_title);
+ }
+ } else {
+ if (is_decoder && !is_encoder) {
+ /* TRANSLATORS: a random program which we can't get the name wants to decode something */
+ title = g_strdup (ngettext ("A program requires an additional plugin to decode this file",
+ "A program requires additional plugins to decode this file", len));
+ } else if (!is_decoder && is_encoder) {
+ /* TRANSLATORS: a random program which we can't get the name wants to encode something */
+ title = g_strdup (ngettext ("A program requires an additional plugin to encode this file",
+ "A program requires additional plugins to encode this file", len));
+ } else {
+ /* TRANSLATORS: a random program which we can't get the name wants to do something (unknown) */
+ title = g_strdup (ngettext ("A program requires an additional plugin for this operation",
+ "A program requires additional plugins for this operation", len));
+ }
+ }
+
+ /* TRANSLATORS: button: confirm to search for packages */
+ ret = gpk_dbus_task_confirm_action (dtask, title, message, _("Search"));
+ g_free (title);
+ g_free (message);
+
+ return ret;
+}
+
+/**
+ * gpk_dbus_task_codec_what_provides_cb:
+ **/
+static void
+gpk_dbus_task_codec_what_provides_cb (PkClient *client, GAsyncResult *res, GpkDbusTask *dtask)
+{
+ GError *error = NULL;
+ GError *error_dbus = NULL;
+ PkResults *results = NULL;
+ GPtrArray *array = NULL;
+ PkError *error_code = NULL;
+ GtkResponseType button;
+ gchar *info_url;
+ const gchar *title;
+ const gchar *message;
+
+ /* get the results */
+ results = pk_client_generic_finish (client, res, &error);
+ if (results == NULL) {
+ error_dbus = g_error_new (GPK_DBUS_ERROR, gpk_dbus_task_get_code_from_gerror (error), "failed to resolve: %s", error->message);
+ gpk_dbus_task_dbus_return_error (dtask, error_dbus);
+ g_error_free (error);
+ g_error_free (error_dbus);
+ goto out;
+ }
+
+ /* check error code */
+ error_code = pk_results_get_error_code (results);
+ if (error_code != NULL) {
+ error_dbus = g_error_new (GPK_DBUS_ERROR, gpk_dbus_task_get_code_from_pkerror (error_code), "failed to resolve: %s", pk_error_get_details (error_code));
+ gpk_dbus_task_dbus_return_error (dtask, error_dbus);
+ g_error_free (error_dbus);
+ goto out;
+ }
+
+ /* get results */
+ array = pk_results_get_package_array (results);
+
+ /* found nothing? */
+ if (array->len == 0) {
+ if (dtask->priv->show_warning) {
+ info_url = gpk_vendor_get_not_found_url (dtask->priv->vendor, GPK_VENDOR_URL_TYPE_CODEC);
+ /* only show the "more info" button if there is a valid link */
+ if (info_url != NULL)
+ gpk_modal_dialog_setup (dtask->priv->dialog, GPK_MODAL_DIALOG_PAGE_WARNING, GPK_MODAL_DIALOG_BUTTON_ACTION);
+ else
+ gpk_modal_dialog_setup (dtask->priv->dialog, GPK_MODAL_DIALOG_PAGE_WARNING, 0);
+ /* TRANSLATORS: failed to search for codec */
+ gpk_modal_dialog_set_title (dtask->priv->dialog, _("Failed to search for plugin"));
+ /* TRANSLATORS: no package sources have the wanted codec */
+ gpk_modal_dialog_set_message (dtask->priv->dialog, _("Could not find plugin in any configured package source"));
+
+ /* TRANSLATORS: button text */
+ gpk_modal_dialog_set_action (dtask->priv->dialog, _("More information"));
+ gpk_modal_dialog_present (dtask->priv->dialog);
+ button = gpk_modal_dialog_run (dtask->priv->dialog);
+ if (button == GTK_RESPONSE_OK)
+ gpk_gnome_open (info_url);
+ g_free (info_url);
+ }
+ error_dbus = g_error_new (GPK_DBUS_ERROR, PK_ERROR_ENUM_PACKAGE_NOT_FOUND, "failed to find codec");
+ gpk_dbus_task_dbus_return_error (dtask, error_dbus);
+ g_error_free (error_dbus);
+ goto out;
+ }
+
+ /* optional */
+ if (!dtask->priv->show_confirm_install) {
+ g_debug ("skip confirm as not allowed to interact with user");
+ goto skip_checks2;
+ }
+
+ title = ngettext ("Install the following plugin", "Install the following plugins", array->len);
+ message = ngettext ("Do you want to install this package now?", "Do you want to install these packages now?", array->len);
+
+ gpk_modal_dialog_setup (dtask->priv->dialog, GPK_MODAL_DIALOG_PAGE_CONFIRM, GPK_MODAL_DIALOG_PACKAGE_LIST);
+ gpk_modal_dialog_set_package_list (dtask->priv->dialog, array);
+ gpk_modal_dialog_set_title (dtask->priv->dialog, title);
+ gpk_modal_dialog_set_message (dtask->priv->dialog, message);
+ gpk_modal_dialog_set_image (dtask->priv->dialog, "dialog-information");
+ /* TRANSLATORS: button: install codecs */
+ gpk_modal_dialog_set_action (dtask->priv->dialog, _("Install"));
+ gpk_modal_dialog_present_with_time (dtask->priv->dialog, dtask->priv->timestamp);
+ button = gpk_modal_dialog_run (dtask->priv->dialog);
+
+ /* close, we're going to fail the method */
+ if (button != GTK_RESPONSE_OK) {
+ gpk_modal_dialog_close (dtask->priv->dialog);
+ error_dbus = g_error_new (GPK_DBUS_ERROR, PK_ERROR_ENUM_TRANSACTION_CANCELLED, "did not agree to download");
+ gpk_dbus_task_dbus_return_error (dtask, error_dbus);
+ g_error_free (error_dbus);
+ goto out;
+ }
+
+skip_checks2:
+ /* install with deps */
+ dtask->priv->package_ids = pk_package_array_to_strv (array);
+ gpk_dbus_task_install_package_ids (dtask);
+out:
+ if (error_code != NULL)
+ g_object_unref (error_code);
+ if (array != NULL)
+ g_ptr_array_unref (array);
+ if (results != NULL)
+ g_object_unref (results);
+}
+
+/**
+ * gpk_dbus_task_install_gstreamer_resources:
+ * @task: a valid #GpkDbusTask instance
+ * @codecs: a codec_type such as <literal>application/text</literal>
+ * @error: a %GError to put the error code and message in, or %NULL
+ *
+ * Install a application to handle a gstreamer request
+ *
+ * Return value: %TRUE if the method succeeded
+ **/
+void
+gpk_dbus_task_install_gstreamer_resources (GpkDbusTask *dtask, gchar **codec_names, GpkDbusTaskFinishedCb finished_cb, gpointer userdata)
+{
+ gboolean ret = TRUE;
+ GError *error_dbus = NULL;
+ gchar **parts = NULL;
+ gchar *message = NULL;
+ GPtrArray *array_title = NULL;
+ GPtrArray *array_search = NULL;
+ gchar **search = NULL;
+ gchar **title = NULL;
+ gchar *title_str = NULL;
+ guint i;
+
+ g_return_if_fail (GPK_IS_DBUS_TASK (dtask));
+ g_return_if_fail (codec_names != NULL);
+
+ /* save callback information */
+ dtask->priv->finished_cb = finished_cb;
+ dtask->priv->finished_userdata = userdata;
+
+ /* check it's not session wide banned */
+ ret = g_settings_get_boolean (dtask->priv->settings, GPK_SETTINGS_ENABLE_CODEC_HELPER);
+ if (!ret) {
+ error_dbus = g_error_new (GPK_DBUS_ERROR, PK_ERROR_ENUM_NOT_AUTHORIZED, "not enabled in GSettings : %s", GPK_SETTINGS_ENABLE_CODEC_HELPER);
+ gpk_dbus_task_dbus_return_error (dtask, error_dbus);
+ g_error_free (error_dbus);
+ goto out;
+ }
+
+ /* optional */
+ if (!dtask->priv->show_confirm_search) {
+ g_debug ("skip confirm as not allowed to interact with user");
+ goto skip_checks;
+ }
+
+ /* confirm */
+ ret = gpk_dbus_task_install_gstreamer_resources_confirm (dtask, codec_names);
+ if (!ret) {
+ error_dbus = g_error_new (GPK_DBUS_ERROR, PK_ERROR_ENUM_TRANSACTION_CANCELLED, "did not agree to search");
+ gpk_dbus_task_dbus_return_error (dtask, error_dbus);
+ g_error_free (error_dbus);
+ goto out;
+ }
+
+skip_checks:
+ gpk_modal_dialog_setup (dtask->priv->dialog, GPK_MODAL_DIALOG_PAGE_PROGRESS, GPK_MODAL_DIALOG_PACKAGE_PADDING);
+ /* TRANSLATORS: search for codec */
+ gpk_modal_dialog_set_title (dtask->priv->dialog, _("Searching for plugins"));
+ gpk_modal_dialog_set_image_status (dtask->priv->dialog, PK_STATUS_ENUM_WAIT);
+
+ /* setup the UI */
+ if (dtask->priv->show_progress)
+ gpk_modal_dialog_present (dtask->priv->dialog);
+
+ /* get the request */
+ array_title = g_ptr_array_new_with_free_func (g_free);
+ array_search = g_ptr_array_new_with_free_func (g_free);
+ for (i=0; codec_names[i] != NULL; i++) {
+ parts = g_strsplit (codec_names[i], "|", 2);
+ g_ptr_array_add (array_title, g_strdup (parts[0]));
+ g_ptr_array_add (array_search, g_strdup (parts[1]));
+ g_strfreev (parts);
+ }
+
+ /* TRANSLATORS: title, searching for codecs */
+ title = pk_ptr_array_to_strv (array_title);
+ title_str = g_strjoinv (", ", title);
+ message = g_strdup_printf (_("Searching for plugin: %s"), title_str);
+ gpk_modal_dialog_set_message (dtask->priv->dialog, message);
+
+ /* get codec packages */
+ search = pk_ptr_array_to_strv (array_search);
+ pk_client_what_provides_async (PK_CLIENT(dtask->priv->task), pk_bitfield_from_enums (PK_FILTER_ENUM_NOT_INSTALLED, PK_FILTER_ENUM_ARCH, PK_FILTER_ENUM_NEWEST, -1),
+#if PK_CHECK_VERSION(0,9,0)
+ search, NULL,
+#else
+ PK_PROVIDES_ENUM_CODEC, search, NULL,
+#endif
+ (PkProgressCallback) gpk_dbus_task_progress_cb, dtask,
+ (GAsyncReadyCallback) gpk_dbus_task_codec_what_provides_cb, dtask);
+out:
+ if (array_title != NULL)
+ g_ptr_array_unref (array_title);
+ if (array_search != NULL)
+ g_ptr_array_unref (array_search);
+ g_strfreev (search);
+ g_strfreev (title);
+ g_free (message);
+ g_free (title_str);
+}
+
+/**
+ * gpk_dbus_task_mime_what_provides_cb:
+ **/
+static void
+gpk_dbus_task_mime_what_provides_cb (PkClient *client, GAsyncResult *res, GpkDbusTask *dtask)
+{
+ GError *error = NULL;
+ GError *error_dbus = NULL;
+ PkResults *results = NULL;
+ GPtrArray *array = NULL;
+ PkError *error_code = NULL;
+ gchar *info_url;
+ GtkResponseType button;
+
+ /* get the results */
+ results = pk_client_generic_finish (client, res, &error);
+ if (results == NULL) {
+ /* TRANSLATORS: we failed to find the package, this shouldn't happen */
+ error_dbus = g_error_new (GPK_DBUS_ERROR, gpk_dbus_task_get_code_from_gerror (error), "failed to search for provides: %s", error->message);
+ gpk_dbus_task_error_msg (dtask, _("Failed to search for provides"), error_dbus);
+ gpk_dbus_task_dbus_return_error (dtask, error_dbus);
+ g_error_free (error);
+ g_error_free (error_dbus);
+ goto out;
+ }
+
+ /* check error code */
+ error_code = pk_results_get_error_code (results);
+ if (error_code != NULL) {
+ error_dbus = g_error_new (GPK_DBUS_ERROR, gpk_dbus_task_get_code_from_pkerror (error_code), "failed to search for provides: %s", pk_error_get_details (error_code));
+ gpk_dbus_task_dbus_return_error (dtask, error_dbus);
+ g_error_free (error_dbus);
+ goto out;
+ }
+
+ /* get results */
+ array = pk_results_get_package_array (results);
+
+ /* found nothing? */
+ if (array->len == 0) {
+ if (dtask->priv->show_warning) {
+ info_url = gpk_vendor_get_not_found_url (dtask->priv->vendor, GPK_VENDOR_URL_TYPE_MIME);
+ /* only show the "more info" button if there is a valid link */
+ if (info_url != NULL)
+ gpk_modal_dialog_setup (dtask->priv->dialog, GPK_MODAL_DIALOG_PAGE_WARNING, GPK_MODAL_DIALOG_BUTTON_ACTION);
+ else
+ gpk_modal_dialog_setup (dtask->priv->dialog, GPK_MODAL_DIALOG_PAGE_WARNING, 0);
+ /* TRANSLATORS: title */
+ gpk_modal_dialog_set_title (dtask->priv->dialog, _("Failed to find software"));
+ /* TRANSLATORS: nothing found in the package sources that helps */
+ gpk_modal_dialog_set_message (dtask->priv->dialog, _("No new applications can be found to handle this type of file"));
+ /* TRANSLATORS: button: show the user a button to get more help finding stuff */
+ gpk_modal_dialog_set_action (dtask->priv->dialog, _("More information"));
+ gpk_modal_dialog_present (dtask->priv->dialog);
+ button = gpk_modal_dialog_run (dtask->priv->dialog);
+ if (button == GTK_RESPONSE_OK)
+ gpk_gnome_open (info_url);
+ g_free (info_url);
+ }
+ error_dbus = g_error_new (GPK_DBUS_ERROR, PK_ERROR_ENUM_PACKAGE_NOT_FOUND, "nothing was found to handle mime type");
+ gpk_dbus_task_dbus_return_error (dtask, error_dbus);
+ g_error_free (error_dbus);
+ goto out;
+ }
+
+ /* populate a chooser and wait for response */
+ gpk_helper_chooser_show (dtask->priv->helper_chooser, array);
+out:
+ if (error_code != NULL)
+ g_object_unref (error_code);
+ if (array != NULL)
+ g_ptr_array_unref (array);
+ if (results != NULL)
+ g_object_unref (results);
+}
+
+/**
+ * gpk_dbus_task_install_mime_types:
+ * @task: a valid #GpkDbusTask instance
+ * @mime_type: a mime_type such as <literal>application/text</literal>
+ * @error: a %GError to put the error code and message in, or %NULL
+ *
+ * Install a application to handle a mime type
+ *
+ * Return value: %TRUE if the method succeeded
+ **/
+void
+gpk_dbus_task_install_mime_types (GpkDbusTask *dtask, gchar **mime_types, GpkDbusTaskFinishedCb finished_cb, gpointer userdata)
+{
+ gboolean ret;
+ GError *error_dbus = NULL;
+ guint len;
+ gchar *message = NULL;
+ gchar *text = NULL;
+
+ g_return_if_fail (GPK_IS_DBUS_TASK (dtask));
+ g_return_if_fail (mime_types != NULL);
+
+ /* save callback information */
+ dtask->priv->finished_cb = finished_cb;
+ dtask->priv->finished_userdata = userdata;
+
+ /* check it's not session wide banned */
+ ret = g_settings_get_boolean (dtask->priv->settings, GPK_SETTINGS_ENABLE_MIME_TYPE_HELPER);
+ if (!ret) {
+ error_dbus = g_error_new (GPK_DBUS_ERROR, PK_ERROR_ENUM_NOT_AUTHORIZED, "not enabled in GSettings : %s", GPK_SETTINGS_ENABLE_MIME_TYPE_HELPER);
+ gpk_dbus_task_dbus_return_error (dtask, error_dbus);
+ g_error_free (error_dbus);
+ goto out;
+ }
+
+ /* optional */
+ if (!dtask->priv->show_confirm_search) {
+ g_debug ("skip confirm as not allowed to interact with user");
+ goto skip_checks;
+ }
+
+ /* make sure the user wants to do action */
+ message = g_strdup_printf ("%s\n\n%s\n\n%s",
+ /* TRANSLATORS: message: mime type opener required */
+ _("An additional program is required to open this type of file:"),
+ mime_types[0],
+ /* TRANSLATORS: message: confirm with the user */
+ _("Do you want to search for a program to open this file type now?"));
+
+ /* hardcode for now as we only support one mime type at a time */
+ len = 1;
+
+ /* make title using application name */
+ if (dtask->priv->parent_title != NULL) {
+ /* TRANSLATORS: string is a program name, e.g. "Movie Player" */
+ text = g_strdup_printf (ngettext ("%s requires a new mime type", "%s requires new mime types", len), dtask->priv->parent_title);
+ } else {
+ /* TRANSLATORS: a random program which we can't get the name wants to do something */
+ text = g_strdup (ngettext ("A program requires a new mime type", "A program requires new mime types", len));
+ }
+
+ /* TRANSLATORS: button: confirm to search for packages */
+ ret = gpk_dbus_task_confirm_action (dtask, text, message, _("Search"));
+ if (!ret) {
+ error_dbus = g_error_new (GPK_DBUS_ERROR, PK_ERROR_ENUM_TRANSACTION_CANCELLED, "did not agree to search");
+ gpk_dbus_task_dbus_return_error (dtask, error_dbus);
+ g_error_free (error_dbus);
+ goto out;
+ }
+
+skip_checks:
+ gpk_modal_dialog_setup (dtask->priv->dialog, GPK_MODAL_DIALOG_PAGE_PROGRESS, 0);
+ /* TRANSLATORS: title: searching for mime type handlers */
+ gpk_modal_dialog_set_title (dtask->priv->dialog, _("Searching for file handlers"));
+ gpk_modal_dialog_set_image_status (dtask->priv->dialog, PK_STATUS_ENUM_WAIT);
+
+ /* setup the UI */
+ if (dtask->priv->show_progress)
+ gpk_modal_dialog_present (dtask->priv->dialog);
+
+ /* action */
+ pk_client_what_provides_async (PK_CLIENT(dtask->priv->task), pk_bitfield_from_enums (PK_FILTER_ENUM_NOT_INSTALLED, PK_FILTER_ENUM_ARCH, PK_FILTER_ENUM_NEWEST, -1),
+#if PK_CHECK_VERSION(0,9,0)
+ mime_types, NULL,
+#else
+ PK_PROVIDES_ENUM_MIMETYPE, mime_types, NULL,
+#endif
+ (PkProgressCallback) gpk_dbus_task_progress_cb, dtask,
+ (GAsyncReadyCallback) gpk_dbus_task_mime_what_provides_cb, dtask);
+ /* wait for async reply */
+out:
+ g_free (text);
+ g_free (message);
+}
+
+/**
+ * gpk_dbus_task_font_tag_to_lang:
+ **/
+gchar *
+gpk_dbus_task_font_tag_to_lang (const gchar *tag)
+{
+ gchar *lang = NULL;
+#if 0
+ *** We do not yet enable this code due to a few bugs in fontconfig ***
+ http://bugs.freedesktop.org/show_bug.cgi?id=18846 and
+ http://bugs.freedesktop.org/show_bug.cgi?id=18847
+
+ FcPattern *pat = NULL;
+ FcChar8 *fclang;
+ FcResult res;
+
+ /* parse the tag */
+ pat = FcNameParse ((FcChar8 *) tag);
+ if (pat == NULL) {
+ g_warning ("cannot parse: '%s'", tag);
+ goto out;
+ }
+ FcPatternPrint (pat);
+ res = FcPatternGetString (pat, FC_LANG, 0, &fclang);
+ if (res != FcResultMatch) {
+ g_warning ("failed to get string for: '%s': %i", tag, res);
+ goto out;
+ }
+ lang = g_strdup ((gchar *) fclang);
+out:
+ if (pat != NULL)
+ FcPatternDestroy (pat);
+#else
+ guint len;
+
+ /* verify we have enough to remove prefix */
+ len = strlen (tag);
+ if (len < 7)
+ goto out;
+ /* this is a bodge */
+ lang = g_strdup (&tag[6]);
+out:
+#endif
+ return lang;
+}
+
+/**
+ * gpk_dbus_task_font_tag_to_localised_name:
+ **/
+gchar *
+gpk_dbus_task_font_tag_to_localised_name (GpkDbusTask *dtask, const gchar *tag)
+{
+ gchar *lang;
+ gchar *language = NULL;
+ gchar *name;
+
+ /* use fontconfig to get the language code */
+ lang = gpk_dbus_task_font_tag_to_lang (tag);
+ if (lang == NULL) {
+ /* TRANSLATORS: we could not parse the ISO639 code from the fontconfig tag name */
+ name = g_strdup_printf ("%s: %s", _("Language tag not parsed"), tag);
+ goto out;
+ }
+
+ /* convert to localisable name */
+ language = gpk_language_iso639_to_language (dtask->priv->language, lang);
+ if (language == NULL) {
+ /* TRANSLATORS: we could not find en_US string for ISO639 code */
+ name = g_strdup_printf ("%s: %s", _("Language code not matched"), lang);
+ goto out;
+ }
+
+ /* get translation, or return untranslated string */
+ name = g_strdup (dgettext("iso_639", language));
+ if (name == NULL)
+ name = g_strdup (language);
+out:
+ g_free (lang);
+ g_free (language);
+ return name;
+}
+
+/**
+ * gpk_dbus_task_fontconfig_what_provides_cb:
+ **/
+static void
+gpk_dbus_task_fontconfig_what_provides_cb (PkClient *client, GAsyncResult *res, GpkDbusTask *dtask)
+{
+ GError *error = NULL;
+ GError *error_dbus = NULL;
+ PkResults *results = NULL;
+ GPtrArray *array = NULL;
+ PkError *error_code = NULL;
+ gchar *title;
+ gchar *info_url;
+ GtkResponseType button;
+
+ /* get the results */
+ results = pk_client_generic_finish (client, res, &error);
+ if (results == NULL) {
+ /* TRANSLATORS: we failed to find the package, this shouldn't happen */
+ error_dbus = g_error_new (GPK_DBUS_ERROR, gpk_dbus_task_get_code_from_gerror (error), "failed to search for provides: %s", error->message);
+// gpk_dbus_task_error_msg (dtask, _("Failed to search for provides"), error_dbus);
+ gpk_dbus_task_dbus_return_error (dtask, error_dbus);
+ g_error_free (error);
+ g_error_free (error_dbus);
+ goto out;
+ }
+
+ /* check error code */
+ error_code = pk_results_get_error_code (results);
+ if (error_code != NULL) {
+ /* TRANSLATORS: we failed to find the package, this shouldn't happen */
+// gpk_dbus_task_error_msg (dtask, _("Failed to search for provides"), pk_error_get_details (error_code));
+ error_dbus = g_error_new (GPK_DBUS_ERROR, gpk_dbus_task_get_code_from_pkerror (error_code), "failed to search for provides: %s", pk_error_get_details (error_code));
+ gpk_dbus_task_dbus_return_error (dtask, error_dbus);
+ g_error_free (error_dbus);
+ goto out;
+ }
+
+ /* get results */
+ array = pk_results_get_package_array (results);
+
+ /* found nothing? */
+ if (array->len == 0) {
+ if (dtask->priv->show_warning) {
+ info_url = gpk_vendor_get_not_found_url (dtask->priv->vendor, GPK_VENDOR_URL_TYPE_FONT);
+ /* TRANSLATORS: title: cannot find in sources */
+ title = ngettext ("Failed to find font", "Failed to find fonts", array->len);
+ /* only show the "more info" button if there is a valid link */
+ if (info_url != NULL)
+ gpk_modal_dialog_setup (dtask->priv->dialog, GPK_MODAL_DIALOG_PAGE_WARNING, GPK_MODAL_DIALOG_BUTTON_ACTION);
+ else
+ gpk_modal_dialog_setup (dtask->priv->dialog, GPK_MODAL_DIALOG_PAGE_WARNING, 0);
+ gpk_modal_dialog_set_title (dtask->priv->dialog, title);
+ /* TRANSLATORS: message: tell the user we suck */
+ gpk_modal_dialog_set_message (dtask->priv->dialog, _("No new fonts can be found for this document"));
+ /* TRANSLATORS: button: show the user a button to get more help finding stuff */
+ gpk_modal_dialog_set_action (dtask->priv->dialog, _("More information"));
+ gpk_modal_dialog_present (dtask->priv->dialog);
+ button = gpk_modal_dialog_run (dtask->priv->dialog);
+ if (button == GTK_RESPONSE_OK)
+ gpk_gnome_open (info_url);
+ g_free (info_url);
+ }
+ error_dbus = g_error_new (GPK_DBUS_ERROR, PK_ERROR_ENUM_PACKAGE_NOT_FOUND, "failed to find font");
+ gpk_dbus_task_dbus_return_error (dtask, error_dbus);
+ g_error_free (error_dbus);
+ goto out;
+ }
+
+ /* optional */
+ if (!dtask->priv->show_confirm_install) {
+ g_debug ("skip confirm as not allowed to interact with user");
+ goto skip_checks;
+ }
+
+ /* TRANSLATORS: title: show a list of fonts */
+ title = ngettext ("Do you want to install this package now?", "Do you want to install these packages now?", array->len);
+ gpk_modal_dialog_setup (dtask->priv->dialog, GPK_MODAL_DIALOG_PAGE_CONFIRM, GPK_MODAL_DIALOG_PACKAGE_LIST);
+ gpk_modal_dialog_set_package_list (dtask->priv->dialog, array);
+ gpk_modal_dialog_set_title (dtask->priv->dialog, title);
+ gpk_modal_dialog_set_message (dtask->priv->dialog, title);
+ gpk_modal_dialog_set_image (dtask->priv->dialog, "dialog-information");
+ /* TRANSLATORS: button: install a font */
+ gpk_modal_dialog_set_action (dtask->priv->dialog, _("Install"));
+ gpk_modal_dialog_present_with_time (dtask->priv->dialog, dtask->priv->timestamp);
+ button = gpk_modal_dialog_run (dtask->priv->dialog);
+
+ /* close, we're going to fail the method */
+ if (button != GTK_RESPONSE_OK) {
+ gpk_modal_dialog_close (dtask->priv->dialog);
+ error_dbus = g_error_new (GPK_DBUS_ERROR, PK_ERROR_ENUM_TRANSACTION_CANCELLED, "did not agree to download");
+ gpk_dbus_task_dbus_return_error (dtask, error_dbus);
+ g_error_free (error_dbus);
+ goto out;
+ }
+
+skip_checks:
+ /* convert to list of package id's */
+ dtask->priv->package_ids = pk_package_array_to_strv (array);
+ gpk_dbus_task_install_package_ids (dtask);
+out:
+ if (error_code != NULL)
+ g_object_unref (error_code);
+ if (array != NULL)
+ g_ptr_array_unref (array);
+ if (results != NULL)
+ g_object_unref (results);
+}
+
+/**
+ * gpk_dbus_task_install_check_exec_ignored:
+ *
+ * Returns %FALSE if the executed program is in the ignored list.
+ **/
+static gboolean
+gpk_dbus_task_install_check_exec_ignored (GpkDbusTask *dtask)
+{
+ gchar *ignored_str;
+ gchar **ignored = NULL;
+ gboolean ret = TRUE;
+ guint i;
+
+ /* check it's not session wide banned */
+ ignored_str = g_settings_get_string (dtask->priv->settings, GPK_SETTINGS_IGNORED_DBUS_REQUESTS);
+ if (ignored_str == NULL)
+ goto out;
+
+ /* check each one */
+ ignored = g_strsplit (ignored_str, ",", -1);
+ for (i=0; ignored[i] != NULL; i++) {
+ if (g_strcmp0 (dtask->priv->exec, ignored[i]) == 0) {
+ ret = FALSE;
+ break;
+ }
+ }
+out:
+ g_free (ignored_str);
+ g_strfreev (ignored);
+ return ret;
+}
+
+/**
+ * gpk_dbus_task_install_fontconfig_resources:
+ * @task: a valid #GpkDbusTask instance
+ * @fonts: font description such as <literal>lang:fr</literal>
+ * @error: a %GError to put the error code and message in, or %NULL
+ *
+ * Install a application to handle a mime type
+ *
+ * Return value: %TRUE if the method succeeded
+ **/
+void
+gpk_dbus_task_install_fontconfig_resources (GpkDbusTask *dtask, gchar **fonts, GpkDbusTaskFinishedCb finished_cb, gpointer userdata)
+{
+ gboolean ret;
+ GPtrArray *array = NULL;
+// GtkResponseType button;
+// gchar *info_url;
+ GError *error_dbus = NULL;
+ guint i;
+ guint len;
+ guint size;
+ gchar *text;
+ gchar *message;
+ const gchar *title;
+ const gchar *title_part;
+ GString *string;
+
+ g_return_if_fail (GPK_IS_DBUS_TASK (dtask));
+ g_return_if_fail (fonts != NULL);
+
+ /* save callback information */
+ dtask->priv->finished_cb = finished_cb;
+ dtask->priv->finished_userdata = userdata;
+
+ /* if this program banned? */
+ ret = gpk_dbus_task_install_check_exec_ignored (dtask);
+ if (!ret) {
+ error_dbus = g_error_new (GPK_DBUS_ERROR, PK_ERROR_ENUM_NOT_AUTHORIZED, "skipping ignored program: %s", dtask->priv->exec);
+ gpk_dbus_task_dbus_return_error (dtask, error_dbus);
+ g_error_free (error_dbus);
+ goto out;
+ }
+
+ /* get number of fonts to install */
+ len = g_strv_length (fonts);
+
+ /* check it's not session wide banned */
+ ret = g_settings_get_boolean (dtask->priv->settings, GPK_SETTINGS_ENABLE_FONT_HELPER);
+ if (!ret) {
+ error_dbus = g_error_new (GPK_DBUS_ERROR, PK_ERROR_ENUM_NOT_AUTHORIZED, "not enabled in GSettings : %s", GPK_SETTINGS_ENABLE_FONT_HELPER);
+ gpk_dbus_task_dbus_return_error (dtask, error_dbus);
+ g_error_free (error_dbus);
+ goto out;
+ }
+
+ /* optional */
+ if (!dtask->priv->show_confirm_search) {
+ g_debug ("skip confirm as not allowed to interact with user");
+ goto skip_checks;
+ }
+
+ /* check we got valid data */
+ for (i=0; i<len; i++) {
+ /* correct prefix */
+ if (!g_str_has_prefix (fonts[i], ":lang=")) {
+ error_dbus = g_error_new (GPK_DBUS_ERROR, PK_ERROR_ENUM_INTERNAL_ERROR, "not recognized prefix: '%s'", fonts[i]);
+ gpk_dbus_task_dbus_return_error (dtask, error_dbus);
+ g_error_free (error_dbus);
+ goto out;
+ }
+ /* no lang code */
+ size = strlen (fonts[i]);
+ if (size < 7 || size > 20) {
+ error_dbus = g_error_new (GPK_DBUS_ERROR, PK_ERROR_ENUM_INTERNAL_ERROR, "lang tag malformed: '%s'", fonts[i]);
+ gpk_dbus_task_dbus_return_error (dtask, error_dbus);
+ g_error_free (error_dbus);
+ goto out;
+ }
+ }
+
+ string = g_string_new ("");
+
+ /* don't use a bullet for one item */
+ if (len == 1) {
+ text = gpk_dbus_task_font_tag_to_localised_name (dtask, fonts[0]);
+ g_string_append_printf (string, "%s\n", text);
+ g_free (text);
+ } else {
+ for (i=0; i<len; i++) {
+ text = gpk_dbus_task_font_tag_to_localised_name (dtask, fonts[i]);
+ g_string_append_printf (string, "• %s\n", text);
+ g_free (text);
+ }
+ }
+ /* display messagebox */
+ text = g_string_free (string, FALSE);
+
+ /* TRANSLATORS: we need to download a new font package to display a document */
+ title = ngettext ("An additional font is required to view this document correctly.",
+ "Additional fonts are required to view this document correctly.", len);
+
+ /* TRANSLATORS: we need to download a new font package to display a document */
+ title_part = ngettext ("Do you want to search for a suitable package now?",
+ "Do you want to search for suitable packages now?", len);
+
+ /* check user wanted operation */
+ message = g_strdup_printf ("%s\n\n%s\n%s", title, text, title_part);
+ g_free (text);
+
+ /* make title using application name */
+ if (dtask->priv->parent_title != NULL) {
+ /* TRANSLATORS: string is a program name, e.g. "Movie Player" */
+ text = g_strdup_printf (ngettext ("%s wants to install a font", "%s wants to install fonts", len), dtask->priv->parent_title);
+ } else {
+ /* TRANSLATORS: a random program which we can't get the name wants to do something */
+ text = g_strdup (ngettext ("A program wants to install a font", "A program wants to install fonts", len));
+ }
+
+ /* TRANSLATORS: button: confirm to search for packages */
+ ret = gpk_dbus_task_confirm_action (dtask, text, message, _("Search"));
+ g_free (text);
+ g_free (message);
+ if (!ret) {
+ error_dbus = g_error_new (GPK_DBUS_ERROR, PK_ERROR_ENUM_TRANSACTION_CANCELLED, "did not agree to search");
+ gpk_dbus_task_dbus_return_error (dtask, error_dbus);
+ g_error_free (error_dbus);
+ goto out;
+ }
+
+skip_checks:
+ /* TRANSLATORS: title to show when searching for font files */
+ title = ngettext ("Searching for font", "Searching for fonts", len);
+ gpk_modal_dialog_setup (dtask->priv->dialog, GPK_MODAL_DIALOG_PAGE_PROGRESS, 0);
+ gpk_modal_dialog_set_title (dtask->priv->dialog, title);
+ gpk_modal_dialog_set_image_status (dtask->priv->dialog, PK_STATUS_ENUM_WAIT);
+
+ /* setup the UI */
+ if (dtask->priv->show_progress)
+ gpk_modal_dialog_present (dtask->priv->dialog);
+
+ /* do each one */
+ pk_client_what_provides_async (PK_CLIENT(dtask->priv->task), pk_bitfield_from_enums (PK_FILTER_ENUM_NOT_INSTALLED, PK_FILTER_ENUM_ARCH, PK_FILTER_ENUM_NEWEST, -1),
+#if PK_CHECK_VERSION(0,9,0)
+ fonts, NULL,
+#else
+ PK_PROVIDES_ENUM_FONT, fonts, NULL,
+#endif
+ (PkProgressCallback) gpk_dbus_task_progress_cb, dtask,
+ (GAsyncReadyCallback) gpk_dbus_task_fontconfig_what_provides_cb, dtask);
+out:
+ if (array != NULL)
+ g_ptr_array_unref (array);
+}
+
+/**
+ * gpk_dbus_task_install_plasma_resources_confirm:
+ **/
+static gboolean
+gpk_dbus_task_install_plasma_resources_confirm (GpkDbusTask *dtask, gchar **service_names)
+{
+ guint i;
+ guint len;
+ const gchar *text;
+ gboolean ret;
+ GString *string;
+ gchar *title;
+ gchar *message;
+
+ len = g_strv_length (service_names);
+
+ /* TRANSLATORS: we are listing the services in a box */
+ text = ngettext ("The following service is required:", "The following services are required:", len);
+ string = g_string_new ("");
+ g_string_append_printf (string, "%s\n\n", text);
+
+ /* don't use a bullet for one item */
+ if (len == 1)
+ g_string_append_printf (string, "%s\n", service_names[0]);
+ else
+ for (i=0; i<len; i++)
+ g_string_append_printf (string, "• %s\n", service_names[i]);
+
+ /* TRANSLATORS: ask for confirmation */
+ message = ngettext ("Do you want to search for this now?", "Do you want to search for these now?", len);
+ g_string_append_printf (string, "\n%s\n", message);
+
+ /* remove last \n */
+ g_string_set_size (string, string->len - 1);
+
+ /* display messagebox */
+ message = g_string_free (string, FALSE);
+ title = g_strdup (ngettext ("Plasma requires an additional service for this operation",
+ "Plasma requires additional services for this operation", len));
+
+ /* TRANSLATORS: button: confirm to search for packages */
+ ret = gpk_dbus_task_confirm_action (dtask, title, message, _("Search"));
+ g_free (title);
+ g_free (message);
+
+ return ret;
+}
+
+/**
+ * gpk_dbus_task_plasma_service_what_provides_cb:
+ **/
+static void
+gpk_dbus_task_plasma_service_what_provides_cb (PkClient *client, GAsyncResult *res, GpkDbusTask *dtask)
+{
+ GError *error = NULL;
+ GError *error_dbus = NULL;
+ PkResults *results = NULL;
+ GPtrArray *array = NULL;
+ PkError *error_code = NULL;
+ GtkResponseType button;
+ gchar *info_url;
+ const gchar *title;
+ const gchar *message;
+
+ /* get the results */
+ results = pk_client_generic_finish (client, res, &error);
+ if (results == NULL) {
+ error_dbus = g_error_new (GPK_DBUS_ERROR, gpk_dbus_task_get_code_from_gerror (error), "failed to resolve: %s", error->message);
+ gpk_dbus_task_dbus_return_error (dtask, error_dbus);
+ g_error_free (error);
+ g_error_free (error_dbus);
+ goto out;
+ }
+
+ /* check error code */
+ error_code = pk_results_get_error_code (results);
+ if (error_code != NULL) {
+ error_dbus = g_error_new (GPK_DBUS_ERROR, gpk_dbus_task_get_code_from_pkerror (error_code), "failed to resolve: %s", pk_error_get_details (error_code));
+ gpk_dbus_task_dbus_return_error (dtask, error_dbus);
+ g_error_free (error_dbus);
+ goto out;
+ }
+
+ /* get results */
+ array = pk_results_get_package_array (results);
+
+ /* found nothing? */
+ if (array->len == 0) {
+ if (dtask->priv->show_warning) {
+ info_url = gpk_vendor_get_not_found_url (dtask->priv->vendor, GPK_VENDOR_URL_TYPE_DEFAULT);
+ /* only show the "more info" button if there is a valid link */
+ if (info_url != NULL)
+ gpk_modal_dialog_setup (dtask->priv->dialog, GPK_MODAL_DIALOG_PAGE_WARNING, GPK_MODAL_DIALOG_BUTTON_ACTION);
+ else
+ gpk_modal_dialog_setup (dtask->priv->dialog, GPK_MODAL_DIALOG_PAGE_WARNING, 0);
+ gpk_modal_dialog_set_title (dtask->priv->dialog, _("Failed to search for Plasma service"));
+ /* TRANSLATORS: no package sources have the wanted Plasma service */
+ gpk_modal_dialog_set_message (dtask->priv->dialog, _("Could not find service in any configured package source"));
+
+ /* TRANSLATORS: button text */
+ gpk_modal_dialog_set_action (dtask->priv->dialog, _("More information"));
+ gpk_modal_dialog_present (dtask->priv->dialog);
+ button = gpk_modal_dialog_run (dtask->priv->dialog);
+ if (button == GTK_RESPONSE_OK)
+ gpk_gnome_open (info_url);
+ g_free (info_url);
+ }
+ error_dbus = g_error_new (GPK_DBUS_ERROR, PK_ERROR_ENUM_PACKAGE_NOT_FOUND, "failed to find Plasma service");
+ gpk_dbus_task_dbus_return_error (dtask, error_dbus);
+ g_error_free (error_dbus);
+ goto out;
+ }
+
+ /* optional */
+ if (!dtask->priv->show_confirm_install) {
+ g_debug ("skip confirm as not allowed to interact with user");
+ goto skip_checks2;
+ }
+
+ title = ngettext ("Install the following plugin", "Install the following plugins", array->len);
+ message = ngettext ("Do you want to install this package now?", "Do you want to install these packages now?", array->len);
+
+ gpk_modal_dialog_setup (dtask->priv->dialog, GPK_MODAL_DIALOG_PAGE_CONFIRM, GPK_MODAL_DIALOG_PACKAGE_LIST);
+ gpk_modal_dialog_set_package_list (dtask->priv->dialog, array);
+ gpk_modal_dialog_set_title (dtask->priv->dialog, title);
+ gpk_modal_dialog_set_message (dtask->priv->dialog, message);
+ gpk_modal_dialog_set_image (dtask->priv->dialog, "dialog-information");
+ /* TRANSLATORS: button: install Plasma services */
+ gpk_modal_dialog_set_action (dtask->priv->dialog, _("Install"));
+ gpk_modal_dialog_present_with_time (dtask->priv->dialog, dtask->priv->timestamp);
+ button = gpk_modal_dialog_run (dtask->priv->dialog);
+
+ /* close, we're going to fail the method */
+ if (button != GTK_RESPONSE_OK) {
+ gpk_modal_dialog_close (dtask->priv->dialog);
+ error_dbus = g_error_new (GPK_DBUS_ERROR, PK_ERROR_ENUM_TRANSACTION_CANCELLED, "did not agree to download");
+ gpk_dbus_task_dbus_return_error (dtask, error_dbus);
+ g_error_free (error_dbus);
+ goto out;
+ }
+
+skip_checks2:
+ /* install with deps */
+ dtask->priv->package_ids = pk_package_array_to_strv (array);
+ gpk_dbus_task_install_package_ids (dtask);
+out:
+ if (error_code != NULL)
+ g_object_unref (error_code);
+ if (array != NULL)
+ g_ptr_array_unref (array);
+ if (results != NULL)
+ g_object_unref (results);
+}
+
+/**
+ * gpk_dbus_task_install_plasma_resources:
+ * @task: a valid #GpkDbusTask instance
+ * @service_names: a service type such as <literal>dataengine-weather</literal>
+ * @error: a %GError to put the error code and message in, or %NULL
+ *
+ * Install a service to handle a Plasma request
+ *
+ * Return value: %TRUE if the method succeeded
+ **/
+static void
+gpk_dbus_task_install_plasma_resources (GpkDbusTask *dtask, gchar **service_names, GpkDbusTaskFinishedCb finished_cb, gpointer userdata)
+{
+ gboolean ret = TRUE;
+ GError *error_dbus = NULL;
+ gchar *message = NULL;
+ GPtrArray *array_title = NULL;
+ GPtrArray *array_search = NULL;
+ gchar **search = NULL;
+ gchar **title = NULL;
+ gchar *title_str = NULL;
+ guint i;
+
+ g_return_if_fail (GPK_IS_DBUS_TASK (dtask));
+ g_return_if_fail (service_names != NULL);
+
+ /* save callback information */
+ dtask->priv->finished_cb = finished_cb;
+ dtask->priv->finished_userdata = userdata;
+
+ /* optional */
+ if (!dtask->priv->show_confirm_search) {
+ g_debug ("skip confirm as not allowed to interact with user");
+ goto skip_checks;
+ }
+
+ /* confirm */
+ ret = gpk_dbus_task_install_plasma_resources_confirm (dtask, service_names);
+ if (!ret) {
+ error_dbus = g_error_new (GPK_DBUS_ERROR, PK_ERROR_ENUM_TRANSACTION_CANCELLED, "did not agree to search");
+ gpk_dbus_task_dbus_return_error (dtask, error_dbus);
+ g_error_free (error_dbus);
+ goto out;
+ }
+
+skip_checks:
+ gpk_modal_dialog_setup (dtask->priv->dialog, GPK_MODAL_DIALOG_PAGE_PROGRESS, GPK_MODAL_DIALOG_PACKAGE_PADDING);
+ /* TRANSLATORS: search for Plasma services */
+ gpk_modal_dialog_set_title (dtask->priv->dialog, _("Searching for services"));
+ gpk_modal_dialog_set_image_status (dtask->priv->dialog, PK_STATUS_ENUM_WAIT);
+
+ /* setup the UI */
+ if (dtask->priv->show_progress)
+ gpk_modal_dialog_present (dtask->priv->dialog);
+
+ /* get the request */
+ array_title = g_ptr_array_new_with_free_func (g_free);
+ array_search = g_ptr_array_new_with_free_func (g_free);
+ for (i=0; service_names[i] != NULL; i++) {
+ g_ptr_array_add (array_title, g_strdup (service_names[i]));
+ g_ptr_array_add (array_search, g_strdup (service_names[i]));
+ }
+
+ /* TRANSLATORS: title, searching for Plasma services */
+ title = pk_ptr_array_to_strv (array_title);
+ title_str = g_strjoinv (", ", title);
+ message = g_strdup_printf (_("Searching for service: %s"), title_str);
+ gpk_modal_dialog_set_message (dtask->priv->dialog, message);
+
+ /* get service packages */
+ search = pk_ptr_array_to_strv (array_search);
+ pk_client_what_provides_async (PK_CLIENT(dtask->priv->task), pk_bitfield_from_enums (PK_FILTER_ENUM_NOT_INSTALLED, PK_FILTER_ENUM_ARCH, PK_FILTER_ENUM_NEWEST, -1),
+#if PK_CHECK_VERSION(0,9,0)
+ search, NULL,
+#else
+ PK_PROVIDES_ENUM_PLASMA_SERVICE, search, NULL,
+#endif
+ (PkProgressCallback) gpk_dbus_task_progress_cb, dtask,
+ (GAsyncReadyCallback) gpk_dbus_task_plasma_service_what_provides_cb, dtask);
+out:
+ if (array_title != NULL)
+ g_ptr_array_unref (array_title);
+ if (array_search != NULL)
+ g_ptr_array_unref (array_search);
+ g_strfreev (search);
+ g_strfreev (title);
+ g_free (message);
+ g_free (title_str);
+}
+
+/**
+ * gpk_dbus_task_install_resources:
+ * @task: a valid #GpkDbusTask instance
+ * @type: type of the resource
+ * @resources: a list of resources
+ * @error: a %GError to put the error code and message in, or %NULL
+ *
+ * Install a resource of the given type
+ *
+ * Return value: %TRUE if the method succeeded
+ **/
+void
+gpk_dbus_task_install_resources (GpkDbusTask *dtask, gchar **resources, GpkDbusTaskFinishedCb finished_cb, gpointer userdata)
+{
+ gpk_dbus_task_install_plasma_resources (dtask, resources, finished_cb, userdata);
+}
+
+/**
+ * gpk_dbus_task_remove_packages_cb:
+ **/
+static void
+gpk_dbus_task_remove_packages_cb (PkTask *task, GAsyncResult *res, GpkDbusTask *dtask)
+{
+ GError *error = NULL;
+ GError *error_dbus = NULL;
+ PkResults *results = NULL;
+ PkError *error_code = NULL;
+
+ /* get the results */
+ results = pk_task_generic_finish (task, res, &error);
+ if (results == NULL) {
+ /* TRANSLATORS: error: failed to remove, detailed error follows */
+ error_dbus = g_error_new (GPK_DBUS_ERROR, gpk_dbus_task_get_code_from_gerror (error), "failed to remove package: %s", error->message);
+ gpk_dbus_task_error_msg (dtask, _("Failed to remove package"), error_dbus);
+ gpk_dbus_task_dbus_return_error (dtask, error_dbus);
+ g_error_free (error);
+ g_error_free (error_dbus);
+ goto out;
+ }
+
+ /* check error code */
+ error_code = pk_results_get_error_code (results);
+ if (error_code != NULL) {
+ error_dbus = g_error_new (GPK_DBUS_ERROR, gpk_dbus_task_get_code_from_pkerror (error_code), "failed to remove package: %s", pk_error_get_details (error_code));
+ gpk_dbus_task_handle_error (dtask, error_code);
+ gpk_dbus_task_dbus_return_error (dtask, error_dbus);
+ g_error_free (error_dbus);
+ goto out;
+ }
+
+ /* we're done */
+ gpk_dbus_task_dbus_return_value (dtask, TRUE);
+out:
+ if (error_code != NULL)
+ g_object_unref (error_code);
+ if (results != NULL)
+ g_object_unref (results);
+}
+
+/**
+ * gpk_dbus_task_printer_driver_what_provides_cb:
+ **/
+static void
+gpk_dbus_task_printer_driver_what_provides_cb (PkClient *client, GAsyncResult *res, GpkDbusTask *dtask)
+{
+ GError *error = NULL;
+ GError *error_dbus = NULL;
+ PkResults *results = NULL;
+ GPtrArray *array = NULL;
+ PkError *error_code = NULL;
+ GtkResponseType button;
+ const gchar *title;
+ const gchar *message;
+
+ /* get the results */
+ results = pk_client_generic_finish (client, res, &error);
+ if (results == NULL) {
+ error_dbus = g_error_new (GPK_DBUS_ERROR, gpk_dbus_task_get_code_from_gerror (error), "failed to resolve: %s", error->message);
+ gpk_dbus_task_dbus_return_error (dtask, error_dbus);
+ g_error_free (error);
+ g_error_free (error_dbus);
+ goto out;
+ }
+
+ /* check error code */
+ error_code = pk_results_get_error_code (results);
+ if (error_code != NULL) {
+ error_dbus = g_error_new (GPK_DBUS_ERROR, gpk_dbus_task_get_code_from_pkerror (error_code), "failed to resolve: %s", pk_error_get_details (error_code));
+ gpk_dbus_task_dbus_return_error (dtask, error_dbus);
+ g_error_free (error_dbus);
+ goto out;
+ }
+
+ /* get results */
+ array = pk_results_get_package_array (results);
+
+ /* found nothing? No problem*/
+ if (array->len == 0) {
+ gpk_modal_dialog_close (dtask->priv->dialog);
+ gpk_dbus_task_dbus_return_value (dtask, FALSE);
+ goto out;
+ }
+
+ /* optional */
+ if (!dtask->priv->show_confirm_install) {
+ g_debug ("skip confirm as not allowed to interact with user");
+ goto skip_checks2;
+ }
+
+ title = ngettext ("Install the following driver", "Install the following drivers", array->len);
+ message = ngettext ("Do you want to install this package now?", "Do you want to install these packages now?", array->len);
+
+ gpk_modal_dialog_setup (dtask->priv->dialog, GPK_MODAL_DIALOG_PAGE_CONFIRM, GPK_MODAL_DIALOG_PACKAGE_LIST);
+ gpk_modal_dialog_set_package_list (dtask->priv->dialog, array);
+ gpk_modal_dialog_set_title (dtask->priv->dialog, title);
+ gpk_modal_dialog_set_message (dtask->priv->dialog, message);
+ gpk_modal_dialog_set_image (dtask->priv->dialog, "dialog-information");
+ /* TRANSLATORS: button: install printer drivers */
+ gpk_modal_dialog_set_action (dtask->priv->dialog, _("Install"));
+ gpk_modal_dialog_present_with_time (dtask->priv->dialog, dtask->priv->timestamp);
+ button = gpk_modal_dialog_run (dtask->priv->dialog);
+
+ /* close, we're going to fail the method */
+ if (button != GTK_RESPONSE_OK) {
+ gpk_modal_dialog_close (dtask->priv->dialog);
+ error_dbus = g_error_new (GPK_DBUS_ERROR, PK_ERROR_ENUM_TRANSACTION_CANCELLED, "did not agree to download");
+ gpk_dbus_task_dbus_return_error (dtask, error_dbus);
+ g_error_free (error_dbus);
+ goto out;
+ }
+
+skip_checks2:
+ /* install with deps */
+ dtask->priv->package_ids = pk_package_array_to_strv (array);
+ gpk_dbus_task_install_package_ids (dtask);
+out:
+ if (error_code != NULL)
+ g_object_unref (error_code);
+ if (array != NULL)
+ g_ptr_array_unref (array);
+ if (results != NULL)
+ g_object_unref (results);
+}
+
+/**
+ * gpk_dbus_task_install_printer_drivers:
+ * @task: a valid #GpkDbusTask instance
+ * @device_ids: list of Device IDs such as <literal>MFG:Foo Inc;MDL:Bar 3000;</literal>
+ * @error: a %GError to put the error code and message in, or %NULL
+ *
+ * Install printer drivers for a given set of models.
+ *
+ * Return value: %TRUE if the method succeeded
+ **/
+void
+gpk_dbus_task_install_printer_drivers (GpkDbusTask *dtask, gchar **device_ids, GpkDbusTaskFinishedCb finished_cb, gpointer userdata)
+{
+ guint i, j;
+ guint len;
+ guint n_tags;
+ guint n_fields;
+ gchar **fields;
+ gchar *mfg;
+ gchar *mdl;
+ gchar *tag;
+ gchar **tags;
+
+ g_return_if_fail (GPK_IS_DBUS_TASK (dtask));
+ g_return_if_fail (device_ids != NULL);
+
+ /* save callback information */
+ dtask->priv->finished_cb = finished_cb;
+ dtask->priv->finished_userdata = userdata;
+
+ gpk_modal_dialog_setup (dtask->priv->dialog,
+ GPK_MODAL_DIALOG_PAGE_PROGRESS,
+ GPK_MODAL_DIALOG_PACKAGE_PADDING);
+ gpk_modal_dialog_set_title (dtask->priv->dialog,
+ _("Searching for packages"));
+ gpk_modal_dialog_set_image_status (dtask->priv->dialog,
+ PK_STATUS_ENUM_WAIT);
+
+ /* setup the UI */
+ if (dtask->priv->show_progress)
+ gpk_modal_dialog_present (dtask->priv->dialog);
+
+ len = g_strv_length (device_ids);
+ if (len > 1)
+ /* hardcode for now as we only support one at a time */
+ len = 1;
+
+ /* make a list of provides tags */
+ tags = g_new0 (gchar *, len);
+ n_tags = 0;
+ for (i=0; i<len; i++) {
+ gchar *p, *ltag;
+ fields = g_strsplit (device_ids[i], ";", 0);
+ n_fields = g_strv_length (fields);
+ mfg = mdl = NULL;
+ for (j=0; j<n_fields && (!mfg || !mdl); j++) {
+ if (g_str_has_prefix (fields[j], "MFG:"))
+ mfg = g_strdup (fields[j] + 4);
+ else if (g_str_has_prefix (fields[j], "MDL:"))
+ mdl = g_strdup (fields[j] + 4);
+ }
+ g_strfreev (fields);
+
+ if (!mfg || !mdl) {
+ g_warning("invalid line '%s', missing field",
+ device_ids[i]);
+ continue;
+ }
+
+ tag = g_strconcat (mfg, ";", mdl, ";", NULL);
+ ltag = g_ascii_strdown (tag, -1);
+ g_free (tag);
+
+ /* Replace spaces with underscores */
+ for (p = ltag; *p != '\0'; p++)
+ if (*p == ' ')
+ *p = '_';
+
+ tags[n_tags++] = g_strdup (ltag);
+ g_free (ltag);
+ }
+
+ if (n_tags == 0) {
+ gpk_dbus_task_dbus_return_value (dtask, FALSE);
+ goto out;
+ }
+
+ tags = g_renew (gchar *, tags, n_tags + 1);
+ tags[n_tags] = NULL;
+
+ /* get driver packages */
+ pk_client_what_provides_async (PK_CLIENT(dtask->priv->task),
+ pk_bitfield_from_enums (PK_FILTER_ENUM_NOT_INSTALLED,
+ PK_FILTER_ENUM_ARCH,
+ PK_FILTER_ENUM_NEWEST,
+ -1),
+#if !PK_CHECK_VERSION(0,9,0)
+ PK_PROVIDES_ENUM_POSTSCRIPT_DRIVER,
+#endif
+ tags, NULL,
+ (PkProgressCallback) gpk_dbus_task_progress_cb, dtask,
+ (GAsyncReadyCallback) gpk_dbus_task_printer_driver_what_provides_cb, dtask);
+
+ out:
+ g_strfreev (tags);
+}
+
+/**
+ * gpk_dbus_task_remove_package_ids:
+ * @task: a valid #GpkDbusTask instance
+ **/
+static void
+gpk_dbus_task_remove_package_ids (GpkDbusTask *dtask)
+{
+ GtkWindow *window;
+
+ gpk_modal_dialog_setup (dtask->priv->dialog, GPK_MODAL_DIALOG_PAGE_PROGRESS, GPK_MODAL_DIALOG_PACKAGE_PADDING);
+ /* TRANSLATORS: title: removing packages */
+ gpk_modal_dialog_set_title (dtask->priv->dialog, _("Removing packages"));
+ if (dtask->priv->show_progress)
+ gpk_modal_dialog_present (dtask->priv->dialog);
+
+ /* ensure parent is set */
+ window = gpk_modal_dialog_get_window (dtask->priv->dialog);
+ gpk_task_set_parent_window (GPK_TASK (dtask->priv->task), window);
+
+ /* remove async */
+ pk_task_remove_packages_async (dtask->priv->task, dtask->priv->package_ids, TRUE, TRUE, NULL,
+ (PkProgressCallback) gpk_dbus_task_progress_cb, dtask,
+ (GAsyncReadyCallback) gpk_dbus_task_remove_packages_cb, dtask);
+}
+
+/**
+ * gpk_dbus_task_remove_package_by_file_search_file_cb:
+ **/
+static void
+gpk_dbus_task_remove_package_by_file_search_file_cb (PkClient *client, GAsyncResult *res, GpkDbusTask *dtask)
+{
+ GError *error = NULL;
+ GError *error_dbus = NULL;
+ PkResults *results = NULL;
+ GPtrArray *array = NULL;
+ PkError *error_code = NULL;
+
+ /* get the results */
+ results = pk_client_generic_finish (client, res, &error);
+ if (results == NULL) {
+ error_dbus = g_error_new (GPK_DBUS_ERROR, gpk_dbus_task_get_code_from_gerror (error), "failed to search by file: %s", error->message);
+ gpk_dbus_task_dbus_return_error (dtask, error_dbus);
+ g_warning ("failed to resolve: %s", error->message);
+ g_error_free (error);
+ g_error_free (error_dbus);
+ goto out;
+ }
+
+ /* check error code */
+ error_code = pk_results_get_error_code (results);
+ if (error_code != NULL) {
+ error_dbus = g_error_new (GPK_DBUS_ERROR, gpk_dbus_task_get_code_from_pkerror (error_code), "failed to search by file: %s", pk_error_get_details (error_code));
+ gpk_dbus_task_dbus_return_error (dtask, error_dbus);
+ g_error_free (error_dbus);
+ goto out;
+ }
+
+ /* get results */
+ array = pk_results_get_package_array (results);
+
+ /* found nothing? */
+ if (array->len == 0) {
+ if (dtask->priv->show_warning) {
+ gpk_modal_dialog_setup (dtask->priv->dialog, GPK_MODAL_DIALOG_PAGE_WARNING, 0);
+ /* TRANSLATORS: failed to find the package for the file */
+ gpk_modal_dialog_set_title (dtask->priv->dialog, _("Failed to find package for this file"));
+ /* TRANSLATORS: nothing found */
+ gpk_modal_dialog_set_message (dtask->priv->dialog, _("The file could not be found in any packages"));
+ /* TRANSLATORS: button: show the user a button to get more help finding stuff */
+ gpk_modal_dialog_present (dtask->priv->dialog);
+ gpk_modal_dialog_run (dtask->priv->dialog);
+ }
+ error_dbus = g_error_new (GPK_DBUS_ERROR, PK_ERROR_ENUM_PACKAGE_NOT_FOUND, "no packages found for this file");
+ gpk_dbus_task_dbus_return_error (dtask, error_dbus);
+ g_error_free (error_dbus);
+ goto out;
+ }
+
+ /* convert to data */
+ dtask->priv->package_ids = pk_package_array_to_strv (array);
+
+ /* remove these packages with deps */
+ gpk_dbus_task_remove_package_ids (dtask);
+out:
+ if (error_code != NULL)
+ g_object_unref (error_code);
+ if (array != NULL)
+ g_ptr_array_unref (array);
+ if (results != NULL)
+ g_object_unref (results);
+}
+
+/**
+ * gpk_dbus_task_remove_package_by_file:
+ * @task: a valid #GpkDbusTask instance
+ * @full_path: a file path name such as <literal>/usr/sbin/packagekitd</literal>
+ * @error: a %GError to put the error code and message in, or %NULL
+ *
+ * Remove a package which provides a file on the system.
+ *
+ * Return value: %TRUE if the method succeeded
+ **/
+void
+gpk_dbus_task_remove_package_by_file (GpkDbusTask *dtask, gchar **full_paths, GpkDbusTaskFinishedCb finished_cb, gpointer userdata)
+{
+ gboolean ret;
+ GError *error_dbus = NULL;
+ guint len;
+ guint i;
+ gchar *text;
+ gchar *message;
+ GString *string;
+
+ g_return_if_fail (GPK_IS_DBUS_TASK (dtask));
+ g_return_if_fail (full_paths != NULL);
+
+ /* save callback information */
+ dtask->priv->finished_cb = finished_cb;
+ dtask->priv->finished_userdata = userdata;
+
+ /* optional */
+ if (!dtask->priv->show_confirm_search) {
+ g_debug ("skip confirm as not allowed to interact with user");
+ goto skip_checks;
+ }
+
+ string = g_string_new ("");
+ len = g_strv_length (full_paths);
+
+ /* don't use a bullet for one item */
+ if (len == 1) {
+ g_string_append_printf (string, "%s\n", full_paths[0]);
+ } else {
+ for (i=0; i<len; i++)
+ g_string_append_printf (string, "• %s\n", full_paths[i]);
+ }
+ /* display messagebox */
+ text = g_string_free (string, FALSE);
+
+ /* check user wanted operation */
+ message = g_strdup_printf ("%s\n\n%s\n\n%s",
+ /* TRANSLATORS: a program wants to remove a file, e.g. /lib/moo.so */
+ ngettext ("The following file will be removed:", "The following files will be removed:", len),
+ text,
+ /* TRANSLATORS: confirm with the user */
+ ngettext ("Do you want to remove this file now?", "Do you want to remove these files now?", len));
+
+ /* make title using application name */
+ if (dtask->priv->parent_title != NULL) {
+ /* TRANSLATORS: string is a program name, e.g. "Movie Player" */
+ text = g_strdup_printf (ngettext ("%s wants to remove a file", "%s wants to remove files", len), dtask->priv->parent_title);
+ } else {
+ /* TRANSLATORS: a random program which we can't get the name wants to do something */
+ text = g_strdup (ngettext ("A program wants to remove a file", "A program wants to remove files", len));
+ }
+
+ /* TRANSLATORS: button: confirm to search for packages */
+ ret = gpk_dbus_task_confirm_action (dtask, text, message, _("Remove"));
+ g_free (text);
+ g_free (message);
+ if (!ret) {
+ error_dbus = g_error_new (GPK_DBUS_ERROR, PK_ERROR_ENUM_TRANSACTION_CANCELLED, "did not agree to search");
+ gpk_dbus_task_dbus_return_error (dtask, error_dbus);
+ g_error_free (error_dbus);
+ goto out;
+ }
+
+skip_checks:
+ /* TRANSLATORS: searching for the package that provides the file */
+ gpk_modal_dialog_set_title (dtask->priv->dialog, _("Searching for file"));
+ gpk_modal_dialog_set_image_status (dtask->priv->dialog, PK_STATUS_ENUM_WAIT);
+
+ /* do search */
+ pk_client_search_files_async (PK_CLIENT(dtask->priv->task), pk_bitfield_from_enums (PK_FILTER_ENUM_ARCH, PK_FILTER_ENUM_NEWEST, PK_FILTER_ENUM_INSTALLED, -1), full_paths, NULL,
+ (PkProgressCallback) gpk_dbus_task_progress_cb, dtask,
+ (GAsyncReadyCallback) gpk_dbus_task_remove_package_by_file_search_file_cb, dtask);
+
+ /* wait for async reply */
+out:
+ return;
+}
+
+/**
+ * gpk_dbus_task_get_package_for_exec:
+ **/
+gchar *
+gpk_dbus_task_get_package_for_exec (GpkDbusTask *dtask, const gchar *exec)
+{
+ const gchar *package_id;
+ gchar *package = NULL;
+ GError *error = NULL;
+ GPtrArray *array = NULL;
+ PkPackage *item;
+ PkResults *results = NULL;
+ gchar **values = NULL;
+ gchar **split = NULL;
+
+ /* find the package name */
+ values = g_strsplit (exec, "&", -1);
+ results = pk_client_search_files (PK_CLIENT(dtask->priv->task), pk_bitfield_value (PK_FILTER_ENUM_INSTALLED), values, NULL,
+ (PkProgressCallback) gpk_dbus_task_progress_cb, dtask, &error);
+ if (results == NULL) {
+ g_warning ("failed to search file: %s", error->message);
+ g_error_free (error);
+ goto out;
+ }
+
+ /* get the list of packages */
+ array = pk_results_get_package_array (results);
+
+ /* nothing found */
+ if (array->len == 0) {
+ g_debug ("cannot find installed package that provides : %s", exec);
+ goto out;
+ }
+
+ /* check we have one */
+ if (array->len != 1)
+ g_warning ("not one return, using first");
+
+ /* copy name */
+ item = g_ptr_array_index (array, 0);
+ package_id = pk_package_get_id (item);
+ split = pk_package_id_split (package_id);
+ package = g_strdup (split[0]);
+ g_debug ("got package %s", package);
+out:
+ g_strfreev (values);
+ g_strfreev (split);
+ if (array != NULL)
+ g_ptr_array_unref (array);
+ if (results != NULL)
+ g_object_unref (results);
+ return package;
+}
+
+/**
+ * gpk_dbus_task_path_is_trusted:
+ **/
+gboolean
+gpk_dbus_task_path_is_trusted (const gchar *exec)
+{
+ gboolean res = FALSE;
+ gchar *path;
+
+ /* special case the plugin helper -- it's trusted */
+
+ path = g_build_filename (LIBEXECDIR, "gst-install-plugins-helper", NULL);
+ res = res || (g_strcmp0 (exec, path) == 0);
+ g_free (path);
+
+ path = g_build_filename (LIBEXECDIR, "pk-gstreamer-install", NULL);
+ res = res || (g_strcmp0 (exec, path) == 0);
+ g_free (path);
+
+ return res;
+}
+
+/**
+ * gpk_dbus_task_set_exec:
+ *
+ * This sets the package name of the application that is trying to install
+ * software, e.g. "totem" and is used for the PkDesktop lookup to provide
+ * a translated name and icon.
+ **/
+gboolean
+gpk_dbus_task_set_exec (GpkDbusTask *dtask, const gchar *exec)
+{
+ GpkX11 *x11;
+ gchar *package = NULL;
+
+ g_return_val_if_fail (GPK_IS_DBUS_TASK (dtask), FALSE);
+
+ /* old values invalid */
+ g_free (dtask->priv->exec);
+ g_free (dtask->priv->parent_title);
+ g_free (dtask->priv->parent_icon_name);
+ dtask->priv->exec = g_strdup (exec);
+ dtask->priv->parent_title = NULL;
+ dtask->priv->parent_icon_name = NULL;
+
+ /* is the binary trusted, i.e. can we probe it's window properties */
+ if (gpk_dbus_task_path_is_trusted (exec) &&
+ dtask->priv->parent_window != NULL) {
+ g_debug ("using application window properties");
+ /* get from window properties */
+ x11 = gpk_x11_new ();
+ gpk_x11_set_window (x11, dtask->priv->parent_window);
+ dtask->priv->parent_title = gpk_x11_get_title (x11);
+ g_object_unref (x11);
+ goto out;
+ }
+
+ /* get from installed database */
+ package = gpk_dbus_task_get_package_for_exec (dtask, exec);
+ g_debug ("got package %s", package);
+ if (package != NULL)
+ dtask->priv->parent_title = g_strdup (package);
+
+ /* fallback to exec - eugh... */
+ if (dtask->priv->parent_title == NULL) {
+ g_debug ("did not get package for %s, using exec basename", package);
+ dtask->priv->parent_title = g_path_get_basename (exec);
+ }
+out:
+ g_free (package);
+ g_debug ("got name=%s, icon=%s", dtask->priv->parent_title, dtask->priv->parent_icon_name);
+ return TRUE;
+}
+
+/**
+ * gpk_dbus_task_class_init:
+ * @klass: The #GpkDbusTaskClass
+ **/
+static void
+gpk_dbus_task_class_init (GpkDbusTaskClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ object_class->finalize = gpk_dbus_task_finalize;
+ g_type_class_add_private (klass, sizeof (GpkDbusTaskPrivate));
+}
+
+/**
+ * gpk_dbus_task_init:
+ * @task: a valid #GpkDbusTask instance
+ **/
+static void
+gpk_dbus_task_init (GpkDbusTask *dtask)
+{
+ GtkWindow *main_window;
+
+ dtask->priv = GPK_DBUS_TASK_GET_PRIVATE (dtask);
+
+ dtask->priv->package_ids = NULL;
+ dtask->priv->files = NULL;
+ dtask->priv->parent_window = NULL;
+ dtask->priv->parent_title = NULL;
+ dtask->priv->exec = NULL;
+ dtask->priv->parent_icon_name = NULL;
+ dtask->priv->cached_error_code = NULL;
+ dtask->priv->context = NULL;
+ dtask->priv->cancellable = g_cancellable_new ();
+ dtask->priv->exit = PK_EXIT_ENUM_FAILED;
+ dtask->priv->show_confirm_search = TRUE;
+ dtask->priv->show_confirm_deps = TRUE;
+ dtask->priv->show_confirm_install = TRUE;
+ dtask->priv->show_progress = TRUE;
+ dtask->priv->show_finished = TRUE;
+ dtask->priv->show_warning = TRUE;
+ dtask->priv->timestamp = 0;
+
+ /* add application specific icons to search path */
+ gtk_icon_theme_append_search_path (gtk_icon_theme_get_default (),
+ GPK_DATA G_DIR_SEPARATOR_S "icons");
+
+ /* only initialize if the application didn't do it before */
+ if (!notify_is_initted ())
+ notify_init (_("Software Install"));
+
+ dtask->priv->vendor = gpk_vendor_new ();
+ dtask->priv->dialog = gpk_modal_dialog_new ();
+ main_window = gpk_modal_dialog_get_window (dtask->priv->dialog);
+ gpk_modal_dialog_set_window_icon (dtask->priv->dialog, "pk-package-installed");
+ g_signal_connect (dtask->priv->dialog, "cancel",
+ G_CALLBACK (gpk_dbus_task_button_cancel_cb), dtask);
+ g_signal_connect (dtask->priv->dialog, "close",
+ G_CALLBACK (gpk_dbus_task_button_close_cb), dtask);
+
+ /* helpers */
+ dtask->priv->helper_run = gpk_helper_run_new ();
+ gpk_helper_run_set_parent (dtask->priv->helper_run, main_window);
+
+ dtask->priv->helper_chooser = gpk_helper_chooser_new ();
+ g_signal_connect (dtask->priv->helper_chooser, "event", G_CALLBACK (gpk_dbus_task_chooser_event_cb), dtask);
+ gpk_helper_chooser_set_parent (dtask->priv->helper_chooser, main_window);
+
+ /* map ISO639 to language names */
+ dtask->priv->language = gpk_language_new ();
+ gpk_language_populate (dtask->priv->language, NULL);
+
+ /* gat session settings */
+ dtask->priv->settings = g_settings_new (GPK_SETTINGS_SCHEMA);
+
+ /* get actions */
+ dtask->priv->control = pk_control_new ();
+ dtask->priv->task = PK_TASK(gpk_task_new ());
+ dtask->priv->roles = pk_control_get_properties (dtask->priv->control, NULL, NULL);
+}
+
+/**
+ * gpk_dbus_task_finalize:
+ * @object: The object to finalize
+ **/
+static void
+gpk_dbus_task_finalize (GObject *object)
+{
+ GpkDbusTask *dtask;
+ GError *error;
+
+ g_return_if_fail (GPK_IS_DBUS_TASK (object));
+
+ dtask = GPK_DBUS_TASK (object);
+ g_return_if_fail (dtask->priv != NULL);
+
+ /* no reply was sent */
+ if (dtask->priv->context != NULL) {
+ error = g_error_new (GPK_DBUS_ERROR, PK_ERROR_ENUM_INTERNAL_ERROR, "context never was returned");
+ gpk_dbus_task_dbus_return_error (dtask, error);
+ g_error_free (error);
+ }
+
+ g_free (dtask->priv->parent_title);
+ g_free (dtask->priv->parent_icon_name);
+ g_free (dtask->priv->exec);
+ if (dtask->priv->cached_error_code != NULL)
+ g_object_unref (dtask->priv->cached_error_code);
+ g_strfreev (dtask->priv->files);
+ g_strfreev (dtask->priv->package_ids);
+ g_object_unref (PK_CLIENT(dtask->priv->task));
+ g_object_unref (dtask->priv->control);
+ g_object_unref (dtask->priv->settings);
+ g_object_unref (dtask->priv->dialog);
+ g_object_unref (dtask->priv->vendor);
+ g_object_unref (dtask->priv->language);
+ g_object_unref (dtask->priv->cancellable);
+ g_object_unref (dtask->priv->helper_run);
+ g_object_unref (dtask->priv->helper_chooser);
+
+ G_OBJECT_CLASS (gpk_dbus_task_parent_class)->finalize (object);
+}
+
+/**
+ * gpk_dbus_task_new:
+ *
+ * PkClient is a nice GObject wrapper for gnome-packagekit and makes installing software easy
+ *
+ * Return value: A new %GpkDbusTask instance
+ **/
+GpkDbusTask *
+gpk_dbus_task_new (void)
+{
+ GpkDbusTask *dtask;
+ dtask = g_object_new (GPK_TYPE_DBUS_TASK, NULL);
+ return GPK_DBUS_TASK (dtask);
+}
Index: gnome-packagekit-3.20.0/src/gpk-dbus-task.h
===================================================================
--- /dev/null
+++ gnome-packagekit-3.20.0/src/gpk-dbus-task.h
@@ -0,0 +1,161 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2009 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef __GPK_DBUS_TASK_H
+#define __GPK_DBUS_TASK_H
+
+#include <glib-object.h>
+#include <dbus/dbus-glib.h>
+#include <packagekit-glib2/packagekit.h>
+
+G_BEGIN_DECLS
+
+#define GPK_TYPE_DBUS_TASK (gpk_dbus_task_get_type ())
+#define GPK_DBUS_TASK(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GPK_TYPE_DBUS_TASK, GpkDbusTask))
+#define GPK_DBUS_TASK_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GPK_TYPE_DBUS_TASK, GpkDbusTaskClass))
+#define GPK_IS_DBUS_TASK(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GPK_TYPE_DBUS_TASK))
+#define GPK_IS_DBUS_TASK_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GPK_TYPE_DBUS_TASK))
+#define GPK_DBUS_TASK_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GPK_TYPE_DBUS_TASK, GpkDbusTaskClass))
+
+typedef struct _GpkDbusTaskPrivate GpkDbusTaskPrivate;
+typedef struct _GpkDbusTask GpkDbusTask;
+typedef struct _GpkDbusTaskClass GpkDbusTaskClass;
+
+struct _GpkDbusTask
+{
+ GObject parent;
+ GpkDbusTaskPrivate *priv;
+};
+
+struct _GpkDbusTaskClass
+{
+ GObjectClass parent_class;
+};
+
+/**
+ * GpkDbusTaskInteract:
+ */
+typedef enum
+{
+ GPK_CLIENT_INTERACT_CONFIRM_SEARCH,
+ GPK_CLIENT_INTERACT_CONFIRM_DEPS,
+ GPK_CLIENT_INTERACT_CONFIRM_INSTALL,
+ GPK_CLIENT_INTERACT_PROGRESS,
+ GPK_CLIENT_INTERACT_FINISHED,
+ GPK_CLIENT_INTERACT_WARNING,
+ GPK_CLIENT_INTERACT_UNKNOWN
+} GpkDbusTaskInteract;
+
+#define GPK_CLIENT_INTERACT_NEVER 0
+#define GPK_CLIENT_INTERACT_ALWAYS pk_bitfield_from_enums (GPK_CLIENT_INTERACT_WARNING, \
+ GPK_CLIENT_INTERACT_CONFIRM_SEARCH, \
+ GPK_CLIENT_INTERACT_CONFIRM_DEPS, \
+ GPK_CLIENT_INTERACT_CONFIRM_INSTALL, \
+ GPK_CLIENT_INTERACT_PROGRESS, \
+ GPK_CLIENT_INTERACT_FINISHED, -1)
+#define GPK_CLIENT_INTERACT_WARNING_CONFIRM_PROGRESS pk_bitfield_from_enums (GPK_CLIENT_INTERACT_WARNING, \
+ GPK_CLIENT_INTERACT_CONFIRM_SEARCH, \
+ GPK_CLIENT_INTERACT_CONFIRM_DEPS, \
+ GPK_CLIENT_INTERACT_CONFIRM_INSTALL, \
+ GPK_CLIENT_INTERACT_PROGRESS, -1)
+#define GPK_CLIENT_INTERACT_WARNING pk_bitfield_from_enums (GPK_CLIENT_INTERACT_WARNING, -1)
+#define GPK_CLIENT_INTERACT_WARNING_PROGRESS pk_bitfield_from_enums (GPK_CLIENT_INTERACT_WARNING, \
+ GPK_CLIENT_INTERACT_PROGRESS, -1)
+
+GQuark gpk_dbus_task_error_quark (void);
+GType gpk_dbus_task_get_type (void);
+GType gpk_dbus_task_error_get_type (void);
+GpkDbusTask *gpk_dbus_task_new (void);
+
+/* callback when done */
+typedef void (*GpkDbusTaskFinishedCb) (GpkDbusTask *dtask,
+ gpointer userdata);
+
+/* methods that expect a DBusGMethodInvocation return */
+void gpk_dbus_task_is_installed (GpkDbusTask *dtask,
+ const gchar *package_name,
+ GpkDbusTaskFinishedCb finished_cb,
+ gpointer userdata);
+void gpk_dbus_task_search_file (GpkDbusTask *dtask,
+ const gchar *search_file,
+ GpkDbusTaskFinishedCb finished_cb,
+ gpointer userdata);
+void gpk_dbus_task_install_package_files (GpkDbusTask *dtask,
+ gchar **files_rel,
+ GpkDbusTaskFinishedCb finished_cb,
+ gpointer userdata);
+void gpk_dbus_task_install_provide_files (GpkDbusTask *dtask,
+ gchar **full_paths,
+ GpkDbusTaskFinishedCb finished_cb,
+ gpointer userdata);
+void gpk_dbus_task_install_mime_types (GpkDbusTask *dtask,
+ gchar **mime_types,
+ GpkDbusTaskFinishedCb finished_cb,
+ gpointer userdata);
+void gpk_dbus_task_install_gstreamer_resources (GpkDbusTask *dtask,
+ gchar **codec_names,
+ GpkDbusTaskFinishedCb finished_cb,
+ gpointer userdata);
+void gpk_dbus_task_install_fontconfig_resources (GpkDbusTask *dtask,
+ gchar **fonts,
+ GpkDbusTaskFinishedCb finished_cb,
+ gpointer userdata);
+void gpk_dbus_task_install_resources (GpkDbusTask *dtask,
+ gchar **resources,
+ GpkDbusTaskFinishedCb finished_cb,
+ gpointer userdata);
+void gpk_dbus_task_install_printer_drivers (GpkDbusTask *dtask,
+ gchar **ids,
+ GpkDbusTaskFinishedCb finished_cb,
+ gpointer userdata);
+void gpk_dbus_task_install_package_names (GpkDbusTask *dtask,
+ gchar **packages,
+ GpkDbusTaskFinishedCb finished_cb,
+ gpointer userdata);
+void gpk_dbus_task_remove_package_by_file (GpkDbusTask *dtask,
+ gchar **full_paths,
+ GpkDbusTaskFinishedCb finished_cb,
+ gpointer userdata);
+
+/* set state */
+gboolean gpk_dbus_task_set_interaction (GpkDbusTask *dtask,
+ PkBitfield interact);
+gboolean gpk_dbus_task_set_timestamp (GpkDbusTask *dtask,
+ guint timeout);
+gboolean gpk_dbus_task_set_context (GpkDbusTask *dtask,
+ DBusGMethodInvocation *context);
+gboolean gpk_dbus_task_set_xid (GpkDbusTask *dtask,
+ guint xid);
+gboolean gpk_dbus_task_set_exec (GpkDbusTask *dtask,
+ const gchar *exec);
+
+/* for self checks */
+gchar *gpk_dbus_task_font_tag_to_localised_name (GpkDbusTask *dtask,
+ const gchar *tag);
+gboolean gpk_dbus_task_path_is_trusted (const gchar *exec);
+gchar *gpk_dbus_task_get_package_for_exec (GpkDbusTask *dtask,
+ const gchar *exec);
+gchar *gpk_dbus_task_font_tag_to_lang (const gchar *tag);
+
+
+G_END_DECLS
+
+#endif /* __GPK_DBUS_TASK_H */
Index: gnome-packagekit-3.20.0/src/gpk-dbus.c
===================================================================
--- /dev/null
+++ gnome-packagekit-3.20.0/src/gpk-dbus.c
@@ -0,0 +1,590 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2008-2009 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include "config.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <errno.h>
+#include <signal.h>
+
+#include <string.h>
+#include <sys/types.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif /* HAVE_UNISTD_H */
+
+#include <sys/wait.h>
+#include <fcntl.h>
+
+#include <glib/gi18n.h>
+#include <dbus/dbus-glib.h>
+#include <dbus/dbus-glib-lowlevel.h>
+#include <packagekit-glib2/packagekit.h>
+
+#include "egg-string.h"
+
+#include "gpk-dbus.h"
+#include "gpk-dbus-task.h"
+#include "gpk-x11.h"
+#include "gpk-common.h"
+
+static void gpk_dbus_finalize (GObject *object);
+
+#define GPK_DBUS_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GPK_TYPE_DBUS, GpkDbusPrivate))
+
+struct GpkDbusPrivate
+{
+ GSettings *settings;
+ gint timeout_tmp;
+ GTimer *timer;
+ guint refcount;
+ GpkX11 *x11;
+ DBusGProxy *proxy_session_pid;
+ DBusGProxy *proxy_system_pid;
+};
+
+G_DEFINE_TYPE (GpkDbus, gpk_dbus, G_TYPE_OBJECT)
+
+/**
+ * gpk_dbus_error_quark:
+ * Return value: Our personal error quark.
+ **/
+GQuark
+gpk_dbus_error_quark (void)
+{
+ static GQuark quark = 0;
+ if (!quark)
+ quark = g_quark_from_static_string ("gpk_dbus_error");
+ return quark;
+}
+
+/**
+ * gpk_dbus_error_get_type:
+ **/
+GType
+gpk_dbus_error_get_type (void)
+{
+ static GType etype = 0;
+
+ if (etype == 0) {
+ guint i;
+ static GEnumValue values[PK_ERROR_ENUM_LAST];
+ for (i = 0; i < PK_ERROR_ENUM_LAST; i++) {
+ values[i].value = i;
+ values[i].value_name = pk_error_enum_to_string (i);
+ values[i].value_nick = pk_error_enum_to_string (i);
+ }
+ etype = g_enum_register_static ("GpkDbusError", values);
+ }
+ return etype;
+}
+
+/**
+ * gpk_dbus_get_idle_time:
+ **/
+guint
+gpk_dbus_get_idle_time (GpkDbus *dbus)
+{
+ guint idle = 0;
+
+ /* we need to return 0 if there is a task in progress */
+ if (dbus->priv->refcount > 0)
+ goto out;
+
+ idle = (guint) g_timer_elapsed (dbus->priv->timer, NULL);
+ g_debug ("we've been idle for %is", idle);
+out:
+ return idle;
+}
+
+/**
+ * gpk_dbus_get_pid_session:
+ **/
+static guint
+gpk_dbus_get_pid_session (GpkDbus *dbus, const gchar *sender)
+{
+ guint pid = G_MAXUINT;
+ gboolean ret;
+ GError *error = NULL;
+
+ /* get pid from DBus (quite slow) */
+ ret = dbus_g_proxy_call (dbus->priv->proxy_session_pid, "GetConnectionUnixProcessID", &error,
+ G_TYPE_STRING, sender,
+ G_TYPE_INVALID,
+ G_TYPE_UINT, &pid,
+ G_TYPE_INVALID);
+ if (!ret) {
+ g_debug ("failed to get pid from session: %s", error->message);
+ g_error_free (error);
+ goto out;
+ }
+out:
+ return pid;
+}
+
+/**
+ * gpk_dbus_get_pid_system:
+ **/
+static guint
+gpk_dbus_get_pid_system (GpkDbus *dbus, const gchar *sender)
+{
+ guint pid = G_MAXUINT;
+ gboolean ret;
+ GError *error = NULL;
+
+ /* get pid from DBus (quite slow) */
+ ret = dbus_g_proxy_call (dbus->priv->proxy_system_pid, "GetConnectionUnixProcessID", &error,
+ G_TYPE_STRING, sender,
+ G_TYPE_INVALID,
+ G_TYPE_UINT, &pid,
+ G_TYPE_INVALID);
+ if (!ret) {
+ g_debug ("failed to get pid from system: %s", error->message);
+ g_error_free (error);
+ goto out;
+ }
+out:
+ return pid;
+}
+
+/**
+ * gpk_dbus_get_pid:
+ **/
+static guint
+gpk_dbus_get_pid (GpkDbus *dbus, const gchar *sender)
+{
+ guint pid;
+
+ g_return_val_if_fail (PK_IS_DBUS (dbus), G_MAXUINT);
+ g_return_val_if_fail (dbus->priv->proxy_session_pid != NULL, G_MAXUINT);
+ g_return_val_if_fail (dbus->priv->proxy_system_pid != NULL, G_MAXUINT);
+ g_return_val_if_fail (sender != NULL, G_MAXUINT);
+
+ /* check system bus first */
+ pid = gpk_dbus_get_pid_system (dbus, sender);
+ if (pid != G_MAXUINT)
+ goto out;
+
+ /* and then session bus */
+ pid = gpk_dbus_get_pid_session (dbus, sender);
+ if (pid != G_MAXUINT)
+ goto out;
+
+ /* should be impossible */
+ g_warning ("could not find pid!");
+out:
+ return pid;
+}
+
+/**
+ * gpk_dbus_get_exec_for_sender:
+ **/
+static gchar *
+gpk_dbus_get_exec_for_sender (GpkDbus *dbus, const gchar *sender)
+{
+ gchar *filename = NULL;
+ gchar *cmdline = NULL;
+ GError *error = NULL;
+ guint pid;
+
+ g_return_val_if_fail (PK_IS_DBUS (dbus), NULL);
+ g_return_val_if_fail (sender != NULL, NULL);
+
+ /* get pid */
+ pid = gpk_dbus_get_pid (dbus, sender);
+ if (pid == G_MAXUINT) {
+ g_warning ("failed to get PID");
+ goto out;
+ }
+
+ /* get command line from proc */
+ filename = g_strdup_printf ("/proc/%i/exe", pid);
+ cmdline = g_file_read_link (filename, &error);
+ if (cmdline == NULL) {
+ g_warning ("failed to find exec: %s", error->message);
+ g_error_free (error);
+ }
+out:
+ g_free (filename);
+ return cmdline;
+}
+
+/**
+ * gpk_dbus_set_interaction_from_text:
+ **/
+static void
+gpk_dbus_set_interaction_from_text (PkBitfield *interact, gint *timeout, const gchar *interaction)
+{
+ guint i;
+ guint len;
+ gchar **interactions;
+ interactions = g_strsplit (interaction, ",", -1);
+ len = g_strv_length (interactions);
+
+ /* do special keys first */
+ for (i=0; i<len; i++) {
+ if (g_strcmp0 (interactions[i], "always") == 0)
+ *interact = GPK_CLIENT_INTERACT_ALWAYS;
+ else if (g_strcmp0 (interactions[i], "never") == 0)
+ *interact = GPK_CLIENT_INTERACT_NEVER;
+ }
+
+ /* add or remove from defaults */
+ for (i=0; i<len; i++) {
+ /* show */
+ if (g_strcmp0 (interactions[i], "show-confirm-search") == 0)
+ pk_bitfield_add (*interact, GPK_CLIENT_INTERACT_CONFIRM_SEARCH);
+ else if (g_strcmp0 (interactions[i], "show-confirm-deps") == 0)
+ pk_bitfield_add (*interact, GPK_CLIENT_INTERACT_CONFIRM_DEPS);
+ else if (g_strcmp0 (interactions[i], "show-confirm-install") == 0)
+ pk_bitfield_add (*interact, GPK_CLIENT_INTERACT_CONFIRM_INSTALL);
+ else if (g_strcmp0 (interactions[i], "show-progress") == 0)
+ pk_bitfield_add (*interact, GPK_CLIENT_INTERACT_PROGRESS);
+ else if (g_strcmp0 (interactions[i], "show-finished") == 0)
+ pk_bitfield_add (*interact, GPK_CLIENT_INTERACT_FINISHED);
+ else if (g_strcmp0 (interactions[i], "show-warning") == 0)
+ pk_bitfield_add (*interact, GPK_CLIENT_INTERACT_WARNING);
+ /* hide */
+ else if (g_strcmp0 (interactions[i], "hide-confirm-search") == 0)
+ pk_bitfield_remove (*interact, GPK_CLIENT_INTERACT_CONFIRM_SEARCH);
+ else if (g_strcmp0 (interactions[i], "hide-confirm-deps") == 0)
+ pk_bitfield_remove (*interact, GPK_CLIENT_INTERACT_CONFIRM_DEPS);
+ else if (g_strcmp0 (interactions[i], "hide-confirm-install") == 0)
+ pk_bitfield_remove (*interact, GPK_CLIENT_INTERACT_CONFIRM_INSTALL);
+ else if (g_strcmp0 (interactions[i], "hide-progress") == 0)
+ pk_bitfield_remove (*interact, GPK_CLIENT_INTERACT_PROGRESS);
+ else if (g_strcmp0 (interactions[i], "hide-finished") == 0)
+ pk_bitfield_remove (*interact, GPK_CLIENT_INTERACT_FINISHED);
+ else if (g_strcmp0 (interactions[i], "hide-warning") == 0)
+ pk_bitfield_remove (*interact, GPK_CLIENT_INTERACT_WARNING);
+ /* wait */
+ else if (g_str_has_prefix (interactions[i], "timeout="))
+ *timeout = atoi (&interactions[i][8]);
+ }
+ g_strfreev (interactions);
+}
+
+/**
+ * gpk_dbus_parse_interaction:
+ **/
+static void
+gpk_dbus_parse_interaction (GpkDbus *dbus, const gchar *interaction, PkBitfield *interact, gint *timeout)
+{
+ gchar *policy;
+
+ /* set temp default */
+ *interact = 0;
+ dbus->priv->timeout_tmp = -1;
+
+ /* get default policy from settings */
+ policy = g_settings_get_string (dbus->priv->settings, GPK_SETTINGS_DBUS_DEFAULT_INTERACTION);
+ if (policy != NULL) {
+ g_debug ("default is %s", policy);
+ gpk_dbus_set_interaction_from_text (interact, &dbus->priv->timeout_tmp, policy);
+ }
+ g_free (policy);
+
+ /* now override with policy from client */
+ gpk_dbus_set_interaction_from_text (interact, &dbus->priv->timeout_tmp, interaction);
+ g_debug ("client is %s", interaction);
+
+ /* now override with enforced policy */
+ policy = g_settings_get_string (dbus->priv->settings, GPK_SETTINGS_DBUS_ENFORCED_INTERACTION);
+ if (policy != NULL) {
+ g_debug ("enforced is %s", policy);
+ gpk_dbus_set_interaction_from_text (interact, &dbus->priv->timeout_tmp, policy);
+ }
+ g_free (policy);
+
+ /* copy from temp */
+ *timeout = dbus->priv->timeout_tmp;
+}
+
+/**
+ * gpk_dbus_create_task:
+ **/
+static GpkDbusTask *
+gpk_dbus_create_task (GpkDbus *dbus, guint32 xid, const gchar *interaction, DBusGMethodInvocation *context)
+{
+ GpkDbusTask *task;
+ PkBitfield interact = 0;
+ gint timeout = 0;
+ gchar *sender;
+ gchar *exec;
+ guint timestamp = 0;
+ gboolean ret;
+
+ task = gpk_dbus_task_new ();
+
+ /* work out what interaction the task should use */
+ gpk_dbus_parse_interaction (dbus, interaction, &interact, &timeout);
+
+ /* set interaction mode */
+ g_debug ("interact=%i", (gint) interact);
+ gpk_dbus_task_set_interaction (task, interact);
+
+ /* try to get the user time of the window */
+ if (xid != 0) {
+ ret = gpk_x11_set_xid (dbus->priv->x11, xid);
+ if (ret)
+ timestamp = gpk_x11_get_user_time (dbus->priv->x11);
+ }
+
+ /* set the context for the return values */
+ gpk_dbus_task_set_context (task, context);
+
+ /* set the last interaction */
+ gpk_dbus_task_set_timestamp (task, timestamp);
+
+ /* set the window for the modal and timestamp */
+ if (xid != 0)
+ gpk_dbus_task_set_xid (task, xid);
+
+ /* get the program name and set */
+ sender = dbus_g_method_get_sender (context);
+ exec = gpk_dbus_get_exec_for_sender (dbus, sender);
+ if (exec != NULL)
+ gpk_dbus_task_set_exec (task, exec);
+
+ /* unref on delete */
+ //g_signal_connect...
+
+ /* reset time */
+ g_timer_reset (dbus->priv->timer);
+ dbus->priv->refcount++;
+
+ g_free (sender);
+ g_free (exec);
+ return task;
+}
+
+/**
+ * gpk_dbus_task_finished_cb:
+ **/
+static void
+gpk_dbus_task_finished_cb (GpkDbusTask *task, GpkDbus *dbus)
+{
+ /* one context has returned */
+ if (dbus->priv->refcount > 0)
+ dbus->priv->refcount--;
+
+ /* reset time */
+ g_timer_reset (dbus->priv->timer);
+
+ g_object_unref (task);
+}
+
+/**
+ * gpk_dbus_is_installed:
+ **/
+void
+gpk_dbus_is_installed (GpkDbus *dbus, const gchar *package_name, const gchar *interaction, DBusGMethodInvocation *context)
+{
+ GpkDbusTask *task;
+ task = gpk_dbus_create_task (dbus, 0, interaction, context);
+ gpk_dbus_task_is_installed (task, package_name, (GpkDbusTaskFinishedCb) gpk_dbus_task_finished_cb, dbus);
+}
+
+/**
+ * gpk_dbus_search_file:
+ **/
+void
+gpk_dbus_search_file (GpkDbus *dbus, const gchar *file_name, const gchar *interaction, DBusGMethodInvocation *context)
+{
+ GpkDbusTask *task;
+ task = gpk_dbus_create_task (dbus, 0, interaction, context);
+ gpk_dbus_task_search_file (task, file_name, (GpkDbusTaskFinishedCb) gpk_dbus_task_finished_cb, dbus);
+}
+
+/**
+ * gpk_dbus_install_package_files:
+ **/
+void
+gpk_dbus_install_package_files (GpkDbus *dbus, guint32 xid, gchar **files, const gchar *interaction, DBusGMethodInvocation *context)
+{
+ GpkDbusTask *task;
+ task = gpk_dbus_create_task (dbus, xid, interaction, context);
+ gpk_dbus_task_install_package_files (task, files, (GpkDbusTaskFinishedCb) gpk_dbus_task_finished_cb, dbus);
+}
+
+/**
+ * gpk_dbus_install_provide_files:
+ **/
+void
+gpk_dbus_install_provide_files (GpkDbus *dbus, guint32 xid, gchar **files, const gchar *interaction, DBusGMethodInvocation *context)
+{
+ GpkDbusTask *task;
+ task = gpk_dbus_create_task (dbus, xid, interaction, context);
+ gpk_dbus_task_install_provide_files (task, files, (GpkDbusTaskFinishedCb) gpk_dbus_task_finished_cb, dbus);
+}
+
+/**
+ * gpk_dbus_remove_package_by_files:
+ **/
+void
+gpk_dbus_remove_package_by_files (GpkDbus *dbus, guint32 xid, gchar **files, const gchar *interaction, DBusGMethodInvocation *context)
+{
+ GpkDbusTask *task;
+ task = gpk_dbus_create_task (dbus, xid, interaction, context);
+ gpk_dbus_task_remove_package_by_file (task, files, (GpkDbusTaskFinishedCb) gpk_dbus_task_finished_cb, dbus);
+}
+
+/**
+ * gpk_dbus_install_package_names:
+ **/
+void
+gpk_dbus_install_package_names (GpkDbus *dbus, guint32 xid, gchar **packages, const gchar *interaction, DBusGMethodInvocation *context)
+{
+ GpkDbusTask *task;
+ task = gpk_dbus_create_task (dbus, xid, interaction, context);
+ gpk_dbus_task_install_package_names (task, packages, (GpkDbusTaskFinishedCb) gpk_dbus_task_finished_cb, dbus);
+}
+
+/**
+ * gpk_dbus_install_mime_types:
+ **/
+void
+gpk_dbus_install_mime_types (GpkDbus *dbus, guint32 xid, gchar **mime_types, const gchar *interaction, DBusGMethodInvocation *context)
+{
+ GpkDbusTask *task;
+ task = gpk_dbus_create_task (dbus, xid, interaction, context);
+ gpk_dbus_task_install_mime_types (task, mime_types, (GpkDbusTaskFinishedCb) gpk_dbus_task_finished_cb, dbus);
+}
+
+/**
+ * gpk_dbus_install_fontconfig_resources:
+ **/
+void
+gpk_dbus_install_fontconfig_resources (GpkDbus *dbus, guint32 xid, gchar **resources, const gchar *interaction, DBusGMethodInvocation *context)
+{
+ GpkDbusTask *task;
+ task = gpk_dbus_create_task (dbus, xid, interaction, context);
+ gpk_dbus_task_install_fontconfig_resources (task, resources, (GpkDbusTaskFinishedCb) gpk_dbus_task_finished_cb, dbus);
+}
+
+/**
+ * gpk_dbus_install_gstreamer_resources:
+ **/
+void
+gpk_dbus_install_gstreamer_resources (GpkDbus *dbus, guint32 xid, gchar **resources, const gchar *interaction, DBusGMethodInvocation *context)
+{
+ GpkDbusTask *task;
+ task = gpk_dbus_create_task (dbus, xid, interaction, context);
+ gpk_dbus_task_install_gstreamer_resources (task, resources, (GpkDbusTaskFinishedCb) gpk_dbus_task_finished_cb, dbus);
+}
+
+/**
+ * gpk_dbus_install_resources:
+ **/
+void
+gpk_dbus_install_resources (GpkDbus *dbus, guint32 xid, const gchar *type, gchar **resources, const gchar *interaction, DBusGMethodInvocation *context)
+{
+ GpkDbusTask *task;
+ task = gpk_dbus_create_task (dbus, xid, interaction, context);
+ gpk_dbus_task_install_resources (task, resources, (GpkDbusTaskFinishedCb) gpk_dbus_task_finished_cb, dbus);
+}
+
+/**
+ * gpk_dbus_install_printer_drivers:
+ **/
+void
+gpk_dbus_install_printer_drivers (GpkDbus *dbus, guint32 xid, gchar **device_ids, const gchar *interaction, DBusGMethodInvocation *context)
+{
+ GpkDbusTask *task;
+ task = gpk_dbus_create_task (dbus, xid, interaction, context);
+ gpk_dbus_task_install_printer_drivers (task, device_ids, (GpkDbusTaskFinishedCb) gpk_dbus_task_finished_cb, dbus);
+}
+
+/**
+ * gpk_dbus_class_init:
+ * @klass: The GpkDbusClass
+ **/
+static void
+gpk_dbus_class_init (GpkDbusClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ object_class->finalize = gpk_dbus_finalize;
+ g_type_class_add_private (klass, sizeof (GpkDbusPrivate));
+}
+
+/**
+ * gpk_dbus_init:
+ * @dbus: This class instance
+ **/
+static void
+gpk_dbus_init (GpkDbus *dbus)
+{
+ DBusGConnection *connection;
+
+ dbus->priv = GPK_DBUS_GET_PRIVATE (dbus);
+ dbus->priv->timeout_tmp = -1;
+ dbus->priv->settings = g_settings_new (GPK_SETTINGS_SCHEMA);
+ dbus->priv->x11 = gpk_x11_new ();
+ dbus->priv->timer = g_timer_new ();
+
+ /* find out PIDs on the session bus */
+ connection = dbus_g_bus_get (DBUS_BUS_SESSION, NULL);
+ dbus->priv->proxy_session_pid = dbus_g_proxy_new_for_name_owner (connection,
+ "org.freedesktop.DBus",
+ "/org/freedesktop/DBus/Bus",
+ "org.freedesktop.DBus", NULL);
+ /* find out PIDs on the system bus */
+ connection = dbus_g_bus_get (DBUS_BUS_SYSTEM, NULL);
+ dbus->priv->proxy_system_pid = dbus_g_proxy_new_for_name_owner (connection,
+ "org.freedesktop.DBus",
+ "/org/freedesktop/DBus/Bus",
+ "org.freedesktop.DBus", NULL);
+}
+
+/**
+ * gpk_dbus_finalize:
+ * @object: The object to finalize
+ **/
+static void
+gpk_dbus_finalize (GObject *object)
+{
+ GpkDbus *dbus;
+ g_return_if_fail (PK_IS_DBUS (object));
+
+ dbus = GPK_DBUS (object);
+ g_return_if_fail (dbus->priv != NULL);
+ g_timer_destroy (dbus->priv->timer);
+ g_object_unref (dbus->priv->settings);
+ g_object_unref (dbus->priv->x11);
+ g_object_unref (dbus->priv->proxy_session_pid);
+ g_object_unref (dbus->priv->proxy_system_pid);
+
+ G_OBJECT_CLASS (gpk_dbus_parent_class)->finalize (object);
+}
+
+/**
+ * gpk_dbus_new:
+ *
+ * Return value: a new GpkDbus object.
+ **/
+GpkDbus *
+gpk_dbus_new (void)
+{
+ GpkDbus *dbus;
+ dbus = g_object_new (GPK_TYPE_DBUS, NULL);
+ return GPK_DBUS (dbus);
+}
Index: gnome-packagekit-3.20.0/src/gpk-dbus.h
===================================================================
--- /dev/null
+++ gnome-packagekit-3.20.0/src/gpk-dbus.h
@@ -0,0 +1,124 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2008 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef __GPK_DBUS_H
+#define __GPK_DBUS_H
+
+#include <glib-object.h>
+#include <dbus/dbus-glib.h>
+
+G_BEGIN_DECLS
+
+#define GPK_TYPE_DBUS (gpk_dbus_get_type ())
+#define GPK_DBUS(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GPK_TYPE_DBUS, GpkDbus))
+#define GPK_DBUS_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GPK_TYPE_DBUS, GpkDbusClass))
+#define PK_IS_DBUS(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GPK_TYPE_DBUS))
+#define PK_IS_DBUS_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GPK_TYPE_DBUS))
+#define GPK_DBUS_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GPK_TYPE_DBUS, GpkDbusClass))
+#define GPK_DBUS_ERROR (gpk_dbus_error_quark ())
+#define GPK_DBUS_TYPE_ERROR (gpk_dbus_error_get_type ())
+
+typedef struct GpkDbusPrivate GpkDbusPrivate;
+
+typedef struct
+{
+ GObject parent;
+ GpkDbusPrivate *priv;
+} GpkDbus;
+
+typedef struct
+{
+ GObjectClass parent_class;
+} GpkDbusClass;
+
+GQuark gpk_dbus_error_quark (void);
+GType gpk_dbus_error_get_type (void);
+GType gpk_dbus_get_type (void);
+GpkDbus *gpk_dbus_new (void);
+
+guint gpk_dbus_get_idle_time (GpkDbus *dbus);
+
+/* org.freedesktop.PackageKit.Query */
+void gpk_dbus_is_installed (GpkDbus *dbus,
+ const gchar *package_name,
+ const gchar *interaction,
+ DBusGMethodInvocation *context);
+void gpk_dbus_search_file (GpkDbus *dbus,
+ const gchar *file_name,
+ const gchar *interaction,
+ DBusGMethodInvocation *context);
+
+/* org.freedesktop.PackageKit.Modify */
+void gpk_dbus_install_provide_files (GpkDbus *dbus,
+ guint32 xid,
+ gchar **files,
+ const gchar *interaction,
+ DBusGMethodInvocation *context);
+void gpk_dbus_install_catalogs (GpkDbus *dbus,
+ guint32 xid,
+ gchar **files,
+ const gchar *interaction,
+ DBusGMethodInvocation *context);
+void gpk_dbus_install_package_files (GpkDbus *dbus,
+ guint32 xid,
+ gchar **files,
+ const gchar *interaction,
+ DBusGMethodInvocation *context);
+void gpk_dbus_install_package_names (GpkDbus *dbus,
+ guint32 xid,
+ gchar **packages,
+ const gchar *interaction,
+ DBusGMethodInvocation *context);
+void gpk_dbus_install_mime_types (GpkDbus *dbus,
+ guint32 xid,
+ gchar **mime_types,
+ const gchar *interaction,
+ DBusGMethodInvocation *context);
+void gpk_dbus_install_fontconfig_resources (GpkDbus *dbus,
+ guint32 xid,
+ gchar **fonts,
+ const gchar *interaction,
+ DBusGMethodInvocation *context);
+void gpk_dbus_install_gstreamer_resources (GpkDbus *dbus,
+ guint32 xid,
+ gchar **codecs,
+ const gchar *interaction,
+ DBusGMethodInvocation *context);
+void gpk_dbus_install_resources (GpkDbus *dbus,
+ guint32 xid,
+ const gchar *type,
+ gchar **resources,
+ const gchar *interaction,
+ DBusGMethodInvocation *context);
+void gpk_dbus_remove_package_by_files (GpkDbus *dbus,
+ guint32 xid,
+ gchar **files,
+ const gchar *interaction,
+ DBusGMethodInvocation *context);
+
+void gpk_dbus_install_printer_drivers (GpkDbus *dbus,
+ guint32 xid,
+ gchar **device_ids,
+ const gchar *interaction,
+ DBusGMethodInvocation *context);
+G_END_DECLS
+
+#endif /* __GPK_DBUS_H */
Index: gnome-packagekit-3.20.0/src/gpk-enum.c
===================================================================
--- gnome-packagekit-3.20.0.orig/src/gpk-enum.c
+++ gnome-packagekit-3.20.0/src/gpk-enum.c
@@ -100,6 +100,46 @@ static const PkEnumMatch enum_status_ico
{0, NULL}
};
+static const PkEnumMatch enum_status_animation[] = {
+ {PK_STATUS_ENUM_UNKNOWN, "help-browser"},
+ {PK_STATUS_ENUM_CANCEL, "pk-action-cleanup"},
+ {PK_STATUS_ENUM_CLEANUP, "pk-action-cleanup"},
+ {PK_STATUS_ENUM_COMMIT, "pk-setup"},
+ {PK_STATUS_ENUM_DEP_RESOLVE, "pk-action-testing"},
+ {PK_STATUS_ENUM_DOWNLOAD_CHANGELOG, "pk-action-refresh-cache"},
+ {PK_STATUS_ENUM_DOWNLOAD_FILELIST, "pk-action-refresh-cache"},
+ {PK_STATUS_ENUM_DOWNLOAD_GROUP, "pk-action-refresh-cache"},
+ {PK_STATUS_ENUM_DOWNLOAD_PACKAGELIST, "pk-action-refresh-cache"},
+ {PK_STATUS_ENUM_DOWNLOAD, "pk-action-download"},
+ {PK_STATUS_ENUM_DOWNLOAD_REPOSITORY, "pk-action-refresh-cache"},
+ {PK_STATUS_ENUM_DOWNLOAD_UPDATEINFO, "pk-action-refresh-cache"},
+ {PK_STATUS_ENUM_FINISHED, "pk-package-cleanup"},
+ {PK_STATUS_ENUM_GENERATE_PACKAGE_LIST, "pk-action-searching"},
+ {PK_STATUS_ENUM_WAITING_FOR_LOCK, "pk-action-waiting"},
+ {PK_STATUS_ENUM_WAITING_FOR_AUTH, "pk-action-waiting"},
+ {PK_STATUS_ENUM_INFO, "process-working"},
+ {PK_STATUS_ENUM_INSTALL, "pk-action-installing"},
+ {PK_STATUS_ENUM_LOADING_CACHE, "pk-action-refresh-cache"},
+ {PK_STATUS_ENUM_OBSOLETE, "pk-package-cleanup"},
+ {PK_STATUS_ENUM_QUERY, "pk-action-searching"},
+ {PK_STATUS_ENUM_REFRESH_CACHE, "pk-action-refresh-cache"},
+ {PK_STATUS_ENUM_REMOVE, "pk-action-removing"},
+ {PK_STATUS_ENUM_REPACKAGING, "pk-package-info"},
+ {PK_STATUS_ENUM_REQUEST, "process-working"},
+ {PK_STATUS_ENUM_RUNNING, "pk-setup"},
+ {PK_STATUS_ENUM_SCAN_APPLICATIONS, "pk-action-searching"},
+ {PK_STATUS_ENUM_SETUP, "pk-package-info"},
+ {PK_STATUS_ENUM_SIG_CHECK, "pk-package-info"},
+ {PK_STATUS_ENUM_TEST_COMMIT, "pk-action-testing"},
+ {PK_STATUS_ENUM_UPDATE, "pk-action-installing"},
+ {PK_STATUS_ENUM_WAIT, "pk-action-waiting"},
+ {PK_STATUS_ENUM_SCAN_PROCESS_LIST, "pk-package-info"},
+ {PK_STATUS_ENUM_CHECK_EXECUTABLE_FILES, "pk-package-info"},
+ {PK_STATUS_ENUM_CHECK_LIBRARIES, "pk-package-info"},
+ {PK_STATUS_ENUM_COPY_FILES, "pk-package-info"},
+ {0, NULL}
+};
+
static const PkEnumMatch enum_role_icon_name[] = {
{PK_ROLE_ENUM_UNKNOWN, "help-browser"}, /* fall though value */
{PK_ROLE_ENUM_ACCEPT_EULA, "pk-package-info"},
@@ -187,6 +227,17 @@ static const PkEnumMatch enum_restart_ic
{0, NULL}
};
+static const PkEnumMatch enum_restart_dialog_icon_name[] = {
+ {PK_RESTART_ENUM_UNKNOWN, "help-browser"}, /* fall though value */
+ {PK_RESTART_ENUM_NONE, "dialog-information"},
+ {PK_RESTART_ENUM_SYSTEM, "dialog-error"},
+ {PK_RESTART_ENUM_SESSION, "dialog-warning"},
+ {PK_RESTART_ENUM_APPLICATION, "dialog-warning"},
+ {PK_RESTART_ENUM_SECURITY_SYSTEM, "dialog-error"},
+ {PK_RESTART_ENUM_SECURITY_SESSION, "dialog-error"},
+ {0, NULL}
+};
+
/**
* gpk_media_type_enum_to_localised_text:
**/
@@ -757,6 +808,32 @@ gpk_restart_enum_to_localised_text (PkRe
}
/**
+ * gpk_update_state_enum_to_localised_text:
+ **/
+const gchar *
+gpk_update_state_enum_to_localised_text (PkUpdateStateEnum state)
+{
+ const gchar *text = NULL;
+ switch (state) {
+ case PK_UPDATE_STATE_ENUM_STABLE:
+ /* TRANSLATORS: A distribution stability level */
+ text = _("Stable");
+ break;
+ case PK_UPDATE_STATE_ENUM_UNSTABLE:
+ /* TRANSLATORS: A distribution stability level */
+ text = _("Unstable");
+ break;
+ case PK_UPDATE_STATE_ENUM_TESTING:
+ /* TRANSLATORS: A distribution stability level */
+ text = _("Testing");
+ break;
+ default:
+ g_warning ("state unrecognized: %i", state);
+ }
+ return text;
+}
+
+/**
* gpk_status_enum_to_localised_text:
**/
const gchar *
@@ -915,6 +992,48 @@ gpk_status_enum_to_localised_text (PkSta
}
/**
+ * gpk_update_enum_to_localised_text:
+ **/
+gchar *
+gpk_update_enum_to_localised_text (PkInfoEnum info, guint number)
+{
+ gchar *text = NULL;
+ switch (info) {
+ case PK_INFO_ENUM_LOW:
+ /* TRANSLATORS: type of update */
+ text = g_strdup_printf (ngettext ("%i trivial update", "%i trivial updates", number), number);
+ break;
+ case PK_INFO_ENUM_NORMAL:
+ /* TRANSLATORS: type of update in the case that we don't have any data */
+ text = g_strdup_printf (ngettext ("%i update", "%i updates", number), number);
+ break;
+ case PK_INFO_ENUM_IMPORTANT:
+ /* TRANSLATORS: type of update */
+ text = g_strdup_printf (ngettext ("%i important update", "%i important updates", number), number);
+ break;
+ case PK_INFO_ENUM_SECURITY:
+ /* TRANSLATORS: type of update */
+ text = g_strdup_printf (ngettext ("%i security update", "%i security updates", number), number);
+ break;
+ case PK_INFO_ENUM_BUGFIX:
+ /* TRANSLATORS: type of update */
+ text = g_strdup_printf (ngettext ("%i bug fix update", "%i bug fix updates", number), number);
+ break;
+ case PK_INFO_ENUM_ENHANCEMENT:
+ /* TRANSLATORS: type of update */
+ text = g_strdup_printf (ngettext ("%i enhancement update", "%i enhancement updates", number), number);
+ break;
+ case PK_INFO_ENUM_BLOCKED:
+ /* TRANSLATORS: number of updates that cannot be installed due to deps */
+ text = g_strdup_printf (ngettext ("%i blocked update", "%i blocked updates", number), number);
+ break;
+ default:
+ g_warning ("update info unrecognized: %s", pk_info_enum_to_string (info));
+ }
+ return text;
+}
+
+/**
* gpk_info_enum_to_localised_text:
**/
const gchar *
@@ -977,7 +1096,7 @@ gpk_info_enum_to_localised_text (PkInfoE
/**
* gpk_info_enum_to_localised_present:
**/
-static const gchar *
+const gchar *
gpk_info_enum_to_localised_present (PkInfoEnum info)
{
const gchar *text = NULL;
@@ -1529,6 +1648,15 @@ gpk_status_enum_to_icon_name (PkStatusEn
}
/**
+ * gpk_status_enum_to_animation:
+ **/
+const gchar *
+gpk_status_enum_to_animation (PkStatusEnum status)
+{
+ return pk_enum_find_string (enum_status_animation, status);
+}
+
+/**
* gpk_role_enum_to_icon_name:
**/
const gchar *
@@ -1560,6 +1688,15 @@ gpk_restart_enum_to_icon_name (PkRestart
}
/**
+ * gpk_restart_enum_to_dialog_icon_name:
+ **/
+const gchar *
+gpk_restart_enum_to_dialog_icon_name (PkRestartEnum restart)
+{
+ return pk_enum_find_string (enum_restart_dialog_icon_name, restart);
+}
+
+/**
* gpk_info_status_enum_to_string:
**/
const gchar *
Index: gnome-packagekit-3.20.0/src/gpk-enum.h
===================================================================
--- gnome-packagekit-3.20.0.orig/src/gpk-enum.h
+++ gnome-packagekit-3.20.0/src/gpk-enum.h
@@ -84,10 +84,13 @@ const gchar *gpk_info_enum_to_localised_
G_GNUC_CONST;
const gchar *gpk_info_enum_to_localised_past (PkInfoEnum info)
G_GNUC_CONST;
+const gchar *gpk_info_enum_to_localised_present (PkInfoEnum info)
+ G_GNUC_CONST;
const gchar *gpk_info_enum_to_icon_name (PkInfoEnum info);
const gchar *gpk_status_enum_to_localised_text (PkStatusEnum status)
G_GNUC_CONST;
const gchar *gpk_status_enum_to_icon_name (PkStatusEnum status);
+const gchar *gpk_status_enum_to_animation (PkStatusEnum status);
const gchar *gpk_restart_enum_to_icon_name (PkRestartEnum restart);
const gchar *gpk_restart_enum_to_dialog_icon_name (PkRestartEnum restart);
const gchar *gpk_error_enum_to_localised_text (PkErrorEnum code)
@@ -95,11 +98,16 @@ const gchar *gpk_error_enum_to_localised
const gchar *gpk_error_enum_to_localised_message (PkErrorEnum code);
const gchar *gpk_restart_enum_to_localised_text (PkRestartEnum restart)
G_GNUC_CONST;
+const gchar *gpk_update_state_enum_to_localised_text (PkUpdateStateEnum state)
+ G_GNUC_CONST;
const gchar *gpk_restart_enum_to_localised_text_future(PkRestartEnum restart)
G_GNUC_CONST;
const gchar *gpk_group_enum_to_localised_text (PkGroupEnum group)
G_GNUC_CONST;
const gchar *gpk_group_enum_to_icon_name (PkGroupEnum group);
+gchar *gpk_update_enum_to_localised_text (PkInfoEnum info,
+ guint number)
+ G_GNUC_CONST;
const gchar *gpk_info_status_enum_to_string (GpkInfoStatusEnum info);
const gchar *gpk_info_status_enum_to_icon_name (GpkInfoStatusEnum info);
Index: gnome-packagekit-3.20.0/src/gpk-error.c
===================================================================
--- gnome-packagekit-3.20.0.orig/src/gpk-error.c
+++ gnome-packagekit-3.20.0/src/gpk-error.c
@@ -58,7 +58,7 @@ gpk_error_dialog_expanded_cb (GObject *o
*
* Shows a modal error, and blocks until the user clicks close
**/
-static gboolean
+gboolean
gpk_error_dialog_modal_with_time (GtkWindow *window, const gchar *title, const gchar *message, const gchar *details, guint timestamp)
{
GtkWidget *widget;
Index: gnome-packagekit-3.20.0/src/gpk-error.h
===================================================================
--- gnome-packagekit-3.20.0.orig/src/gpk-error.h
+++ gnome-packagekit-3.20.0/src/gpk-error.h
@@ -33,6 +33,11 @@ gboolean gpk_error_dialog_modal (GtkW
const gchar *title,
const gchar *message,
const gchar *details);
+gboolean gpk_error_dialog_modal_with_time (GtkWindow *window,
+ const gchar *title,
+ const gchar *message,
+ const gchar *details,
+ guint timestamp);
G_END_DECLS
Index: gnome-packagekit-3.20.0/src/gpk-gnome.c
===================================================================
--- /dev/null
+++ gnome-packagekit-3.20.0/src/gpk-gnome.c
@@ -0,0 +1,49 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2008 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include "config.h"
+
+#include <glib.h>
+#include <gtk/gtk.h>
+#include <string.h>
+
+#include "gpk-gnome.h"
+
+/**
+ * gpk_gnome_open:
+ * @url: a url such as <literal>http://www.hughsie.com</literal>
+ **/
+gboolean
+gpk_gnome_open (const gchar *url)
+{
+ gboolean ret;
+ GError *error = NULL;
+
+ g_return_val_if_fail (url != NULL, FALSE);
+
+ ret = gtk_show_uri (NULL, url, GDK_CURRENT_TIME, &error);
+
+ if (!ret) {
+ g_warning ("spawn of '%s' failed", url);
+ g_error_free (error);
+ }
+ return ret;
+}
Index: gnome-packagekit-3.20.0/src/gpk-gnome.h
===================================================================
--- /dev/null
+++ gnome-packagekit-3.20.0/src/gpk-gnome.h
@@ -0,0 +1,33 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2008 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef __GPK_GNOME_H
+#define __GPK_GNOME_H
+
+#include <glib.h>
+
+G_BEGIN_DECLS
+
+gboolean gpk_gnome_open (const gchar *url);
+
+G_END_DECLS
+
+#endif /* __GPK_GNOME_H */
Index: gnome-packagekit-3.20.0/src/gpk-helper-chooser.c
===================================================================
--- /dev/null
+++ gnome-packagekit-3.20.0/src/gpk-helper-chooser.c
@@ -0,0 +1,348 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2009 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include "config.h"
+
+#include <glib/gi18n.h>
+#include <gtk/gtk.h>
+#include <packagekit-glib2/packagekit.h>
+
+#include "gpk-helper-chooser.h"
+#include "gpk-marshal.h"
+#include "gpk-gnome.h"
+#include "gpk-common.h"
+#include "gpk-enum.h"
+
+static void gpk_helper_chooser_finalize (GObject *object);
+
+#define GPK_HELPER_CHOOSER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GPK_TYPE_HELPER_CHOOSER, GpkHelperChooserPrivate))
+
+struct GpkHelperChooserPrivate
+{
+ GtkBuilder *builder;
+ gchar *package_id;
+ GtkListStore *list_store;
+};
+
+enum {
+ GPK_HELPER_CHOOSER_EVENT,
+ GPK_HELPER_CHOOSER_LAST_SIGNAL
+};
+
+enum {
+ GPK_CHOOSER_COLUMN_ICON,
+ GPK_CHOOSER_COLUMN_TEXT,
+ GPK_CHOOSER_COLUMN_ID,
+ GPK_CHOOSER_COLUMN_LAST
+};
+
+static guint signals [GPK_HELPER_CHOOSER_LAST_SIGNAL] = { 0 };
+G_DEFINE_TYPE (GpkHelperChooser, gpk_helper_chooser, G_TYPE_OBJECT)
+
+/**
+ * gpk_helper_chooser_button_install_cb:
+ **/
+static void
+gpk_helper_chooser_button_install_cb (GtkWidget *widget, GpkHelperChooser *helper)
+{
+ widget = GTK_WIDGET (gtk_builder_get_object (helper->priv->builder, "dialog_simple"));
+ gtk_widget_hide (widget);
+ g_signal_emit (helper, signals [GPK_HELPER_CHOOSER_EVENT], 0, GTK_RESPONSE_YES, helper->priv->package_id);
+}
+
+/**
+ * gpk_helper_chooser_button_cancel_cb:
+ **/
+static void
+gpk_helper_chooser_button_cancel_cb (GtkWidget *widget, GpkHelperChooser *helper)
+{
+ widget = GTK_WIDGET (gtk_builder_get_object (helper->priv->builder, "dialog_simple"));
+ gtk_widget_hide (widget);
+ g_signal_emit (helper, signals [GPK_HELPER_CHOOSER_EVENT], 0, GTK_RESPONSE_NO, helper->priv->package_id);
+}
+
+/**
+ * gpk_helper_chooser_button_response_cb:
+ **/
+static void
+gpk_helper_chooser_button_response_cb (GtkDialog *dialog, GtkResponseType response_id, GpkHelperChooser *helper)
+{
+ if (response_id == GTK_RESPONSE_DELETE_EVENT) {
+ gtk_widget_hide (GTK_WIDGET (dialog));
+ g_signal_emit (helper, signals [GPK_HELPER_CHOOSER_EVENT], 0, GTK_RESPONSE_NO, helper->priv->package_id);
+ }
+}
+
+/**
+ * gpk_helper_chooser_treeview_clicked_cb:
+ **/
+static void
+gpk_helper_chooser_treeview_clicked_cb (GtkTreeSelection *selection, GpkHelperChooser *helper)
+{
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+
+ /* This will only work in single or browse selection mode! */
+ if (gtk_tree_selection_get_selected (selection, &model, &iter)) {
+ g_free (helper->priv->package_id);
+ gtk_tree_model_get (model, &iter, GPK_CHOOSER_COLUMN_ID, &helper->priv->package_id, -1);
+
+ /* show package_id */
+ g_debug ("selected row is: %s", helper->priv->package_id);
+ } else {
+ g_debug ("no row selected");
+ }
+}
+
+/**
+ * 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);
+ /* TRANSLATORS: column for the application icon */
+ column = gtk_tree_view_column_new_with_attributes (_("Icon"), renderer,
+ "icon-name", GPK_CHOOSER_COLUMN_ICON, NULL);
+ gtk_tree_view_append_column (treeview, column);
+
+ /* column for text */
+ renderer = gtk_cell_renderer_text_new ();
+ /* TRANSLATORS: column for the application name */
+ column = gtk_tree_view_column_new_with_attributes (_("Package"), renderer,
+ "markup", GPK_CHOOSER_COLUMN_TEXT, NULL);
+ gtk_tree_view_column_set_sort_column_id (column, GPK_CHOOSER_COLUMN_TEXT);
+ gtk_tree_view_append_column (treeview, column);
+ gtk_tree_view_column_set_expand (column, TRUE);
+}
+
+/**
+ * gpk_helper_chooser_show:
+ *
+ * Return value: if we agreed
+ **/
+gboolean
+gpk_helper_chooser_show (GpkHelperChooser *helper, GPtrArray *list)
+{
+ GtkWidget *widget;
+ gchar *text;
+ const gchar *icon_name;
+ guint i;
+ PkPackage *item;
+ GtkTreeIter iter;
+ PkInfoEnum info;
+ gchar *package_id = NULL;
+ gchar *summary = NULL;
+
+ g_return_val_if_fail (GPK_IS_HELPER_CHOOSER (helper), FALSE);
+ g_return_val_if_fail (list != NULL, FALSE);
+
+ /* see what we've got already */
+ widget = GTK_WIDGET (gtk_builder_get_object (helper->priv->builder, "dialog_simple"));
+ for (i=0; i<list->len; i++) {
+ item = g_ptr_array_index (list, i);
+ g_object_get (item,
+ "info", &info,
+ "package-id", &package_id,
+ "summary", &summary,
+ NULL);
+ g_debug ("package '%s' got:", package_id);
+
+ /* put formatted text into treeview */
+ gtk_list_store_append (helper->priv->list_store, &iter);
+ text = gpk_package_id_format_twoline (gtk_widget_get_style_context (widget),
+ package_id,
+ summary);
+ icon_name = gpk_info_enum_to_icon_name (info);
+ gtk_list_store_set (helper->priv->list_store, &iter,
+ GPK_CHOOSER_COLUMN_TEXT, text,
+ GPK_CHOOSER_COLUMN_ID, package_id, -1);
+ gtk_list_store_set (helper->priv->list_store, &iter, GPK_CHOOSER_COLUMN_ICON, icon_name, -1);
+ g_free (package_id);
+ g_free (summary);
+ g_free (text);
+ }
+
+ /* show window */
+ gtk_widget_show (widget);
+
+ return TRUE;
+}
+
+/**
+ * gpk_helper_chooser_set_parent:
+ **/
+gboolean
+gpk_helper_chooser_set_parent (GpkHelperChooser *helper, GtkWindow *window)
+{
+ GtkWindow *widget;
+
+ g_return_val_if_fail (GPK_IS_HELPER_CHOOSER (helper), FALSE);
+ g_return_val_if_fail (window != NULL, FALSE);
+
+ /* make modal if window set */
+ widget = GTK_WINDOW (gtk_builder_get_object (helper->priv->builder, "dialog_simple"));
+ gtk_window_set_transient_for (widget, window);
+ gtk_window_set_modal (widget, TRUE);
+
+ /* this is a modal popup, so don't show a window title */
+ gtk_window_set_title (widget, "");
+
+ return TRUE;
+}
+
+/**
+ * gpk_helper_chooser_class_init:
+ * @klass: The GpkHelperChooserClass
+ **/
+static void
+gpk_helper_chooser_class_init (GpkHelperChooserClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ object_class->finalize = gpk_helper_chooser_finalize;
+ g_type_class_add_private (klass, sizeof (GpkHelperChooserPrivate));
+ signals [GPK_HELPER_CHOOSER_EVENT] =
+ g_signal_new ("event",
+ G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GpkHelperChooserClass, event),
+ NULL, NULL, gpk_marshal_VOID__UINT_STRING,
+ G_TYPE_NONE, 2, G_TYPE_UINT, G_TYPE_STRING);
+}
+
+/**
+ * gpk_helper_chooser_init:
+ **/
+static void
+gpk_helper_chooser_init (GpkHelperChooser *helper)
+{
+ GtkWidget *widget;
+ guint retval;
+ GError *error = NULL;
+ GtkWidget *button;
+ GtkTreeSelection *selection;
+
+ helper->priv = GPK_HELPER_CHOOSER_GET_PRIVATE (helper);
+
+ helper->priv->package_id = NULL;
+
+ /* get UI */
+ helper->priv->builder = gtk_builder_new ();
+ retval = gtk_builder_add_from_file (helper->priv->builder, GPK_DATA "/gpk-log.ui", &error);
+ if (retval == 0) {
+ g_warning ("failed to load ui: %s", error->message);
+ g_error_free (error);
+ }
+
+ /* connect up default actions */
+ widget = GTK_WIDGET (gtk_builder_get_object (helper->priv->builder, "dialog_simple"));
+ g_signal_connect (GTK_DIALOG (widget), "response", G_CALLBACK (gpk_helper_chooser_button_response_cb), helper);
+
+ /* set icon name */
+ widget = GTK_WIDGET (gtk_builder_get_object (helper->priv->builder, "dialog_simple"));
+ gtk_window_set_icon_name (GTK_WINDOW (widget), GPK_ICON_SOFTWARE_INSTALLER);
+ gtk_window_set_title (GTK_WINDOW (widget), _("Applications that can open this type of file"));
+
+ /* set a size, if the screen allows */
+ gpk_window_set_size_request (GTK_WINDOW (widget), 600, 300);
+
+ /* connect up buttons */
+ widget = GTK_WIDGET (gtk_builder_get_object (helper->priv->builder, "button_close"));
+ g_signal_connect (widget, "clicked", G_CALLBACK (gpk_helper_chooser_button_cancel_cb), helper);
+
+ /* TRANSLATORS: button label, install */
+ button = gtk_button_new_with_mnemonic (_("_Install"));
+ g_signal_connect (button, "clicked", G_CALLBACK (gpk_helper_chooser_button_install_cb), helper);
+
+ /* TRANSLATORS: button tooltip */
+ gtk_widget_set_tooltip_text (button, _("Install package"));
+
+ /* add to box */
+ widget = GTK_WIDGET (gtk_builder_get_object (helper->priv->builder, "dialog_simple"));
+ widget = gtk_dialog_get_action_area (GTK_DIALOG(widget));
+ gtk_box_pack_start (GTK_BOX (widget), button, FALSE, FALSE, 0);
+ gtk_widget_show (button);
+
+ /* hide the filter box */
+ widget = GTK_WIDGET (gtk_builder_get_object (helper->priv->builder, "hbox_filter"));
+ gtk_widget_hide (widget);
+
+ /* hide the refresh button */
+ widget = GTK_WIDGET (gtk_builder_get_object (helper->priv->builder, "button_refresh"));
+ gtk_widget_hide (widget);
+
+ /* create list stores */
+ helper->priv->list_store = gtk_list_store_new (GPK_CHOOSER_COLUMN_LAST, G_TYPE_STRING,
+ G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING);
+
+ /* create package_id tree view */
+ widget = GTK_WIDGET (gtk_builder_get_object (helper->priv->builder, "treeview_simple"));
+ gtk_tree_view_set_model (GTK_TREE_VIEW (widget),
+ GTK_TREE_MODEL (helper->priv->list_store));
+
+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (widget));
+ g_signal_connect (selection, "changed",
+ G_CALLBACK (gpk_helper_chooser_treeview_clicked_cb), helper);
+
+ /* add columns to the tree view */
+ pk_treeview_add_general_columns (GTK_TREE_VIEW (widget));
+ gtk_tree_view_columns_autosize (GTK_TREE_VIEW (widget));
+ gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (widget), FALSE);
+}
+
+/**
+ * gpk_helper_chooser_finalize:
+ **/
+static void
+gpk_helper_chooser_finalize (GObject *object)
+{
+ GtkWidget *widget;
+ GpkHelperChooser *helper;
+
+ g_return_if_fail (GPK_IS_HELPER_CHOOSER (object));
+
+ helper = GPK_HELPER_CHOOSER (object);
+
+ /* hide window */
+ widget = GTK_WIDGET (gtk_builder_get_object (helper->priv->builder, "dialog_simple"));
+ if (GTK_IS_WIDGET (widget))
+ gtk_widget_hide (widget);
+ g_free (helper->priv->package_id);
+ g_object_unref (helper->priv->builder);
+
+ G_OBJECT_CLASS (gpk_helper_chooser_parent_class)->finalize (object);
+}
+
+/**
+ * gpk_helper_chooser_new:
+ **/
+GpkHelperChooser *
+gpk_helper_chooser_new (void)
+{
+ GpkHelperChooser *helper;
+ helper = g_object_new (GPK_TYPE_HELPER_CHOOSER, NULL);
+ return GPK_HELPER_CHOOSER (helper);
+}
+
Index: gnome-packagekit-3.20.0/src/gpk-helper-chooser.h
===================================================================
--- /dev/null
+++ gnome-packagekit-3.20.0/src/gpk-helper-chooser.h
@@ -0,0 +1,65 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2009 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef __GPK_HELPER_CHOOSER_H
+#define __GPK_HELPER_CHOOSER_H
+
+#include <glib-object.h>
+#include <gtk/gtk.h>
+#include <packagekit-glib2/packagekit.h>
+
+G_BEGIN_DECLS
+
+#define GPK_TYPE_HELPER_CHOOSER (gpk_helper_chooser_get_type ())
+#define GPK_HELPER_CHOOSER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GPK_TYPE_HELPER_CHOOSER, GpkHelperChooser))
+#define GPK_HELPER_CHOOSER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GPK_TYPE_HELPER_CHOOSER, GpkHelperChooserClass))
+#define GPK_IS_HELPER_CHOOSER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GPK_TYPE_HELPER_CHOOSER))
+#define GPK_IS_HELPER_CHOOSER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GPK_TYPE_HELPER_CHOOSER))
+#define GPK_HELPER_CHOOSER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GPK_TYPE_HELPER_CHOOSER, GpkHelperChooserClass))
+#define GPK_HELPER_CHOOSER_ERROR (gpk_helper_chooser_error_quark ())
+#define GPK_HELPER_CHOOSER_TYPE_ERROR (gpk_helper_chooser_error_get_type ())
+
+typedef struct GpkHelperChooserPrivate GpkHelperChooserPrivate;
+
+typedef struct
+{
+ GObject parent;
+ GpkHelperChooserPrivate *priv;
+} GpkHelperChooser;
+
+typedef struct
+{
+ void (* event) (GpkHelperChooser *helper,
+ GtkResponseType type,
+ const gchar *package_id);
+ GObjectClass parent_class;
+} GpkHelperChooserClass;
+
+GType gpk_helper_chooser_get_type (void);
+GpkHelperChooser *gpk_helper_chooser_new (void);
+gboolean gpk_helper_chooser_set_parent (GpkHelperChooser *helper,
+ GtkWindow *window);
+gboolean gpk_helper_chooser_show (GpkHelperChooser *helper,
+ GPtrArray *list);
+
+G_END_DECLS
+
+#endif /* __GPK_HELPER_CHOOSER_H */
Index: gnome-packagekit-3.20.0/src/gpk-helper-run.c
===================================================================
--- /dev/null
+++ gnome-packagekit-3.20.0/src/gpk-helper-run.c
@@ -0,0 +1,392 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2009 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include "config.h"
+
+#include <glib/gi18n.h>
+#include <gtk/gtk.h>
+#include <packagekit-glib2/packagekit.h>
+#include <gio/gdesktopappinfo.h>
+
+#include "gpk-helper-run.h"
+#include "gpk-marshal.h"
+#include "gpk-gnome.h"
+#include "gpk-common.h"
+#include "gpk-enum.h"
+
+static void gpk_helper_run_finalize (GObject *object);
+
+#define GPK_HELPER_RUN_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GPK_TYPE_HELPER_RUN, GpkHelperRunPrivate))
+
+struct GpkHelperRunPrivate
+{
+ GtkBuilder *builder;
+ GtkListStore *list_store;
+};
+
+enum {
+ GPK_CHOOSER_COLUMN_ICON,
+ GPK_CHOOSER_COLUMN_TEXT,
+ GPK_CHOOSER_COLUMN_FILENAME,
+ GPK_CHOOSER_COLUMN_LAST
+};
+
+G_DEFINE_TYPE (GpkHelperRun, gpk_helper_run, G_TYPE_OBJECT)
+
+/**
+ * gpk_helper_run_path:
+ **/
+static gboolean
+gpk_helper_run_path (GpkHelperRun *helper, const gchar *filename)
+{
+ gboolean ret = FALSE;
+ GError *error = NULL;
+ GAppInfo *app = NULL;
+
+ /* check have value */
+ if (filename == NULL) {
+ g_warning ("no full path");
+ goto out;
+ }
+
+ /* launch application */
+ app = G_APP_INFO(g_desktop_app_info_new_from_filename (filename));
+ ret = g_app_info_launch (app, NULL, NULL, &error);
+ if (!ret) {
+ g_warning ("failed to launch: %s", error->message);
+ g_error_free (error);
+ }
+out:
+ if (app != NULL)
+ g_object_unref (app);
+ return ret;
+}
+
+/**
+ * gpk_helper_run_button_run_cb:
+ **/
+static void
+gpk_helper_run_button_run_cb (GtkWidget *widget, GpkHelperRun *helper)
+{
+ GtkTreeView *treeview;
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+ GtkTreeSelection *selection;
+ gboolean ret;
+ gchar *filename;
+
+ /* get selection */
+ treeview = GTK_TREE_VIEW (gtk_builder_get_object (helper->priv->builder, "treeview_simple"));
+ selection = gtk_tree_view_get_selection (treeview);
+ ret = gtk_tree_selection_get_selected (selection, &model, &iter);
+ if (!ret) {
+ g_warning ("failed to get selection");
+ return;
+ }
+
+ gtk_tree_model_get (model, &iter, GPK_CHOOSER_COLUMN_FILENAME, &filename, -1);
+ gpk_helper_run_path (helper, filename);
+ g_free (filename);
+}
+
+/**
+ * gpk_helper_run_button_close_cb:
+ **/
+static void
+gpk_helper_run_button_close_cb (GtkWidget *widget, GpkHelperRun *helper)
+{
+ widget = GTK_WIDGET (gtk_builder_get_object (helper->priv->builder, "dialog_simple"));
+ gtk_widget_hide (widget);
+}
+
+/**
+ * gpk_helper_run_delete_event_cb:
+ **/
+static gboolean
+gpk_helper_run_delete_event_cb (GtkWidget *widget, GdkEvent *event, GpkHelperRun *helper)
+{
+ widget = GTK_WIDGET (gtk_builder_get_object (helper->priv->builder, "dialog_simple"));
+ gtk_widget_hide (widget);
+ return FALSE;
+}
+
+/**
+ * gpk_helper_run_treeview_clicked_cb:
+ **/
+static void
+gpk_helper_run_treeview_clicked_cb (GtkTreeSelection *selection, GpkHelperRun *helper)
+{
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+ gchar *filename = NULL;
+
+ /* This will only work in single or browse selection mode! */
+ if (gtk_tree_selection_get_selected (selection, &model, &iter)) {
+ g_free (filename);
+ gtk_tree_model_get (model, &iter, GPK_CHOOSER_COLUMN_FILENAME, &filename, -1);
+
+ /* show full path */
+ g_debug ("selected row is: %s", filename);
+ } else {
+ g_debug ("no row selected");
+ }
+ g_free (filename);
+}
+
+/**
+ * gpk_helper_run_row_activated_cb:
+ **/
+static void
+gpk_helper_run_row_activated_cb (GtkTreeView *treeview, GtkTreePath *path,
+ GtkTreeViewColumn *col, GpkHelperRun *helper)
+{
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+ gboolean ret;
+ gchar *filename;
+
+ /* get selection */
+ model = gtk_tree_view_get_model (treeview);
+ ret = gtk_tree_model_get_iter (model, &iter, path);
+ if (!ret) {
+ g_warning ("failed to get selection");
+ return;
+ }
+
+ gtk_tree_model_get (model, &iter, GPK_CHOOSER_COLUMN_FILENAME, &filename, -1);
+ gpk_helper_run_path (helper, filename);
+ g_free (filename);
+}
+
+/**
+ * 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);
+ /* TRANSLATORS: column for the application icon */
+ column = gtk_tree_view_column_new_with_attributes (_("Icon"), renderer,
+ "icon-name", GPK_CHOOSER_COLUMN_ICON, NULL);
+ gtk_tree_view_append_column (treeview, column);
+
+ /* column for text */
+ renderer = gtk_cell_renderer_text_new ();
+ /* TRANSLATORS: column for the package name */
+ column = gtk_tree_view_column_new_with_attributes (_("Package"), renderer,
+ "markup", GPK_CHOOSER_COLUMN_TEXT, NULL);
+ gtk_tree_view_column_set_sort_column_id (column, GPK_CHOOSER_COLUMN_TEXT);
+ gtk_tree_view_append_column (treeview, column);
+ gtk_tree_view_column_set_expand (column, TRUE);
+}
+
+/**
+ * gpk_helper_run_add_package_ids:
+ **/
+static guint
+gpk_helper_run_add_package_ids (GpkHelperRun *helper, gchar **package_ids)
+{
+ return 0;
+}
+
+/**
+ * gpk_helper_run_show:
+ *
+ * Return value: if we agreed
+ **/
+gboolean
+gpk_helper_run_show (GpkHelperRun *helper, gchar **package_ids)
+{
+ GtkWidget *widget;
+ guint len;
+
+ g_return_val_if_fail (GPK_IS_HELPER_RUN (helper), FALSE);
+ g_return_val_if_fail (package_ids != NULL, FALSE);
+
+ /* clear old list */
+ gtk_list_store_clear (helper->priv->list_store);
+
+ /* add all the apps */
+ len = gpk_helper_run_add_package_ids (helper, package_ids);
+ if (len == 0) {
+ g_debug ("no executable file for %s", package_ids[0]);
+ goto out;
+ }
+
+ /* show window */
+ widget = GTK_WIDGET (gtk_builder_get_object (helper->priv->builder, "dialog_simple"));
+ gtk_widget_show (widget);
+out:
+ return TRUE;
+}
+
+/**
+ * gpk_helper_run_set_parent:
+ **/
+gboolean
+gpk_helper_run_set_parent (GpkHelperRun *helper, GtkWindow *window)
+{
+ GtkWindow *widget;
+
+ g_return_val_if_fail (GPK_IS_HELPER_RUN (helper), FALSE);
+ g_return_val_if_fail (window != NULL, FALSE);
+
+ /* make modal if window set */
+ widget = GTK_WINDOW (gtk_builder_get_object (helper->priv->builder, "dialog_simple"));
+ gtk_window_set_transient_for (widget, window);
+ gtk_window_set_modal (widget, TRUE);
+
+ /* this is a modal popup */
+ gtk_window_set_type_hint (widget, GDK_WINDOW_TYPE_HINT_DIALOG);
+
+ return TRUE;
+}
+
+/**
+ * gpk_helper_run_class_init:
+ * @klass: The GpkHelperRunClass
+ **/
+static void
+gpk_helper_run_class_init (GpkHelperRunClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ object_class->finalize = gpk_helper_run_finalize;
+ g_type_class_add_private (klass, sizeof (GpkHelperRunPrivate));
+}
+
+/**
+ * gpk_helper_run_init:
+ **/
+static void
+gpk_helper_run_init (GpkHelperRun *helper)
+{
+ GtkWidget *widget;
+ GtkWidget *button;
+ guint retval;
+ GError *error = NULL;
+ GtkTreeSelection *selection;
+ GtkBox *box;
+
+ helper->priv = GPK_HELPER_RUN_GET_PRIVATE (helper);
+
+ /* get UI */
+ helper->priv->builder = gtk_builder_new ();
+ retval = gtk_builder_add_from_file (helper->priv->builder, GPK_DATA "/gpk-log.ui", &error);
+ if (retval == 0) {
+ g_warning ("failed to load ui: %s", error->message);
+ g_error_free (error);
+ }
+
+ /* connect up default actions */
+ widget = GTK_WIDGET (gtk_builder_get_object (helper->priv->builder, "dialog_simple"));
+ g_signal_connect (widget, "delete_event", G_CALLBACK (gpk_helper_run_delete_event_cb), helper);
+
+ /* set icon name */
+ gtk_window_set_icon_name (GTK_WINDOW (widget), GPK_ICON_SOFTWARE_INSTALLER);
+
+ /* set a size, if the screen allows */
+ gpk_window_set_size_request (GTK_WINDOW (widget), 600, 300);
+
+ /* connect up buttons */
+ widget = GTK_WIDGET (gtk_builder_get_object (helper->priv->builder, "button_close"));
+ g_signal_connect (widget, "clicked", G_CALLBACK (gpk_helper_run_button_close_cb), helper);
+
+ /* hide the filter box */
+ widget = GTK_WIDGET (gtk_builder_get_object (helper->priv->builder, "hbox_filter"));
+ gtk_widget_hide (widget);
+
+ /* hide the refresh button */
+ widget = GTK_WIDGET (gtk_builder_get_object (helper->priv->builder, "button_refresh"));
+ gtk_widget_hide (widget);
+
+ /* set icon name */
+ widget = GTK_WIDGET (gtk_builder_get_object (helper->priv->builder, "dialog_simple"));
+ gtk_window_set_icon_name (GTK_WINDOW (widget), GPK_ICON_SOFTWARE_INSTALLER);
+ /* TRANSLATORS: window title: do we want to execute a program we just installed? */
+ gtk_window_set_title (GTK_WINDOW (widget), _("Run new application?"));
+
+ /* add run button */
+ button = gtk_button_new_with_mnemonic (_("_Run"));
+ box = GTK_BOX (gtk_dialog_get_action_area (GTK_DIALOG (widget)));
+ gtk_box_pack_start (box, button, FALSE, FALSE, 0);
+ gtk_widget_show (button);
+ g_signal_connect (button, "clicked", G_CALLBACK (gpk_helper_run_button_run_cb), helper);
+
+ /* create list stores */
+ helper->priv->list_store = gtk_list_store_new (GPK_CHOOSER_COLUMN_LAST, G_TYPE_STRING,
+ G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING);
+
+ /* create package_id tree view */
+ widget = GTK_WIDGET (gtk_builder_get_object (helper->priv->builder, "treeview_simple"));
+ gtk_tree_view_set_model (GTK_TREE_VIEW (widget),
+ GTK_TREE_MODEL (helper->priv->list_store));
+ g_signal_connect (GTK_TREE_VIEW (widget), "row-activated",
+ G_CALLBACK (gpk_helper_run_row_activated_cb), helper);
+
+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (widget));
+ g_signal_connect (selection, "changed",
+ G_CALLBACK (gpk_helper_run_treeview_clicked_cb), helper);
+
+ /* add columns to the tree view */
+ pk_treeview_add_general_columns (GTK_TREE_VIEW (widget));
+ gtk_tree_view_columns_autosize (GTK_TREE_VIEW (widget));
+ gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (widget), FALSE);
+}
+
+/**
+ * gpk_helper_run_finalize:
+ **/
+static void
+gpk_helper_run_finalize (GObject *object)
+{
+ GtkWidget *widget;
+ GpkHelperRun *helper;
+
+ g_return_if_fail (GPK_IS_HELPER_RUN (object));
+
+ helper = GPK_HELPER_RUN (object);
+
+ /* hide window */
+ widget = GTK_WIDGET (gtk_builder_get_object (helper->priv->builder, "dialog_simple"));
+ if (GTK_IS_WIDGET (widget))
+ gtk_widget_hide (widget);
+ g_object_unref (helper->priv->builder);
+ g_object_unref (helper->priv->list_store);
+
+ G_OBJECT_CLASS (gpk_helper_run_parent_class)->finalize (object);
+}
+
+/**
+ * gpk_helper_run_new:
+ **/
+GpkHelperRun *
+gpk_helper_run_new (void)
+{
+ GpkHelperRun *helper;
+ helper = g_object_new (GPK_TYPE_HELPER_RUN, NULL);
+ return GPK_HELPER_RUN (helper);
+}
+
Index: gnome-packagekit-3.20.0/src/gpk-helper-run.h
===================================================================
--- /dev/null
+++ gnome-packagekit-3.20.0/src/gpk-helper-run.h
@@ -0,0 +1,61 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2009 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef __GPK_HELPER_RUN_H
+#define __GPK_HELPER_RUN_H
+
+#include <glib-object.h>
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+#define GPK_TYPE_HELPER_RUN (gpk_helper_run_get_type ())
+#define GPK_HELPER_RUN(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GPK_TYPE_HELPER_RUN, GpkHelperRun))
+#define GPK_HELPER_RUN_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GPK_TYPE_HELPER_RUN, GpkHelperRunClass))
+#define GPK_IS_HELPER_RUN(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GPK_TYPE_HELPER_RUN))
+#define GPK_IS_HELPER_RUN_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GPK_TYPE_HELPER_RUN))
+#define GPK_HELPER_RUN_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GPK_TYPE_HELPER_RUN, GpkHelperRunClass))
+#define GPK_HELPER_RUN_ERROR (gpk_helper_run_error_quark ())
+#define GPK_HELPER_RUN_TYPE_ERROR (gpk_helper_run_error_get_type ())
+
+typedef struct GpkHelperRunPrivate GpkHelperRunPrivate;
+
+typedef struct
+{
+ GObject parent;
+ GpkHelperRunPrivate *priv;
+} GpkHelperRun;
+
+typedef struct
+{
+ GObjectClass parent_class;
+} GpkHelperRunClass;
+
+GType gpk_helper_run_get_type (void);
+GpkHelperRun *gpk_helper_run_new (void);
+gboolean gpk_helper_run_set_parent (GpkHelperRun *helper,
+ GtkWindow *window);
+gboolean gpk_helper_run_show (GpkHelperRun *helper,
+ gchar **package_ids);
+
+G_END_DECLS
+
+#endif /* __GPK_HELPER_RUN_H */
Index: gnome-packagekit-3.20.0/src/gpk-install-local-file.c
===================================================================
--- /dev/null
+++ gnome-packagekit-3.20.0/src/gpk-install-local-file.c
@@ -0,0 +1,139 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2007-2008 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include "config.h"
+
+#include <glib.h>
+#include <glib/gi18n.h>
+#include <gtk/gtk.h>
+#include <locale.h>
+#include <dbus/dbus-glib.h>
+
+#include "gpk-common.h"
+#include "gpk-error.h"
+#include "gpk-dbus.h"
+#include "gpk-debug.h"
+
+/**
+ * main:
+ **/
+int
+main (int argc, char *argv[])
+{
+ GOptionContext *context;
+ gboolean ret;
+ GError *error = NULL;
+ gchar **files = NULL;
+ gchar *tmp;
+ gchar *current_dir;
+ guint i;
+ DBusGConnection *connection;
+ DBusGProxy *proxy = NULL;
+
+ const GOptionEntry options[] = {
+ { G_OPTION_REMAINING, '\0', 0, G_OPTION_ARG_FILENAME_ARRAY, &files,
+ /* TRANSLATORS: command line option: a list of files to install */
+ _("Files to install"), NULL },
+ { NULL}
+ };
+
+ setlocale (LC_ALL, "");
+
+ bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
+ bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
+ textdomain (GETTEXT_PACKAGE);
+
+ gtk_init (&argc, &argv);
+
+ /* TRANSLATORS: program name: application to install a package to provide a file */
+ g_set_application_name (_("Software Install"));
+ context = g_option_context_new ("gpk-install-local-file");
+ g_option_context_set_summary (context, _("PackageKit File Installer"));
+ g_option_context_add_main_entries (context, options, NULL);
+ g_option_context_add_group (context, gpk_debug_get_option_group ());
+ g_option_context_add_group (context, gtk_get_option_group (TRUE));
+ g_option_context_parse (context, &argc, &argv, NULL);
+ g_option_context_free (context);
+
+ /* TRANSLATORS: title to pass to to the user if there are not enough privs */
+ ret = gpk_check_privileged_user (_("Local file installer"), TRUE);
+ if (!ret)
+ goto out;
+
+ if (files == NULL) {
+ /* TRANSLATORS: could not install a package that contained the file we wanted */
+ gpk_error_dialog (_("Failed to install a package to provide a file"),
+ /* TRANSLATORS: nothing selected */
+ _("You need to specify a file to install"), NULL);
+ goto out;
+ }
+
+ /* make sure we don't pass relative paths to the session-interface */
+ /* (this is needed if install-local-files is executed from the command-line) */
+ current_dir = g_get_current_dir ();
+ for (i = 0; files[i] != NULL; i++) {
+ if (!g_str_has_prefix (files[i], "/")) {
+ tmp = g_build_filename (current_dir, files[i], NULL);
+ g_free (files[i]);
+ files[i] = tmp;
+ }
+ }
+ g_free (current_dir);
+
+ /* check dbus connections, exit if not valid */
+ connection = dbus_g_bus_get (DBUS_BUS_SESSION, &error);
+ if (connection == NULL) {
+ g_warning ("%s", error->message);
+ goto out;
+ }
+
+ /* get a connection */
+ proxy = dbus_g_proxy_new_for_name (connection,
+ "org.freedesktop.PackageKit",
+ "/org/freedesktop/PackageKit",
+ "org.freedesktop.PackageKit.Modify");
+ if (proxy == NULL) {
+ g_warning ("Cannot connect to session service");
+ goto out;
+ }
+
+ /* don't timeout, as dbus-glib sets the timeout ~25 seconds */
+ dbus_g_proxy_set_default_timeout (proxy, INT_MAX);
+
+ /* do method */
+ ret = dbus_g_proxy_call (proxy, "InstallPackageFiles", &error,
+ G_TYPE_UINT, 0, /* xid */
+ G_TYPE_STRV, files, /* data */
+ G_TYPE_STRING, "hide-finished,show-warnings", /* interaction */
+ G_TYPE_INVALID,
+ G_TYPE_INVALID);
+ if (!ret) {
+ g_warning ("%s", error->message);
+ goto out;
+ }
+out:
+ if (error != NULL)
+ g_error_free (error);
+ if (proxy != NULL)
+ g_object_unref (proxy);
+ g_strfreev (files);
+ return !ret;
+}
Index: gnome-packagekit-3.20.0/src/gpk-language.c
===================================================================
--- /dev/null
+++ gnome-packagekit-3.20.0/src/gpk-language.c
@@ -0,0 +1,196 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2008 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include "config.h"
+
+#include <string.h>
+#include <glib.h>
+
+#include "gpk-language.h"
+
+static void gpk_language_finalize (GObject *object);
+
+#define GPK_LANGUAGE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GPK_TYPE_LANGUAGE, GpkLanguagePrivate))
+
+struct GpkLanguagePrivate
+{
+ GHashTable *hash;
+};
+
+G_DEFINE_TYPE (GpkLanguage, gpk_language, G_TYPE_OBJECT)
+
+/**
+ * gpk_language_parser_start_element:
+ **/
+static void
+gpk_language_parser_start_element (GMarkupParseContext *context, const gchar *element_name,
+ const gchar **attribute_names, const gchar **attribute_values,
+ gpointer user_data, GError **error)
+{
+ guint i, len;
+ const gchar *code1 = NULL;
+ const gchar *code2b = NULL;
+ const gchar *name = NULL;
+ GpkLanguage *language = user_data;
+
+ if (strcmp (element_name, "iso_639_entry") != 0)
+ return;
+
+ /* find data */
+ len = g_strv_length ((gchar**)attribute_names);
+ for (i=0; i<len; i++) {
+ if (strcmp (attribute_names[i], "iso_639_1_code") == 0)
+ code1 = attribute_values[i];
+ if (strcmp (attribute_names[i], "iso_639_2B_code") == 0)
+ code2b = attribute_values[i];
+ if (strcmp (attribute_names[i], "name") == 0)
+ name = attribute_values[i];
+ }
+
+ /* not valid entry */
+ if (name == NULL)
+ return;
+
+ /* add both to hash */
+ if (code1 != NULL)
+ g_hash_table_insert (language->priv->hash, g_strdup (code1), g_strdup (name));
+ if (code2b != NULL)
+ g_hash_table_insert (language->priv->hash, g_strdup (code2b), g_strdup (name));
+}
+
+/* trivial parser */
+static const GMarkupParser gpk_language_markup_parser =
+{
+ gpk_language_parser_start_element,
+ NULL, /* end_element */
+ NULL, /* characters */
+ NULL, /* passthrough */
+ NULL /* error */
+};
+
+/**
+ * gpk_language_populate:
+ *
+ * <iso_639_entry iso_639_2B_code="hun" iso_639_2T_code="hun" iso_639_1_code="hu" name="Hungarian" />
+ **/
+gboolean
+gpk_language_populate (GpkLanguage *language, GError **error)
+{
+ gboolean ret = FALSE;
+ gchar *contents = NULL;
+ gchar *filename;
+ gsize size;
+ GMarkupParseContext *context = NULL;
+
+ /* find filename */
+ filename = g_build_filename (DATADIR, "xml", "iso-codes", "iso_639.xml", NULL);
+ if (!g_file_test (filename, G_FILE_TEST_EXISTS)) {
+ g_free (filename);
+ filename = g_build_filename ("/usr", "share", "xml", "iso-codes", "iso_639.xml", NULL);
+ }
+ if (!g_file_test (filename, G_FILE_TEST_EXISTS)) {
+ g_set_error (error, 1, 0, "cannot find source file : '%s'", filename);
+ goto out;
+ }
+
+ /* get contents */
+ ret = g_file_get_contents (filename, &contents, &size, error);
+ if (!ret)
+ goto out;
+
+ /* create parser */
+ context = g_markup_parse_context_new (&gpk_language_markup_parser, G_MARKUP_PREFIX_ERROR_POSITION, language, NULL);
+
+ /* parse data */
+ ret = g_markup_parse_context_parse (context, contents, (gssize) size, error);
+ if (!ret)
+ goto out;
+out:
+ if (context != NULL)
+ g_markup_parse_context_free (context);
+ g_free (filename);
+ g_free (contents);
+ return ret;
+}
+
+/**
+ * gpk_language_iso639_to_language:
+ **/
+gchar *
+gpk_language_iso639_to_language (GpkLanguage *language, const gchar *iso639)
+{
+ return g_strdup (g_hash_table_lookup (language->priv->hash, iso639));
+}
+
+/**
+ * gpk_language_finalize:
+ * @object: The object to finalize
+ **/
+static void
+gpk_language_finalize (GObject *object)
+{
+ GpkLanguage *language;
+
+ g_return_if_fail (GPK_IS_LANGUAGE (object));
+
+ language = GPK_LANGUAGE (object);
+
+ g_return_if_fail (language->priv != NULL);
+ g_hash_table_unref (language->priv->hash);
+
+ G_OBJECT_CLASS (gpk_language_parent_class)->finalize (object);
+}
+
+/**
+ * gpk_language_init:
+ * @language: This class instance
+ **/
+static void
+gpk_language_init (GpkLanguage *language)
+{
+ language->priv = GPK_LANGUAGE_GET_PRIVATE (language);
+ language->priv->hash = g_hash_table_new_full (g_str_hash, g_str_equal, (GDestroyNotify) g_free, (GDestroyNotify) g_free);
+}
+
+/**
+ * gpk_language_class_init:
+ * @klass: The GpkLanguageClass
+ **/
+static void
+gpk_language_class_init (GpkLanguageClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ object_class->finalize = gpk_language_finalize;
+ g_type_class_add_private (klass, sizeof (GpkLanguagePrivate));
+}
+
+/**
+ * gpk_language_new:
+ *
+ * Return value: a new GpkLanguage object.
+ **/
+GpkLanguage *
+gpk_language_new (void)
+{
+ GpkLanguage *language;
+ language = g_object_new (GPK_TYPE_LANGUAGE, NULL);
+ return GPK_LANGUAGE (language);
+}
Index: gnome-packagekit-3.20.0/src/gpk-language.h
===================================================================
--- /dev/null
+++ gnome-packagekit-3.20.0/src/gpk-language.h
@@ -0,0 +1,60 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2008 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef __GPK_LANGUAGE_H
+#define __GPK_LANGUAGE_H
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define GPK_TYPE_LANGUAGE (gpk_language_get_type ())
+#define GPK_LANGUAGE(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GPK_TYPE_LANGUAGE, GpkLanguage))
+#define GPK_LANGUAGE_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GPK_TYPE_LANGUAGE, GpkLanguageClass))
+#define GPK_IS_LANGUAGE(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GPK_TYPE_LANGUAGE))
+#define GPK_IS_LANGUAGE_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GPK_TYPE_LANGUAGE))
+#define GPK_LANGUAGE_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GPK_TYPE_LANGUAGE, GpkLanguageClass))
+#define GPK_LANGUAGE_ERROR (gpk_language_error_quark ())
+#define GPK_LANGUAGE_TYPE_ERROR (gpk_language_error_get_type ())
+
+typedef struct GpkLanguagePrivate GpkLanguagePrivate;
+
+typedef struct
+{
+ GObject parent;
+ GpkLanguagePrivate *priv;
+} GpkLanguage;
+
+typedef struct
+{
+ GObjectClass parent_class;
+} GpkLanguageClass;
+
+GType gpk_language_get_type (void);
+GpkLanguage *gpk_language_new (void);
+gboolean gpk_language_populate (GpkLanguage *language,
+ GError **error);
+gchar *gpk_language_iso639_to_language (GpkLanguage *language,
+ const gchar *iso639);
+
+G_END_DECLS
+
+#endif /* __GPK_LANGUAGE_H */
Index: gnome-packagekit-3.20.0/src/gpk-log.c
===================================================================
--- gnome-packagekit-3.20.0.orig/src/gpk-log.c
+++ gnome-packagekit-3.20.0/src/gpk-log.c
@@ -32,6 +32,7 @@
#include <packagekit-glib2/packagekit.h>
#include "gpk-common.h"
+#include "gpk-gnome.h"
#include "gpk-debug.h"
static GtkBuilder *builder = NULL;
Index: gnome-packagekit-3.20.0/src/gpk-marshal.list
===================================================================
--- /dev/null
+++ gnome-packagekit-3.20.0/src/gpk-marshal.list
@@ -0,0 +1,3 @@
+VOID:UINT,STRING
+VOID:UINT,STRING,STRING
+
Index: gnome-packagekit-3.20.0/src/gpk-modal-dialog.c
===================================================================
--- /dev/null
+++ gnome-packagekit-3.20.0/src/gpk-modal-dialog.c
@@ -0,0 +1,861 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2008 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include "config.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <errno.h>
+#include <signal.h>
+
+#include <string.h>
+#include <sys/types.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif /* HAVE_UNISTD_H */
+#include <sys/wait.h>
+#include <fcntl.h>
+#include <glib/gi18n.h>
+#include <packagekit-glib2/packagekit.h>
+
+#include "egg-string.h"
+
+#include "gpk-animated-icon.h"
+#include "gpk-modal-dialog.h"
+#include "gpk-common.h"
+#include "gpk-gnome.h"
+#include "gpk-enum.h"
+
+static void gpk_modal_dialog_finalize (GObject *object);
+
+#define GPK_MODAL_DIALOG_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GPK_TYPE_CLIENT_DIALOG, GpkModalDialogPrivate))
+
+struct _GpkModalDialogPrivate
+{
+ GtkBuilder *builder;
+ guint pulse_timer_id;
+ gboolean show_progress_files;
+ gboolean has_parent;
+ GMainLoop *loop;
+ GtkResponseType response;
+ GtkListStore *store;
+ gchar *title;
+ gboolean set_image;
+ GpkModalDialogPage page;
+ PkBitfield options;
+ GtkWidget *image_status;
+};
+
+enum {
+ GPK_MODAL_DIALOG_CLOSE,
+ GPK_MODAL_DIALOG_QUIT,
+ GPK_MODAL_DIALOG_ACTION,
+ GPK_MODAL_DIALOG_CANCEL,
+ LAST_SIGNAL
+};
+
+enum {
+ GPK_MODAL_DIALOG_STORE_IMAGE,
+ GPK_MODAL_DIALOG_STORE_ID,
+ GPK_MODAL_DIALOG_STORE_TEXT,
+ GPK_MODAL_DIALOG_STORE_LAST
+};
+
+static guint signals [LAST_SIGNAL] = { 0 };
+G_DEFINE_TYPE (GpkModalDialog, gpk_modal_dialog, G_TYPE_OBJECT)
+
+/**
+ * gpk_modal_dialog_show_widget:
+ **/
+static void
+gpk_modal_dialog_show_widget (GpkModalDialog *dialog, const gchar *name, gboolean enabled)
+{
+ GtkWidget *widget;
+ widget = GTK_WIDGET (gtk_builder_get_object (dialog->priv->builder, name));
+ if (enabled)
+ gtk_widget_show (widget);
+ else
+ gtk_widget_hide (widget);
+}
+
+/**
+ * gpk_modal_dialog_setup:
+ **/
+gboolean
+gpk_modal_dialog_setup (GpkModalDialog *dialog, GpkModalDialogPage page, PkBitfield options)
+{
+ GtkLabel *label;
+ g_return_val_if_fail (GPK_IS_CLIENT_DIALOG (dialog), FALSE);
+
+ /* reset state */
+ dialog->priv->set_image = FALSE;
+ dialog->priv->page = page;
+ dialog->priv->options = options;
+ label = GTK_LABEL (gtk_builder_get_object (dialog->priv->builder, "label_message"));
+ gtk_label_set_label (label, "");
+ gpk_modal_dialog_set_action (dialog, NULL);
+ return TRUE;
+}
+
+/**
+ * gpk_modal_dialog_present_with_time:
+ **/
+gboolean
+gpk_modal_dialog_present_with_time (GpkModalDialog *dialog, guint32 timestamp)
+{
+ GtkWidget *widget;
+ PkBitfield bitfield = 0;
+
+ g_return_val_if_fail (GPK_IS_CLIENT_DIALOG (dialog), FALSE);
+
+ widget = GTK_WIDGET (gtk_builder_get_object (dialog->priv->builder, "label_title"));
+ gtk_widget_show (widget);
+ gtk_widget_show (dialog->priv->image_status);
+ /* helper */
+ if (dialog->priv->page == GPK_MODAL_DIALOG_PAGE_CONFIRM) {
+ if (!dialog->priv->set_image)
+ gpk_modal_dialog_set_image (dialog, "dialog-question");
+ bitfield = pk_bitfield_from_enums (GPK_MODAL_DIALOG_WIDGET_BUTTON_CANCEL,
+ GPK_MODAL_DIALOG_WIDGET_BUTTON_ACTION,
+ GPK_MODAL_DIALOG_WIDGET_MESSAGE,
+ -1);
+ gpk_modal_dialog_set_allow_cancel (dialog, TRUE);
+ } else if (dialog->priv->page == GPK_MODAL_DIALOG_PAGE_FINISHED) {
+ if (!dialog->priv->set_image)
+ gpk_modal_dialog_set_image (dialog, "dialog-information");
+ bitfield = pk_bitfield_from_enums (GPK_MODAL_DIALOG_WIDGET_BUTTON_CLOSE,
+ GPK_MODAL_DIALOG_WIDGET_MESSAGE,
+ -1);
+ } else if (dialog->priv->page == GPK_MODAL_DIALOG_PAGE_CONFIRM) {
+ if (!dialog->priv->set_image)
+ gpk_modal_dialog_set_image (dialog, "dialog-question");
+ bitfield = pk_bitfield_from_enums (GPK_MODAL_DIALOG_WIDGET_BUTTON_CLOSE,
+ GPK_MODAL_DIALOG_WIDGET_BUTTON_ACTION,
+ GPK_MODAL_DIALOG_WIDGET_MESSAGE,
+ -1);
+ } else if (dialog->priv->page == GPK_MODAL_DIALOG_PAGE_WARNING) {
+ if (!dialog->priv->set_image)
+ gpk_modal_dialog_set_image (dialog, "dialog-warning");
+ bitfield = pk_bitfield_from_enums (GPK_MODAL_DIALOG_WIDGET_BUTTON_CLOSE,
+ GPK_MODAL_DIALOG_WIDGET_MESSAGE,
+ -1);
+ } else if (dialog->priv->page == GPK_MODAL_DIALOG_PAGE_PROGRESS) {
+ if (!dialog->priv->set_image)
+ gpk_modal_dialog_set_image (dialog, "dialog-warning");
+ bitfield = pk_bitfield_from_enums (GPK_MODAL_DIALOG_WIDGET_BUTTON_CLOSE,
+ GPK_MODAL_DIALOG_WIDGET_BUTTON_CANCEL,
+ GPK_MODAL_DIALOG_WIDGET_PROGRESS_BAR,
+ -1);
+ }
+
+ /* we can specify extras */
+ bitfield += dialog->priv->options;
+
+ gpk_modal_dialog_show_widget (dialog, "button_cancel", pk_bitfield_contain (bitfield, GPK_MODAL_DIALOG_WIDGET_BUTTON_CANCEL));
+ gpk_modal_dialog_show_widget (dialog, "button_close", pk_bitfield_contain (bitfield, GPK_MODAL_DIALOG_WIDGET_BUTTON_CLOSE));
+ gpk_modal_dialog_show_widget (dialog, "button_action", pk_bitfield_contain (bitfield, GPK_MODAL_DIALOG_WIDGET_BUTTON_ACTION));
+ gpk_modal_dialog_show_widget (dialog, "progressbar_percent", pk_bitfield_contain (bitfield, GPK_MODAL_DIALOG_WIDGET_PROGRESS_BAR));
+ gpk_modal_dialog_show_widget (dialog, "label_message", pk_bitfield_contain (bitfield, GPK_MODAL_DIALOG_WIDGET_MESSAGE));
+ gpk_modal_dialog_show_widget (dialog, "scrolledwindow_packages", pk_bitfield_contain (bitfield, GPK_MODAL_DIALOG_WIDGET_PACKAGE_LIST));
+ gpk_modal_dialog_show_widget (dialog, "label_force_height", pk_bitfield_contain (bitfield, GPK_MODAL_DIALOG_WIDGET_PADDING));
+
+ /* always force width */
+ gpk_modal_dialog_show_widget (dialog, "label_force_width", TRUE);
+
+ /* show */
+ widget = GTK_WIDGET (gtk_builder_get_object (dialog->priv->builder, "dialog_client"));
+ gtk_widget_realize (widget);
+ gtk_window_present_with_time (GTK_WINDOW (widget), timestamp);
+
+ return TRUE;
+}
+
+/**
+ * gpk_modal_dialog_present:
+ **/
+gboolean
+gpk_modal_dialog_present (GpkModalDialog *dialog)
+{
+ return gpk_modal_dialog_present_with_time (dialog, 0);
+}
+
+/**
+ * gpk_modal_dialog_set_parent:
+ **/
+gboolean
+gpk_modal_dialog_set_parent (GpkModalDialog *dialog, GdkWindow *window)
+{
+ GtkWidget *widget;
+ GdkWindow *window_ours;
+ g_return_val_if_fail (GPK_IS_CLIENT_DIALOG (dialog), FALSE);
+
+ /* never set, and nothing now */
+ if (window == NULL && !dialog->priv->has_parent)
+ return TRUE;
+
+ /* not sure what to do here, should probably unparent somehow */
+ if (window == NULL) {
+ g_warning ("parent set NULL when already modal with another window, setting non-modal");
+ widget = GTK_WIDGET (gtk_builder_get_object (dialog->priv->builder, "dialog_client"));
+ gtk_window_set_modal (GTK_WINDOW (widget), FALSE);
+ dialog->priv->has_parent = FALSE;
+
+ /* use the saved title if it exists */
+ if (dialog->priv->title != NULL)
+ gpk_modal_dialog_set_title (dialog, dialog->priv->title);
+
+ return FALSE;
+ }
+
+ /* check we are a valid window */
+ if (!GDK_WINDOW (window)) {
+ g_warning ("not a valid GdkWindow!");
+ return FALSE;
+ }
+
+ widget = GTK_WIDGET (gtk_builder_get_object (dialog->priv->builder, "dialog_client"));
+ gtk_widget_realize (widget);
+ gtk_window_set_modal (GTK_WINDOW (widget), TRUE);
+ window_ours = gtk_widget_get_window (widget);
+ gdk_window_set_transient_for (window_ours, window);
+ dialog->priv->has_parent = TRUE;
+ return TRUE;
+}
+
+/**
+ * gpk_modal_dialog_set_window_title:
+ **/
+static gboolean
+gpk_modal_dialog_set_window_title (GpkModalDialog *dialog, const gchar *title)
+{
+ GtkWindow *window;
+
+ g_return_val_if_fail (GPK_IS_CLIENT_DIALOG (dialog), FALSE);
+ g_return_val_if_fail (title != NULL, FALSE);
+
+ g_debug ("setting window title: %s", title);
+ window = GTK_WINDOW (gtk_builder_get_object (dialog->priv->builder, "dialog_client"));
+ gtk_window_set_title (window, title);
+ return TRUE;
+}
+
+/**
+ * gpk_modal_dialog_set_window_icon:
+ **/
+gboolean
+gpk_modal_dialog_set_window_icon (GpkModalDialog *dialog, const gchar *icon)
+{
+ GtkWindow *window;
+
+ g_return_val_if_fail (GPK_IS_CLIENT_DIALOG (dialog), FALSE);
+ g_return_val_if_fail (icon != NULL, FALSE);
+
+ g_debug ("setting window icon: %s", icon);
+ window = GTK_WINDOW (gtk_builder_get_object (dialog->priv->builder, "dialog_client"));
+ gtk_window_set_icon_name (window, icon);
+ return TRUE;
+}
+
+/**
+ * gpk_modal_dialog_set_title:
+ **/
+gboolean
+gpk_modal_dialog_set_title (GpkModalDialog *dialog, const gchar *title)
+{
+ GtkLabel *label;
+ GtkWidget *widget;
+ gchar *title_bold;
+
+ g_return_val_if_fail (GPK_IS_CLIENT_DIALOG (dialog), FALSE);
+ g_return_val_if_fail (title != NULL, FALSE);
+
+ /* only set the window title if we are non-modal */
+ if (!dialog->priv->has_parent) {
+ widget = GTK_WIDGET (gtk_builder_get_object (dialog->priv->builder,
+ "dialog_client"));
+ gtk_window_set_modal (GTK_WINDOW (widget), FALSE);
+ }
+
+ /* we save this in case we are non-modal and have to use a title */
+ g_free (dialog->priv->title);
+ dialog->priv->title = g_strdup (title);
+
+ title_bold = g_strdup_printf ("<b><big>%s</big></b>", title);
+ g_debug ("setting title: %s", title_bold);
+ label = GTK_LABEL (gtk_builder_get_object (dialog->priv->builder, "label_title"));
+ gtk_label_set_markup (label, title_bold);
+ g_free (title_bold);
+ return TRUE;
+}
+
+/**
+ * gpk_modal_dialog_set_message:
+ **/
+gboolean
+gpk_modal_dialog_set_message (GpkModalDialog *dialog, const gchar *message)
+{
+ GtkLabel *label;
+
+ g_return_val_if_fail (GPK_IS_CLIENT_DIALOG (dialog), FALSE);
+ g_return_val_if_fail (message != NULL, FALSE);
+
+ /* ignore this if it's uninteresting */
+ if (!dialog->priv->show_progress_files)
+ return FALSE;
+
+ g_debug ("setting message: %s", message);
+ label = GTK_LABEL (gtk_builder_get_object (dialog->priv->builder, "label_message"));
+ gtk_label_set_markup (label, message);
+ return TRUE;
+}
+
+/**
+ * gpk_modal_dialog_set_action:
+ **/
+gboolean
+gpk_modal_dialog_set_action (GpkModalDialog *dialog, const gchar *action)
+{
+ GtkWidget *widget;
+
+ g_return_val_if_fail (GPK_IS_CLIENT_DIALOG (dialog), FALSE);
+
+ g_debug ("setting action: %s", action);
+ widget = GTK_WIDGET (gtk_builder_get_object (dialog->priv->builder, "button_action"));
+ if (action != NULL)
+ gtk_button_set_label (GTK_BUTTON (widget), action);
+ else
+ gtk_widget_hide (widget);
+ return TRUE;
+}
+
+/**
+ * gpk_modal_dialog_pulse_progress:
+ **/
+static gboolean
+gpk_modal_dialog_pulse_progress (GpkModalDialog *dialog)
+{
+ GtkWidget *widget;
+ static guint rate_limit = 0;
+
+ g_return_val_if_fail (GPK_IS_CLIENT_DIALOG (dialog), FALSE);
+
+ /* debug so we can catch polling */
+ if (rate_limit++ % 20 == 0)
+ g_debug ("polling check");
+
+ widget = GTK_WIDGET (gtk_builder_get_object (dialog->priv->builder, "progressbar_percent"));
+ gtk_progress_bar_pulse (GTK_PROGRESS_BAR (widget));
+ return TRUE;
+}
+
+/**
+ * gpk_modal_dialog_make_progressbar_pulse:
+ **/
+static void
+gpk_modal_dialog_make_progressbar_pulse (GpkModalDialog *dialog)
+{
+ GtkProgressBar *progress_bar;
+ if (dialog->priv->pulse_timer_id == 0) {
+ progress_bar = GTK_PROGRESS_BAR (gtk_builder_get_object (dialog->priv->builder, "progressbar_percent"));
+ gtk_progress_bar_set_pulse_step (progress_bar, 0.04);
+ dialog->priv->pulse_timer_id = g_timeout_add (75, (GSourceFunc) gpk_modal_dialog_pulse_progress, dialog);
+ g_source_set_name_by_id (dialog->priv->pulse_timer_id, "[GpkModalDialog] pulse");
+ }
+}
+
+/**
+ * gpk_modal_dialog_set_percentage:
+ **/
+gboolean
+gpk_modal_dialog_set_percentage (GpkModalDialog *dialog, gint percentage)
+{
+ GtkProgressBar *progress_bar;
+
+ g_return_val_if_fail (GPK_IS_CLIENT_DIALOG (dialog), FALSE);
+ g_return_val_if_fail (percentage <= 100, FALSE);
+
+ g_debug ("setting percentage: %u", percentage);
+
+ progress_bar = GTK_PROGRESS_BAR (gtk_builder_get_object (dialog->priv->builder, "progressbar_percent"));
+ if (dialog->priv->pulse_timer_id != 0) {
+ g_source_remove (dialog->priv->pulse_timer_id);
+ dialog->priv->pulse_timer_id = 0;
+ }
+
+ /* either pulse or set percentage */
+ if (percentage < 0)
+ gpk_modal_dialog_make_progressbar_pulse (dialog);
+ else
+ gtk_progress_bar_set_fraction (progress_bar, (gfloat) percentage / 100.0);
+ return TRUE;
+}
+
+/**
+ * gpk_modal_dialog_set_remaining:
+ **/
+gboolean
+gpk_modal_dialog_set_remaining (GpkModalDialog *dialog, guint remaining)
+{
+ GtkProgressBar *progress_bar;
+ gchar *timestring = NULL;
+ gchar *text = NULL;
+
+ g_return_val_if_fail (GPK_IS_CLIENT_DIALOG (dialog), FALSE);
+
+ g_debug ("setting remaining: %u", remaining);
+ progress_bar = GTK_PROGRESS_BAR (gtk_builder_get_object (dialog->priv->builder, "progressbar_percent"));
+
+ /* unknown */
+ if (remaining == 0) {
+ gtk_progress_bar_set_text (GTK_PROGRESS_BAR (progress_bar), "");
+ goto out;
+ }
+
+ /* get time text */
+ timestring = gpk_time_to_imprecise_string (remaining);
+ text = g_strdup_printf (_("Remaining time: %s"), timestring);
+ gtk_progress_bar_set_text (progress_bar, text);
+out:
+ g_free (timestring);
+ g_free (text);
+ return TRUE;
+}
+
+/**
+ * gpk_modal_dialog_set_image:
+ **/
+gboolean
+gpk_modal_dialog_set_image (GpkModalDialog *dialog, const gchar *image)
+{
+ g_return_val_if_fail (GPK_IS_CLIENT_DIALOG (dialog), FALSE);
+ g_return_val_if_fail (image != NULL, FALSE);
+
+ /* set state */
+ dialog->priv->set_image = TRUE;
+
+ g_debug ("setting image: %s", image);
+ gpk_animated_icon_enable_animation (GPK_ANIMATED_ICON (dialog->priv->image_status), FALSE);
+ gtk_image_set_from_icon_name (GTK_IMAGE (dialog->priv->image_status), image, GTK_ICON_SIZE_DIALOG);
+ return TRUE;
+}
+
+/**
+ * gpk_modal_dialog_set_image_status:
+ **/
+gboolean
+gpk_modal_dialog_set_image_status (GpkModalDialog *dialog, PkStatusEnum status)
+{
+ g_return_val_if_fail (GPK_IS_CLIENT_DIALOG (dialog), FALSE);
+
+ /* set state */
+ dialog->priv->set_image = TRUE;
+ gpk_set_animated_icon_from_status (GPK_ANIMATED_ICON (dialog->priv->image_status), status, GTK_ICON_SIZE_DIALOG);
+ return TRUE;
+}
+
+/**
+ * gpk_modal_dialog_get_window:
+ **/
+GtkWindow *
+gpk_modal_dialog_get_window (GpkModalDialog *dialog)
+{
+ GtkWindow *window;
+
+ g_return_val_if_fail (GPK_IS_CLIENT_DIALOG (dialog), NULL);
+
+ window = GTK_WINDOW (gtk_builder_get_object (dialog->priv->builder, "dialog_client"));
+ return window;
+}
+
+/**
+ * gpk_modal_dialog_set_allow_cancel:
+ **/
+gboolean
+gpk_modal_dialog_set_allow_cancel (GpkModalDialog *dialog, gboolean can_cancel)
+{
+ GtkWidget *widget;
+
+ g_return_val_if_fail (GPK_IS_CLIENT_DIALOG (dialog), FALSE);
+
+ widget = GTK_WIDGET (gtk_builder_get_object (dialog->priv->builder, "button_cancel"));
+ gtk_widget_set_sensitive (widget, can_cancel);
+
+ return TRUE;
+}
+
+/**
+ * gpk_modal_dialog_run:
+ **/
+GtkResponseType
+gpk_modal_dialog_run (GpkModalDialog *dialog)
+{
+ g_return_val_if_fail (GPK_IS_CLIENT_DIALOG (dialog), FALSE);
+
+ /* already running */
+ if (g_main_loop_is_running (dialog->priv->loop))
+ g_main_loop_quit (dialog->priv->loop);
+
+ dialog->priv->response = GTK_RESPONSE_NONE;
+ g_main_loop_run (dialog->priv->loop);
+
+ return dialog->priv->response;
+}
+
+/**
+ * gpk_modal_dialog_close:
+ **/
+gboolean
+gpk_modal_dialog_close (GpkModalDialog *dialog)
+{
+ GtkWidget *widget;
+
+ g_return_val_if_fail (GPK_IS_CLIENT_DIALOG (dialog), FALSE);
+
+ widget = GTK_WIDGET (gtk_builder_get_object (dialog->priv->builder, "dialog_client"));
+ gtk_widget_hide (widget);
+
+ if (dialog->priv->pulse_timer_id != 0) {
+ g_source_remove (dialog->priv->pulse_timer_id);
+ dialog->priv->pulse_timer_id = 0;
+ }
+
+ gpk_animated_icon_enable_animation (GPK_ANIMATED_ICON (dialog->priv->image_status), FALSE);
+ return TRUE;
+}
+
+/**
+ * gpk_modal_dialog_window_delete_cb:
+ **/
+static gboolean
+gpk_modal_dialog_window_delete_cb (GtkWidget *widget, GdkEvent *event, GpkModalDialog *dialog)
+{
+ dialog->priv->response = GTK_RESPONSE_DELETE_EVENT;
+ gpk_modal_dialog_close (dialog);
+ if (g_main_loop_is_running (dialog->priv->loop))
+ g_main_loop_quit (dialog->priv->loop);
+ /* do not destroy the window */
+ return TRUE;
+}
+
+/**
+ * gpk_modal_dialog_button_close_cb:
+ **/
+static void
+gpk_modal_dialog_button_close_cb (GtkWidget *widget_button, GpkModalDialog *dialog)
+{
+ dialog->priv->response = GTK_RESPONSE_CLOSE;
+ g_main_loop_quit (dialog->priv->loop);
+
+ if (dialog->priv->pulse_timer_id != 0) {
+ g_source_remove (dialog->priv->pulse_timer_id);
+ dialog->priv->pulse_timer_id = 0;
+ }
+
+ gpk_animated_icon_enable_animation (GPK_ANIMATED_ICON (dialog->priv->image_status), FALSE);
+ if (g_main_loop_is_running (dialog->priv->loop))
+ g_main_loop_quit (dialog->priv->loop);
+ else
+ g_signal_emit (dialog, signals [GPK_MODAL_DIALOG_CLOSE], 0);
+}
+
+/**
+ * gpk_modal_dialog_button_action_cb:
+ **/
+static void
+gpk_modal_dialog_button_action_cb (GtkWidget *widget_button, GpkModalDialog *dialog)
+{
+ dialog->priv->response = GTK_RESPONSE_OK;
+ g_main_loop_quit (dialog->priv->loop);
+ if (g_main_loop_is_running (dialog->priv->loop))
+ g_main_loop_quit (dialog->priv->loop);
+ else
+ g_signal_emit (dialog, signals [GPK_MODAL_DIALOG_ACTION], 0);
+}
+
+/**
+ * gpk_modal_dialog_button_cancel_cb:
+ **/
+static void
+gpk_modal_dialog_button_cancel_cb (GtkWidget *widget_button, GpkModalDialog *dialog)
+{
+ dialog->priv->response = GTK_RESPONSE_CANCEL;
+ if (g_main_loop_is_running (dialog->priv->loop))
+ g_main_loop_quit (dialog->priv->loop);
+ else
+ g_signal_emit (dialog, signals [GPK_MODAL_DIALOG_CANCEL], 0);
+}
+
+/**
+ * gpk_modal_dialog_set_package_list:
+ **/
+gboolean
+gpk_modal_dialog_set_package_list (GpkModalDialog *dialog, const GPtrArray *list)
+{
+ GtkTreeIter iter;
+ PkPackage *item;
+ const gchar *icon;
+ gchar *text;
+ guint i;
+ GtkWidget *widget;
+ gchar **split;
+ PkInfoEnum info;
+ gchar *package_id = NULL;
+ gchar *summary = NULL;
+
+ gtk_list_store_clear (dialog->priv->store);
+
+ widget = GTK_WIDGET (gtk_builder_get_object (dialog->priv->builder, "scrolledwindow_packages"));
+ if (list->len > 5)
+ gtk_widget_set_size_request (widget, -1, 300);
+ else if (list->len > 1)
+ gtk_widget_set_size_request (widget, -1, 150);
+
+ /* add each well */
+ for (i=0; i<list->len; i++) {
+ item = g_ptr_array_index (list, i);
+ g_object_get (item,
+ "info", &info,
+ NULL);
+
+ /* not installed, so ignore icon */
+ if (info == PK_INFO_ENUM_DOWNLOADING ||
+ info == PK_INFO_ENUM_CLEANUP)
+ continue;
+
+ g_object_get (item,
+ "package-id", &package_id,
+ "summary", &summary,
+ NULL);
+
+ text = gpk_package_id_format_twoline (gtk_widget_get_style_context (widget),
+ package_id, summary);
+
+ /* get the icon */
+ split = pk_package_id_split (package_id);
+ icon = gpk_info_enum_to_icon_name (PK_INFO_ENUM_INSTALLED);
+ gtk_list_store_append (dialog->priv->store, &iter);
+ gtk_list_store_set (dialog->priv->store, &iter,
+ GPK_MODAL_DIALOG_STORE_IMAGE, icon,
+ GPK_MODAL_DIALOG_STORE_ID, package_id,
+ GPK_MODAL_DIALOG_STORE_TEXT, text,
+ -1);
+ g_strfreev (split);
+ g_free (package_id);
+ g_free (summary);
+ g_free (text);
+ }
+
+ return TRUE;
+}
+
+/**
+ * gpk_dialog_treeview_for_package_list:
+ **/
+static gboolean
+gpk_dialog_treeview_for_package_list (GpkModalDialog *dialog)
+{
+ GtkTreeView *treeview;
+ GtkCellRenderer *renderer;
+ GtkTreeViewColumn *column;
+ GtkTreeSelection *selection;
+
+ treeview = GTK_TREE_VIEW (gtk_builder_get_object (dialog->priv->builder, "treeview_packages"));
+
+ /* column for images */
+ column = gtk_tree_view_column_new ();
+ renderer = gtk_cell_renderer_pixbuf_new ();
+ g_object_set (renderer, "stock-size", GTK_ICON_SIZE_DND, NULL);
+ gtk_tree_view_column_pack_start (column, renderer, FALSE);
+ gtk_tree_view_column_add_attribute (column, renderer, "icon-name", GPK_MODAL_DIALOG_STORE_IMAGE);
+ gtk_tree_view_append_column (treeview, column);
+
+ /* column for name */
+ renderer = gtk_cell_renderer_text_new ();
+ /* TRANSLATORS: column for the package name */
+ column = gtk_tree_view_column_new_with_attributes (_("Name"), renderer,
+ "markup", GPK_MODAL_DIALOG_STORE_TEXT, NULL);
+ gtk_tree_view_column_set_sort_column_id (column, GPK_MODAL_DIALOG_STORE_TEXT);
+ gtk_tree_view_append_column (treeview, column);
+
+ /* set some common options */
+ gtk_tree_view_set_headers_visible (treeview, FALSE);
+ selection = gtk_tree_view_get_selection (treeview);
+ gtk_tree_selection_set_mode (selection, GTK_SELECTION_NONE);
+ gtk_tree_selection_unselect_all (selection);
+
+ return TRUE;
+}
+
+/**
+ * gpk_modal_dialog_class_init:
+ * @klass: The GpkModalDialogClass
+ **/
+static void
+gpk_modal_dialog_class_init (GpkModalDialogClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ object_class->finalize = gpk_modal_dialog_finalize;
+ g_type_class_add_private (klass, sizeof (GpkModalDialogPrivate));
+ signals [GPK_MODAL_DIALOG_QUIT] =
+ g_signal_new ("quit",
+ G_TYPE_FROM_CLASS (object_class),
+ G_SIGNAL_RUN_LAST,
+ 0, NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+ signals [GPK_MODAL_DIALOG_CLOSE] =
+ g_signal_new ("close",
+ G_TYPE_FROM_CLASS (object_class),
+ G_SIGNAL_RUN_LAST,
+ 0, NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+ signals [GPK_MODAL_DIALOG_ACTION] =
+ g_signal_new ("action",
+ G_TYPE_FROM_CLASS (object_class),
+ G_SIGNAL_RUN_LAST,
+ 0, NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+ signals [GPK_MODAL_DIALOG_CANCEL] =
+ g_signal_new ("cancel",
+ G_TYPE_FROM_CLASS (object_class),
+ G_SIGNAL_RUN_LAST,
+ 0, NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+}
+
+/**
+ * gpk_modal_dialog_init:
+ * @dialog: This class instance
+ **/
+static void
+gpk_modal_dialog_init (GpkModalDialog *dialog)
+{
+ GtkWidget *widget;
+ GtkTreeView *treeview;
+ guint retval;
+ GError *error = NULL;
+ GtkBox *box;
+
+ dialog->priv = GPK_MODAL_DIALOG_GET_PRIVATE (dialog);
+
+ dialog->priv->loop = g_main_loop_new (NULL, FALSE);
+ dialog->priv->response = GTK_RESPONSE_NONE;
+ dialog->priv->pulse_timer_id = 0;
+ dialog->priv->show_progress_files = TRUE;
+ dialog->priv->has_parent = FALSE;
+ dialog->priv->set_image = FALSE;
+ dialog->priv->page = GPK_MODAL_DIALOG_PAGE_UNKNOWN;
+ dialog->priv->options = 0;
+ dialog->priv->title = NULL;
+
+ dialog->priv->store = gtk_list_store_new (GPK_MODAL_DIALOG_STORE_LAST,
+ G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING);
+
+ /* get UI */
+ dialog->priv->builder = gtk_builder_new ();
+ retval = gtk_builder_add_from_file (dialog->priv->builder, GPK_DATA "/gpk-client.ui", &error);
+ if (retval == 0) {
+ g_warning ("failed to load ui: %s", error->message);
+ g_error_free (error);
+ goto out_build;
+ }
+
+ /* add animated widget */
+ dialog->priv->image_status = gpk_animated_icon_new ();
+ box = GTK_BOX (gtk_builder_get_object (dialog->priv->builder, "hbox_status"));
+ gtk_box_pack_start (box, dialog->priv->image_status, FALSE, FALSE, 0);
+ gtk_widget_show (dialog->priv->image_status);
+
+ gpk_dialog_treeview_for_package_list (dialog);
+
+ treeview = GTK_TREE_VIEW (gtk_builder_get_object (dialog->priv->builder, "treeview_packages"));
+ gtk_tree_view_set_model (treeview, GTK_TREE_MODEL (dialog->priv->store));
+
+ /* common stuff */
+ widget = GTK_WIDGET (gtk_builder_get_object (dialog->priv->builder, "dialog_client"));
+ g_signal_connect (widget, "delete_event", G_CALLBACK (gpk_modal_dialog_window_delete_cb), dialog);
+ widget = GTK_WIDGET (gtk_builder_get_object (dialog->priv->builder, "button_close"));
+ g_signal_connect (widget, "clicked", G_CALLBACK (gpk_modal_dialog_button_close_cb), dialog);
+ widget = GTK_WIDGET (gtk_builder_get_object (dialog->priv->builder, "button_action"));
+ g_signal_connect (widget, "clicked", G_CALLBACK (gpk_modal_dialog_button_action_cb), dialog);
+ widget = GTK_WIDGET (gtk_builder_get_object (dialog->priv->builder, "button_cancel"));
+ g_signal_connect (widget, "clicked", G_CALLBACK (gpk_modal_dialog_button_cancel_cb), dialog);
+
+ /* set the message text an absolute width so it's forced to wrap */
+ widget = GTK_WIDGET (gtk_builder_get_object (dialog->priv->builder, "label_message"));
+ gtk_label_set_max_width_chars (GTK_LABEL (widget), 80);
+
+out_build:
+ /* clear status and progress text */
+ gpk_modal_dialog_set_window_title (dialog, "");
+ gpk_modal_dialog_set_title (dialog, "");
+ gpk_modal_dialog_set_message (dialog, "");
+}
+
+/**
+ * gpk_modal_dialog_finalize:
+ * @object: The object to finalize
+ **/
+static void
+gpk_modal_dialog_finalize (GObject *object)
+{
+ GpkModalDialog *dialog;
+ g_return_if_fail (GPK_IS_CLIENT_DIALOG (object));
+
+ dialog = GPK_MODAL_DIALOG (object);
+ g_return_if_fail (dialog->priv != NULL);
+
+ /* no updates, we're about to rip the builder up */
+ if (dialog->priv->pulse_timer_id != 0)
+ g_source_remove (dialog->priv->pulse_timer_id);
+
+ /* if it's closed, then hide */
+ gpk_modal_dialog_close (dialog);
+
+ /* shouldn't be, but just in case */
+ if (g_main_loop_is_running (dialog->priv->loop)) {
+ g_warning ("mainloop running on exit");
+ g_main_loop_quit (dialog->priv->loop);
+ }
+
+ g_object_unref (dialog->priv->store);
+ g_object_unref (dialog->priv->builder);
+ g_main_loop_unref (dialog->priv->loop);
+ g_free (dialog->priv->title);
+
+ G_OBJECT_CLASS (gpk_modal_dialog_parent_class)->finalize (object);
+}
+
+/**
+ * gpk_modal_dialog_new:
+ *
+ * Return value: a new GpkModalDialog object.
+ **/
+GpkModalDialog *
+gpk_modal_dialog_new (void)
+{
+ GpkModalDialog *dialog;
+ dialog = g_object_new (GPK_TYPE_CLIENT_DIALOG, NULL);
+ return GPK_MODAL_DIALOG (dialog);
+}
Index: gnome-packagekit-3.20.0/src/gpk-modal-dialog.h
===================================================================
--- /dev/null
+++ gnome-packagekit-3.20.0/src/gpk-modal-dialog.h
@@ -0,0 +1,127 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2008 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef __GPK_MODAL_DIALOG_H
+#define __GPK_MODAL_DIALOG_H
+
+#include <glib-object.h>
+#include <gtk/gtk.h>
+#include <packagekit-glib2/packagekit.h>
+
+G_BEGIN_DECLS
+
+#define GPK_TYPE_CLIENT_DIALOG (gpk_modal_dialog_get_type ())
+#define GPK_MODAL_DIALOG(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GPK_TYPE_CLIENT_DIALOG, GpkModalDialog))
+#define GPK_MODAL_DIALOG_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GPK_TYPE_CLIENT_DIALOG, GpkModalDialogClass))
+#define GPK_IS_CLIENT_DIALOG(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GPK_TYPE_CLIENT_DIALOG))
+#define GPK_IS_CLIENT_DIALOG_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GPK_TYPE_CLIENT_DIALOG))
+#define GPK_MODAL_DIALOG_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GPK_TYPE_CLIENT_DIALOG, GpkModalDialogClass))
+#define GPK_MODAL_DIALOG_ERROR (gpk_modal_dialog_error_quark ())
+#define GPK_MODAL_DIALOG_TYPE_ERROR (gpk_modal_dialog_error_get_type ())
+
+/**
+ * GpkModalDialogPage:
+ */
+typedef enum
+{
+ GPK_MODAL_DIALOG_PAGE_CONFIRM,
+ GPK_MODAL_DIALOG_PAGE_PROGRESS,
+ GPK_MODAL_DIALOG_PAGE_FINISHED,
+ GPK_MODAL_DIALOG_PAGE_WARNING,
+ GPK_MODAL_DIALOG_PAGE_CUSTOM,
+ GPK_MODAL_DIALOG_PAGE_UNKNOWN
+} GpkModalDialogPage;
+
+/**
+ * GpkModalDialogWidgets:
+ */
+typedef enum
+{
+ GPK_MODAL_DIALOG_WIDGET_BUTTON_CANCEL,
+ GPK_MODAL_DIALOG_WIDGET_BUTTON_CLOSE,
+ GPK_MODAL_DIALOG_WIDGET_BUTTON_ACTION,
+ GPK_MODAL_DIALOG_WIDGET_PADDING,
+ GPK_MODAL_DIALOG_WIDGET_PACKAGE_LIST,
+ GPK_MODAL_DIALOG_WIDGET_PROGRESS_BAR,
+ GPK_MODAL_DIALOG_WIDGET_MESSAGE,
+ GPK_MODAL_DIALOG_WIDGET_UNKNOWN
+} GpkModalDialogWidgets;
+
+/* helpers */
+#define GPK_MODAL_DIALOG_PACKAGE_PADDING pk_bitfield_from_enums (GPK_MODAL_DIALOG_WIDGET_PADDING, GPK_MODAL_DIALOG_WIDGET_MESSAGE, -1)
+#define GPK_MODAL_DIALOG_PACKAGE_LIST pk_bitfield_value (GPK_MODAL_DIALOG_WIDGET_PACKAGE_LIST)
+#define GPK_MODAL_DIALOG_BUTTON_ACTION pk_bitfield_value (GPK_MODAL_DIALOG_WIDGET_BUTTON_ACTION)
+
+typedef struct _GpkModalDialogPrivate GpkModalDialogPrivate;
+typedef struct _GpkModalDialog GpkModalDialog;
+typedef struct _GpkModalDialogClass GpkModalDialogClass;
+
+struct _GpkModalDialog
+{
+ GObject parent;
+ GpkModalDialogPrivate *priv;
+};
+
+struct _GpkModalDialogClass
+{
+ GObjectClass parent_class;
+};
+
+GQuark gpk_modal_dialog_error_quark (void);
+GType gpk_modal_dialog_get_type (void);
+GpkModalDialog *gpk_modal_dialog_new (void);
+
+gboolean gpk_modal_dialog_present (GpkModalDialog *dialog);
+gboolean gpk_modal_dialog_present_with_time (GpkModalDialog *dialog,
+ guint32 timestamp);
+gboolean gpk_modal_dialog_set_package_list (GpkModalDialog *dialog,
+ const GPtrArray *list);
+gboolean gpk_modal_dialog_set_parent (GpkModalDialog *dialog,
+ GdkWindow *window);
+gboolean gpk_modal_dialog_set_window_icon (GpkModalDialog *dialog,
+ const gchar *icon);
+gboolean gpk_modal_dialog_set_title (GpkModalDialog *dialog,
+ const gchar *title);
+gboolean gpk_modal_dialog_set_message (GpkModalDialog *dialog,
+ const gchar *message);
+gboolean gpk_modal_dialog_set_action (GpkModalDialog *dialog,
+ const gchar *action);
+gboolean gpk_modal_dialog_set_percentage (GpkModalDialog *dialog,
+ gint percentage);
+gboolean gpk_modal_dialog_set_remaining (GpkModalDialog *dialog,
+ guint remaining);
+gboolean gpk_modal_dialog_set_image (GpkModalDialog *dialog,
+ const gchar *image);
+gboolean gpk_modal_dialog_set_image_status (GpkModalDialog *dialog,
+ PkStatusEnum status);
+gboolean gpk_modal_dialog_set_allow_cancel (GpkModalDialog *dialog,
+ gboolean can_cancel);
+GtkWindow *gpk_modal_dialog_get_window (GpkModalDialog *dialog);
+GtkResponseType gpk_modal_dialog_run (GpkModalDialog *dialog);
+gboolean gpk_modal_dialog_close (GpkModalDialog *dialog);
+gboolean gpk_modal_dialog_setup (GpkModalDialog *dialog,
+ GpkModalDialogPage page,
+ PkBitfield options);
+
+G_END_DECLS
+
+#endif /* __GPK_MODAL_DIALOG_H */
+
Index: gnome-packagekit-3.20.0/src/gpk-prefs.c
===================================================================
--- gnome-packagekit-3.20.0.orig/src/gpk-prefs.c
+++ gnome-packagekit-3.20.0/src/gpk-prefs.c
@@ -32,6 +32,7 @@
#include "gpk-debug.h"
#include "gpk-enum.h"
#include "gpk-error.h"
+#include "gpk-gnome.h"
typedef struct {
const gchar *id_tmp;
Index: gnome-packagekit-3.20.0/src/gpk-self-test.c
===================================================================
--- gnome-packagekit-3.20.0.orig/src/gpk-self-test.c
+++ gnome-packagekit-3.20.0/src/gpk-self-test.c
@@ -25,8 +25,12 @@
#include "egg-markdown.h"
#include "gpk-common.h"
+#include "gpk-dbus.h"
+#include "gpk-dbus-task.h"
#include "gpk-enum.h"
#include "gpk-error.h"
+#include "gpk-language.h"
+#include "gpk-modal-dialog.h"
#include "gpk-task.h"
@@ -106,6 +110,15 @@ gpk_test_enum_func (void)
}
}
+ /* check we convert all the status animation enums */
+ for (i = PK_STATUS_ENUM_UNKNOWN+1; i < PK_STATUS_ENUM_UNKNOWN; i++) {
+ string = gpk_status_enum_to_animation (i);
+ if (string == NULL || g_strcmp0 (string, "help-browser") == 0) {
+ g_warning ("failed to get %s", pk_status_enum_to_string (i));
+ break;
+ }
+ }
+
/* check we convert all the info icon names enums */
for (i = PK_INFO_ENUM_UNKNOWN+1; i < PK_INFO_ENUM_LAST; i++) {
string = gpk_info_enum_to_icon_name (i);
@@ -199,6 +212,197 @@ gpk_test_enum_func (void)
}
static void
+gpk_test_dbus_task_func (void)
+{
+ GpkDbusTask *dtask;
+ gchar *lang;
+ gchar *language;
+ gchar *package;
+ gboolean ret;
+// const gchar *fonts[] = { ":lang=mn", NULL };
+// GError *error;
+
+ /* get GpkDbusTask object */
+ dtask = gpk_dbus_task_new ();
+ g_assert (dtask);
+
+ /* convert tag to lang */
+ lang = gpk_dbus_task_font_tag_to_lang (":lang=mn");
+ g_assert_cmpstr (lang, ==, "mn");
+ g_free (lang);
+
+ /* convert tag to language */
+ language = gpk_dbus_task_font_tag_to_localised_name (dtask, ":lang=mn");
+ g_assert_cmpstr (language, ==, "Mongolian");
+ g_free (language);
+
+ /* test trusted path */
+// ret = gpk_dbus_task_path_is_trusted ("/usr/libexec/gst-install-plugins-helper");
+// g_assert (ret);
+
+ /* test trusted path */
+ ret = gpk_dbus_task_path_is_trusted ("/usr/bin/totem");
+ g_assert (!ret);
+
+ /* get package for exec */
+ package = gpk_dbus_task_get_package_for_exec (dtask, "/usr/bin/totem");
+ g_assert_cmpstr (package, ==, "totem");
+ g_free (package);
+
+ /* set exec */
+ ret = gpk_dbus_task_set_exec (dtask, "/usr/bin/totem");
+ g_assert (ret);
+#if 0
+ /* install fonts (no UI) */
+ error = NULL;
+ gpk_dbus_task_set_interaction (dtask, GPK_CLIENT_INTERACT_NEVER);
+ ret = gpk_dbus_task_install_fontconfig_resources (dtask, (gchar**)fonts, NULL, &error);
+ g_assert_no_error (error);
+ g_assert (ret);
+
+ /* install fonts (if found) */
+ error = NULL;
+ gpk_dbus_task_set_interaction (dtask, pk_bitfield_from_enums (GPK_CLIENT_INTERACT_CONFIRM_SEARCH, GPK_CLIENT_INTERACT_FINISHED, -1));
+ ret = gpk_dbus_task_install_fontconfig_resources (dtask, (gchar**)fonts, NULL, &error);
+ g_assert_no_error (error);
+ g_assert (ret);
+
+ /* install fonts (always) */
+ error = NULL;
+ gpk_dbus_task_set_interaction (dtask, GPK_CLIENT_INTERACT_ALWAYS);
+ ret = gpk_dbus_task_install_fontconfig_resources (dtask, (gchar**)fonts, NULL, &error);
+ g_assert_no_error (error);
+ g_assert (ret);
+#endif
+}
+
+static void
+gpk_test_modal_dialog_func (void)
+{
+ GtkResponseType button;
+ GpkModalDialog *dialog = NULL;
+ GPtrArray *array;
+ PkPackage *item;
+ gboolean ret;
+
+ /* get GpkModalDialog object */
+ dialog = gpk_modal_dialog_new ();
+ g_assert (dialog);
+
+ /* set some packages */
+ array = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref);
+ item = pk_package_new ();
+ ret = pk_package_set_id (item, "totem;001;i386;fedora", NULL);
+ g_assert (ret);
+ g_object_set (item,
+ "info", PK_INFO_ENUM_INSTALLED,
+ "summary", "Totem is a music player for GNOME",
+ NULL);
+ g_ptr_array_add (array, item);
+ item = pk_package_new ();
+ ret = pk_package_set_id (item, "totem;001;i386;fedora", NULL);
+ g_assert (ret);
+ g_object_set (item,
+ "info", PK_INFO_ENUM_AVAILABLE,
+ "summary", "Amarok is a music player for KDE",
+ NULL);
+ g_ptr_array_add (array, item);
+ gpk_modal_dialog_set_package_list (dialog, array);
+ g_ptr_array_unref (array);
+
+ /* help button */
+ gpk_modal_dialog_setup (dialog, GPK_MODAL_DIALOG_PAGE_WARNING, 0);
+ gpk_modal_dialog_set_title (dialog, "Button press test");
+ gpk_modal_dialog_set_message (dialog, "Please press close");
+ gpk_modal_dialog_set_image (dialog, "dialog-warning");
+ gpk_modal_dialog_present (dialog);
+ button = gpk_modal_dialog_run (dialog);
+ g_assert_cmpint (button, ==, GTK_RESPONSE_CLOSE);
+
+ /* confirm button */
+ gpk_modal_dialog_setup (dialog, GPK_MODAL_DIALOG_PAGE_CONFIRM, 0);
+ gpk_modal_dialog_set_title (dialog, "Button press test with a really really long title");
+ gpk_modal_dialog_set_message (dialog, "Please press Uninstall\n\nThis is a really really, really,\nreally long title <i>with formatting</i>");
+ gpk_modal_dialog_set_image (dialog, "dialog-information");
+ gpk_modal_dialog_set_action (dialog, "Uninstall");
+ gpk_modal_dialog_present (dialog);
+ button = gpk_modal_dialog_run (dialog);
+ g_assert_cmpint (button, ==, GTK_RESPONSE_OK);
+
+ /* no message */
+ gpk_modal_dialog_setup (dialog, GPK_MODAL_DIALOG_PAGE_PROGRESS, 0);
+ gpk_modal_dialog_set_title (dialog, "Refresh cache");
+ gpk_modal_dialog_set_image_status (dialog, PK_STATUS_ENUM_REFRESH_CACHE);
+ gpk_modal_dialog_set_percentage (dialog, -1);
+ gpk_modal_dialog_present (dialog);
+ gpk_modal_dialog_run (dialog);
+
+ /* progress */
+ gpk_modal_dialog_setup (dialog, GPK_MODAL_DIALOG_PAGE_PROGRESS, GPK_MODAL_DIALOG_PACKAGE_PADDING);
+ gpk_modal_dialog_set_title (dialog, "Button press test");
+ gpk_modal_dialog_set_message (dialog, "Please press cancel");
+ gpk_modal_dialog_set_image_status (dialog, PK_STATUS_ENUM_RUNNING);
+ gpk_modal_dialog_set_percentage (dialog, 50);
+ gpk_modal_dialog_present (dialog);
+ button = gpk_modal_dialog_run (dialog);
+ g_assert_cmpint (button, ==, GTK_RESPONSE_CANCEL);
+
+ /* progress */
+ gpk_modal_dialog_setup (dialog, GPK_MODAL_DIALOG_PAGE_PROGRESS, pk_bitfield_from_enums (GPK_MODAL_DIALOG_WIDGET_MESSAGE, -1));
+ gpk_modal_dialog_set_title (dialog, "Button press test");
+ gpk_modal_dialog_set_message (dialog, "Please press close");
+ gpk_modal_dialog_set_image_status (dialog, PK_STATUS_ENUM_INSTALL);
+ gpk_modal_dialog_set_percentage (dialog, -1);
+ gpk_modal_dialog_present (dialog);
+ button = gpk_modal_dialog_run (dialog);
+ g_assert_cmpint (button, ==, GTK_RESPONSE_CLOSE);
+
+ /* confirm install button */
+ gpk_modal_dialog_setup (dialog, GPK_MODAL_DIALOG_PAGE_CONFIRM, GPK_MODAL_DIALOG_PACKAGE_LIST);
+ gpk_modal_dialog_set_title (dialog, "Button press test");
+ gpk_modal_dialog_set_message (dialog, "Please press Install if you can see the package list");
+ gpk_modal_dialog_set_image (dialog, "dialog-information");
+ gpk_modal_dialog_set_action (dialog, "Install");
+ gpk_modal_dialog_present (dialog);
+ button = gpk_modal_dialog_run (dialog);
+ g_assert_cmpint (button, ==, GTK_RESPONSE_OK);
+
+ gpk_modal_dialog_close (dialog);
+
+ g_object_unref (dialog);
+}
+
+static void
+gpk_test_language_func (void)
+{
+ gboolean ret;
+ gchar *lang;
+ GError *error = NULL;
+ GpkLanguage *language = NULL;
+
+ /* get GpkLanguage object */
+ language = gpk_language_new ();
+ g_assert (language != NULL);
+
+ /* populate */
+ ret = gpk_language_populate (language, &error);
+ g_assert_no_error (error);
+ g_assert (ret);
+
+ /* get data (present) */
+ lang = gpk_language_iso639_to_language (language, "en");
+ g_assert_cmpstr (lang, ==, "English");
+ g_free (lang);
+
+ /* get data (missing) */
+ lang = gpk_language_iso639_to_language (language, "notgoingtoexist");
+ g_assert_cmpstr (lang, ==, NULL);
+
+ g_object_unref (language);
+>>>>>>> parent of 52b1ece... Remove unused functionality
+}
+
+static void
gpk_test_error_func (void)
{
gboolean ret;
@@ -212,6 +416,17 @@ gpk_test_error_func (void)
}
static void
+gpk_test_dbus_func (void)
+{
+ GpkDbus *dbus = NULL;
+
+ /* get GpkDbus object */
+ dbus = gpk_dbus_new ();
+ g_assert (dbus);
+ g_object_unref (dbus);
+}
+
+static void
gpk_test_common_func (void)
{
gchar *text;
@@ -554,8 +769,12 @@ main (int argc, char **argv)
g_test_add_func ("/gnome-packagekit/enum", gpk_test_enum_func);
g_test_add_func ("/gnome-packagekit/common", gpk_test_common_func);
+ g_test_add_func ("/gnome-packagekit/language", gpk_test_language_func);
g_test_add_func ("/gnome-packagekit/markdown", gpk_test_markdown_func);
+ g_test_add_func ("/gnome-packagekit/dbus", gpk_test_dbus_func);
+ g_test_add_func ("/gnome-packagekit/dbus-task", gpk_test_dbus_task_func);
if (g_test_thorough ()) {
+ g_test_add_func ("/gnome-packagekit/modal-dialog", gpk_test_modal_dialog_func);
g_test_add_func ("/gnome-packagekit/error", gpk_test_error_func);
g_test_add_func ("/gnome-packagekit/task", gpk_test_task_func);
}
Index: gnome-packagekit-3.20.0/src/gpk-session.c
===================================================================
--- /dev/null
+++ gnome-packagekit-3.20.0/src/gpk-session.c
@@ -0,0 +1,361 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2008-2009 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include "config.h"
+
+#include <string.h>
+#include <glib.h>
+#include <glib/gi18n.h>
+#include <dbus/dbus-glib.h>
+
+#include "gpk-session.h"
+#include "gpk-common.h"
+
+static void gpk_session_finalize (GObject *object);
+
+#define GPK_SESSION_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GPK_TYPE_SESSION, GpkSessionPrivate))
+
+#define GPK_SESSION_MANAGER_SERVICE "org.gnome.SessionManager"
+#define GPK_SESSION_MANAGER_PATH "/org/gnome/SessionManager"
+#define GPK_SESSION_MANAGER_INTERFACE "org.gnome.SessionManager"
+#define GPK_SESSION_MANAGER_PRESENCE_PATH "/org/gnome/SessionManager/Presence"
+#define GPK_SESSION_MANAGER_PRESENCE_INTERFACE "org.gnome.SessionManager.Presence"
+#define GPK_SESSION_MANAGER_CLIENT_PRIVATE_INTERFACE "org.gnome.SessionManager.ClientPrivate"
+#define GPK_DBUS_PROPERTIES_INTERFACE "org.freedesktop.DBus.Properties"
+
+typedef enum {
+ GPK_SESSION_STATUS_ENUM_AVAILABLE = 0,
+ GPK_SESSION_STATUS_ENUM_INVISIBLE,
+ GPK_SESSION_STATUS_ENUM_BUSY,
+ GPK_SESSION_STATUS_ENUM_IDLE,
+ GPK_SESSION_STATUS_ENUM_UNKNOWN
+} GpkSessionStatusEnum;
+
+typedef enum {
+ GPK_SESSION_INHIBIT_MASK_LOGOUT = 1,
+ GPK_SESSION_INHIBIT_MASK_SWITCH = 2,
+ GPK_SESSION_INHIBIT_MASK_SUSPEND = 4,
+ GPK_SESSION_INHIBIT_MASK_IDLE = 8
+} GpkSessionInhibitMask;
+
+struct GpkSessionPrivate
+{
+ DBusGProxy *proxy;
+ DBusGProxy *proxy_presence;
+ DBusGProxy *proxy_client_private;
+ DBusGProxy *proxy_prop;
+ gboolean is_idle_old;
+ gboolean is_inhibited_old;
+};
+
+enum {
+ IDLE_CHANGED,
+ INHIBITED_CHANGED,
+ STOP,
+ QUERY_END_SESSION,
+ END_SESSION,
+ CANCEL_END_SESSION,
+ LAST_SIGNAL
+};
+
+static guint signals [LAST_SIGNAL] = { 0 };
+static gpointer gpk_session_object = NULL;
+
+G_DEFINE_TYPE (GpkSession, gpk_session, G_TYPE_OBJECT)
+
+/**
+ * gpk_session_logout:
+ **/
+gboolean
+gpk_session_logout (GpkSession *session)
+{
+ g_return_val_if_fail (GPK_IS_SESSION (session), FALSE);
+
+ /* no gnome-session */
+ if (session->priv->proxy == NULL) {
+ g_warning ("no gnome-session");
+ return FALSE;
+ }
+
+ /* we have to use no reply, as the SM calls into g-p-m to get the can_suspend property */
+ dbus_g_proxy_call_no_reply (session->priv->proxy, "Logout",
+ G_TYPE_UINT, 1, /* no confirmation, but use inhibitors */
+ G_TYPE_INVALID);
+ return TRUE;
+}
+
+/**
+ * gpk_session_presence_status_changed_cb:
+ **/
+static void
+gpk_session_presence_status_changed_cb (DBusGProxy *proxy, guint status, GpkSession *session)
+{
+ gboolean is_idle;
+ is_idle = (status == GPK_SESSION_STATUS_ENUM_IDLE);
+ if (is_idle != session->priv->is_idle_old) {
+ g_debug ("emitting idle-changed : (%i)", is_idle);
+ session->priv->is_idle_old = is_idle;
+ g_signal_emit (session, signals [IDLE_CHANGED], 0, is_idle);
+ }
+}
+
+/**
+ * gpk_session_is_idle:
+ **/
+static gboolean
+gpk_session_is_idle (GpkSession *session)
+{
+ gboolean ret;
+ gboolean is_idle = FALSE;
+ GError *error = NULL;
+ GValue *value;
+
+ /* no gnome-session */
+ if (session->priv->proxy_prop == NULL) {
+ g_warning ("no gnome-session");
+ goto out;
+ }
+
+ value = g_new0(GValue, 1);
+ /* find out if this change altered the inhibited state */
+ ret = dbus_g_proxy_call (session->priv->proxy_prop, "Get", &error,
+ G_TYPE_STRING, GPK_SESSION_MANAGER_PRESENCE_INTERFACE,
+ G_TYPE_STRING, "status",
+ G_TYPE_INVALID,
+ G_TYPE_VALUE, value,
+ G_TYPE_INVALID);
+ if (!ret) {
+ g_warning ("failed to get idle status: %s", error->message);
+ g_error_free (error);
+ is_idle = FALSE;
+ goto out;
+ }
+ is_idle = (g_value_get_uint (value) == GPK_SESSION_STATUS_ENUM_IDLE);
+ g_free (value);
+out:
+ return is_idle;
+}
+
+/**
+ * gpk_session_is_inhibited:
+ **/
+static gboolean
+gpk_session_is_inhibited (GpkSession *session)
+{
+ gboolean ret;
+ gboolean is_inhibited = FALSE;
+ GError *error = NULL;
+
+ /* no gnome-session */
+ if (session->priv->proxy == NULL) {
+ g_warning ("no gnome-session");
+ goto out;
+ }
+
+ /* find out if this change altered the inhibited state */
+ ret = dbus_g_proxy_call (session->priv->proxy, "IsInhibited", &error,
+ G_TYPE_UINT, GPK_SESSION_INHIBIT_MASK_IDLE,
+ G_TYPE_INVALID,
+ G_TYPE_BOOLEAN, &is_inhibited,
+ G_TYPE_INVALID);
+ if (!ret) {
+ g_warning ("failed to get inhibit status: %s", error->message);
+ g_error_free (error);
+ is_inhibited = FALSE;
+ }
+out:
+ return is_inhibited;
+}
+
+/**
+ * gpk_session_inhibit_changed_cb:
+ **/
+static void
+gpk_session_inhibit_changed_cb (DBusGProxy *proxy, const gchar *id, GpkSession *session)
+{
+ gboolean is_inhibited;
+
+ is_inhibited = gpk_session_is_inhibited (session);
+ if (is_inhibited != session->priv->is_inhibited_old) {
+ g_debug ("emitting inhibited-changed : (%i)", is_inhibited);
+ session->priv->is_inhibited_old = is_inhibited;
+ g_signal_emit (session, signals [INHIBITED_CHANGED], 0, is_inhibited);
+ }
+}
+
+/**
+ * gpk_session_class_init:
+ * @klass: This class instance
+ **/
+static void
+gpk_session_class_init (GpkSessionClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ object_class->finalize = gpk_session_finalize;
+ g_type_class_add_private (klass, sizeof (GpkSessionPrivate));
+
+ signals [IDLE_CHANGED] =
+ g_signal_new ("idle-changed",
+ G_TYPE_FROM_CLASS (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GpkSessionClass, idle_changed),
+ NULL, NULL, g_cclosure_marshal_VOID__BOOLEAN,
+ G_TYPE_NONE, 1, G_TYPE_BOOLEAN);
+ signals [INHIBITED_CHANGED] =
+ g_signal_new ("inhibited-changed",
+ G_TYPE_FROM_CLASS (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GpkSessionClass, inhibited_changed),
+ NULL, NULL, g_cclosure_marshal_VOID__BOOLEAN,
+ G_TYPE_NONE, 1, G_TYPE_BOOLEAN);
+ signals [STOP] =
+ g_signal_new ("stop",
+ G_TYPE_FROM_CLASS (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GpkSessionClass, stop),
+ NULL, NULL, g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+ signals [QUERY_END_SESSION] =
+ g_signal_new ("query-end-session",
+ G_TYPE_FROM_CLASS (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GpkSessionClass, query_end_session),
+ NULL, NULL, g_cclosure_marshal_VOID__UINT,
+ G_TYPE_NONE, 1, G_TYPE_UINT);
+ signals [END_SESSION] =
+ g_signal_new ("end-session",
+ G_TYPE_FROM_CLASS (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GpkSessionClass, end_session),
+ NULL, NULL, g_cclosure_marshal_VOID__UINT,
+ G_TYPE_NONE, 1, G_TYPE_UINT);
+ signals [CANCEL_END_SESSION] =
+ g_signal_new ("cancel-end-session",
+ G_TYPE_FROM_CLASS (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GpkSessionClass, cancel_end_session),
+ NULL, NULL, g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+}
+
+/**
+ * gpk_session_init:
+ * @session: This class instance
+ **/
+static void
+gpk_session_init (GpkSession *session)
+{
+ DBusGConnection *connection;
+ GError *error = NULL;
+
+ session->priv = GPK_SESSION_GET_PRIVATE (session);
+ session->priv->is_idle_old = FALSE;
+ session->priv->is_inhibited_old = FALSE;
+ session->priv->proxy_client_private = NULL;
+
+ connection = dbus_g_bus_get (DBUS_BUS_SESSION, NULL);
+
+ /* get org.gnome.Session interface */
+ session->priv->proxy = dbus_g_proxy_new_for_name_owner (connection, GPK_SESSION_MANAGER_SERVICE,
+ GPK_SESSION_MANAGER_PATH,
+ GPK_SESSION_MANAGER_INTERFACE, &error);
+ if (session->priv->proxy == NULL) {
+ g_warning ("DBUS error: %s", error->message);
+ g_error_free (error);
+ return;
+ }
+
+ /* get org.gnome.Session.Presence interface */
+ session->priv->proxy_presence = dbus_g_proxy_new_for_name_owner (connection, GPK_SESSION_MANAGER_SERVICE,
+ GPK_SESSION_MANAGER_PRESENCE_PATH,
+ GPK_SESSION_MANAGER_PRESENCE_INTERFACE, &error);
+ if (session->priv->proxy_presence == NULL) {
+ g_warning ("DBUS error: %s", error->message);
+ g_error_free (error);
+ return;
+ }
+
+ /* get properties interface */
+ session->priv->proxy_prop = dbus_g_proxy_new_for_name_owner (connection, GPK_SESSION_MANAGER_SERVICE,
+ GPK_SESSION_MANAGER_PRESENCE_PATH,
+ GPK_DBUS_PROPERTIES_INTERFACE, &error);
+ if (session->priv->proxy_prop == NULL) {
+ g_warning ("DBUS error: %s", error->message);
+ g_error_free (error);
+ return;
+ }
+
+ /* get StatusChanged */
+ dbus_g_proxy_add_signal (session->priv->proxy_presence, "StatusChanged", G_TYPE_UINT, G_TYPE_INVALID);
+ dbus_g_proxy_connect_signal (session->priv->proxy_presence, "StatusChanged", G_CALLBACK (gpk_session_presence_status_changed_cb), session, NULL);
+
+ /* get InhibitorAdded */
+ dbus_g_proxy_add_signal (session->priv->proxy, "InhibitorAdded", DBUS_TYPE_G_OBJECT_PATH, G_TYPE_INVALID);
+ dbus_g_proxy_connect_signal (session->priv->proxy, "InhibitorAdded", G_CALLBACK (gpk_session_inhibit_changed_cb), session, NULL);
+
+ /* get InhibitorRemoved */
+ dbus_g_proxy_add_signal (session->priv->proxy, "InhibitorRemoved", DBUS_TYPE_G_OBJECT_PATH, G_TYPE_INVALID);
+ dbus_g_proxy_connect_signal (session->priv->proxy, "InhibitorRemoved", G_CALLBACK (gpk_session_inhibit_changed_cb), session, NULL);
+
+ /* coldplug */
+ session->priv->is_inhibited_old = gpk_session_is_inhibited (session);
+ session->priv->is_idle_old = gpk_session_is_idle (session);
+ g_debug ("idle: %i, inhibited: %i", session->priv->is_idle_old, session->priv->is_inhibited_old);
+}
+
+/**
+ * gpk_session_finalize:
+ * @object: This class instance
+ **/
+static void
+gpk_session_finalize (GObject *object)
+{
+ GpkSession *session;
+ g_return_if_fail (object != NULL);
+ g_return_if_fail (GPK_IS_SESSION (object));
+
+ session = GPK_SESSION (object);
+ session->priv = GPK_SESSION_GET_PRIVATE (session);
+
+ g_object_unref (session->priv->proxy);
+ g_object_unref (session->priv->proxy_presence);
+ if (session->priv->proxy_client_private != NULL)
+ g_object_unref (session->priv->proxy_client_private);
+ g_object_unref (session->priv->proxy_prop);
+
+ G_OBJECT_CLASS (gpk_session_parent_class)->finalize (object);
+}
+
+/**
+ * gpk_session_new:
+ * Return value: new GpkSession instance.
+ **/
+GpkSession *
+gpk_session_new (void)
+{
+ if (gpk_session_object != NULL) {
+ g_object_ref (gpk_session_object);
+ } else {
+ gpk_session_object = g_object_new (GPK_TYPE_SESSION, NULL);
+ g_object_add_weak_pointer (gpk_session_object, &gpk_session_object);
+ }
+ return GPK_SESSION (gpk_session_object);
+}
Index: gnome-packagekit-3.20.0/src/gpk-session.h
===================================================================
--- /dev/null
+++ gnome-packagekit-3.20.0/src/gpk-session.h
@@ -0,0 +1,69 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2008-2009 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef __GPK_SESSION_H
+#define __GPK_SESSION_H
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define GPK_TYPE_SESSION (gpk_session_get_type ())
+#define GPK_SESSION(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GPK_TYPE_SESSION, GpkSession))
+#define GPK_SESSION_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GPK_TYPE_SESSION, GpkSessionClass))
+#define GPK_IS_SESSION(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GPK_TYPE_SESSION))
+#define GPK_IS_SESSION_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GPK_TYPE_SESSION))
+#define GPK_SESSION_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GPK_TYPE_SESSION, GpkSessionClass))
+
+typedef struct GpkSessionPrivate GpkSessionPrivate;
+
+typedef struct
+{
+ GObject parent;
+ GpkSessionPrivate *priv;
+} GpkSession;
+
+typedef struct
+{
+ GObjectClass parent_class;
+ void (* idle_changed) (GpkSession *session,
+ gboolean is_idle);
+ void (* inhibited_changed) (GpkSession *session,
+ gboolean is_inhibited);
+ /* just exit */
+ void (* stop) (GpkSession *session);
+ /* reply with EndSessionResponse */
+ void (* query_end_session) (GpkSession *session,
+ guint flags);
+ /* reply with EndSessionResponse */
+ void (* end_session) (GpkSession *session,
+ guint flags);
+ void (* cancel_end_session) (GpkSession *session);
+} GpkSessionClass;
+
+GType gpk_session_get_type (void);
+GpkSession *gpk_session_new (void);
+
+gboolean gpk_session_logout (GpkSession *session);
+
+G_END_DECLS
+
+#endif /* __GPK_SESSION_H */
Index: gnome-packagekit-3.20.0/src/gpk-task.c
===================================================================
--- gnome-packagekit-3.20.0.orig/src/gpk-task.c
+++ gnome-packagekit-3.20.0/src/gpk-task.c
@@ -25,6 +25,7 @@
#include <packagekit-glib2/packagekit.h>
#include "gpk-task.h"
+#include "gpk-gnome.h"
#include "gpk-common.h"
#include "gpk-enum.h"
#include "gpk-dialog.h"
Index: gnome-packagekit-3.20.0/src/gpk-vendor.c
===================================================================
--- /dev/null
+++ gnome-packagekit-3.20.0/src/gpk-vendor.c
@@ -0,0 +1,159 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2008 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include "config.h"
+
+#include <glib/gi18n.h>
+
+#include "egg-string.h"
+#include "gpk-vendor.h"
+
+static void gpk_vendor_finalize (GObject *object);
+
+#define GPK_VENDOR_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GPK_TYPE_VENDOR, GpkVendorPrivate))
+
+struct GpkVendorPrivate
+{
+ GKeyFile *file;
+};
+
+G_DEFINE_TYPE (GpkVendor, gpk_vendor, G_TYPE_OBJECT)
+
+/**
+ * gpk_vendor_class_init:
+ * @klass: The GpkVendorClass
+ **/
+static void
+gpk_vendor_class_init (GpkVendorClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ object_class->finalize = gpk_vendor_finalize;
+ g_type_class_add_private (klass, sizeof (GpkVendorPrivate));
+}
+
+/**
+ * gpk_vendor_type_to_string:
+ **/
+static const gchar *
+gpk_vendor_type_to_string (GpkVendorUrlType type)
+{
+ if (type == GPK_VENDOR_URL_TYPE_CODEC)
+ return "CodecUrl";
+ if (type == GPK_VENDOR_URL_TYPE_FONT)
+ return "FontUrl";
+ if (type == GPK_VENDOR_URL_TYPE_MIME)
+ return "MimeUrl";
+ if (type == GPK_VENDOR_URL_TYPE_HARDWARE)
+ return "HardwareUrl";
+ return "DefaultUrl";
+}
+
+/**
+ * gpk_vendor_get_not_found_url:
+ **/
+gchar *
+gpk_vendor_get_not_found_url (GpkVendor *vendor, GpkVendorUrlType type)
+{
+ const gchar *key;
+ gchar *url = NULL;
+
+ /* get data */
+ key = gpk_vendor_type_to_string (type);
+ url = g_key_file_get_string (vendor->priv->file, "PackagesNotFound", key, NULL);
+
+ /* none is a special value */
+ if (g_strcmp0 (url, "none") == 0) {
+ g_free (url);
+ url = NULL;
+ }
+
+ /* got a valid URL */
+ if (url != NULL)
+ goto out;
+
+ /* default has no fallback */
+ if (type == GPK_VENDOR_URL_TYPE_DEFAULT)
+ goto out;
+
+ /* get fallback data */
+ g_debug ("using fallback");
+ key = gpk_vendor_type_to_string (GPK_VENDOR_URL_TYPE_DEFAULT);
+ url = g_key_file_get_string (vendor->priv->file, "PackagesNotFound", key, NULL);
+
+ /* none is a special value */
+ if (g_strcmp0 (url, "none") == 0) {
+ g_free (url);
+ url = NULL;
+ }
+out:
+ g_debug ("url=%s", url);
+ return url;
+}
+
+/**
+ * gpk_vendor_init:
+ * @vendor: This class instance
+ **/
+static void
+gpk_vendor_init (GpkVendor *vendor)
+{
+ gboolean ret;
+
+ vendor->priv = GPK_VENDOR_GET_PRIVATE (vendor);
+
+ vendor->priv->file = g_key_file_new ();
+ ret = g_key_file_load_from_file (vendor->priv->file, "/etc/PackageKit/Vendor.conf", G_KEY_FILE_NONE, NULL);
+ if (!ret)
+ g_warning ("file not found");
+}
+
+/**
+ * gpk_vendor_finalize:
+ * @object: The object to finalize
+ **/
+static void
+gpk_vendor_finalize (GObject *object)
+{
+ GpkVendor *vendor;
+
+ g_return_if_fail (PK_IS_VENDOR (object));
+
+ vendor = GPK_VENDOR (object);
+ g_return_if_fail (vendor->priv != NULL);
+
+ g_key_file_free (vendor->priv->file);
+
+ G_OBJECT_CLASS (gpk_vendor_parent_class)->finalize (object);
+}
+
+/**
+ * gpk_vendor_new:
+ *
+ * Return value: a new GpkVendor object.
+ **/
+GpkVendor *
+gpk_vendor_new (void)
+{
+ GpkVendor *vendor;
+ vendor = g_object_new (GPK_TYPE_VENDOR, NULL);
+ return GPK_VENDOR (vendor);
+}
+
Index: gnome-packagekit-3.20.0/src/gpk-vendor.h
===================================================================
--- /dev/null
+++ gnome-packagekit-3.20.0/src/gpk-vendor.h
@@ -0,0 +1,70 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2008 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef __GPK_VENDOR_H
+#define __GPK_VENDOR_H
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define GPK_TYPE_VENDOR (gpk_vendor_get_type ())
+#define GPK_VENDOR(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GPK_TYPE_VENDOR, GpkVendor))
+#define GPK_VENDOR_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GPK_TYPE_VENDOR, GpkVendorClass))
+#define PK_IS_VENDOR(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GPK_TYPE_VENDOR))
+#define PK_IS_VENDOR_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GPK_TYPE_VENDOR))
+#define GPK_VENDOR_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GPK_TYPE_VENDOR, GpkVendorClass))
+#define GPK_VENDOR_ERROR (gpk_vendor_error_quark ())
+#define GPK_VENDOR_TYPE_ERROR (gpk_vendor_error_get_type ())
+
+typedef struct GpkVendorPrivate GpkVendorPrivate;
+
+typedef struct
+{
+ GObject parent;
+ GpkVendorPrivate *priv;
+} GpkVendor;
+
+typedef struct
+{
+ GObjectClass parent_class;
+} GpkVendorClass;
+
+/**
+ * GpkModalDialogWidgets:
+ */
+typedef enum
+{
+ GPK_VENDOR_URL_TYPE_CODEC,
+ GPK_VENDOR_URL_TYPE_FONT,
+ GPK_VENDOR_URL_TYPE_MIME,
+ GPK_VENDOR_URL_TYPE_HARDWARE,
+ GPK_VENDOR_URL_TYPE_DEFAULT
+} GpkVendorUrlType;
+
+GType gpk_vendor_get_type (void);
+GpkVendor *gpk_vendor_new (void);
+gchar *gpk_vendor_get_not_found_url (GpkVendor *vendor,
+ GpkVendorUrlType type);
+
+G_END_DECLS
+
+#endif /* __GPK_VENDOR_H */
Index: gnome-packagekit-3.20.0/src/gpk-x11.c
===================================================================
--- /dev/null
+++ gnome-packagekit-3.20.0/src/gpk-x11.c
@@ -0,0 +1,250 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2007-2008 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include "config.h"
+
+#include <glib/gi18n.h>
+#include <gdk/gdk.h>
+#include <gdk/gdkx.h>
+#include <X11/Xatom.h>
+
+#include "egg-string.h"
+
+#include "gpk-x11.h"
+
+static void gpk_x11_finalize (GObject *object);
+
+#define GPK_X11_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GPK_TYPE_X11, GpkX11Private))
+
+struct GpkX11Private
+{
+ GdkDisplay *gdk_display;
+ Display *display;
+ Window window;
+};
+
+G_DEFINE_TYPE (GpkX11, gpk_x11, G_TYPE_OBJECT)
+
+/**
+ * gpk_x11_set_xid:
+ **/
+gboolean
+gpk_x11_set_xid (GpkX11 *x11, guint32 xid)
+{
+ GdkWindow *window;
+
+ g_return_val_if_fail (GPK_IS_X11 (x11), FALSE);
+
+ window = gdk_x11_window_foreign_new_for_display (x11->priv->gdk_display, xid);
+ if (window == NULL)
+ return FALSE;
+
+ /* save the x state */
+ x11->priv->display = GDK_DISPLAY_XDISPLAY (x11->priv->gdk_display);
+ x11->priv->window = GDK_WINDOW_XID (window);
+
+ return TRUE;
+}
+
+/**
+ * gpk_x11_set_window:
+ **/
+gboolean
+gpk_x11_set_window (GpkX11 *x11, GdkWindow *window)
+{
+ g_return_val_if_fail (GPK_IS_X11 (x11), FALSE);
+
+ /* save the x state */
+ x11->priv->display = GDK_DISPLAY_XDISPLAY (x11->priv->gdk_display);
+ x11->priv->window = GDK_WINDOW_XID (window);
+
+ return TRUE;
+}
+
+/**
+ * gpk_x11_get_user_time:
+ **/
+guint32
+gpk_x11_get_user_time (GpkX11 *x11)
+{
+ guint32 timestamp = 0;
+ Atom atom = None;
+ Atom type;
+ gint format;
+ gulong nitems;
+ gulong bytes_after;
+ Window *win = NULL;
+ int rc;
+ int err;
+
+ g_return_val_if_fail (GPK_IS_X11 (x11), 0);
+
+ /* check we have a window */
+ if (x11->priv->window == None) {
+ g_debug ("no window, so cannot get user_time");
+ goto out;
+ }
+
+ /* get _NET_WM_USER_TIME_WINDOW which points to a window on which you can find the _NET_WM_USER_TIME property */
+ gdk_error_trap_push ();
+ atom = gdk_x11_get_xatom_by_name_for_display (x11->priv->gdk_display, "_NET_WM_USER_TIME_WINDOW");
+ rc = XGetWindowProperty (x11->priv->display, x11->priv->window, atom, 0, G_MAXLONG, False, XA_WINDOW,
+ &type, &format, &nitems, &bytes_after, (void*) &win);
+ err = gdk_error_trap_pop ();
+ if (err != Success || rc != Success) {
+ g_warning ("couldn't get _NET_WM_USER_TIME_WINDOW");
+ goto out;
+ }
+
+ /* is not a window */
+ if (type != XA_WINDOW) {
+ g_warning ("not type XA_WINDOW");
+ goto out;
+ }
+
+ /* get _NET_WM_USER_TIME so we can get the user time */
+ gdk_error_trap_push ();
+ atom = gdk_x11_get_xatom_by_name_for_display (x11->priv->gdk_display, "_NET_WM_USER_TIME");
+ rc = XGetWindowProperty (x11->priv->display, *win, atom, 0, G_MAXLONG, False, XA_CARDINAL,
+ &type, &format, &nitems, &bytes_after, (void*) ×tamp);
+ err = gdk_error_trap_pop ();
+ if (err != Success || rc != Success) {
+ g_warning ("couldn't get _NET_WM_USER_TIME");
+ goto out;
+ }
+
+ /* is not a window */
+ if (type != XA_CARDINAL) {
+ g_warning ("not type XA_CARDINAL");
+ goto out;
+ }
+out:
+ if (win != NULL)
+ XFree (win);
+ return timestamp;
+}
+
+/**
+ * gpk_x11_get_title:
+ **/
+gchar *
+gpk_x11_get_title (GpkX11 *x11)
+{
+ gchar *title = NULL;
+ Atom atom = None;
+ Atom atom_type = None;
+ gchar *data = NULL;
+ Atom type;
+ gint format;
+ gulong nitems;
+ gulong bytes_after;
+ int rc;
+
+ g_return_val_if_fail (GPK_IS_X11 (x11), NULL);
+
+ /* check we have a window */
+ if (x11->priv->window == None) {
+ g_debug ("no window, so cannot get user_time");
+ goto out;
+ }
+
+ /* get _NET_WM_NAME */
+ gdk_error_trap_push ();
+ atom = gdk_x11_get_xatom_by_name_for_display (x11->priv->gdk_display, "_NET_WM_NAME");
+ atom_type = gdk_x11_get_xatom_by_name_for_display (x11->priv->gdk_display, "UTF8_STRING");
+ rc = XGetWindowProperty (x11->priv->display, x11->priv->window, atom, 0, G_MAXLONG, False, atom_type,
+ &type, &format, &nitems, &bytes_after, (void*) &data);
+ gdk_error_trap_pop_ignored ();
+ if (rc == Success && nitems > 0) {
+ title = g_strdup (data);
+ goto out;
+ }
+
+ /* we failed to get the UTF8 title, try plain old WM_NAME */
+ gdk_error_trap_push ();
+ rc = XGetWindowProperty (x11->priv->display, x11->priv->window, XA_WM_NAME, 0, G_MAXLONG, False, XA_STRING,
+ &type, &format, &nitems, &bytes_after, (void*) &data);
+ gdk_error_trap_pop_ignored ();
+ if (rc == Success && nitems > 0) {
+ title = g_strdup (data);
+ goto out;
+ }
+ g_warning ("failed to get X11 name for window %i", (gint) x11->priv->window);
+out:
+ if (data != NULL)
+ XFree (data);
+ return title;
+}
+
+/**
+ * gpk_x11_class_init:
+ * @klass: The GpkX11Class
+ **/
+static void
+gpk_x11_class_init (GpkX11Class *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ object_class->finalize = gpk_x11_finalize;
+ g_type_class_add_private (klass, sizeof (GpkX11Private));
+}
+
+/**
+ * gpk_x11_init:
+ * @x11: This class instance
+ **/
+static void
+gpk_x11_init (GpkX11 *x11)
+{
+ x11->priv = GPK_X11_GET_PRIVATE (x11);
+ x11->priv->display = NULL;
+ x11->priv->window = None;
+ x11->priv->gdk_display = gdk_display_get_default ();
+}
+
+/**
+ * gpk_x11_finalize:
+ * @object: The object to finalize
+ **/
+static void
+gpk_x11_finalize (GObject *object)
+{
+ GpkX11 *x11;
+ g_return_if_fail (GPK_IS_X11 (object));
+ x11 = GPK_X11 (object);
+
+ g_return_if_fail (x11->priv != NULL);
+
+ G_OBJECT_CLASS (gpk_x11_parent_class)->finalize (object);
+}
+
+/**
+ * gpk_x11_new:
+ *
+ * Return value: a new GpkX11 object.
+ **/
+GpkX11 *
+gpk_x11_new (void)
+{
+ GpkX11 *x11;
+ x11 = g_object_new (GPK_TYPE_X11, NULL);
+ return GPK_X11 (x11);
+}
+
Index: gnome-packagekit-3.20.0/src/gpk-x11.h
===================================================================
--- /dev/null
+++ gnome-packagekit-3.20.0/src/gpk-x11.h
@@ -0,0 +1,63 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2008 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef __GPK_X11_H
+#define __GPK_X11_H
+
+#include <glib-object.h>
+#include <gdk/gdk.h>
+
+G_BEGIN_DECLS
+
+#define GPK_TYPE_X11 (gpk_x11_get_type ())
+#define GPK_X11(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GPK_TYPE_X11, GpkX11))
+#define GPK_X11_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GPK_TYPE_X11, GpkX11Class))
+#define GPK_IS_X11(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GPK_TYPE_X11))
+#define GPK_IS_X11_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GPK_TYPE_X11))
+#define GPK_X11_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GPK_TYPE_X11, GpkX11Class))
+#define GPK_X11_ERROR (gpk_x11_error_quark ())
+#define GPK_X11_TYPE_ERROR (gpk_x11_error_get_type ())
+
+typedef struct GpkX11Private GpkX11Private;
+
+typedef struct
+{
+ GObject parent;
+ GpkX11Private *priv;
+} GpkX11;
+
+typedef struct
+{
+ GObjectClass parent_class;
+} GpkX11Class;
+
+GType gpk_x11_get_type (void);
+GpkX11 *gpk_x11_new (void);
+gboolean gpk_x11_set_xid (GpkX11 *x11,
+ guint32 xid);
+gboolean gpk_x11_set_window (GpkX11 *x11,
+ GdkWindow *window);
+guint32 gpk_x11_get_user_time (GpkX11 *x11);
+gchar *gpk_x11_get_title (GpkX11 *x11);
+
+G_END_DECLS
+
+#endif /* __GPK_X11_H */
Index: gnome-packagekit-3.20.0/src/org.freedesktop.PackageKit.xml
===================================================================
--- /dev/null
+++ gnome-packagekit-3.20.0/src/org.freedesktop.PackageKit.xml
@@ -0,0 +1,506 @@
+<!DOCTYPE node PUBLIC
+"-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
+"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd" [
+ <!ENTITY ERROR_GENERAL "org.freedesktop.PackageKit.Denied">
+]>
+<node name="/" xmlns:doc="http://www.freedesktop.org/dbus/1.0/doc.dtd">
+
+ <interface name="org.freedesktop.PackageKit.Query">
+ <doc:doc>
+ <doc:description>
+ <doc:para>
+ The interface used for quering the package database.
+ </doc:para>
+ </doc:description>
+ </doc:doc>
+
+ <!--*****************************************************************************************-->
+ <method name="IsInstalled">
+ <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
+ <doc:doc>
+ <doc:description>
+ <doc:para>
+ Finds out if the package is installed.
+ </doc:para>
+ </doc:description>
+ </doc:doc>
+ <arg type="s" name="package_name" direction="in">
+ <doc:doc>
+ <doc:summary>
+ <doc:para>
+ A package name, e.g. <doc:tt>hal-info</doc:tt>
+ </doc:para>
+ </doc:summary>
+ </doc:doc>
+ </arg>
+ <arg type="s" name="interaction" direction="in">
+ <doc:doc>
+ <doc:summary>
+ <doc:para>
+ An optional interaction mode, e.g.
+ <doc:tt>timeout=10</doc:tt>
+ </doc:para>
+ </doc:summary>
+ </doc:doc>
+ </arg>
+ <arg type="b" name="installed" direction="out">
+ <doc:doc>
+ <doc:summary>
+ <doc:para>
+ If the package is installed.
+ </doc:para>
+ </doc:summary>
+ </doc:doc>
+ </arg>
+ </method>
+
+ <!--*****************************************************************************************-->
+ <method name="SearchFile">
+ <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
+ <doc:doc>
+ <doc:description>
+ <doc:para>
+ Finds the package name for an installed or available file
+ </doc:para>
+ </doc:description>
+ </doc:doc>
+ <arg type="s" name="file_name" direction="in">
+ <doc:doc>
+ <doc:summary>
+ <doc:para>
+ A package name, e.g. <doc:tt>/usr/share/help/gimp/index.html</doc:tt>
+ </doc:para>
+ </doc:summary>
+ </doc:doc>
+ </arg>
+ <arg type="s" name="interaction" direction="in">
+ <doc:doc>
+ <doc:summary>
+ <doc:para>
+ An optional interaction mode, e.g.
+ <doc:tt>timeout=10</doc:tt>
+ </doc:para>
+ </doc:summary>
+ </doc:doc>
+ </arg>
+ <arg type="b" name="installed" direction="out">
+ <doc:doc>
+ <doc:summary>
+ <doc:para>
+ If the package is installed.
+ </doc:para>
+ </doc:summary>
+ </doc:doc>
+ </arg>
+ <arg type="s" name="package_name" direction="out">
+ <doc:doc>
+ <doc:summary>
+ <doc:para>
+ The package name of the file, e.g. <doc:tt>hal-info</doc:tt>
+ </doc:para>
+ </doc:summary>
+ </doc:doc>
+ </arg>
+ </method>
+ </interface>
+
+ <!-- ######################################################################################### -->
+ <interface name="org.freedesktop.PackageKit.Modify">
+ <doc:doc>
+ <doc:description>
+ <doc:para>
+ The interface used for modifying the package database.
+ </doc:para>
+ </doc:description>
+ </doc:doc>
+
+ <!--*****************************************************************************************-->
+ <method name="InstallPackageFiles">
+ <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
+ <doc:doc>
+ <doc:description>
+ <doc:para>
+ Installs local package files or service packs.
+ </doc:para>
+ </doc:description>
+ </doc:doc>
+ <arg type="u" name="xid" direction="in">
+ <doc:doc>
+ <doc:summary>
+ <doc:para>
+ The X window handle ID, used for focus stealing prevention and setting modality.
+ </doc:para>
+ </doc:summary>
+ </doc:doc>
+ </arg>
+ <arg type="as" name="files" direction="in">
+ <doc:doc>
+ <doc:summary>
+ <doc:para>
+ An array of file names.
+ </doc:para>
+ </doc:summary>
+ </doc:doc>
+ </arg>
+ <arg type="s" name="interaction" direction="in">
+ <doc:doc>
+ <doc:summary>
+ <doc:para>
+ An interaction mode that specifies which UI elements should be shown
+ or hidden different from the user default, e.g.
+ <doc:tt>hide-confirm-search,hide-confirm-deps,hide-confirm-install,show-progress</doc:tt>.
+ The show options are:
+ <doc:tt>show-confirm-search,show-confirm-deps,show-confirm-install,show-progress,show-finished,show-warning</doc:tt>.
+ The hide options are:
+ <doc:tt>hide-confirm-search,hide-confirm-deps,hide-confirm-install,hide-progress,hide-finished,hide-warning</doc:tt>.
+ Convenience options such as:
+ <doc:tt>never</doc:tt>, <doc:tt>defaults</doc:tt> or <doc:tt>always</doc:tt>.
+ are also available.
+ </doc:para>
+ </doc:summary>
+ </doc:doc>
+ </arg>
+ </method>
+
+ <!--*****************************************************************************************-->
+ <method name="InstallProvideFiles">
+ <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
+ <doc:doc>
+ <doc:description>
+ <doc:para>
+ Installs packages to provide files.
+ </doc:para>
+ </doc:description>
+ </doc:doc>
+ <arg type="u" name="xid" direction="in">
+ <doc:doc>
+ <doc:summary>
+ <doc:para>
+ The X window handle ID, used for focus stealing prevention and setting modality.
+ </doc:para>
+ </doc:summary>
+ </doc:doc>
+ </arg>
+ <arg type="as" name="files" direction="in">
+ <doc:doc>
+ <doc:summary>
+ <doc:para>
+ An array of file names.
+ </doc:para>
+ </doc:summary>
+ </doc:doc>
+ </arg>
+ <arg type="s" name="interaction" direction="in">
+ <doc:doc>
+ <doc:summary>
+ <doc:para>
+ An optional interaction mode, e.g.
+ <doc:tt>show-confirm-search,show-confirm-deps,show-confirm-install,show-progress,show-finished,show-warning</doc:tt>
+ </doc:para>
+ </doc:summary>
+ </doc:doc>
+ </arg>
+ </method>
+
+ <!--*****************************************************************************************-->
+ <method name="InstallPackageNames">
+ <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
+ <doc:doc>
+ <doc:description>
+ <doc:para>
+ Installs packages from a configured package source.
+ </doc:para>
+ </doc:description>
+ </doc:doc>
+ <arg type="u" name="xid" direction="in">
+ <doc:doc>
+ <doc:summary>
+ <doc:para>
+ The X window handle ID, used for focus stealing prevention and setting modality.
+ </doc:para>
+ </doc:summary>
+ </doc:doc>
+ </arg>
+ <arg type="as" name="packages" direction="in">
+ <doc:doc>
+ <doc:summary>
+ <doc:para>
+ An array of package names.
+ </doc:para>
+ </doc:summary>
+ </doc:doc>
+ </arg>
+ <arg type="s" name="interaction" direction="in">
+ <doc:doc>
+ <doc:summary>
+ <doc:para>
+ An optional interaction mode, e.g.
+ <doc:tt>show-confirm-search,show-confirm-deps,show-confirm-install,show-progress,show-finished,show-warning</doc:tt>
+ </doc:para>
+ </doc:summary>
+ </doc:doc>
+ </arg>
+ </method>
+
+ <!--*****************************************************************************************-->
+ <method name="InstallMimeTypes">
+ <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
+ <doc:doc>
+ <doc:description>
+ <doc:para>
+ Installs mimetype handlers from a configured package source.
+ </doc:para>
+ </doc:description>
+ </doc:doc>
+ <arg type="u" name="xid" direction="in">
+ <doc:doc>
+ <doc:summary>
+ <doc:para>
+ The X window handle ID, used for focus stealing prevention and setting modality.
+ </doc:para>
+ </doc:summary>
+ </doc:doc>
+ </arg>
+ <arg type="as" name="mime_types" direction="in">
+ <doc:doc>
+ <doc:summary>
+ <doc:para>
+ An array of mime types, e.g. <doc:tt>text/plain</doc:tt>
+ </doc:para>
+ </doc:summary>
+ </doc:doc>
+ </arg>
+ <arg type="s" name="interaction" direction="in">
+ <doc:doc>
+ <doc:summary>
+ <doc:para>
+ An optional interaction mode, e.g.
+ <doc:tt>show-confirm-search,show-confirm-deps,show-confirm-install,show-progress,show-finished,show-warning</doc:tt>
+ </doc:para>
+ </doc:summary>
+ </doc:doc>
+ </arg>
+ </method>
+
+ <!--*****************************************************************************************-->
+ <method name="InstallFontconfigResources">
+ <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
+ <doc:doc>
+ <doc:description>
+ <doc:para>
+ Installs fontconfig resources (usually fonts) from a configured package source.
+ </doc:para>
+ </doc:description>
+ </doc:doc>
+ <arg type="u" name="xid" direction="in">
+ <doc:doc>
+ <doc:summary>
+ <doc:para>
+ The X window handle ID, used for focus stealing prevention and setting modality.
+ </doc:para>
+ </doc:summary>
+ </doc:doc>
+ </arg>
+ <arg type="as" name="resources" direction="in">
+ <doc:doc>
+ <doc:summary>
+ <doc:para>
+ An array of font descriptors from fontconfig, e.g. <doc:tt>:lang=mn</doc:tt>
+ </doc:para>
+ </doc:summary>
+ </doc:doc>
+ </arg>
+ <arg type="s" name="interaction" direction="in">
+ <doc:doc>
+ <doc:summary>
+ <doc:para>
+ An optional interaction mode, e.g.
+ <doc:tt>show-confirm-search,show-confirm-deps,show-confirm-install,show-progress,show-finished,show-warning</doc:tt>
+ </doc:para>
+ </doc:summary>
+ </doc:doc>
+ </arg>
+ </method>
+
+ <!--*****************************************************************************************-->
+ <method name="InstallGStreamerResources">
+ <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
+ <doc:doc>
+ <doc:description>
+ <doc:para>
+ Installs GStreamer fontconfig resources (usually codecs) from a configured package source.
+ </doc:para>
+ </doc:description>
+ </doc:doc>
+ <arg type="u" name="xid" direction="in">
+ <doc:doc>
+ <doc:summary>
+ <doc:para>
+ The X window handle ID, used for focus stealing prevention and setting modality.
+ </doc:para>
+ </doc:summary>
+ </doc:doc>
+ </arg>
+ <arg type="as" name="resources" direction="in">
+ <doc:doc>
+ <doc:summary>
+ <doc:para>
+ An array of codecs descriptors from <doc:tt>pk-gstreamer-install</doc:tt>, e.g.
+ <doc:tt>Advanced Streaming Format (ASF) demuxer|decoder-video/x-ms-asf</doc:tt>
+ </doc:para>
+ </doc:summary>
+ </doc:doc>
+ </arg>
+ <arg type="s" name="interaction" direction="in">
+ <doc:doc>
+ <doc:summary>
+ <doc:para>
+ An optional interaction mode, e.g.
+ <doc:tt>show-confirm-search,show-confirm-deps,show-confirm-install,show-progress,show-finished,show-warning</doc:tt>
+ </doc:para>
+ </doc:summary>
+ </doc:doc>
+ </arg>
+ </method>
+
+ <!--*****************************************************************************************-->
+ <method name="InstallResources">
+ <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
+ <doc:doc>
+ <doc:description>
+ <doc:para>
+ Installs resources of a given type from a configured package source.
+ </doc:para>
+ </doc:description>
+ </doc:doc>
+ <arg type="u" name="xid" direction="in">
+ <doc:doc>
+ <doc:summary>
+ <doc:para>
+ The X window handle ID, used for focus stealing prevention and setting modality.
+ </doc:para>
+ </doc:summary>
+ </doc:doc>
+ </arg>
+ <arg type="s" name="type" direction="in">
+ <doc:doc>
+ <doc:summary>
+ <doc:para>
+ The type of resource to request, e.g. <doc:tt>plasma-service</doc:tt>
+ </doc:para>
+ </doc:summary>
+ </doc:doc>
+ </arg>
+ <arg type="as" name="resources" direction="in">
+ <doc:doc>
+ <doc:summary>
+ <doc:para>
+ An array of resource descriptors
+ </doc:para>
+ </doc:summary>
+ </doc:doc>
+ </arg>
+ <arg type="s" name="interaction" direction="in">
+ <doc:doc>
+ <doc:summary>
+ <doc:para>
+ An optional interaction mode, e.g.
+ <doc:tt>show-confirm-search,show-confirm-deps,show-confirm-install,show-progress,show-finished,show-warning</doc:tt>
+ </doc:para>
+ </doc:summary>
+ </doc:doc>
+ </arg>
+ </method>
+
+ <!--*****************************************************************************************-->
+ <method name="RemovePackageByFiles">
+ <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
+ <doc:doc>
+ <doc:description>
+ <doc:para>
+ Removes packages that provide the given local files.
+ </doc:para>
+ </doc:description>
+ </doc:doc>
+ <arg type="u" name="xid" direction="in">
+ <doc:doc>
+ <doc:summary>
+ <doc:para>
+ The X window handle ID, used for focus stealing prevention and setting modality.
+ </doc:para>
+ </doc:summary>
+ </doc:doc>
+ </arg>
+ <arg type="as" name="files" direction="in">
+ <doc:doc>
+ <doc:summary>
+ <doc:para>
+ An array of file names.
+ </doc:para>
+ </doc:summary>
+ </doc:doc>
+ </arg>
+ <arg type="s" name="interaction" direction="in">
+ <doc:doc>
+ <doc:summary>
+ <doc:para>
+ An interaction mode that specifies which UI elements should be shown
+ or hidden different from the user default, e.g.
+ <doc:tt>hide-confirm-search,hide-confirm-deps,hide-confirm-install,show-progress</doc:tt>.
+ The show options are:
+ <doc:tt>show-confirm-search,show-confirm-deps,show-confirm-install,show-progress,show-finished,show-warning</doc:tt>.
+ The hide options are:
+ <doc:tt>hide-confirm-search,hide-confirm-deps,hide-confirm-install,hide-progress,hide-finished,hide-warning</doc:tt>.
+ Convenience options such as:
+ <doc:tt>never</doc:tt>, <doc:tt>defaults</doc:tt> or <doc:tt>always</doc:tt>.
+ are also available.
+ </doc:para>
+ </doc:summary>
+ </doc:doc>
+ </arg>
+ </method>
+
+ <method name="InstallPrinterDrivers">
+ <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
+ <doc:doc>
+ <doc:description>
+ <doc:para>
+ Installs printer drivers from a configured package source.
+ </doc:para>
+ </doc:description>
+ </doc:doc>
+ <arg type="u" name="xid" direction="in">
+ <doc:doc>
+ <doc:summary>
+ <doc:para>
+ The X window handle ID, used for focus stealing prevention and setting modality.
+ </doc:para>
+ </doc:summary>
+ </doc:doc>
+ </arg>
+ <arg type="as" name="resources" direction="in">
+ <doc:doc>
+ <doc:summary>
+ <doc:para>
+ An array of printer model descriptors in IEEE 1284
+ Device ID format,
+ e.g. <doc:tt>MFG:Hewlett-Packard;MDL:HP LaserJet
+ 6MP;</doc:tt>.
+ </doc:para>
+ </doc:summary>
+ </doc:doc>
+ </arg>
+ <arg type="s" name="interaction" direction="in">
+ <doc:doc>
+ <doc:summary>
+ <doc:para>
+ An optional interaction mode, e.g.
+ <doc:tt>show-confirm-search,show-confirm-deps,show-confirm-install,show-progress,show-finished,show-warning</doc:tt>
+ </doc:para>
+ </doc:summary>
+ </doc:doc>
+ </arg>
+ </method>
+ </interface>
+</node>
+
Index: gnome-packagekit-3.20.0/src/gpk-update-viewer.c
===================================================================
--- gnome-packagekit-3.20.0.orig/src/gpk-update-viewer.c
+++ gnome-packagekit-3.20.0/src/gpk-update-viewer.c
@@ -21,6 +21,7 @@
#include "config.h"
+#include <dbus/dbus-glib.h>
#include <gdk/gdkkeysyms.h>
#include <glib/gi18n.h>
#include <glib/gi18n.h>
@@ -42,6 +43,7 @@
#include "gpk-dialog.h"
#include "gpk-enum.h"
#include "gpk-error.h"
+#include "gpk-session.h"
#include "gpk-task.h"
#include "gpk-debug.h"
@@ -206,28 +208,33 @@ gpk_update_viewer_check_restart (void)
gboolean show_button = TRUE;
GError *error = NULL;
+ g_print ("gpk update viewer check restart\n");
/* get the text */
title = gpk_restart_enum_to_localised_text (restart_update);
if (restart_update == PK_RESTART_ENUM_SYSTEM) {
/* TRANSLATORS: the message text for the restart */
message = _("Some of the updates that were installed require the computer to be restarted before the changes will be applied.");
+ g_print ("%s\n", message);
/* TRANSLATORS: the button text for the restart */
button = _("Restart Computer");
} else if (restart_update == PK_RESTART_ENUM_SECURITY_SYSTEM) {
/* TRANSLATORS: the message text for the restart */
message = _("Some of the updates that were installed require the computer to be restarted to remain secure.");
+ g_print ("%s\n", message);
/* TRANSLATORS: the button text for the restart */
button = _("Restart Computer");
} else if (restart_update == PK_RESTART_ENUM_SESSION) {
/* TRANSLATORS: the message text for the log out */
message = _("Some of the updates that were installed require you to log out and back in before the changes will be applied.");
+ g_print ("%s\n", message);
/* TRANSLATORS: the button text for the log out */
button = _("Log Out");
} else if (restart_update == PK_RESTART_ENUM_APPLICATION) {
/* TRANSLATORS: the message text for the application restart */
message = _("Some of the updates that were installed require you to restart this application before the changes will be applied.");
+ g_print ("%s\n", message);
/* TRANSLATORS: the button text for the application restart */
button = _("Restart Application");
@@ -239,6 +246,7 @@ gpk_update_viewer_check_restart (void)
} else if (restart_update == PK_RESTART_ENUM_SECURITY_SESSION) {
/* TRANSLATORS: the message text for the log out */
message = _("Some of the updates that were installed require you to log out and back in to remain secure.");
+ g_print ("%s\n", message);
/* TRANSLATORS: the button text for the log out */
button = _("Log Out");
@@ -288,6 +296,13 @@ gpk_update_viewer_check_restart (void)
g_error_free (error);
}
#endif
+ } else if (restart_update == PK_RESTART_ENUM_SESSION) {
+ GpkSession *session;
+ session = gpk_session_new ();
+ /* use gnome-session to log out */
+ g_print ("gpk session logout\n");
+ gpk_session_logout (session);
+ g_object_unref (session);
} else if (restart_update == PK_RESTART_ENUM_APPLICATION) {
char cmd[256] = {0};
/* need to wait for PackageKit to finish too */
@@ -425,9 +440,11 @@ gpk_update_viewer_update_packages_cb (Pk
GtkTreeView *treeview;
GtkTreeModel *model;
+ g_print ("gpk update viewer update packages cb\n");
/* get the results */
results = pk_task_generic_finish (task, res, &error);
if (results == NULL) {
+ g_print ("results == NULL\n");
/* not a PK error */
if (error->domain != PK_CLIENT_ERROR) {
/* TRANSLATORS: the PackageKit request did not complete, and it did not send an error */
@@ -459,6 +476,7 @@ gpk_update_viewer_update_packages_cb (Pk
/* check error code */
error_code = pk_results_get_error_code (results);
if (error_code != NULL) {
+ g_print ("failed to update packages\n");
g_warning ("failed to update packages: %s, %s",
pk_error_enum_to_string (pk_error_get_code (error_code)),
pk_error_get_details (error_code));
@@ -481,6 +499,7 @@ gpk_update_viewer_update_packages_cb (Pk
/* get the worst restart case */
restart = pk_results_get_require_restart_worst (results);
+ g_print ("require restart worst: %d\n", restart);
if (restart > restart_update)
restart_update = restart;
@@ -489,6 +508,8 @@ gpk_update_viewer_update_packages_cb (Pk
gpk_update_viewer_check_blocked_packages (array);
/* check restart */
+ g_print ("restart: %d\n", restart);
+ g_print ("check restart: %d\n", restart_update);
if (restart_update == PK_RESTART_ENUM_SYSTEM ||
restart_update == PK_RESTART_ENUM_SESSION ||
restart_update == PK_RESTART_ENUM_APPLICATION ||
@@ -498,6 +519,7 @@ gpk_update_viewer_update_packages_cb (Pk
gpk_update_viewer_quit ();
goto out;
} else {
+ g_print ("no need to restart update\n");
goto out;
}
@@ -1221,6 +1243,7 @@ gpk_update_viewer_button_install_cb (Gtk
GtkTreeView *treeview;
gchar **package_ids = NULL;
+ g_print ("button install cb\n");
/* hide the upgrade viewbox from now on */
widget = GTK_WIDGET(gtk_builder_get_object (builder, "viewport_upgrade"));
gtk_widget_hide (widget);
@@ -1438,6 +1461,7 @@ gpk_update_viewer_reconsider_info (void)
gchar *text_size;
PkNetworkEnum state;
+ g_print ("reconsider info\n");
/* update global state */
gpk_update_viewer_update_global_state ();
@@ -1561,6 +1585,7 @@ gpk_update_viewer_treeview_update_toggle
GtkTreeView *treeview;
GtkTreeModel *model;
+ g_print ("treeview update toggled\n");
treeview = GTK_TREE_VIEW(gtk_builder_get_object (builder, "treeview_updates"));
model = gtk_tree_view_get_model (treeview);
@@ -3663,6 +3688,7 @@ main (int argc, char *argv[])
bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
textdomain (GETTEXT_PACKAGE);
+ dbus_g_thread_init ();
gtk_init (&argc, &argv);
context = g_option_context_new (NULL);