libpurple/purpleavatar.c

changeset 43301
0e43dc8462e8
parent 43300
0604c6839974
child 43302
e7b0bbfec5d5
equal deleted inserted replaced
43300:0604c6839974 43301:0e43dc8462e8
1 /*
2 * Purple - Internet Messaging Library
3 * Copyright (C) Pidgin Developers <devel@pidgin.im>
4 *
5 * Purple is the legal property of its developers, whose names are too numerous
6 * to list here. Please refer to the COPYRIGHT file distributed with this
7 * source distribution.
8 *
9 * This library is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by the Free
11 * Software Foundation; either version 2 of the License, or (at your option)
12 * any later version.
13 *
14 * This library is distributed in the hope that it will be useful, but WITHOUT
15 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
17 * more details.
18 *
19 * You should have received a copy of the GNU General Public License along with
20 * this library; if not, see <https://www.gnu.org/licenses/>.
21 */
22
23 #include "purpleavatar.h"
24
25 struct _PurpleAvatar {
26 GObject parent;
27
28 char *filename;
29
30 GdkPixbuf *pixbuf;
31
32 gboolean animated;
33 GdkPixbufAnimation *animation;
34
35 PurpleTags *tags;
36 };
37
38 enum {
39 PROP_0,
40 PROP_FILENAME,
41 PROP_PIXBUF,
42 PROP_ANIMATED,
43 PROP_ANIMATION,
44 PROP_TAGS,
45 N_PROPERTIES,
46 };
47 static GParamSpec *properties[N_PROPERTIES] = {NULL, };
48
49 /******************************************************************************
50 * Helpers
51 *****************************************************************************/
52 static void
53 purple_avatar_set_filename(PurpleAvatar *avatar, const char *filename) {
54 g_return_if_fail(PURPLE_IS_AVATAR(avatar));
55
56 if(g_set_str(&avatar->filename, filename)) {
57 g_object_notify_by_pspec(G_OBJECT(avatar), properties[PROP_FILENAME]);
58 }
59 }
60
61 static PurpleAvatar *
62 purple_avatar_new_common(const char *filename, GdkPixbufAnimation *animation) {
63 PurpleAvatar *avatar = NULL;
64
65 avatar = g_object_new(PURPLE_TYPE_AVATAR, "filename", filename, NULL);
66
67 if(gdk_pixbuf_animation_is_static_image(animation)) {
68 /* If we loaded a static image, grab the static image and set it to our
69 * pixbuf member, clear the animation, and return the new avatar.
70 */
71
72 avatar->pixbuf = gdk_pixbuf_animation_get_static_image(animation);
73 g_object_ref(avatar->pixbuf);
74
75 g_clear_object(&animation);
76 } else {
77 /* If we did load an animation, set the appropriate properties and
78 * return the avatar.
79 */
80 avatar->animated = TRUE;
81 avatar->animation = animation;
82 }
83
84 return avatar;
85 }
86
87 /******************************************************************************
88 * GObject Implementation
89 *****************************************************************************/
90 G_DEFINE_FINAL_TYPE(PurpleAvatar, purple_avatar, G_TYPE_OBJECT)
91
92 static void
93 purple_avatar_get_property(GObject *obj, guint param_id, GValue *value,
94 GParamSpec *pspec)
95 {
96 PurpleAvatar *avatar = PURPLE_AVATAR(obj);
97
98 switch(param_id) {
99 case PROP_FILENAME:
100 g_value_set_string(value, purple_avatar_get_filename(avatar));
101 break;
102 case PROP_PIXBUF:
103 g_value_set_object(value, purple_avatar_get_pixbuf(avatar));
104 break;
105 case PROP_ANIMATED:
106 g_value_set_boolean(value, purple_avatar_get_animated(avatar));
107 break;
108 case PROP_ANIMATION:
109 g_value_set_object(value, purple_avatar_get_animation(avatar));
110 break;
111 case PROP_TAGS:
112 g_value_set_object(value, purple_avatar_get_tags(avatar));
113 break;
114 default:
115 G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
116 break;
117 }
118 }
119
120 static void
121 purple_avatar_set_property(GObject *obj, guint param_id, const GValue *value,
122 GParamSpec *pspec)
123 {
124 PurpleAvatar *avatar = PURPLE_AVATAR(obj);
125
126 switch(param_id) {
127 case PROP_FILENAME:
128 purple_avatar_set_filename(avatar, g_value_get_string(value));
129 break;
130 default:
131 G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
132 break;
133 }
134 }
135
136 static void
137 purple_avatar_finalize(GObject *obj) {
138 PurpleAvatar *avatar = PURPLE_AVATAR(obj);
139
140 g_clear_pointer(&avatar->filename, g_free);
141 g_clear_object(&avatar->pixbuf);
142 g_clear_object(&avatar->animation);
143 g_clear_object(&avatar->tags);
144
145 G_OBJECT_CLASS(purple_avatar_parent_class)->finalize(obj);
146 }
147
148 static void
149 purple_avatar_init(PurpleAvatar *avatar) {
150 avatar->tags = purple_tags_new();
151 }
152
153 static void
154 purple_avatar_class_init(PurpleAvatarClass *klass) {
155 GObjectClass *obj_class = G_OBJECT_CLASS(klass);
156
157 obj_class->finalize = purple_avatar_finalize;
158 obj_class->get_property = purple_avatar_get_property;
159 obj_class->set_property = purple_avatar_set_property;
160
161 /**
162 * PurpleAvatar:filename:
163 *
164 * The filename that this avatar was created from.
165 *
166 * Since: 3.0
167 */
168 properties[PROP_FILENAME] = g_param_spec_string(
169 "filename", NULL, NULL,
170 NULL,
171 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
172
173 /**
174 * PurpleAvatar:pixbuf:
175 *
176 * The [class@GdkPixbuf.Pixbuf] of the avatar. If
177 * [property@Purple.Avatar:animated] is %TRUE, this will be a static frame
178 * from the animation.
179 *
180 * Since: 3.0
181 */
182 properties[PROP_PIXBUF] = g_param_spec_object(
183 "pixbuf", NULL, NULL,
184 GDK_TYPE_PIXBUF,
185 G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
186
187 /**
188 * PurpleAvatar:animated:
189 *
190 * Whether or not this avatar is animated.
191 *
192 * Since: 3.0
193 */
194 properties[PROP_ANIMATED] = g_param_spec_boolean(
195 "animated", NULL, NULL,
196 FALSE,
197 G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
198
199 /**
200 * PurpleAvatar:animation:
201 *
202 * The [class@GdkPixbuf.PixbufAnimation] if
203 * [property@Purple.Avatar:animated] is %TRUE.
204 *
205 * Since: 3.0
206 */
207 properties[PROP_ANIMATION] = g_param_spec_object(
208 "animation", NULL, NULL,
209 GDK_TYPE_PIXBUF_ANIMATION,
210 G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
211
212 /**
213 * PurpleAvatar:tags:
214 *
215 * The [class@Purple.Tags] for the avatar.
216 *
217 * Since: 3.0
218 */
219 properties[PROP_TAGS] = g_param_spec_object(
220 "tags", NULL, NULL,
221 PURPLE_TYPE_TAGS,
222 G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
223
224 g_object_class_install_properties(obj_class, N_PROPERTIES, properties);
225 }
226
227 /******************************************************************************
228 * Public API
229 *****************************************************************************/
230 PurpleAvatar *
231 purple_avatar_new_from_filename(const char *filename, GError **error) {
232 GdkPixbufAnimation *animation = NULL;
233 GError *local_error = NULL;
234
235 g_return_val_if_fail(filename != NULL, NULL);
236
237 animation = gdk_pixbuf_animation_new_from_file(filename, &local_error);
238 if(!GDK_IS_PIXBUF_ANIMATION(animation) || local_error != NULL) {
239 g_clear_object(&animation);
240
241 g_propagate_error(error, local_error);
242
243 return NULL;
244 }
245
246 return purple_avatar_new_common(filename, animation);
247 }
248
249 PurpleAvatar *
250 purple_avatar_new_from_resource(const char *resource_path, GError **error) {
251 GdkPixbufAnimation *animation = NULL;
252 GError *local_error = NULL;
253
254 g_return_val_if_fail(resource_path != NULL, NULL);
255
256 animation = gdk_pixbuf_animation_new_from_resource(resource_path,
257 &local_error);
258 if(!GDK_IS_PIXBUF_ANIMATION(animation) || local_error != NULL) {
259 g_clear_object(&animation);
260
261 g_propagate_error(error, local_error);
262
263 return NULL;
264 }
265
266 return purple_avatar_new_common(NULL, animation);
267 }
268
269 const char *
270 purple_avatar_get_filename(PurpleAvatar *avatar) {
271 g_return_val_if_fail(PURPLE_IS_AVATAR(avatar), NULL);
272
273 return avatar->filename;
274 }
275
276 GdkPixbuf *
277 purple_avatar_get_pixbuf(PurpleAvatar *avatar) {
278 g_return_val_if_fail(PURPLE_IS_AVATAR(avatar), NULL);
279
280 if(avatar->animated) {
281 return gdk_pixbuf_animation_get_static_image(avatar->animation);
282 }
283
284 return avatar->pixbuf;
285 }
286
287 gboolean
288 purple_avatar_get_animated(PurpleAvatar *avatar) {
289 g_return_val_if_fail(PURPLE_IS_AVATAR(avatar), FALSE);
290
291 return avatar->animated;
292 }
293
294 GdkPixbufAnimation *
295 purple_avatar_get_animation(PurpleAvatar *avatar) {
296 g_return_val_if_fail(PURPLE_IS_AVATAR(avatar), NULL);
297
298 return avatar->animation;
299 }
300
301 PurpleTags *
302 purple_avatar_get_tags(PurpleAvatar *avatar) {
303 g_return_val_if_fail(PURPLE_IS_AVATAR(avatar), NULL);
304
305 return avatar->tags;
306 }

mercurial