[gnome-software] Allow plugins to add more than one icon
- From: Richard Hughes <rhughes src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-software] Allow plugins to add more than one icon
- Date: Fri, 27 May 2016 15:31:36 +0000 (UTC)
commit 6dc4e947835052f0a8e3e5bf35d17c0f78a23f4d
Author: Richard Hughes <richard hughsie com>
Date: Fri May 27 15:11:51 2016 +0100
Allow plugins to add more than one icon
This will allow us to add a stock icon that falls back to a 128x128 cached icon
on failure to load in the future.
doc/api/gnome-software-docs.xml | 2 +-
src/gs-app.c | 65 ++++++++++++----------
src/gs-app.h | 4 +-
src/gs-plugin-loader.c | 6 +-
src/plugins/gs-appstream.c | 8 ++--
src/plugins/gs-plugin-dummy.c | 6 +-
src/plugins/gs-plugin-epiphany.c | 12 ++++-
src/plugins/gs-plugin-fedora-distro-upgrades.c | 2 +-
src/plugins/gs-plugin-flatpak.c | 4 +-
src/plugins/gs-plugin-fwupd.c | 2 +-
src/plugins/gs-plugin-icons.c | 70 ++++++++++++++----------
src/plugins/gs-plugin-packagekit.c | 2 +-
src/plugins/gs-plugin-shell-extensions.c | 2 +-
13 files changed, 106 insertions(+), 79 deletions(-)
---
diff --git a/doc/api/gnome-software-docs.xml b/doc/api/gnome-software-docs.xml
index 1e111a2..2f473f7 100644
--- a/doc/api/gnome-software-docs.xml
+++ b/doc/api/gnome-software-docs.xml
@@ -225,7 +225,7 @@ gs_plugin_add_installed (GsPlugin *plugin,
icon = as_icon_new ();
as_icon_set_kind (icon, AS_ICON_KIND_STOCK);
as_icon_set_name (icon, "input-gaming");
- gs_app_set_icon (app, icon);
+ gs_app_add_icon (app, icon);
/* return new app */
gs_app_list_add (list, app);
diff --git a/src/gs-app.c b/src/gs-app.c
index ddb6d60..323fde1 100644
--- a/src/gs-app.c
+++ b/src/gs-app.c
@@ -61,7 +61,7 @@ struct _GsApp
gchar *id;
gchar *name;
GsAppQuality name_quality;
- AsIcon *icon;
+ GPtrArray *icons;
GPtrArray *sources;
GPtrArray *source_ids;
gchar *project_group;
@@ -111,6 +111,7 @@ struct _GsApp
gboolean license_is_free;
GsApp *runtime;
GFile *local_file;
+ GdkPixbuf *pixbuf;
};
enum {
@@ -230,20 +231,22 @@ gs_app_to_string (GsApp *app)
gs_app_get_kudos_percentage (app));
if (app->name != NULL)
gs_app_kv_lpad (str, "name", app->name);
- if (app->icon != NULL) {
+ gs_app_kv_printf (str, "pixbuf", "%p", app->pixbuf);
+ for (i = 0; i < app->icons->len; i++) {
+ AsIcon *icon = g_ptr_array_index (app->icons, i);
gs_app_kv_lpad (str, "icon-kind",
- as_icon_kind_to_string (as_icon_get_kind (app->icon)));
+ as_icon_kind_to_string (as_icon_get_kind (icon)));
gs_app_kv_printf (str, "icon-pixbuf", "%p",
- as_icon_get_pixbuf (app->icon));
- if (as_icon_get_name (app->icon) != NULL)
+ as_icon_get_pixbuf (icon));
+ if (as_icon_get_name (icon) != NULL)
gs_app_kv_lpad (str, "icon-name",
- as_icon_get_name (app->icon));
- if (as_icon_get_prefix (app->icon) != NULL)
+ as_icon_get_name (icon));
+ if (as_icon_get_prefix (icon) != NULL)
gs_app_kv_lpad (str, "icon-prefix",
- as_icon_get_prefix (app->icon));
- if (as_icon_get_filename (app->icon) != NULL)
+ as_icon_get_prefix (icon));
+ if (as_icon_get_filename (icon) != NULL)
gs_app_kv_lpad (str, "icon-filename",
- as_icon_get_filename (app->icon));
+ as_icon_get_filename (icon));
}
if (app->match_value != 0)
gs_app_kv_printf (str, "match-value", "%05x", app->match_value);
@@ -1004,38 +1007,41 @@ GdkPixbuf *
gs_app_get_pixbuf (GsApp *app)
{
g_return_val_if_fail (GS_IS_APP (app), NULL);
- if (app->icon == NULL)
- return NULL;
- return as_icon_get_pixbuf (app->icon);
+ return app->pixbuf;
}
/**
- * gs_app_get_icon:
+ * gs_app_get_icons:
* @app: a #GsApp
*
- * Gets the icon for the application.
+ * Gets the icons for the application.
*
- * Returns: a #AsIcon, or %NULL for unset
+ * Returns: (transfer none) (element-type AsIcon): an array of icons
**/
-AsIcon *
-gs_app_get_icon (GsApp *app)
+GPtrArray *
+gs_app_get_icons (GsApp *app)
{
g_return_val_if_fail (GS_IS_APP (app), NULL);
- return app->icon;
+ return app->icons;
}
/**
- * gs_app_set_icon:
+ * gs_app_add_icon:
* @app: a #GsApp
- * @icon: a #AsIcon
+ * @icon: a #AsIcon, or %NULL to remove all icons
*
- * Sets an icon to use for the application.
+ * Adds an icon to use for the application.
+ * If the first icon added cannot be loaded then the next one is tried.
**/
void
-gs_app_set_icon (GsApp *app, AsIcon *icon)
+gs_app_add_icon (GsApp *app, AsIcon *icon)
{
g_return_if_fail (GS_IS_APP (app));
- g_set_object (&app->icon, icon);
+ if (icon == NULL) {
+ g_ptr_array_set_size (app->icons, 0);
+ return;
+ }
+ g_ptr_array_add (app->icons, g_object_ref (icon));
}
/**
@@ -1109,11 +1115,7 @@ void
gs_app_set_pixbuf (GsApp *app, GdkPixbuf *pixbuf)
{
g_return_if_fail (GS_IS_APP (app));
- if (app->icon == NULL) {
- g_warning ("trying to set pixbuf on %s with no icon", app->id);
- return;
- }
- as_icon_set_pixbuf (app->icon, pixbuf);
+ g_set_object (&app->pixbuf, pixbuf);
}
typedef enum {
@@ -2685,7 +2687,6 @@ gs_app_dispose (GObject *object)
{
GsApp *app = GS_APP (object);
- g_clear_object (&app->icon);
g_clear_object (&app->runtime);
g_clear_pointer (&app->addons, g_ptr_array_unref);
@@ -2693,6 +2694,7 @@ gs_app_dispose (GObject *object)
g_clear_pointer (&app->related, g_ptr_array_unref);
g_clear_pointer (&app->screenshots, g_ptr_array_unref);
g_clear_pointer (&app->reviews, g_ptr_array_unref);
+ g_clear_pointer (&app->icons, g_ptr_array_unref);
G_OBJECT_CLASS (gs_app_parent_class)->dispose (object);
}
@@ -2736,6 +2738,8 @@ gs_app_finalize (GObject *object)
g_error_free (app->last_error);
if (app->local_file != NULL)
g_object_unref (app->local_file);
+ if (app->pixbuf != NULL)
+ g_object_unref (app->pixbuf);
G_OBJECT_CLASS (gs_app_parent_class)->finalize (object);
}
@@ -2859,6 +2863,7 @@ gs_app_init (GsApp *app)
app->history = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref);
app->screenshots = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref);
app->reviews = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref);
+ app->icons = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref);
app->metadata = g_hash_table_new_full (g_str_hash,
g_str_equal,
g_free,
diff --git a/src/gs-app.h b/src/gs-app.h
index dc679fb..a152dda 100644
--- a/src/gs-app.h
+++ b/src/gs-app.h
@@ -185,8 +185,8 @@ void gs_app_set_management_plugin (GsApp *app,
GdkPixbuf *gs_app_get_pixbuf (GsApp *app);
void gs_app_set_pixbuf (GsApp *app,
GdkPixbuf *pixbuf);
-AsIcon *gs_app_get_icon (GsApp *app);
-void gs_app_set_icon (GsApp *app,
+GPtrArray *gs_app_get_icons (GsApp *app);
+void gs_app_add_icon (GsApp *app,
AsIcon *icon);
GFile *gs_app_get_local_file (GsApp *app);
void gs_app_set_local_file (GsApp *app,
diff --git a/src/gs-plugin-loader.c b/src/gs-plugin-loader.c
index c757ea4..9ebbb98 100644
--- a/src/gs-plugin-loader.c
+++ b/src/gs-plugin-loader.c
@@ -920,7 +920,7 @@ gs_plugin_loader_add_os_update_item (GsAppList *list)
ic = as_icon_new ();
as_icon_set_kind (ic, AS_ICON_KIND_STOCK);
as_icon_set_name (ic, "software-update-available-symbolic");
- gs_app_set_icon (app_os, ic);
+ gs_app_add_icon (app_os, ic);
gs_app_list_add (list, app_os);
}
@@ -3933,14 +3933,14 @@ gs_plugin_loader_file_to_app_thread_cb (GTask *task,
/* check the apps have an icon set */
for (j = 0; j < gs_app_list_length (state->list); j++) {
GsApp *app = gs_app_list_index (state->list, j);
- if (gs_app_get_icon (app) == NULL) {
+ if (gs_app_get_icons(app)->len == 0) {
g_autoptr(AsIcon) ic = as_icon_new ();
as_icon_set_kind (ic, AS_ICON_KIND_STOCK);
if (gs_app_get_kind (app) == AS_APP_KIND_SOURCE)
as_icon_set_name (ic, "x-package-repository");
else
as_icon_set_name (ic, "application-x-executable");
- gs_app_set_icon (app, ic);
+ gs_app_add_icon (app, ic);
}
}
diff --git a/src/plugins/gs-appstream.c b/src/plugins/gs-appstream.c
index ee5044d..b0cbbfb 100644
--- a/src/plugins/gs-appstream.c
+++ b/src/plugins/gs-appstream.c
@@ -47,10 +47,10 @@ gs_refine_item_pixbuf (GsPlugin *plugin, GsApp *app, AsApp *item)
cachedir = g_path_get_basename (fn);
as_icon_set_prefix (icon, cachedir);
}
- gs_app_set_icon (app, icon);
+ gs_app_add_icon (app, icon);
break;
case AS_ICON_KIND_STOCK:
- gs_app_set_icon (app, icon);
+ gs_app_add_icon (app, icon);
break;
case AS_ICON_KIND_LOCAL:
/* does not exist, so try to find using the icon theme */
@@ -60,7 +60,7 @@ gs_refine_item_pixbuf (GsPlugin *plugin, GsApp *app, AsApp *item)
as_icon_get_name (icon));
as_icon_set_kind (icon, AS_ICON_KIND_STOCK);
}
- gs_app_set_icon (app, icon);
+ gs_app_add_icon (app, icon);
break;
case AS_ICON_KIND_CACHED:
if (gs_plugin_get_scale (plugin) == 2)
@@ -72,7 +72,7 @@ gs_refine_item_pixbuf (GsPlugin *plugin, GsApp *app, AsApp *item)
as_app_get_id (item));
return;
}
- gs_app_set_icon (app, icon);
+ gs_app_add_icon (app, icon);
break;
default:
g_warning ("icon kind unknown for %s", as_app_get_id (item));
diff --git a/src/plugins/gs-plugin-dummy.c b/src/plugins/gs-plugin-dummy.c
index 6fbe61c..f0f087f 100644
--- a/src/plugins/gs-plugin-dummy.c
+++ b/src/plugins/gs-plugin-dummy.c
@@ -154,7 +154,7 @@ gs_plugin_add_search (GsPlugin *plugin,
app = gs_app_new ("chiron.desktop");
gs_app_set_name (app, GS_APP_QUALITY_NORMAL, "Chiron");
gs_app_set_summary (app, GS_APP_QUALITY_NORMAL, "A teaching application");
- gs_app_set_icon (app, ic);
+ gs_app_add_icon (app, ic);
gs_app_set_size_installed (app, 42 * 1024 * 1024);
gs_app_set_size_download (app, 50 * 1024 * 1024);
gs_app_set_kind (app, AS_APP_KIND_DESKTOP);
@@ -197,7 +197,7 @@ gs_plugin_add_updates (GsPlugin *plugin,
gs_app_set_summary (app, GS_APP_QUALITY_NORMAL, "A teaching application");
gs_app_set_update_details (app, "Do not crash when using libvirt.");
gs_app_set_update_urgency (app, AS_URGENCY_KIND_HIGH);
- gs_app_set_icon (app, ic);
+ gs_app_add_icon (app, ic);
gs_app_set_kind (app, AS_APP_KIND_DESKTOP);
gs_app_set_state (app, AS_APP_STATE_UPDATABLE_LIVE);
gs_app_set_management_plugin (app, gs_plugin_get_name (plugin));
@@ -491,7 +491,7 @@ gs_plugin_add_distro_upgrades (GsPlugin *plugin,
gs_app_set_metadata (app, "GnomeSoftware::UpgradeBanner-css",
"background: url('" DATADIR "/gnome-software/upgrade-bg.png');"
"background-size: 100% 100%;");
- gs_app_set_icon (app, ic);
+ gs_app_add_icon (app, ic);
gs_app_list_add (list, app);
gs_plugin_cache_add (plugin, "release-rawhide", app);
diff --git a/src/plugins/gs-plugin-epiphany.c b/src/plugins/gs-plugin-epiphany.c
index 0e3a473..85028c0 100644
--- a/src/plugins/gs-plugin-epiphany.c
+++ b/src/plugins/gs-plugin-epiphany.c
@@ -75,6 +75,7 @@ gs_plugin_app_install (GsPlugin *plugin, GsApp *app,
GCancellable *cancellable, GError **error)
{
AsIcon *icon;
+ GPtrArray *icons;
gboolean ret = TRUE;
gsize kf_length;
g_autoptr(GError) error_local = NULL;
@@ -108,7 +109,16 @@ gs_plugin_app_install (GsPlugin *plugin, GsApp *app,
/* symlink icon */
epi_icon = g_build_filename (epi_dir, "app-icon.png", NULL);
symlink_icon = g_file_new_for_path (epi_icon);
- icon = gs_app_get_icon (app);
+ icons = gs_app_get_icons (app);
+ if (icons->len == 0) {
+ g_set_error (error,
+ GS_PLUGIN_ERROR,
+ GS_PLUGIN_ERROR_FAILED,
+ "no icons for %s",
+ gs_app_get_id (app));
+ return FALSE;
+ }
+ icon = g_ptr_array_index (icons, 0);
ret = g_file_make_symbolic_link (symlink_icon,
as_icon_get_filename (icon),
NULL,
diff --git a/src/plugins/gs-plugin-fedora-distro-upgrades.c b/src/plugins/gs-plugin-fedora-distro-upgrades.c
index 9af2cfc..262ddf8 100644
--- a/src/plugins/gs-plugin-fedora-distro-upgrades.c
+++ b/src/plugins/gs-plugin-fedora-distro-upgrades.c
@@ -372,7 +372,7 @@ gs_plugin_add_distro_upgrades (GsPlugin *plugin,
gs_app_add_quirk (app, AS_APP_QUIRK_PROVENANCE);
gs_app_add_quirk (app, AS_APP_QUIRK_NOT_REVIEWABLE);
gs_app_set_origin_ui (app, distro_info->name);
- gs_app_set_icon (app, ic);
+ gs_app_add_icon (app, ic);
gs_app_set_management_plugin (app, "packagekit");
/* just use the release notes */
diff --git a/src/plugins/gs-plugin-flatpak.c b/src/plugins/gs-plugin-flatpak.c
index b05fc91..1a17893 100644
--- a/src/plugins/gs-plugin-flatpak.c
+++ b/src/plugins/gs-plugin-flatpak.c
@@ -354,7 +354,7 @@ gs_plugin_flatpak_create_installed (GsPlugin *plugin,
icon = as_icon_new ();
as_icon_set_kind (icon, AS_ICON_KIND_STOCK);
as_icon_set_name (icon, "system-run-symbolic");
- gs_app_set_icon (app, icon);
+ gs_app_add_icon (app, icon);
break;
default:
g_set_error_literal (error,
@@ -1399,7 +1399,7 @@ gs_plugin_file_to_app (GsPlugin *plugin,
icon = as_icon_new ();
as_icon_set_kind (icon, AS_ICON_KIND_STOCK);
as_icon_set_name (icon, "application-x-executable");
- gs_app_set_icon (app, icon);
+ gs_app_add_icon (app, icon);
}
/* not quite true: this just means we can update this specific app */
diff --git a/src/plugins/gs-plugin-fwupd.c b/src/plugins/gs-plugin-fwupd.c
index c8305ec..a13c04d 100644
--- a/src/plugins/gs-plugin-fwupd.c
+++ b/src/plugins/gs-plugin-fwupd.c
@@ -214,7 +214,7 @@ gs_plugin_fwupd_new_app_from_results (FwupdResult *res)
icon = as_icon_new ();
as_icon_set_kind (icon, AS_ICON_KIND_STOCK);
as_icon_set_name (icon, "application-x-firmware");
- gs_app_set_icon (app, icon);
+ gs_app_add_icon (app, icon);
if (fwupd_result_get_update_id (res) != NULL) {
gs_app_set_id (app, fwupd_result_get_update_id (res));
diff --git a/src/plugins/gs-plugin-icons.c b/src/plugins/gs-plugin-icons.c
index e6f3cae..16d47cb 100644
--- a/src/plugins/gs-plugin-icons.c
+++ b/src/plugins/gs-plugin-icons.c
@@ -221,8 +221,8 @@ gs_plugin_refine_app (GsPlugin *plugin,
GCancellable *cancellable,
GError **error)
{
- AsIcon *icon;
- g_autoptr(GdkPixbuf) pixbuf = NULL;
+ GPtrArray *icons;
+ guint i;
/* not required */
if ((flags & GS_PLUGIN_REFINE_FLAGS_REQUIRE_ICON) == 0)
@@ -231,34 +231,46 @@ gs_plugin_refine_app (GsPlugin *plugin,
/* invalid */
if (gs_app_get_pixbuf (app) != NULL)
return TRUE;
- icon = gs_app_get_icon (app);
- if (icon == NULL)
- return TRUE;
- /* handle different icon types */
- switch (as_icon_get_kind (icon)) {
- case AS_ICON_KIND_LOCAL:
- pixbuf = gs_plugin_icons_load_local (plugin, icon, error);
- break;
- case AS_ICON_KIND_STOCK:
- pixbuf = gs_plugin_icons_load_stock (plugin, icon, error);
- break;
- case AS_ICON_KIND_REMOTE:
- pixbuf = gs_plugin_icons_load_remote (plugin, icon, error);
- break;
- case AS_ICON_KIND_CACHED:
- pixbuf = gs_plugin_icons_load_cached (plugin, icon, error);
- break;
- default:
- g_set_error (error,
- GS_PLUGIN_ERROR,
- GS_PLUGIN_ERROR_FAILED,
- "icon kind '%s' unknown",
- as_icon_kind_to_string (as_icon_get_kind (icon)));
- break;
+ /* process all icons */
+ icons = gs_app_get_icons (app);
+ for (i = 0; i < icons->len; i++) {
+ AsIcon *icon = g_ptr_array_index (icons, i);
+ g_autoptr(GdkPixbuf) pixbuf = NULL;
+ g_autoptr(GError) error_local = NULL;
+
+ /* handle different icon types */
+ switch (as_icon_get_kind (icon)) {
+ case AS_ICON_KIND_LOCAL:
+ pixbuf = gs_plugin_icons_load_local (plugin, icon, &error_local);
+ break;
+ case AS_ICON_KIND_STOCK:
+ pixbuf = gs_plugin_icons_load_stock (plugin, icon, &error_local);
+ break;
+ case AS_ICON_KIND_REMOTE:
+ pixbuf = gs_plugin_icons_load_remote (plugin, icon, &error_local);
+ break;
+ case AS_ICON_KIND_CACHED:
+ pixbuf = gs_plugin_icons_load_cached (plugin, icon, &error_local);
+ break;
+ default:
+ g_set_error (&error_local,
+ GS_PLUGIN_ERROR,
+ GS_PLUGIN_ERROR_FAILED,
+ "icon kind '%s' unknown",
+ as_icon_kind_to_string (as_icon_get_kind (icon)));
+ break;
+ }
+ if (pixbuf != NULL) {
+ gs_app_set_pixbuf (app, pixbuf);
+ break;
+ }
+
+ /* we failed, but keep going */
+ g_debug ("failed to load icon for %s: %s",
+ gs_app_get_id (app),
+ error_local->message);
}
- if (pixbuf == NULL)
- return FALSE;
- gs_app_set_pixbuf (app, pixbuf);
+
return TRUE;
}
diff --git a/src/plugins/gs-plugin-packagekit.c b/src/plugins/gs-plugin-packagekit.c
index 331b773..57e4ffc 100644
--- a/src/plugins/gs-plugin-packagekit.c
+++ b/src/plugins/gs-plugin-packagekit.c
@@ -401,7 +401,7 @@ gs_plugin_app_install (GsPlugin *plugin,
/* get the new icon from the package */
gs_app_set_local_file (app, NULL);
- gs_app_set_icon (app, NULL);
+ gs_app_add_icon (app, NULL);
gs_app_set_pixbuf (app, NULL);
break;
default:
diff --git a/src/plugins/gs-plugin-shell-extensions.c b/src/plugins/gs-plugin-shell-extensions.c
index a8b219c..daae0fd 100644
--- a/src/plugins/gs-plugin-shell-extensions.c
+++ b/src/plugins/gs-plugin-shell-extensions.c
@@ -201,7 +201,7 @@ gs_plugin_shell_extensions_add_app (GsPlugin *plugin,
ic = as_icon_new ();
as_icon_set_kind (ic, AS_ICON_KIND_STOCK);
as_icon_set_name (ic, "application-x-addon-symbolic");
- gs_app_set_icon (app, ic);
+ gs_app_add_icon (app, ic);
/* add categories */
gs_app_add_category (app, "Addons");
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]