1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
2  *
3  * Copyright (C) 2014-2016 Richard Hughes <richard@hughsie.com>
4  *
5  * SPDX-License-Identifier: LGPL-2.1+
6  */
7 
8 /**
9  * SECTION:as-suggest
10  * @short_description: Object representing a single suggest used in a screenshot.
11  * @include: appstream-glib.h
12  * @stability: Stable
13  *
14  * Screenshot may have multiple versions of an suggest in different resolutions
15  * or aspect ratios. This object allows access to the location and size of a
16  * single suggest.
17  *
18  * See also: #AsScreenshot
19  */
20 
21 #include "config.h"
22 
23 #include "as-suggest-private.h"
24 #include "as-node-private.h"
25 #include "as-ref-string.h"
26 #include "as-utils-private.h"
27 
28 typedef struct
29 {
30 	AsSuggestKind		 kind;
31 	GPtrArray		*ids;	/* utf8 */
32 } AsSuggestPrivate;
33 
G_DEFINE_TYPE_WITH_PRIVATE(AsSuggest,as_suggest,G_TYPE_OBJECT)34 G_DEFINE_TYPE_WITH_PRIVATE (AsSuggest, as_suggest, G_TYPE_OBJECT)
35 
36 #define GET_PRIVATE(o) (as_suggest_get_instance_private (o))
37 
38 static void
39 as_suggest_finalize (GObject *object)
40 {
41 	AsSuggest *suggest = AS_SUGGEST (object);
42 	AsSuggestPrivate *priv = GET_PRIVATE (suggest);
43 
44 	g_ptr_array_unref (priv->ids);
45 
46 	G_OBJECT_CLASS (as_suggest_parent_class)->finalize (object);
47 }
48 
49 static void
as_suggest_init(AsSuggest * suggest)50 as_suggest_init (AsSuggest *suggest)
51 {
52 	AsSuggestPrivate *priv = GET_PRIVATE (suggest);
53 	priv->ids = g_ptr_array_new_with_free_func ((GDestroyNotify) as_ref_string_unref);
54 }
55 
56 static void
as_suggest_class_init(AsSuggestClass * klass)57 as_suggest_class_init (AsSuggestClass *klass)
58 {
59 	GObjectClass *object_class = G_OBJECT_CLASS (klass);
60 	object_class->finalize = as_suggest_finalize;
61 }
62 
63 
64 /**
65  * as_suggest_kind_from_string:
66  * @kind: the string.
67  *
68  * Converts the text representation to an enumerated value.
69  *
70  * Returns: (transfer full): a #AsSuggestKind, or %AS_SUGGEST_KIND_UNKNOWN for unknown.
71  *
72  * Since: 0.6.1
73  **/
74 AsSuggestKind
as_suggest_kind_from_string(const gchar * kind)75 as_suggest_kind_from_string (const gchar *kind)
76 {
77 	if (g_strcmp0 (kind, "upstream") == 0)
78 		return AS_SUGGEST_KIND_UPSTREAM;
79 	if (g_strcmp0 (kind, "heuristic") == 0)
80 		return AS_SUGGEST_KIND_HEURISTIC;
81 	return AS_SUGGEST_KIND_UNKNOWN;
82 }
83 
84 /**
85  * as_suggest_kind_to_string:
86  * @kind: the #AsSuggestKind.
87  *
88  * Converts the enumerated value to an text representation.
89  *
90  * Returns: string version of @kind
91  *
92  * Since: 0.6.1
93  **/
94 const gchar *
as_suggest_kind_to_string(AsSuggestKind kind)95 as_suggest_kind_to_string (AsSuggestKind kind)
96 {
97 	if (kind == AS_SUGGEST_KIND_UPSTREAM)
98 		return "upstream";
99 	if (kind == AS_SUGGEST_KIND_HEURISTIC)
100 		return "heuristic";
101 	return NULL;
102 }
103 
104 /**
105  * as_suggest_get_ids:
106  * @suggest: a #AsSuggest instance.
107  *
108  * Gets the suggest ids if set.
109  *
110  * Returns: (transfer none) (element-type utf8): the #GPtrArray, or %NULL
111  *
112  * Since: 0.6.1
113  **/
114 GPtrArray *
as_suggest_get_ids(AsSuggest * suggest)115 as_suggest_get_ids (AsSuggest *suggest)
116 {
117 	AsSuggestPrivate *priv = GET_PRIVATE (suggest);
118 	g_return_val_if_fail (AS_IS_SUGGEST (suggest), NULL);
119 	return priv->ids;
120 }
121 
122 /**
123  * as_suggest_get_kind:
124  * @suggest: a #AsSuggest instance.
125  *
126  * Gets the suggest kind.
127  *
128  * Returns: the #AsSuggestKind
129  *
130  * Since: 0.6.1
131  **/
132 AsSuggestKind
as_suggest_get_kind(AsSuggest * suggest)133 as_suggest_get_kind (AsSuggest *suggest)
134 {
135 	AsSuggestPrivate *priv = GET_PRIVATE (suggest);
136 	g_return_val_if_fail (AS_IS_SUGGEST (suggest), AS_SUGGEST_KIND_UNKNOWN);
137 	return priv->kind;
138 }
139 
140 /**
141  * as_suggest_set_kind:
142  * @suggest: a #AsSuggest instance.
143  * @kind: the #AsSuggestKind, e.g. %AS_SUGGEST_KIND_UPSTREAM.
144  *
145  * Sets the suggest kind.
146  *
147  * Since: 0.6.1
148  **/
149 void
as_suggest_set_kind(AsSuggest * suggest,AsSuggestKind kind)150 as_suggest_set_kind (AsSuggest *suggest, AsSuggestKind kind)
151 {
152 	AsSuggestPrivate *priv = GET_PRIVATE (suggest);
153 	g_return_if_fail (AS_IS_SUGGEST (suggest));
154 	priv->kind = kind;
155 }
156 
157 /**
158  * as_suggest_add_id:
159  * @suggest: a #AsSuggest instance.
160  * @id: an application ID, e.g. `gimp.desktop`
161  *
162  * Add a the suggest application ID.
163  *
164  * Since: 0.6.1
165  **/
166 void
as_suggest_add_id(AsSuggest * suggest,const gchar * id)167 as_suggest_add_id (AsSuggest *suggest, const gchar *id)
168 {
169 	AsSuggestPrivate *priv = GET_PRIVATE (suggest);
170 	g_return_if_fail (AS_IS_SUGGEST (suggest));
171 	g_ptr_array_add (priv->ids, as_ref_string_new (id));
172 }
173 
174 /**
175  * as_suggest_node_insert: (skip)
176  * @suggest: a #AsSuggest instance.
177  * @parent: the parent #GNode to use..
178  * @ctx: the #AsNodeContext
179  *
180  * Inserts the suggest into the DOM tree.
181  *
182  * Returns: (transfer none): A populated #GNode
183  *
184  * Since: 0.6.1
185  **/
186 GNode *
as_suggest_node_insert(AsSuggest * suggest,GNode * parent,AsNodeContext * ctx)187 as_suggest_node_insert (AsSuggest *suggest, GNode *parent, AsNodeContext *ctx)
188 {
189 	AsSuggestPrivate *priv = GET_PRIVATE (suggest);
190 	GNode *n;
191 	guint i;
192 
193 	g_return_val_if_fail (AS_IS_SUGGEST (suggest), NULL);
194 
195 	n = as_node_insert (parent, "suggests", NULL,
196 			    AS_NODE_INSERT_FLAG_NONE,
197 			    NULL);
198 	if (priv->kind != AS_SUGGEST_KIND_UNKNOWN) {
199 		as_node_add_attribute (n,
200 				       "type",
201 				       as_suggest_kind_to_string (priv->kind));
202 	}
203 	for (i = 0; i < priv->ids->len; i++) {
204 		const gchar *id = g_ptr_array_index (priv->ids, i);
205 		as_node_insert (n, "id", id,
206 				AS_NODE_INSERT_FLAG_NONE,
207 				NULL);
208 	}
209 	return n;
210 }
211 
212 /**
213  * as_suggest_node_parse:
214  * @suggest: a #AsSuggest instance.
215  * @node: a #GNode.
216  * @ctx: a #AsNodeContext.
217  * @error: A #GError or %NULL.
218  *
219  * Populates the object from a DOM node.
220  *
221  * Returns: %TRUE for success
222  *
223  * Since: 0.6.1
224  **/
225 gboolean
as_suggest_node_parse(AsSuggest * suggest,GNode * node,AsNodeContext * ctx,GError ** error)226 as_suggest_node_parse (AsSuggest *suggest, GNode *node,
227 		       AsNodeContext *ctx, GError **error)
228 {
229 	AsNode *c;
230 	const gchar *tmp;
231 
232 	tmp = as_node_get_attribute (node, "type");
233 	if (tmp != NULL)
234 		as_suggest_set_kind (suggest, as_suggest_kind_from_string (tmp));
235 	for (c = node->children; c != NULL; c = c->next) {
236 		if (as_node_get_tag (c) == AS_TAG_ID)
237 			as_suggest_add_id (suggest, as_node_get_data (c));
238 	}
239 	return TRUE;
240 }
241 
242 /**
243  * as_suggest_node_parse_dep11:
244  * @suggest: a #AsSuggest instance.
245  * @node: a #GNode.
246  * @ctx: a #AsNodeContext.
247  * @error: A #GError or %NULL.
248  *
249  * Populates the object from a DEP-11 node.
250  *
251  * Returns: %TRUE for success
252  *
253  * Since: 0.6.1
254  **/
255 gboolean
as_suggest_node_parse_dep11(AsSuggest * im,GNode * node,AsNodeContext * ctx,GError ** error)256 as_suggest_node_parse_dep11 (AsSuggest *im, GNode *node,
257 			     AsNodeContext *ctx, GError **error)
258 {
259 	return TRUE;
260 }
261 
262 /**
263  * as_suggest_new:
264  *
265  * Creates a new #AsSuggest.
266  *
267  * Returns: (transfer full): a #AsSuggest
268  *
269  * Since: 0.6.1
270  **/
271 AsSuggest *
as_suggest_new(void)272 as_suggest_new (void)
273 {
274 	AsSuggest *suggest;
275 	suggest = g_object_new (AS_TYPE_SUGGEST, NULL);
276 	return AS_SUGGEST (suggest);
277 }
278 
279