Skip to content
Permalink
master
Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
Go to file
 
 
Cannot retrieve contributors at this time
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
*
* Copyright (C) 2015-2022 Matthias Klumpp <matthias@tenstral.net>
*
* Licensed under the GNU Lesser General Public License Version 2.1
*
* This library is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 2.1 of the license, or
* (at your option) any later version.
*
* This library 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* SECTION: as-icon
* @short_description: Describes an icon of an application.
* @include: appstream.h
*/
#include "config.h"
#include "as-icon-private.h"
#include "as-utils-private.h"
typedef struct
{
AsIconKind kind;
gchar *name;
gchar *url;
gchar *filename;
guint width;
guint height;
guint scale;
} AsIconPrivate;
G_DEFINE_TYPE_WITH_PRIVATE (AsIcon, as_icon, G_TYPE_OBJECT)
#define GET_PRIVATE(o) (as_icon_get_instance_private (o))
/**
* as_icon_kind_to_string:
* @kind: the %AsIconKind.
*
* Converts the enumerated value to an text representation.
*
* Returns: string version of @kind
**/
const gchar*
as_icon_kind_to_string (AsIconKind kind)
{
if (kind == AS_ICON_KIND_CACHED)
return "cached";
if (kind == AS_ICON_KIND_LOCAL)
return "local";
if (kind == AS_ICON_KIND_REMOTE)
return "remote";
if (kind == AS_ICON_KIND_STOCK)
return "stock";
return "unknown";
}
/**
* as_icon_kind_from_string:
* @kind_str: the string.
*
* Converts the text representation to an enumerated value.
*
* Returns: a #AsIconKind or %AS_ICON_KIND_UNKNOWN for unknown
**/
AsIconKind
as_icon_kind_from_string (const gchar *kind_str)
{
if (g_strcmp0 (kind_str, "cached") == 0)
return AS_ICON_KIND_CACHED;
if (g_strcmp0 (kind_str, "local") == 0)
return AS_ICON_KIND_LOCAL;
if (g_strcmp0 (kind_str, "remote") == 0)
return AS_ICON_KIND_REMOTE;
if (g_strcmp0 (kind_str, "stock") == 0)
return AS_ICON_KIND_STOCK;
return AS_ICON_KIND_UNKNOWN;
}
/**
* as_icon_finalize:
**/
static void
as_icon_finalize (GObject *object)
{
AsIcon *icon = AS_ICON (object);
AsIconPrivate *priv = GET_PRIVATE (icon);
g_free (priv->name);
g_free (priv->url);
g_free (priv->filename);
G_OBJECT_CLASS (as_icon_parent_class)->finalize (object);
}
/**
* as_icon_init:
**/
static void
as_icon_init (AsIcon *icon)
{
AsIconPrivate *priv = GET_PRIVATE (icon);
priv->scale = 1;
}
/**
* as_icon_class_init:
**/
static void
as_icon_class_init (AsIconClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->finalize = as_icon_finalize;
}
/**
* as_icon_get_kind:
* @icon: a #AsIcon instance.
*
* Gets the icon kind.
*
* Returns: the #AsIconKind
**/
AsIconKind
as_icon_get_kind (AsIcon *icon)
{
AsIconPrivate *priv = GET_PRIVATE (icon);
return priv->kind;
}
/**
* as_icon_set_kind:
* @icon: a #AsIcon instance.
* @kind: the #AsIconKind, e.g. %AS_ICON_KIND_CACHED.
*
* Sets the icon kind.
**/
void
as_icon_set_kind (AsIcon *icon, AsIconKind kind)
{
AsIconPrivate *priv = GET_PRIVATE (icon);
priv->kind = kind;
}
/**
* as_icon_get_name:
* @icon: a #AsIcon instance.
*
* Returns: the stock name of the icon. In case the icon is not of kind
* "stock", the basename of the icon filename or URL is returned.
**/
const gchar*
as_icon_get_name (AsIcon *icon)
{
AsIconPrivate *priv = GET_PRIVATE (icon);
if (priv->name == NULL) {
if (priv->filename != NULL)
priv->name = g_path_get_basename (priv->filename);
else if (priv->url != NULL)
priv->name = as_filebasename_from_uri (priv->url);
}
return priv->name;
}
/**
* as_icon_set_name:
* @icon: a #AsIcon instance.
* @name: the icon stock name, e.g. "gwenview"
*
* Sets the stock name or basename to use for the icon.
**/
void
as_icon_set_name (AsIcon *icon, const gchar *name)
{
AsIconPrivate *priv = GET_PRIVATE (icon);
as_assign_string_safe (priv->name, name);
}
/**
* as_icon_get_url:
* @icon: a #AsIcon instance.
*
* Gets the icon URL, pointing at a remote location. HTTPS and FTP urls are allowed.
* This property is only set for icons of type %AS_ICON_KIND_REMOTE
*
* Returns: the URL
**/
const gchar*
as_icon_get_url (AsIcon *icon)
{
AsIconPrivate *priv = GET_PRIVATE (icon);
if (priv->url == NULL && priv->filename != NULL) {
priv->url = g_strdup_printf ("file://%s", priv->filename);
}
return priv->url;
}
/**
* as_icon_set_url:
* @icon: a #AsIcon instance.
* @url: the new icon URL.
*
* Sets the icon URL.
**/
void
as_icon_set_url (AsIcon *icon, const gchar *url)
{
AsIconPrivate *priv = GET_PRIVATE (icon);
as_assign_string_safe (priv->url, url);
}
/**
* as_icon_get_filename:
* @icon: a #AsIcon instance.
*
* Returns: The absolute path for the icon on disk.
* This is only set for icons of kind %AS_ICON_KIND_LOCAL or
* %AS_ICON_KIND_CACHED.
**/
const gchar*
as_icon_get_filename (AsIcon *icon)
{
AsIconPrivate *priv = GET_PRIVATE (icon);
return priv->filename;
}
/**
* as_icon_set_filename:
* @icon: a #AsIcon instance.
* @filename: the new icon URL.
*
* Sets the icon absolute filename.
**/
void
as_icon_set_filename (AsIcon *icon, const gchar *filename)
{
AsIconPrivate *priv = GET_PRIVATE (icon);
as_assign_string_safe (priv->filename, filename);
/* invalidate URL */
if (priv->url != NULL) {
g_free (g_steal_pointer (&priv->url));
}
}
/**
* as_icon_get_width:
* @icon: a #AsIcon instance.
*
* Returns: The icon width in pixels, or 0 if unknown.
**/
guint
as_icon_get_width (AsIcon *icon)
{
AsIconPrivate *priv = GET_PRIVATE (icon);
return priv->width;
}
/**
* as_icon_set_width:
* @icon: a #AsIcon instance.
* @width: the width in pixels.
*
* Sets the icon width.
**/
void
as_icon_set_width (AsIcon *icon, guint width)
{
AsIconPrivate *priv = GET_PRIVATE (icon);
priv->width = width;
}
/**
* as_icon_get_height:
* @icon: a #AsIcon instance.
*
* Returns: The icon height in pixels, or 0 if unknown.
**/
guint
as_icon_get_height (AsIcon *icon)
{
AsIconPrivate *priv = GET_PRIVATE (icon);
return priv->height;
}
/**
* as_icon_set_height:
* @icon: a #AsIcon instance.
* @height: the height in pixels.
*
* Sets the icon height.
**/
void
as_icon_set_height (AsIcon *icon, guint height)
{
AsIconPrivate *priv = GET_PRIVATE (icon);
priv->height = height;
}
/**
* as_icon_get_scale:
* @icon: a #AsIcon instance.
*
* Returns: The icon scaling factor.
*
* Since: 0.11.0
**/
guint
as_icon_get_scale (AsIcon *icon)
{
AsIconPrivate *priv = GET_PRIVATE (icon);
return priv->scale;
}
/**
* as_icon_set_scale:
* @icon: a #AsIcon instance.
* @scale: the icon scaling factor.
*
* Sets the icon scaling factor used for HiDPI displays.
*
* Since: 0.11.0
**/
void
as_icon_set_scale (AsIcon *icon, guint scale)
{
AsIconPrivate *priv = GET_PRIVATE (icon);
priv->scale = scale;
}
/**
* as_xml_icon_set_size_from_node:
*/
static void
as_xml_icon_set_size_from_node (xmlNode *node, AsIcon *icon)
{
gchar *val;
val = as_xml_get_prop_value (node, "width");
if (val != NULL) {
as_icon_set_width (icon, g_ascii_strtoll (val, NULL, 10));
g_free (val);
}
val = as_xml_get_prop_value (node, "height");
if (val != NULL) {
as_icon_set_height (icon, g_ascii_strtoll (val, NULL, 10));
g_free (val);
}
val = as_xml_get_prop_value (node, "scale");
if (val != NULL) {
as_icon_set_scale (icon, g_ascii_strtoll (val, NULL, 10));
g_free (val);
}
}
/**
* as_icon_load_from_xml:
* @icon: an #AsIcon
* @ctx: the AppStream document context.
* @node: the XML node.
* @error: a #GError.
*
* Loads data from an XML node.
**/
gboolean
as_icon_load_from_xml (AsIcon *icon, AsContext *ctx, xmlNode *node, GError **error)
{
AsIconPrivate *priv = GET_PRIVATE (icon);
g_autofree gchar *type_str = NULL;
g_autofree gchar *content = NULL;
content = as_xml_get_node_value (node);
if (content == NULL)
return FALSE;
type_str = as_xml_get_prop_value (node, "type");
if (g_strcmp0 (type_str, "stock") == 0) {
priv->kind = AS_ICON_KIND_STOCK;
as_icon_set_name (icon, content);
} else if (g_strcmp0 (type_str, "cached") == 0) {
priv->kind = AS_ICON_KIND_CACHED;
as_icon_set_filename (icon, content);
as_xml_icon_set_size_from_node (node, icon);
} else if (g_strcmp0 (type_str, "local") == 0) {
priv->kind = AS_ICON_KIND_LOCAL;
as_icon_set_filename (icon, content);
as_xml_icon_set_size_from_node (node, icon);
} else if (g_strcmp0 (type_str, "remote") == 0) {
priv->kind = AS_ICON_KIND_REMOTE;
if (!as_context_has_media_baseurl (ctx)) {
/* no baseurl, we can just set the value as URL */
as_icon_set_url (icon, content);
} else {
/* handle the media baseurl */
g_free (priv->url);
priv->url = g_build_filename (as_context_get_media_baseurl (ctx), content, NULL);
}
as_xml_icon_set_size_from_node (node, icon);
}
return TRUE;
}
/**
* as_icon_to_xml_node:
* @icon: an #AsIcon
* @ctx: the AppStream document context.
* @root: XML node to attach the new nodes to.
*
* Serializes the data to an XML node.
**/
void
as_icon_to_xml_node (AsIcon *icon, AsContext *ctx, xmlNode *root)
{
AsIconPrivate *priv = GET_PRIVATE (icon);
xmlNode *n;
const gchar *value;
if (priv->kind == AS_ICON_KIND_LOCAL)
value = as_icon_get_filename (icon);
else if (priv->kind == AS_ICON_KIND_REMOTE)
value = as_icon_get_url (icon);
else
value = as_icon_get_name (icon);
if (value == NULL)
return;
n = as_xml_add_text_node (root, "icon", value);
as_xml_add_text_prop (n, "type", as_icon_kind_to_string (priv->kind));
if (priv->kind != AS_ICON_KIND_STOCK) {
if (priv->width > 0) {
g_autofree gchar *size = NULL;
size = g_strdup_printf ("%i", as_icon_get_width (icon));
as_xml_add_text_prop (n, "width", size);
}
if (priv->height > 0) {
g_autofree gchar *size = NULL;
size = g_strdup_printf ("%i", as_icon_get_height (icon));
as_xml_add_text_prop (n, "height", size);
}
if (priv->scale > 1) {
g_autofree gchar *scale = NULL;
scale = g_strdup_printf ("%i", as_icon_get_scale (icon));
as_xml_add_text_prop (n, "scale", scale);
}
}
}
/**
* as_icon_new:
*
* Creates a new #AsIcon.
*
* Returns: (transfer full): a #AsIcon
**/
AsIcon*
as_icon_new (void)
{
AsIcon *icon;
icon = g_object_new (AS_TYPE_ICON, NULL);
return AS_ICON (icon);
}