6e46e7f95362f3cfa0433cde46d02a5775314c36
[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, write to the
17  * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
18  * Boston, MA 02111-1307, USA.
19  *
20  * Author: Alexander Larsson <alexl@redhat.com>
21  */
22
23 #include <config.h>
24
25 #include "gfileicon.h"
26 #include "gsimpleasyncresult.h"
27
28 static void g_file_icon_icon_iface_init          (GIconIface          *iface);
29 static void g_file_icon_loadable_icon_iface_init (GLoadableIconIface  *iface);
30 static void g_file_icon_load_async               (GLoadableIcon       *icon,
31                                                   int                  size,
32                                                   GCancellable        *cancellable,
33                                                   GAsyncReadyCallback  callback,
34                                                   gpointer             user_data);
35
36 struct _GFileIcon
37 {
38   GObject parent_instance;
39
40   GFile *file;
41 };
42
43 struct _GFileIconClass
44 {
45   GObjectClass parent_class;
46 };
47
48 G_DEFINE_TYPE_WITH_CODE (GFileIcon, g_file_icon, G_TYPE_OBJECT,
49                          G_IMPLEMENT_INTERFACE (G_TYPE_ICON,
50                                                 g_file_icon_icon_iface_init);
51                          G_IMPLEMENT_INTERFACE (G_TYPE_LOADABLE_ICON,
52                                                 g_file_icon_loadable_icon_iface_init);
53                          )
54   
55 static void
56 g_file_icon_finalize (GObject *object)
57 {
58   GFileIcon *icon;
59
60   icon = G_FILE_ICON (object);
61
62   g_object_unref (icon->file);
63   
64   if (G_OBJECT_CLASS (g_file_icon_parent_class)->finalize)
65     (*G_OBJECT_CLASS (g_file_icon_parent_class)->finalize) (object);
66 }
67
68 static void
69 g_file_icon_class_init (GFileIconClass *klass)
70 {
71   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
72   
73   gobject_class->finalize = g_file_icon_finalize;
74 }
75
76 static void
77 g_file_icon_init (GFileIcon *file)
78 {
79 }
80
81 /**
82  * g_file_icon_new:
83  * @file:
84  * 
85  * Returns: 
86  **/
87 GIcon *
88 g_file_icon_new (GFile *file)
89 {
90   GFileIcon *icon;
91
92   g_return_val_if_fail (G_IS_FILE (file), NULL);
93
94   icon = g_object_new (G_TYPE_FILE_ICON, NULL);
95   icon->file = g_object_ref (file);
96   
97   return G_ICON (icon);
98 }
99
100 /**
101  * g_file_icon_get_file:
102  * @icon:
103  * 
104  * Returns: 
105  **/
106 GFile *
107 g_file_icon_get_file (GFileIcon *icon)
108 {
109   g_return_val_if_fail (G_IS_FILE_ICON (icon), NULL);
110
111   return icon->file;
112 }
113
114 static guint
115 g_file_icon_hash (GIcon *icon)
116 {
117   GFileIcon *file_icon = G_FILE_ICON (icon);
118
119   return g_file_hash (file_icon->file);
120 }
121
122 static gboolean
123 g_file_icon_equal (GIcon *icon1,
124                    GIcon *icon2)
125 {
126   GFileIcon *file1 = G_FILE_ICON (icon1);
127   GFileIcon *file2 = G_FILE_ICON (icon2);
128   
129   return g_file_equal (file1->file, file2->file);
130 }
131
132
133 static void
134 g_file_icon_icon_iface_init (GIconIface *iface)
135 {
136   iface->hash = g_file_icon_hash;
137   iface->equal = g_file_icon_equal;
138 }
139
140
141 static GInputStream *
142 g_file_icon_load (GLoadableIcon        *icon,
143                   int                   size,
144                   char                **type,
145                   GCancellable         *cancellable,
146                   GError              **error)
147 {
148   GFileInputStream *stream;
149   GFileIcon *file_icon = G_FILE_ICON (icon);
150
151   stream = g_file_read (file_icon->file,
152                         cancellable,
153                         error);
154   
155   return G_INPUT_STREAM (stream);
156 }
157
158 typedef struct {
159   GLoadableIcon *icon;
160   GAsyncReadyCallback callback;
161   gpointer user_data;
162 } LoadData;
163
164 static void
165 load_data_free (LoadData *data)
166 {
167   g_object_unref (data->icon);
168   g_free (data);
169 }
170
171 static void
172 load_async_callback (GObject *source_object,
173                      GAsyncResult *res,
174                      gpointer user_data)
175 {
176   GFileInputStream *stream;
177   GError *error = NULL;
178   GSimpleAsyncResult *simple;
179   LoadData *data = user_data;
180
181   stream = g_file_read_finish (G_FILE (source_object), res, &error);
182   
183   if (stream == NULL)
184     {
185       simple = g_simple_async_result_new_from_error (G_OBJECT (data->icon),
186                                                      data->callback,
187                                                      data->user_data,
188                                                      error);
189       g_error_free (error);
190     }
191   else
192     {
193       simple = g_simple_async_result_new (G_OBJECT (data->icon),
194                                           data->callback,
195                                           data->user_data,
196                                           g_file_icon_load_async);
197       
198       g_simple_async_result_set_op_res_gpointer (simple,
199                                                  stream,
200                                                  g_object_unref);
201   }
202
203
204   g_simple_async_result_complete (simple);
205   
206   load_data_free (data);
207 }
208
209 static void
210 g_file_icon_load_async  (GLoadableIcon        *icon,
211                          int                   size,
212                          GCancellable         *cancellable,
213                          GAsyncReadyCallback   callback,
214                          gpointer              user_data)
215 {
216   GFileIcon *file_icon = G_FILE_ICON (icon);
217   LoadData *data;
218
219   data = g_new0 (LoadData, 1);
220   data->icon = g_object_ref (icon);
221   data->callback = callback;
222   data->user_data = user_data;
223   
224   g_file_read_async (file_icon->file, 0,
225                      cancellable,
226                      load_async_callback, data);
227   
228 }
229
230 static GInputStream *
231 g_file_icon_load_finish (GLoadableIcon        *icon,
232                          GAsyncResult         *res,
233                          char                **type,
234                          GError              **error)
235 {
236   GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
237   gpointer op;
238
239   g_assert (g_simple_async_result_get_source_tag (simple) == g_file_icon_load_async);
240
241   if (type)
242     *type = NULL;
243   
244   op = g_simple_async_result_get_op_res_gpointer (simple);
245   if (op)
246     return g_object_ref (op);
247   
248   return NULL;
249 }
250
251 static void
252 g_file_icon_loadable_icon_iface_init (GLoadableIconIface *iface)
253 {
254   iface->load = g_file_icon_load;
255   iface->load_async = g_file_icon_load_async;
256   iface->load_finish = g_file_icon_load_finish;
257 }