[kdbus] Add README.md file
[platform/upstream/glib.git] / gio / gfileicon.c
1 /* GIO - GLib Input, Output and Streaming Library
2  * 
3  * Copyright (C) 2006-2007 Red Hat, Inc.
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General
16  * Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
17  *
18  * Author: Alexander Larsson <alexl@redhat.com>
19  */
20
21 #include "config.h"
22
23 #include "gfileicon.h"
24 #include "gfile.h"
25 #include "gicon.h"
26 #include "glibintl.h"
27 #include "gloadableicon.h"
28 #include "ginputstream.h"
29 #include "gtask.h"
30 #include "gioerror.h"
31
32
33 /**
34  * SECTION:gfileicon
35  * @short_description: Icons pointing to an image file
36  * @include: gio/gio.h
37  * @see_also: #GIcon, #GLoadableIcon
38  * 
39  * #GFileIcon specifies an icon by pointing to an image file
40  * to be used as icon.
41  * 
42  **/
43
44 static void g_file_icon_icon_iface_init          (GIconIface          *iface);
45 static void g_file_icon_loadable_icon_iface_init (GLoadableIconIface  *iface);
46 static void g_file_icon_load_async               (GLoadableIcon       *icon,
47                                                   int                  size,
48                                                   GCancellable        *cancellable,
49                                                   GAsyncReadyCallback  callback,
50                                                   gpointer             user_data);
51
52 struct _GFileIcon
53 {
54   GObject parent_instance;
55
56   GFile *file;
57 };
58
59 struct _GFileIconClass
60 {
61   GObjectClass parent_class;
62 };
63
64 enum
65 {
66   PROP_0,
67   PROP_FILE
68 };
69
70 G_DEFINE_TYPE_WITH_CODE (GFileIcon, g_file_icon, G_TYPE_OBJECT,
71                          G_IMPLEMENT_INTERFACE (G_TYPE_ICON,
72                                                 g_file_icon_icon_iface_init)
73                          G_IMPLEMENT_INTERFACE (G_TYPE_LOADABLE_ICON,
74                                                 g_file_icon_loadable_icon_iface_init))
75
76 static void
77 g_file_icon_get_property (GObject    *object,
78                           guint       prop_id,
79                           GValue     *value,
80                           GParamSpec *pspec)
81 {
82   GFileIcon *icon = G_FILE_ICON (object);
83
84   switch (prop_id)
85     {
86       case PROP_FILE:
87         g_value_set_object (value, icon->file);
88         break;
89
90       default:
91         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
92     }
93 }
94
95 static void
96 g_file_icon_set_property (GObject      *object,
97                           guint         prop_id,
98                           const GValue *value,
99                           GParamSpec   *pspec)
100 {
101   GFileIcon *icon = G_FILE_ICON (object);
102
103   switch (prop_id)
104     {
105       case PROP_FILE:
106         icon->file = G_FILE (g_value_dup_object (value));
107         break;
108
109       default:
110         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
111     }
112 }
113
114 static void
115 g_file_icon_finalize (GObject *object)
116 {
117   GFileIcon *icon;
118
119   icon = G_FILE_ICON (object);
120
121   if (icon->file)
122     g_object_unref (icon->file);
123
124   G_OBJECT_CLASS (g_file_icon_parent_class)->finalize (object);
125 }
126
127 static void
128 g_file_icon_class_init (GFileIconClass *klass)
129 {
130   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
131   
132   gobject_class->get_property = g_file_icon_get_property;
133   gobject_class->set_property = g_file_icon_set_property;
134   gobject_class->finalize = g_file_icon_finalize;
135
136   /**
137    * GFileIcon:file:
138    *
139    * The file containing the icon.
140    */
141   g_object_class_install_property (gobject_class, PROP_FILE,
142                                    g_param_spec_object ("file",
143                                                         P_("file"),
144                                                         P_("The file containing the icon"),
145                                                         G_TYPE_FILE,
146                                                         G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_BLURB | G_PARAM_STATIC_NICK));
147 }
148
149 static void
150 g_file_icon_init (GFileIcon *file)
151 {
152 }
153
154 /**
155  * g_file_icon_new:
156  * @file: a #GFile.
157  * 
158  * Creates a new icon for a file.
159  * 
160  * Returns: (transfer full) (type GFileIcon): a #GIcon for the given
161  *   @file, or %NULL on error.
162  **/
163 GIcon *
164 g_file_icon_new (GFile *file)
165 {
166   g_return_val_if_fail (G_IS_FILE (file), NULL);
167
168   return G_ICON (g_object_new (G_TYPE_FILE_ICON, "file", file, NULL));
169 }
170
171 /**
172  * g_file_icon_get_file:
173  * @icon: a #GIcon.
174  * 
175  * Gets the #GFile associated with the given @icon.
176  * 
177  * Returns: (transfer none): a #GFile, or %NULL.
178  **/
179 GFile *
180 g_file_icon_get_file (GFileIcon *icon)
181 {
182   g_return_val_if_fail (G_IS_FILE_ICON (icon), NULL);
183
184   return icon->file;
185 }
186
187 static guint
188 g_file_icon_hash (GIcon *icon)
189 {
190   GFileIcon *file_icon = G_FILE_ICON (icon);
191
192   return g_file_hash (file_icon->file);
193 }
194
195 static gboolean
196 g_file_icon_equal (GIcon *icon1,
197                    GIcon *icon2)
198 {
199   GFileIcon *file1 = G_FILE_ICON (icon1);
200   GFileIcon *file2 = G_FILE_ICON (icon2);
201   
202   return g_file_equal (file1->file, file2->file);
203 }
204
205 static gboolean
206 g_file_icon_to_tokens (GIcon *icon,
207                        GPtrArray *tokens,
208                        gint  *out_version)
209 {
210   GFileIcon *file_icon = G_FILE_ICON (icon);
211
212   g_return_val_if_fail (out_version != NULL, FALSE);
213
214   *out_version = 0;
215
216   g_ptr_array_add (tokens, g_file_get_uri (file_icon->file));
217   return TRUE;
218 }
219
220 static GIcon *
221 g_file_icon_from_tokens (gchar  **tokens,
222                          gint     num_tokens,
223                          gint     version,
224                          GError **error)
225 {
226   GIcon *icon;
227   GFile *file;
228
229   icon = NULL;
230
231   if (version != 0)
232     {
233       g_set_error (error,
234                    G_IO_ERROR,
235                    G_IO_ERROR_INVALID_ARGUMENT,
236                    _("Can't handle version %d of GFileIcon encoding"),
237                    version);
238       goto out;
239     }
240
241   if (num_tokens != 1)
242     {
243       g_set_error_literal (error,
244                            G_IO_ERROR,
245                            G_IO_ERROR_INVALID_ARGUMENT,
246                            _("Malformed input data for GFileIcon"));
247       goto out;
248     }
249
250   file = g_file_new_for_uri (tokens[0]);
251   icon = g_file_icon_new (file);
252   g_object_unref (file);
253
254  out:
255   return icon;
256 }
257
258 static GVariant *
259 g_file_icon_serialize (GIcon *icon)
260 {
261   GFileIcon *file_icon = G_FILE_ICON (icon);
262
263   return g_variant_new ("(sv)", "file", g_variant_new_take_string (g_file_get_uri (file_icon->file)));
264 }
265
266 static void
267 g_file_icon_icon_iface_init (GIconIface *iface)
268 {
269   iface->hash = g_file_icon_hash;
270   iface->equal = g_file_icon_equal;
271   iface->to_tokens = g_file_icon_to_tokens;
272   iface->from_tokens = g_file_icon_from_tokens;
273   iface->serialize = g_file_icon_serialize;
274 }
275
276
277 static GInputStream *
278 g_file_icon_load (GLoadableIcon  *icon,
279                   int            size,
280                   char          **type,
281                   GCancellable   *cancellable,
282                   GError        **error)
283 {
284   GFileInputStream *stream;
285   GFileIcon *file_icon = G_FILE_ICON (icon);
286
287   stream = g_file_read (file_icon->file,
288                         cancellable,
289                         error);
290
291   if (stream && type)
292     *type = NULL;
293   
294   return G_INPUT_STREAM (stream);
295 }
296
297 static void
298 load_async_callback (GObject      *source_object,
299                      GAsyncResult *res,
300                      gpointer      user_data)
301 {
302   GFileInputStream *stream;
303   GError *error = NULL;
304   GTask *task = user_data;
305
306   stream = g_file_read_finish (G_FILE (source_object), res, &error);
307   if (stream == NULL)
308     g_task_return_error (task, error);
309   else
310     g_task_return_pointer (task, stream, g_object_unref);
311   g_object_unref (task);
312 }
313
314 static void
315 g_file_icon_load_async (GLoadableIcon       *icon,
316                         int                  size,
317                         GCancellable        *cancellable,
318                         GAsyncReadyCallback  callback,
319                         gpointer             user_data)
320 {
321   GFileIcon *file_icon = G_FILE_ICON (icon);
322   GTask *task;
323
324   task = g_task_new (icon, cancellable, callback, user_data);
325   
326   g_file_read_async (file_icon->file, 0,
327                      cancellable,
328                      load_async_callback, task);
329 }
330
331 static GInputStream *
332 g_file_icon_load_finish (GLoadableIcon  *icon,
333                          GAsyncResult   *res,
334                          char          **type,
335                          GError        **error)
336 {
337   g_return_val_if_fail (g_task_is_valid (res, icon), NULL);
338
339   if (type)
340     *type = NULL;
341   
342   return g_task_propagate_pointer (G_TASK (res), error);
343 }
344
345 static void
346 g_file_icon_loadable_icon_iface_init (GLoadableIconIface *iface)
347 {
348   iface->load = g_file_icon_load;
349   iface->load_async = g_file_icon_load_async;
350   iface->load_finish = g_file_icon_load_finish;
351 }