summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--client/as-util.c14
-rw-r--r--libappstream-builder/asb-app.c49
-rw-r--r--libappstream-builder/asb-task.c2
-rw-r--r--libappstream-builder/plugins/asb-plugin-desktop.c40
-rw-r--r--libappstream-builder/plugins/asb-plugin-font.c13
-rw-r--r--libappstream-builder/plugins/asb-plugin-gstreamer.c9
-rw-r--r--libappstream-builder/plugins/asb-plugin-ibus-sql.c10
-rw-r--r--libappstream-builder/plugins/asb-plugin-ibus-xml.c9
-rw-r--r--libappstream-glib/as-app.c235
-rw-r--r--libappstream-glib/as-app.h15
-rw-r--r--libappstream-glib/as-self-test.c58
-rw-r--r--libappstream-glib/as-store.c16
12 files changed, 291 insertions, 179 deletions
diff --git a/client/as-util.c b/client/as-util.c
index cda081d..46716db 100644
--- a/client/as-util.c
+++ b/client/as-util.c
@@ -647,10 +647,10 @@ as_util_appdata_from_desktop (AsUtilPrivate *priv, gchar **values, GError **erro
}
/* set things that don't belong in the AppData file */
- as_app_set_icon (app, NULL, -1);
g_ptr_array_set_size (as_app_get_keywords (app, NULL), 0);
g_ptr_array_set_size (as_app_get_categories (app), 0);
g_ptr_array_set_size (as_app_get_mimetypes (app), 0);
+ g_ptr_array_set_size (as_app_get_icons (app), 0);
/* add urls */
as_app_add_url (app, AS_URL_KIND_HOMEPAGE,
@@ -2092,11 +2092,13 @@ as_util_validate_strict (AsUtilPrivate *priv, gchar **values, GError **error)
static gboolean
as_util_check_root_app_icon (AsApp *app, GError **error)
{
+ AsIcon *icon_default;
_cleanup_free_ gchar *icon = NULL;
_cleanup_object_unref_ GdkPixbuf *pb = NULL;
/* nothing found */
- if (as_app_get_icon (app) == NULL) {
+ icon_default = as_app_get_icon_default (app);
+ if (icon_default == NULL) {
g_set_error (error,
AS_ERROR,
AS_ERROR_FAILED,
@@ -2106,18 +2108,18 @@ as_util_check_root_app_icon (AsApp *app, GError **error)
}
/* is stock icon */
- if (as_utils_is_stock_icon_name (as_app_get_icon (app)))
+ if (as_utils_is_stock_icon_name (as_icon_get_name (icon_default)))
return TRUE;
/* can we find it */
icon = as_utils_find_icon_filename (g_getenv ("DESTDIR"),
- as_app_get_icon (app),
+ as_icon_get_name (icon_default),
error);
if (icon == NULL) {
g_prefix_error (error,
"%s missing icon %s: ",
as_app_get_id (app),
- as_app_get_icon (app));
+ as_icon_get_name (icon_default));
return FALSE;
}
@@ -2127,7 +2129,7 @@ as_util_check_root_app_icon (AsApp *app, GError **error)
g_prefix_error (error,
"%s invalid icon %s: ",
as_app_get_id (app),
- as_app_get_icon (app));
+ as_icon_get_name (icon_default));
return FALSE;
}
diff --git a/libappstream-builder/asb-app.c b/libappstream-builder/asb-app.c
index c5acbcf..09d4ed6 100644
--- a/libappstream-builder/asb-app.c
+++ b/libappstream-builder/asb-app.c
@@ -39,7 +39,6 @@ typedef struct _AsbAppPrivate AsbAppPrivate;
struct _AsbAppPrivate
{
GPtrArray *requires_appdata;
- GPtrArray *pixbufs; /* of GdkPixbuf */
AsbPackage *pkg;
gboolean ignore_requires_appdata;
gboolean hidpi_enabled;
@@ -59,7 +58,6 @@ asb_app_finalize (GObject *object)
AsbAppPrivate *priv = GET_PRIVATE (app);
g_ptr_array_unref (priv->requires_appdata);
- g_ptr_array_unref (priv->pixbufs);
if (priv->pkg != NULL)
g_object_unref (priv->pkg);
@@ -74,7 +72,6 @@ asb_app_init (AsbApp *app)
{
AsbAppPrivate *priv = GET_PRIVATE (app);
priv->requires_appdata = g_ptr_array_new_with_free_func (g_free);
- priv->pixbufs = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref);
/* all untrusted */
as_app_set_trust_flags (AS_APP (app),
@@ -165,22 +162,6 @@ asb_app_set_requires_appdata (AsbApp *app, gboolean requires_appdata)
}
/**
- * asb_app_add_pixbuf:
- * @app: A #AsbApp
- * @pixbuf: a #GdkPixbuf
- *
- * Adds an icon for the application.
- *
- * Since: 0.3.1
- **/
-void
-asb_app_add_pixbuf (AsbApp *app, GdkPixbuf *pixbuf)
-{
- AsbAppPrivate *priv = GET_PRIVATE (app);
- g_ptr_array_add (priv->pixbufs, g_object_ref (pixbuf));
-}
-
-/**
* asb_app_get_requires_appdata:
* @app: A #AsbApp
*
@@ -323,35 +304,51 @@ gboolean
asb_app_save_resources (AsbApp *app, GError **error)
{
AsbAppPrivate *priv = GET_PRIVATE (app);
+ AsIcon *icon;
AsScreenshot *ss;
- guint i;
GdkPixbuf *pixbuf;
+ GPtrArray *icons;
GPtrArray *screenshots;
+ guint i;
/* any non-stock icon set */
- for (i = 0; i < priv->pixbufs->len; i++) {
+ icons = as_app_get_icons (AS_APP (app));
+ for (i = 0; i < icons->len; i++) {
const gchar *tmpdir;
_cleanup_free_ gchar *filename = NULL;
_cleanup_free_ gchar *size_str = NULL;
+ /* don't save stock icons */
+ icon = g_ptr_array_index (icons, i);
+ if (as_icon_get_kind (icon) == AS_ICON_KIND_STOCK)
+ continue;
+
/* save to disk */
- pixbuf = g_ptr_array_index (priv->pixbufs, i);
tmpdir = asb_package_get_config (priv->pkg, "TempDir");
if (priv->hidpi_enabled) {
size_str = g_strdup_printf ("%ux%u",
- gdk_pixbuf_get_width (pixbuf),
- gdk_pixbuf_get_height (pixbuf));
+ as_icon_get_width (icon),
+ as_icon_get_height (icon));
filename = g_build_filename (tmpdir,
"icons",
size_str,
- as_app_get_icon (AS_APP (app)),
+ as_icon_get_name (icon),
NULL);
} else {
filename = g_build_filename (tmpdir,
"icons",
- as_app_get_icon (AS_APP (app)),
+ as_icon_get_name (icon),
NULL);
}
+ pixbuf = as_icon_get_pixbuf (icon);
+ if (pixbuf == NULL) {
+ g_set_error (error,
+ AS_APP_ERROR,
+ AS_APP_ERROR_FAILED,
+ "No pixbuf for %s",
+ as_icon_get_name (icon));
+ return FALSE;
+ }
if (!gdk_pixbuf_save (pixbuf, filename, "png", error, NULL))
return FALSE;
diff --git a/libappstream-builder/asb-task.c b/libappstream-builder/asb-task.c
index 1c55fee..5d5a105 100644
--- a/libappstream-builder/asb-task.c
+++ b/libappstream-builder/asb-task.c
@@ -388,7 +388,7 @@ asb_task_process (AsbTask *task, GError **error_not_used)
/* don't include apps that have no icon */
if (as_app_get_id_kind (AS_APP (app)) != AS_ID_KIND_ADDON) {
- if (as_app_get_icon (AS_APP (app)) == NULL)
+ if (as_app_get_icon_default (AS_APP (app)) == NULL)
as_app_add_veto (AS_APP (app), "Has no Icon");
}
diff --git a/libappstream-builder/plugins/asb-plugin-desktop.c b/libappstream-builder/plugins/asb-plugin-desktop.c
index 362dd2d..54f5163 100644
--- a/libappstream-builder/plugins/asb-plugin-desktop.c
+++ b/libappstream-builder/plugins/asb-plugin-desktop.c
@@ -201,6 +201,9 @@ asb_plugin_desktop_add_icons (AsbPlugin *plugin,
guint min_icon_size;
_cleanup_free_ gchar *fn_hidpi = NULL;
_cleanup_free_ gchar *fn = NULL;
+ _cleanup_free_ gchar *name = NULL;
+ _cleanup_object_unref_ AsIcon *icon_hidpi = NULL;
+ _cleanup_object_unref_ AsIcon *icon = NULL;
_cleanup_object_unref_ GdkPixbuf *pixbuf_hidpi = NULL;
_cleanup_object_unref_ GdkPixbuf *pixbuf = NULL;
@@ -246,7 +249,13 @@ asb_plugin_desktop_add_icons (AsbPlugin *plugin,
}
/* save in target directory */
- asb_app_add_pixbuf (app, pixbuf);
+ name = g_strdup_printf ("%s.png", as_app_get_id_filename (AS_APP (app)));
+ icon = as_icon_new ();
+ as_icon_set_pixbuf (icon, pixbuf);
+ as_icon_set_name (icon, name, -1);
+ as_icon_set_kind (icon, AS_ICON_KIND_CACHED);
+ as_icon_set_prefix (icon, as_app_get_icon_path (AS_APP (app)));
+ as_app_add_icon (AS_APP (app), icon);
/* is HiDPI disabled */
if (!asb_context_get_hidpi_enabled (plugin->ctx))
@@ -269,7 +278,14 @@ asb_plugin_desktop_add_icons (AsbPlugin *plugin,
gdk_pixbuf_get_height (pixbuf_hidpi) <= gdk_pixbuf_get_height (pixbuf))
return TRUE;
as_app_add_kudo_kind (AS_APP (app), AS_KUDO_KIND_HI_DPI_ICON);
- asb_app_add_pixbuf (app, pixbuf_hidpi);
+
+ /* save icon */
+ icon_hidpi = as_icon_new ();
+ as_icon_set_pixbuf (icon_hidpi, pixbuf_hidpi);
+ as_icon_set_name (icon_hidpi, name, -1);
+ as_icon_set_kind (icon_hidpi, AS_ICON_KIND_CACHED);
+ as_icon_set_prefix (icon_hidpi, as_app_get_icon_path (AS_APP (app)));
+ as_app_add_icon (AS_APP (app), icon_hidpi);
return TRUE;
}
@@ -284,7 +300,7 @@ asb_plugin_process_filename (AsbPlugin *plugin,
const gchar *tmpdir,
GError **error)
{
- const gchar *key;
+ AsIcon *icon;
gboolean ret;
_cleanup_free_ gchar *app_id = NULL;
_cleanup_free_ gchar *full_filename = NULL;
@@ -314,27 +330,23 @@ asb_plugin_process_filename (AsbPlugin *plugin,
asb_app_add_requires_appdata (app, "Category=DesktopSettings");
/* is the icon a stock-icon-name? */
- key = as_app_get_icon (AS_APP (app));
- if (key != NULL) {
- if (as_app_get_icon_kind (AS_APP (app)) == AS_ICON_KIND_STOCK) {
+ icon = as_app_get_icon_default (AS_APP (app));
+ if (icon != NULL) {
+ _cleanup_free_ gchar *key;
+ key = g_strdup (as_icon_get_name (icon));
+ if (as_icon_get_kind (icon) == AS_ICON_KIND_STOCK) {
asb_package_log (pkg,
ASB_PACKAGE_LOG_LEVEL_DEBUG,
"using stock icon %s", key);
} else {
_cleanup_error_free_ GError *error_local = NULL;
+ g_ptr_array_set_size (as_app_get_icons (AS_APP (app)), 0);
ret = asb_plugin_desktop_add_icons (plugin,
app,
tmpdir,
key,
&error_local);
- if (ret) {
- _cleanup_free_ gchar *fn = NULL;
- fn = g_strdup_printf ("%s.png",
- as_app_get_id_filename (AS_APP (app)));
- as_app_set_icon (AS_APP (app), fn, -1);
- as_app_set_icon_kind (AS_APP (app),
- AS_ICON_KIND_CACHED);
- } else {
+ if (!ret) {
as_app_add_veto (AS_APP (app), "%s",
error_local->message);
}
diff --git a/libappstream-builder/plugins/asb-plugin-font.c b/libappstream-builder/plugins/asb-plugin-font.c
index 1684c73..8014c36 100644
--- a/libappstream-builder/plugins/asb-plugin-font.c
+++ b/libappstream-builder/plugins/asb-plugin-font.c
@@ -614,8 +614,7 @@ asb_plugin_process_filename (AsbPlugin *plugin,
/* generate icon */
tmp = as_app_get_metadata_item (AS_APP (app), "FontIconText");
if (tmp != NULL) {
- icon_filename = g_strdup_printf ("%s.png", as_app_get_id_filename (AS_APP (app)));
- as_app_set_icon (AS_APP (app), icon_filename, -1);
+ _cleanup_object_unref_ AsIcon *icon = NULL;
pixbuf = asb_font_get_pixbuf (ft_face, 64, 64, tmp, error);
if (pixbuf == NULL) {
ret = FALSE;
@@ -632,8 +631,14 @@ asb_plugin_process_filename (AsbPlugin *plugin,
64, 64, tmp);
goto out;
}
- as_app_set_icon_kind (AS_APP (app), AS_ICON_KIND_CACHED);
- asb_app_add_pixbuf (app, pixbuf);
+
+ /* add icon */
+ icon_filename = g_strdup_printf ("%s.png", as_app_get_id_filename (AS_APP (app)));
+ icon = as_icon_new ();
+ as_icon_set_kind (icon, AS_ICON_KIND_CACHED);
+ as_icon_set_name (icon, icon_filename, -1);
+ as_icon_set_pixbuf (icon, pixbuf);
+ as_app_add_icon (AS_APP (app), icon);
}
/* add */
diff --git a/libappstream-builder/plugins/asb-plugin-gstreamer.c b/libappstream-builder/plugins/asb-plugin-gstreamer.c
index 25641fe..b205f3a 100644
--- a/libappstream-builder/plugins/asb-plugin-gstreamer.c
+++ b/libappstream-builder/plugins/asb-plugin-gstreamer.c
@@ -142,6 +142,7 @@ asb_plugin_process (AsbPlugin *plugin,
guint j;
_cleanup_free_ gchar *app_id = NULL;
_cleanup_object_unref_ AsbApp *app = NULL;
+ _cleanup_object_unref_ AsIcon *icon = NULL;
_cleanup_string_free_ GString *str = NULL;
/* use the pkgname suffix as the app-id */
@@ -158,13 +159,17 @@ asb_plugin_process (AsbPlugin *plugin,
app = asb_app_new (pkg, app_id);
as_app_set_id_kind (AS_APP (app), AS_ID_KIND_CODEC);
as_app_set_name (AS_APP (app), "C", "GStreamer Multimedia Codecs", -1);
- as_app_set_icon (AS_APP (app), "application-x-executable", -1);
asb_app_set_requires_appdata (app, TRUE);
asb_app_set_hidpi_enabled (app, asb_context_get_hidpi_enabled (plugin->ctx));
- as_app_set_icon_kind (AS_APP (app), AS_ICON_KIND_STOCK);
as_app_add_category (AS_APP (app), "Addons", -1);
as_app_add_category (AS_APP (app), "Codecs", -1);
+ /* add icon */
+ icon = as_icon_new ();
+ as_icon_set_kind (icon, AS_ICON_KIND_STOCK);
+ as_icon_set_name (icon, "application-x-executable", -1);
+ as_app_add_icon (AS_APP (app), icon);
+
for (i = 0; data[i].path != NULL; i++) {
if (!asb_utils_is_file_in_tmpdir (tmpdir, data[i].path))
continue;
diff --git a/libappstream-builder/plugins/asb-plugin-ibus-sql.c b/libappstream-builder/plugins/asb-plugin-ibus-sql.c
index 6f680f9..cffbc9b 100644
--- a/libappstream-builder/plugins/asb-plugin-ibus-sql.c
+++ b/libappstream-builder/plugins/asb-plugin-ibus-sql.c
@@ -97,6 +97,7 @@ asb_plugin_process_filename (AsbPlugin *plugin,
_cleanup_free_ gchar *name = NULL;
_cleanup_free_ gchar *symbol = NULL;
_cleanup_object_unref_ AsbApp *app = NULL;
+ _cleanup_object_unref_ AsIcon *icon = NULL;
_cleanup_strv_free_ gchar **languages = NULL;
/* open IME database */
@@ -189,8 +190,6 @@ asb_plugin_process_filename (AsbPlugin *plugin,
as_app_set_id_kind (AS_APP (app), AS_ID_KIND_INPUT_METHOD);
as_app_add_category (AS_APP (app), "Addons", -1);
as_app_add_category (AS_APP (app), "InputSources", -1);
- as_app_set_icon (AS_APP (app), "system-run-symbolic", -1);
- as_app_set_icon_kind (AS_APP (app), AS_ICON_KIND_STOCK);
as_app_set_name (AS_APP (app), "C", name, -1);
as_app_set_comment (AS_APP (app), "C", description, -1);
if (symbol != NULL && symbol[0] != '\0')
@@ -206,6 +205,13 @@ asb_plugin_process_filename (AsbPlugin *plugin,
}
asb_app_set_requires_appdata (app, TRUE);
asb_app_set_hidpi_enabled (app, asb_context_get_hidpi_enabled (plugin->ctx));
+
+ /* add icon */
+ icon = as_icon_new ();
+ as_icon_set_kind (icon, AS_ICON_KIND_STOCK);
+ as_icon_set_name (icon, "system-run-symbolic", -1);
+ as_app_add_icon (AS_APP (app), icon);
+
asb_plugin_add_app (apps, AS_APP (app));
out:
if (db != NULL)
diff --git a/libappstream-builder/plugins/asb-plugin-ibus-xml.c b/libappstream-builder/plugins/asb-plugin-ibus-xml.c
index d808d8a..a450cec 100644
--- a/libappstream-builder/plugins/asb-plugin-ibus-xml.c
+++ b/libappstream-builder/plugins/asb-plugin-ibus-xml.c
@@ -86,6 +86,7 @@ asb_plugin_process_filename (AsbPlugin *plugin,
_cleanup_free_ gchar *data = NULL;
_cleanup_free_ gchar *filename_tmp;
_cleanup_object_unref_ AsbApp *app = NULL;
+ _cleanup_object_unref_ AsIcon *icon = NULL;
_cleanup_strv_free_ gchar **languages = NULL;
_cleanup_strv_free_ gchar **lines = NULL;
@@ -120,11 +121,15 @@ asb_plugin_process_filename (AsbPlugin *plugin,
as_app_set_id_kind (AS_APP (app), AS_ID_KIND_INPUT_METHOD);
as_app_add_category (AS_APP (app), "Addons", -1);
as_app_add_category (AS_APP (app), "InputSources", -1);
- as_app_set_icon (AS_APP (app), "system-run-symbolic", -1);
- as_app_set_icon_kind (AS_APP (app), AS_ICON_KIND_STOCK);
asb_app_set_requires_appdata (app, TRUE);
asb_app_set_hidpi_enabled (app, asb_context_get_hidpi_enabled (plugin->ctx));
+ /* add icon */
+ icon = as_icon_new ();
+ as_icon_set_kind (icon, AS_ICON_KIND_STOCK);
+ as_icon_set_name (icon, "system-run-symbolic", -1);
+ as_app_add_icon (AS_APP (app), icon);
+
/* read the component header which all input methods have */
n = as_node_find (root, "component/description");
if (n != NULL) {
diff --git a/libappstream-glib/as-app.c b/libappstream-glib/as-app.c
index 9341abd..c8a0737 100644
--- a/libappstream-glib/as-app.c
+++ b/libappstream-glib/as-app.c
@@ -40,6 +40,7 @@
#include "as-app-private.h"
#include "as-cleanup.h"
#include "as-enums.h"
+#include "as-icon-private.h"
#include "as-node-private.h"
#include "as-provide-private.h"
#include "as-release-private.h"
@@ -73,11 +74,11 @@ struct _AsAppPrivate
GPtrArray *releases; /* of AsRelease */
GPtrArray *provides; /* of AsProvide */
GPtrArray *screenshots; /* of AsScreenshot */
+ GPtrArray *icons; /* of AsIcon */
GPtrArray *vetos; /* of string */
AsAppSourceKind source_kind;
AsAppState state;
AsAppTrustFlags trust_flags;
- gchar *icon;
gchar *icon_path;
gchar *id_filename;
gchar *id;
@@ -243,7 +244,6 @@ as_app_finalize (GObject *object)
AsApp *app = AS_APP (object);
AsAppPrivate *priv = GET_PRIVATE (app);
- g_free (priv->icon);
g_free (priv->icon_path);
g_free (priv->id_filename);
g_free (priv->id);
@@ -272,6 +272,7 @@ as_app_finalize (GObject *object)
g_ptr_array_unref (priv->releases);
g_ptr_array_unref (priv->provides);
g_ptr_array_unref (priv->screenshots);
+ g_ptr_array_unref (priv->icons);
g_ptr_array_unref (priv->token_cache);
g_ptr_array_unref (priv->vetos);
@@ -309,6 +310,7 @@ as_app_init (AsApp *app)
priv->releases = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref);
priv->provides = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref);
priv->screenshots = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref);
+ priv->icons = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref);
priv->token_cache = g_ptr_array_new_with_free_func ((GDestroyNotify) as_app_token_item_free);
priv->vetos = g_ptr_array_new_with_free_func (g_free);
@@ -586,6 +588,23 @@ as_app_get_screenshots (AsApp *app)
}
/**
+ * as_app_get_icons:
+ * @app: a #AsApp instance.
+ *
+ * Gets any icons the application has defined.
+ *
+ * Returns: (element-type AsIcon) (transfer none): an array
+ *
+ * Since: 0.3.1
+ **/
+GPtrArray *
+as_app_get_icons (AsApp *app)
+{
+ AsAppPrivate *priv = GET_PRIVATE (app);
+ return priv->icons;
+}
+
+/**
* as_app_get_names:
* @app: a #AsApp instance.
*
@@ -893,41 +912,6 @@ as_app_get_problems (AsApp *app)
}
/**
- * as_app_get_icon_kind:
- * @app: a #AsApp instance.
- *
- * Gets the icon kind.
- *
- * Returns: enumerated value
- *
- * Since: 0.1.0
- **/
-AsIconKind
-as_app_get_icon_kind (AsApp *app)
-{
- AsAppPrivate *priv = GET_PRIVATE (app);
- return priv->icon_kind;
-}
-
-/**
- * as_app_get_icon:
- * @app: a #AsApp instance.
- *
- * Gets the application icon. Use as_app_get_icon_path() if you need the create
- * a full filename.
- *
- * Returns: string, or %NULL if unset
- *
- * Since: 0.1.0
- **/
-const gchar *
-as_app_get_icon (AsApp *app)
-{
- AsAppPrivate *priv = GET_PRIVATE (app);
- return priv->icon;
-}
-
-/**
* as_app_get_pkgname_default:
* @app: a #AsApp instance.
*
@@ -1569,32 +1553,6 @@ as_app_set_update_contact (AsApp *app,
}
/**
- * as_app_set_icon:
- * @app: a #AsApp instance.
- * @icon: the icon filename or URL.
- * @icon_len: the size of @icon, or -1 if %NULL-terminated.
- *
- * Set the application icon.
- *
- * Since: 0.1.0
- **/
-void
-as_app_set_icon (AsApp *app, const gchar *icon, gssize icon_len)
-{
- AsAppPrivate *priv = GET_PRIVATE (app);
-
- /* handle untrusted */
- if ((priv->trust_flags & AS_APP_TRUST_FLAG_CHECK_VALID_UTF8) > 0 &&
- !as_app_validate_utf8 (icon, icon_len)) {
- priv->problems |= AS_APP_PROBLEM_NOT_VALID_UTF8;
- return;
- }
-
- g_free (priv->icon);
- priv->icon = as_strndup (icon, icon_len);
-}
-
-/**
* as_app_set_icon_path:
* @app: a #AsApp instance.
* @icon_path: the local path.
@@ -1621,22 +1579,6 @@ as_app_set_icon_path (AsApp *app, const gchar *icon_path, gssize icon_path_len)
}
/**
- * as_app_set_icon_kind:
- * @app: a #AsApp instance.
- * @icon_kind: the #AsIconKind.
- *
- * Sets the icon kind.
- *
- * Since: 0.1.0
- **/
-void
-as_app_set_icon_kind (AsApp *app, AsIconKind icon_kind)
-{
- AsAppPrivate *priv = GET_PRIVATE (app);
- priv->icon_kind = icon_kind;
-}
-
-/**
* as_app_parse_locale:
**/
static gchar *
@@ -2084,6 +2026,36 @@ as_app_add_screenshot (AsApp *app, AsScreenshot *screenshot)
}
/**
+ * as_app_add_icon:
+ * @app: a #AsApp instance.
+ * @icon: a #AsIcon instance.
+ *
+ * Adds a icon to an application.
+ *
+ * Since: 0.3.1
+ **/
+void
+as_app_add_icon (AsApp *app, AsIcon *icon)
+{
+ AsAppPrivate *priv = GET_PRIVATE (app);
+
+ /* handle untrusted */
+ if ((priv->trust_flags & AS_APP_TRUST_FLAG_CHECK_DUPLICATES) > 0) {
+ AsIcon *ic_tmp;
+ guint i;
+ for (i = 0; i < priv->icons->len; i++) {
+ ic_tmp = g_ptr_array_index (priv->icons, i);
+ if (as_icon_get_pixbuf (ic_tmp) != NULL)
+ continue;
+ if (g_strcmp0 (as_icon_get_name (ic_tmp),
+ as_icon_get_name (icon)) == 0)
+ return;
+ }
+ }
+ g_ptr_array_add (priv->icons, g_object_ref (icon));
+}
+
+/**
* as_app_add_pkgname:
* @app: a #AsApp instance.
* @pkgname: the package name.
@@ -2428,6 +2400,12 @@ as_app_subsume_private (AsApp *app, AsApp *donor, AsAppSubsumeFlags flags)
as_app_add_screenshot (app, ss);
}
+ /* icons */
+ for (i = 0; i < priv->icons->len; i++) {
+ AsIcon *ic = g_ptr_array_index (priv->icons, i);
+ as_app_add_icon (app, ic);
+ }
+
/* mimetypes */
for (i = 0; i < priv->mimetypes->len; i++) {
tmp = g_ptr_array_index (priv->mimetypes, i);
@@ -2460,12 +2438,6 @@ as_app_subsume_private (AsApp *app, AsApp *donor, AsAppSubsumeFlags flags)
as_app_subsume_dict (papp->urls, priv->urls, overwrite);
as_app_subsume_keywords (app, donor, overwrite);
- /* icon */
- if (priv->icon != NULL)
- as_app_set_icon (app, priv->icon, -1);
- if (priv->icon_kind != AS_ICON_KIND_UNKNOWN)
- as_app_set_icon_kind (app, priv->icon_kind);
-
/* source */
if (priv->source_file != NULL)
as_app_set_source_file (app, priv->source_file);
@@ -2788,10 +2760,9 @@ as_app_node_insert (AsApp *app, GNode *parent, gdouble api_version)
}
/* <icon> */
- if (priv->icon != NULL) {
- as_node_insert (node_app, "icon", priv->icon, 0,
- "type", as_icon_kind_to_string (priv->icon_kind),
- NULL);
+ for (i = 0; i < priv->icons->len; i++) {
+ AsIcon *ic = g_ptr_array_index (priv->icons, i);
+ as_icon_node_insert (ic, node_app, api_version);
}
/* <categories> */
@@ -3071,11 +3042,15 @@ as_app_node_parse_child (AsApp *app, GNode *n, AsAppParseFlags flags, GError **e
/* <icon> */
case AS_TAG_ICON:
- tmp = as_node_get_attribute (n, "type");
- as_app_set_icon_kind (app, as_icon_kind_from_string (tmp));
- g_free (priv->icon);
- priv->icon = as_node_take_data (n);
+ {
+ _cleanup_object_unref_ AsIcon *ic = NULL;
+ ic = as_icon_new ();
+ as_icon_set_prefix (ic, priv->icon_path);
+ if (!as_icon_node_parse (ic, n, error))
+ return FALSE;
+ as_app_add_icon (app, ic);
break;
+ }
/* <categories> */
case AS_TAG_CATEGORIES:
@@ -3345,6 +3320,7 @@ as_app_node_parse_full (AsApp *app, GNode *node, AsAppParseFlags flags, GError *
g_ptr_array_set_size (priv->pkgnames, 0);
g_ptr_array_set_size (priv->architectures, 0);
g_ptr_array_set_size (priv->extends, 0);
+ g_ptr_array_set_size (priv->icons, 0);
g_hash_table_remove_all (priv->keywords);
}
for (n = node->children; n != NULL; n = n->next) {
@@ -3453,11 +3429,11 @@ as_app_node_parse_dep11 (AsApp *app, GNode *node, GError **error)
}
if (g_strcmp0 (tmp, "Icon") == 0) {
for (c = n->children; c != NULL; c = c->next) {
- if (g_strcmp0 (as_yaml_node_get_key (c), "cached") == 0) {
- as_app_set_icon (app, as_yaml_node_get_value (c), -1);
- as_app_set_icon_kind (app, AS_ICON_KIND_CACHED);
- continue;
- }
+ _cleanup_object_unref_ AsIcon *ic = NULL;
+ ic = as_icon_new ();
+ if (!as_icon_node_parse_dep11 (ic, c, error))
+ return FALSE;
+ as_app_add_icon (app, ic);
}
continue;
}
@@ -3813,14 +3789,20 @@ as_app_parse_file_key (AsApp *app,
key,
NULL);
if (tmp != NULL && tmp[0] != '\0') {
- as_app_set_icon (app, tmp, -1);
+ AsIcon *icon;
+ dot = g_strstr_len (tmp, -1, ".");
+ if (dot != NULL)
+ *dot = '\0';
+ icon = as_icon_new ();
+ as_icon_set_name (icon, tmp, -1);
dot = g_strstr_len (tmp, -1, ".");
if (dot != NULL)
*dot = '\0';
if (as_utils_is_stock_icon_name (tmp)) {
- as_app_set_icon (app, tmp, -1);
- as_app_set_icon_kind (app, AS_ICON_KIND_STOCK);
+ as_icon_set_name (icon, tmp, -1);
+ as_icon_set_kind (icon, AS_ICON_KIND_STOCK);
}
+ as_app_add_icon (app, icon);
}
/* Categories */
@@ -4036,7 +4018,7 @@ as_app_parse_desktop_file (AsApp *app,
}
/* all applications require icons */
- if (as_app_get_icon (app) == NULL)
+ if (as_app_get_icons(app)->len == 0)
as_app_add_veto (app, "%s has no icon", app_id);
return TRUE;
@@ -4318,6 +4300,55 @@ as_app_get_vetos (AsApp *app)
}
/**
+ * as_app_get_icon_default:
+ * @app: A #AsApp
+ *
+ * Finds the default icon.
+ *
+ * Returns: (transfer none): a #AsIcon, or %NULL
+ *
+ * Since: 0.3.1
+ **/
+AsIcon *
+as_app_get_icon_default (AsApp *app)
+{
+ AsAppPrivate *priv = GET_PRIVATE (app);
+ AsIcon *icon;
+
+ if (priv->icons->len == 0)
+ return NULL;
+ icon = g_ptr_array_index (priv->icons, 0);
+ return icon;
+}
+
+/**
+ * as_app_get_icon_for_size:
+ * @app: A #AsApp
+ * @width: Size in pixels
+ * @height: Size in pixels
+ *
+ * Finds an icon of a specific size.
+ *
+ * Returns: (transfer none): a #AsIcon, or %NULL
+ *
+ * Since: 0.3.1
+ **/
+AsIcon *
+as_app_get_icon_for_size (AsApp *app, guint width, guint height)
+{
+ AsAppPrivate *priv = GET_PRIVATE (app);
+ guint i;
+
+ for (i = 0; i < priv->icons->len; i++) {
+ AsIcon *ic = g_ptr_array_index (priv->icons, i);
+ if (as_icon_get_width (ic) == width &&
+ as_icon_get_height (ic) == height)
+ return ic;
+ }
+ return NULL;
+}
+
+/**
* as_app_add_veto:
* @app: A #AsApp
* @fmt: format string
diff --git a/libappstream-glib/as-app.h b/libappstream-glib/as-app.h
index f6c562d..57fdb61 100644
--- a/libappstream-glib/as-app.h
+++ b/libappstream-glib/as-app.h
@@ -29,6 +29,7 @@
#include <glib-object.h>
#include "as-enums.h"
+#include "as-icon.h"
#include "as-provide.h"
#include "as-release.h"
#include "as-screenshot.h"
@@ -213,7 +214,6 @@ const gchar *as_app_source_kind_to_string (AsAppSourceKind source_kind);
const gchar *as_app_state_to_string (AsAppState state);
/* getters */
-AsIconKind as_app_get_icon_kind (AsApp *app);
AsIdKind as_app_get_id_kind (AsApp *app);
AsAppSourceKind as_app_get_source_kind (AsApp *app);
AsAppState as_app_get_state (AsApp *app);
@@ -232,6 +232,7 @@ GPtrArray *as_app_get_architectures (AsApp *app);
GPtrArray *as_app_get_releases (AsApp *app);
GPtrArray *as_app_get_provides (AsApp *app);
GPtrArray *as_app_get_screenshots (AsApp *app);
+GPtrArray *as_app_get_icons (AsApp *app);
GHashTable *as_app_get_names (AsApp *app);
GHashTable *as_app_get_comments (AsApp *app);
GHashTable *as_app_get_developer_names (AsApp *app);
@@ -239,7 +240,6 @@ GHashTable *as_app_get_metadata (AsApp *app);
GHashTable *as_app_get_descriptions (AsApp *app);
GHashTable *as_app_get_urls (AsApp *app);
GPtrArray *as_app_get_vetos (AsApp *app);
-const gchar *as_app_get_icon (AsApp *app);
const gchar *as_app_get_icon_path (AsApp *app);
const gchar *as_app_get_id_filename (AsApp *app);
const gchar *as_app_get_id (AsApp *app);
@@ -299,14 +299,9 @@ void as_app_set_source_pkgname (AsApp *app,
void as_app_set_update_contact (AsApp *app,
const gchar *update_contact,
gssize update_contact_len);
-void as_app_set_icon (AsApp *app,
- const gchar *icon,
- gssize icon_len);
void as_app_set_icon_path (AsApp *app,
const gchar *icon_path,
gssize icon_path_len);
-void as_app_set_icon_kind (AsApp *app,
- AsIconKind icon_kind);
void as_app_set_name (AsApp *app,
const gchar *locale,
const gchar *name,
@@ -354,6 +349,8 @@ void as_app_add_provide (AsApp *app,
AsProvide *provide);
void as_app_add_screenshot (AsApp *app,
AsScreenshot *screenshot);
+void as_app_add_icon (AsApp *app,
+ AsIcon *icon);
void as_app_add_language (AsApp *app,
gint percentage,
const gchar *locale,
@@ -402,6 +399,10 @@ gboolean as_app_to_file (AsApp *app,
GFile *file,
GCancellable *cancellable,
GError **error);
+AsIcon *as_app_get_icon_default (AsApp *app);
+AsIcon *as_app_get_icon_for_size (AsApp *app,
+ guint width,
+ guint height);
G_END_DECLS
diff --git a/libappstream-glib/as-self-test.c b/libappstream-glib/as-self-test.c
index 2ccc5e5..f9d3dbb 100644
--- a/libappstream-glib/as-self-test.c
+++ b/libappstream-glib/as-self-test.c
@@ -665,9 +665,11 @@ as_test_screenshot_func (void)
static void
as_test_app_func (void)
{
+ AsIcon *ic;
GError *error = NULL;
GNode *n;
GNode *root;
+ GPtrArray *icons;
GString *xml;
gboolean ret;
const gchar *src =
@@ -748,9 +750,7 @@ as_test_app_func (void)
g_assert_cmpstr (as_app_get_name (app, "pl"), ==, "Oprogramowanie");
g_assert_cmpstr (as_app_get_comment (app, NULL), ==, "Application manager");
g_assert_cmpstr (as_app_get_developer_name (app, NULL), ==, "GNOME Foundation");
- g_assert_cmpstr (as_app_get_icon (app), ==, "org.gnome.Software.png");
g_assert_cmpstr (as_app_get_source_pkgname (app), ==, "gnome-software-src");
- g_assert_cmpint (as_app_get_icon_kind (app), ==, AS_ICON_KIND_CACHED);
g_assert_cmpint (as_app_get_source_kind (app), ==, AS_APP_SOURCE_KIND_UNKNOWN);
g_assert_cmpstr (as_app_get_project_group (app), ==, "GNOME");
g_assert_cmpstr (as_app_get_project_license (app), ==, "GPLv2+");
@@ -770,6 +770,19 @@ as_test_app_func (void)
g_assert (!as_app_has_kudo_kind (app, AS_KUDO_KIND_USER_DOCS));
as_node_unref (root);
+ /* check icons */
+ icons = as_app_get_icons (app);
+ g_assert (icons != NULL);
+ g_assert_cmpint (icons->len, ==, 1);
+
+ /* check we can get a specific icon */
+ ic = as_app_get_icon_for_size (app, 999, 999);
+ g_assert (ic == NULL);
+ ic = as_app_get_icon_for_size (app, 64, 64);
+ g_assert (ic != NULL);
+ g_assert_cmpstr (as_icon_get_name (ic), ==, "org.gnome.Software.png");
+ g_assert_cmpint (as_icon_get_kind (ic), ==, AS_ICON_KIND_CACHED);
+
/* back to node */
root = as_node_new ();
n = as_app_node_insert (app, root, 0.8);
@@ -1088,6 +1101,7 @@ static void
as_test_store_local_app_install_func (void)
{
AsApp *app;
+ AsIcon *ic;
GError *error = NULL;
gboolean ret;
_cleanup_free_ gchar *filename = NULL;
@@ -1108,10 +1122,17 @@ as_test_store_local_app_install_func (void)
g_assert (app != NULL);
g_assert_cmpstr (as_app_get_name (app, "C"), ==, "Test");
g_assert_cmpstr (as_app_get_comment (app, "C"), ==, "A test program");
- g_assert_cmpstr (as_app_get_icon (app), ==, "test");
- g_assert_cmpint (as_app_get_icon_kind (app), ==, AS_ICON_KIND_CACHED);
g_assert_cmpint (as_app_get_source_kind (app), ==, AS_APP_SOURCE_KIND_APPSTREAM);
+ /* check icons */
+ g_assert_cmpint (as_app_get_icons(app)->len, ==, 1);
+ ic = as_app_get_icon_default (app);
+ g_assert (ic != NULL);
+ g_assert_cmpstr (as_icon_get_name (ic), ==, "test");
+ g_assert_cmpint (as_icon_get_kind (ic), ==, AS_ICON_KIND_CACHED);
+ g_assert_cmpint (as_icon_get_width (ic), ==, 0);
+ g_assert_cmpint (as_icon_get_height (ic), ==, 0);
+
/* ensure we reference the correct file */
source_file = g_build_filename (filename, "/usr", "share", "app-install",
"desktop", "test.desktop", NULL);
@@ -1240,6 +1261,7 @@ as_test_app_validate_style_func (void)
static void
as_test_app_parse_file_func (void)
{
+ AsIcon *ic;
GError *error = NULL;
gboolean ret;
_cleanup_free_ gchar *filename = NULL;
@@ -1262,8 +1284,6 @@ as_test_app_parse_file_func (void)
"Inspect and compare installed color profiles");
g_assert_cmpstr (as_app_get_comment (app, "pl"), ==,
"Badanie i porównywanie zainstalowanych profilów kolorów");
- g_assert_cmpstr (as_app_get_icon (app), ==, "audio-input-microphone");
- g_assert_cmpint (as_app_get_icon_kind (app), ==, AS_ICON_KIND_STOCK);
g_assert_cmpint (as_app_get_vetos(app)->len, ==, 1);
g_assert_cmpstr (as_app_get_project_group (app), ==, NULL);
g_assert_cmpstr (as_app_get_source_file (app), ==, filename);
@@ -1273,6 +1293,15 @@ as_test_app_parse_file_func (void)
g_assert (as_app_has_category (app, "System"));
g_assert (!as_app_has_category (app, "NotGoingToExist"));
+ /* check icons */
+ g_assert_cmpint (as_app_get_icons(app)->len, ==, 1);
+ ic = as_app_get_icon_default (app);
+ g_assert (ic != NULL);
+ g_assert_cmpstr (as_icon_get_name (ic), ==, "audio-input-microphone");
+ g_assert_cmpint (as_icon_get_kind (ic), ==, AS_ICON_KIND_STOCK);
+ g_assert_cmpint (as_icon_get_width (ic), ==, 0);
+ g_assert_cmpint (as_icon_get_height (ic), ==, 0);
+
/* reparse with heuristics */
ret = as_app_parse_file (app,
filename,
@@ -1737,14 +1766,18 @@ as_test_node_localized_wrap2_func (void)
static void
as_test_app_subsume_func (void)
{
+ AsIcon *ic;
GList *list;
_cleanup_object_unref_ AsApp *app = NULL;
_cleanup_object_unref_ AsApp *donor = NULL;
+ _cleanup_object_unref_ AsIcon *icon = NULL;
_cleanup_object_unref_ AsScreenshot *ss = NULL;
donor = as_app_new ();
+ icon = as_icon_new ();
+ as_icon_set_name (icon, "gtk-find", -1);
+ as_app_add_icon (donor, icon);
as_app_set_state (donor, AS_APP_STATE_INSTALLED);
- as_app_set_icon (donor, "gtk-find", -1);
as_app_add_pkgname (donor, "hal", -1);
as_app_add_language (donor, -1, "en_GB", -1);
as_app_add_metadata (donor, "donor", "true", -1);
@@ -1761,7 +1794,6 @@ as_test_app_subsume_func (void)
as_app_subsume_full (app, donor, AS_APP_SUBSUME_FLAG_NO_OVERWRITE);
as_app_add_screenshot (app, ss);
- g_assert_cmpstr (as_app_get_icon (app), ==, "gtk-find");
g_assert_cmpstr (as_app_get_metadata_item (app, "donor"), ==, "true");
g_assert_cmpstr (as_app_get_metadata_item (app, "overwrite"), ==, "2222");
g_assert_cmpstr (as_app_get_metadata_item (donor, "recipient"), ==, NULL);
@@ -1773,6 +1805,15 @@ as_test_app_subsume_func (void)
g_assert_cmpint (g_list_length (list), ==, 1);
g_list_free (list);
+ /* check icon */
+ g_assert_cmpint (as_app_get_icons(app)->len, ==, 1);
+ ic = as_app_get_icon_default (app);
+ g_assert (ic != NULL);
+ g_assert_cmpstr (as_icon_get_name (ic), ==, "gtk-find");
+ g_assert_cmpint (as_icon_get_kind (ic), ==, AS_ICON_KIND_UNKNOWN);
+ g_assert_cmpint (as_icon_get_width (ic), ==, 0);
+ g_assert_cmpint (as_icon_get_height (ic), ==, 0);
+
/* test both ways */
as_app_subsume_full (app, donor, AS_APP_SUBSUME_FLAG_BOTH_WAYS);
g_assert_cmpstr (as_app_get_metadata_item (app, "donor"), ==, "true");
@@ -2963,4 +3004,3 @@ main (int argc, char **argv)
return g_test_run ();
}
-
diff --git a/libappstream-glib/as-store.c b/libappstream-glib/as-store.c
index 75872a4..1a39651 100644
--- a/libappstream-glib/as-store.c
+++ b/libappstream-glib/as-store.c
@@ -1298,10 +1298,14 @@ as_store_load_app_install_file (AsStore *store,
const gchar *path_icons,
GError **error)
{
+ AsIcon *icon;
+ GPtrArray *icons;
+ guint i;
_cleanup_error_free_ GError *error_local = NULL;
_cleanup_object_unref_ AsApp *app;
app = as_app_new ();
+ as_app_set_icon_path (app, path_icons, -1);
if (!as_app_parse_file (app,
filename,
AS_APP_PARSE_FLAG_USE_HEURISTICS,
@@ -1320,9 +1324,14 @@ as_store_load_app_install_file (AsStore *store,
error_local->message);
return FALSE;
}
- if (as_app_get_icon_kind (app) == AS_ICON_KIND_UNKNOWN)
- as_app_set_icon_kind (app, AS_ICON_KIND_CACHED);
- as_app_set_icon_path (app, path_icons, -1);
+
+ /* convert all the icons */
+ icons = as_app_get_icons (app);
+ for (i = 0; i < icons->len; i++) {
+ icon = g_ptr_array_index (icons, i);
+ if (as_icon_get_kind (icon) == AS_ICON_KIND_UNKNOWN)
+ as_icon_set_kind (icon, AS_ICON_KIND_CACHED);
+ }
as_store_add_app_install_screenshot (app);
as_store_add_app (store, app);
@@ -1439,7 +1448,6 @@ as_store_load_installed (AsStore *store,
/* set lower priority than AppStream entries */
as_app_set_priority (app, -1);
- as_app_set_icon_kind (app, AS_ICON_KIND_STOCK);
as_app_set_state (app, AS_APP_STATE_INSTALLED);
as_store_add_app (store, app);
}