]> Pileus Git - ~andy/gtk/blob - gtk/gtkfilesystem.c
Initial revision
[~andy/gtk] / gtk / gtkfilesystem.c
1 /* GTK - The GIMP Toolkit
2  * gtkfilesystem.c: Abstract file system interfaces
3  * Copyright (C) 2003, 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 Public
16  * 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
21 #include "gtkfilesystem.h"
22
23 struct _GtkFileInfo
24 {
25   GtkFileTime modification_time;
26   gint64 size;
27   gchar *display_name;
28   gchar *mime_type;
29   GdkPixbuf *icon;
30   guint is_folder : 1;
31   guint is_hidden : 1;
32 };
33
34 static void gtk_file_system_base_init (gpointer g_class);
35 static void gtk_file_folder_base_init (gpointer g_class);
36
37 GQuark
38 gtk_file_system_error_quark (void)
39 {
40   static GQuark quark = 0;
41   if (quark == 0)
42     quark = g_quark_from_static_string ("gtk-file-system-error-quark");
43   return quark;
44 }
45
46 /*****************************************
47  *             GtkFileInfo               *
48  *****************************************/
49 GType
50 gtk_file_info_get_type (void)
51 {
52   static GType our_type = 0;
53   
54   if (our_type == 0)
55     our_type = g_boxed_type_register_static ("GtkFileInfo",
56                                              (GBoxedCopyFunc) gtk_file_info_copy,
57                                              (GBoxedFreeFunc) gtk_file_info_free);
58
59   return our_type;
60 }
61
62 GtkFileInfo *
63 gtk_file_info_new  (void)
64 {
65   GtkFileInfo *info;
66   
67   info = g_new0 (GtkFileInfo, 1);
68
69   return info;
70 }
71
72 GtkFileInfo *
73 gtk_file_info_copy (GtkFileInfo *info)
74 {
75   GtkFileInfo *new_info;
76
77   g_return_val_if_fail (info != NULL, NULL);
78
79   new_info = g_memdup (info, sizeof (GtkFileInfo));
80   if (new_info->display_name)
81     new_info->display_name = g_strdup (new_info->display_name);
82   if (new_info->mime_type)
83     new_info->mime_type = g_strdup (new_info->mime_type);
84   if (new_info->icon)
85     g_object_ref (new_info->icon);
86
87   return new_info;
88 }
89
90 void
91 gtk_file_info_free (GtkFileInfo *info)
92 {
93   g_return_if_fail (info != NULL);
94
95   if (info->display_name)
96     g_free (info->display_name);
97   if (info->mime_type)
98     g_free (info->mime_type);
99   if (info->icon)
100     g_object_unref (info->icon);
101 }
102
103 G_CONST_RETURN gchar *
104 gtk_file_info_get_display_name (const GtkFileInfo *info)
105 {
106   g_return_val_if_fail (info != NULL, NULL);
107   
108   return info->display_name;
109 }
110
111 void
112 gtk_file_info_set_display_name (GtkFileInfo *info,
113                                 const gchar *display_name)
114 {
115   g_return_if_fail (info != NULL);
116
117   if (info->display_name)
118     g_free (info->display_name);
119
120   info->display_name = g_strdup (display_name);
121 }
122
123 gboolean
124 gtk_file_info_get_is_folder (const GtkFileInfo *info)
125 {
126   g_return_val_if_fail (info != NULL, FALSE);
127   
128   return info->is_folder;
129 }
130
131 void
132 gtk_file_info_set_is_folder (GtkFileInfo *info,
133                              gboolean     is_folder)
134 {
135   g_return_if_fail (info != NULL);
136
137   info->is_folder = is_folder != FALSE;
138 }
139
140 gboolean
141 gtk_file_info_get_is_hidden (const GtkFileInfo *info)
142 {
143   g_return_val_if_fail (info != NULL, FALSE);
144   
145   return info->is_hidden;
146 }
147
148 void
149 gtk_file_info_set_is_hidden (GtkFileInfo *info,
150                              gboolean     is_hidden)
151 {
152   g_return_if_fail (info != NULL);
153
154   info->is_hidden = is_hidden != FALSE;
155 }
156
157 G_CONST_RETURN gchar *
158 gtk_file_info_get_mime_type (const GtkFileInfo *info)
159 {
160   g_return_val_if_fail (info != NULL, NULL);
161   
162   return info->mime_type;
163 }
164
165 void
166 gtk_file_info_set_mime_type (GtkFileInfo *info,
167                              const gchar *mime_type)
168 {
169   g_return_if_fail (info != NULL);
170   
171   if (info->mime_type)
172     g_free (info->mime_type);
173
174   info->mime_type = g_strdup (mime_type);
175 }
176
177 GtkFileTime
178 gtk_file_info_get_modification_time (const GtkFileInfo *info)
179 {
180   g_return_val_if_fail (info != NULL, 0);
181
182   return info->modification_time;
183 }
184
185 void
186 gtk_file_info_set_modification_time (GtkFileInfo *info,
187                                      GtkFileTime  modification_time)
188 {
189   g_return_if_fail (info != NULL);
190   
191   info->modification_time = modification_time;
192 }
193
194 gint64
195 gtk_file_info_get_size (const GtkFileInfo *info)
196 {
197   g_return_val_if_fail (info != NULL, 0);
198   
199   return info->size;
200 }
201
202 void
203 gtk_file_info_set_size (GtkFileInfo *info,
204                         gint64       size)
205 {
206   g_return_if_fail (info != NULL);
207   g_return_if_fail (size < 0);
208   
209   info->size = size;
210 }
211
212 GdkPixbuf *
213 gtk_file_info_get_icon (const GtkFileInfo *info)
214 {
215   g_return_val_if_fail (info != NULL, NULL);
216
217   return info->icon;
218 }
219
220 void
221 gtk_file_info_set_icon (GtkFileInfo *info,
222                         GdkPixbuf   *icon)
223 {
224   g_return_if_fail (info != NULL);
225   g_return_if_fail (icon == NULL || GDK_IS_PIXBUF (icon));
226
227   if (icon != info->icon)
228     {
229       if (info->icon)
230         g_object_unref (info->icon);
231
232       info->icon = icon;
233       
234       if (info->icon)
235         g_object_ref (info->icon);
236     }
237 }
238
239 /*****************************************
240  *             GtkFileSystem             *
241  *****************************************/
242 GType
243 gtk_file_system_get_type (void)
244 {
245   static GType file_system_type = 0;
246
247   if (!file_system_type)
248     {
249       static const GTypeInfo file_system_info =
250       {
251         sizeof (GtkFileSystemIface),  /* class_size */
252         gtk_file_system_base_init,    /* base_init */
253         NULL,                         /* base_finalize */
254       };
255
256       file_system_type = g_type_register_static (G_TYPE_INTERFACE,
257                                                  "GtkFileSystem",
258                                                  &file_system_info, 0);
259     }
260
261   return file_system_type;
262 }
263
264 static void
265 gtk_file_system_base_init (gpointer g_class)
266 {
267   static gboolean initialized = FALSE;
268   
269   if (!initialized)
270     {
271       GType iface_type = G_TYPE_FROM_INTERFACE (g_class);
272
273       g_signal_new ("roots_changed",
274                     iface_type,
275                     G_SIGNAL_RUN_LAST,
276                     G_STRUCT_OFFSET (GtkFileSystemIface, roots_changed),
277                     NULL, NULL,
278                     g_cclosure_marshal_VOID__VOID,
279                     G_TYPE_NONE, 0);
280
281       initialized = TRUE;
282     }
283 }
284
285 GSList *
286 gtk_file_system_list_roots (GtkFileSystem  *file_system)
287 {
288   g_return_val_if_fail (GTK_IS_FILE_SYSTEM (file_system), NULL);
289
290   return GTK_FILE_SYSTEM_GET_IFACE (file_system)->list_roots (file_system);
291 }
292
293 GtkFileInfo *
294 gtk_file_system_get_root_info  (GtkFileSystem    *file_system,
295                                 const gchar      *uri,
296                                 GtkFileInfoType   types,
297                                 GError          **error)
298 {
299   g_return_val_if_fail (GTK_IS_FILE_SYSTEM (file_system), NULL);
300   g_return_val_if_fail (uri != NULL, NULL);
301   g_return_val_if_fail (error == NULL || *error == NULL, NULL);
302
303   return GTK_FILE_SYSTEM_GET_IFACE (file_system)->get_root_info (file_system, uri, types, error);
304 }
305
306 GtkFileFolder *
307 gtk_file_system_get_folder (GtkFileSystem    *file_system,
308                             const gchar      *uri,
309                             GtkFileInfoType   types,
310                             GError          **error)
311 {
312   g_return_val_if_fail (GTK_IS_FILE_SYSTEM (file_system), NULL);
313   g_return_val_if_fail (uri != NULL, NULL);
314   g_return_val_if_fail (error == NULL || *error == NULL, NULL);
315
316   return GTK_FILE_SYSTEM_GET_IFACE (file_system)->get_folder (file_system, uri, types, error);
317 }
318
319 gboolean
320 gtk_file_system_create_folder(GtkFileSystem    *file_system,
321                               const gchar      *uri,
322                               GError          **error)
323 {
324   g_return_val_if_fail (GTK_IS_FILE_SYSTEM (file_system), FALSE);
325   g_return_val_if_fail (uri != NULL, FALSE);
326   g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
327
328   return GTK_FILE_SYSTEM_GET_IFACE (file_system)->create_folder (file_system, uri, error);
329 }
330
331 gboolean
332 gtk_file_system_get_parent (GtkFileSystem *file_system,
333                             const gchar   *uri,
334                             gchar         **parent,
335                             GError        **error)
336 {
337   gchar *tmp_parent = NULL;
338   gboolean result;
339   
340   g_return_val_if_fail (GTK_IS_FILE_SYSTEM (file_system), FALSE);
341   g_return_val_if_fail (uri != NULL, FALSE);
342   g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
343
344   result = GTK_FILE_SYSTEM_GET_IFACE (file_system)->get_parent (file_system, uri, &tmp_parent, error);
345   g_assert (result || tmp_parent == NULL);
346
347   if (parent)
348     *parent = tmp_parent;
349
350   return result;
351 }
352
353 gchar *
354 gtk_file_system_make_uri (GtkFileSystem    *file_system,
355                           const gchar      *base_uri,
356                           const gchar      *display_name,
357                           GError          **error)
358 {
359   g_return_val_if_fail (GTK_IS_FILE_SYSTEM (file_system), NULL);
360   g_return_val_if_fail (base_uri != NULL, NULL);
361   g_return_val_if_fail (display_name != NULL, NULL);
362   g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
363
364   return GTK_FILE_SYSTEM_GET_IFACE (file_system)->make_uri (file_system, base_uri, display_name, error);
365 }
366
367
368 /*****************************************
369  *             GtkFileFolder             *
370  *****************************************/
371 GType
372 gtk_file_folder_get_type (void)
373 {
374   static GType file_folder_type = 0;
375
376   if (!file_folder_type)
377     {
378       static const GTypeInfo file_folder_info =
379       {
380         sizeof (GtkFileFolderIface),  /* class_size */
381         gtk_file_folder_base_init,    /* base_init */
382         NULL,                         /* base_finalize */
383       };
384
385       file_folder_type = g_type_register_static (G_TYPE_INTERFACE,
386                                                  "GtkFileFolder",
387                                                  &file_folder_info, 0);
388     }
389
390   return file_folder_type;
391 }
392
393 static void
394 gtk_file_folder_base_init (gpointer g_class)
395 {
396   static gboolean initialized = FALSE;
397   
398   if (!initialized)
399     {
400       GType iface_type = G_TYPE_FROM_INTERFACE (g_class);
401
402       g_signal_new ("deleted",
403                     iface_type,
404                     G_SIGNAL_RUN_LAST,
405                     G_STRUCT_OFFSET (GtkFileFolderIface, deleted),
406                     NULL, NULL,
407                     g_cclosure_marshal_VOID__VOID,
408                     G_TYPE_NONE, 0);
409       g_signal_new ("file_added",
410                     iface_type,
411                     G_SIGNAL_RUN_LAST,
412                     G_STRUCT_OFFSET (GtkFileFolderIface, file_added),
413                     NULL, NULL,
414                     g_cclosure_marshal_VOID__STRING,
415                     G_TYPE_NONE, 0);
416       g_signal_new ("file_changed",
417                     iface_type,
418                     G_SIGNAL_RUN_LAST,
419                     G_STRUCT_OFFSET (GtkFileFolderIface, file_changed),
420                     NULL, NULL,
421                     g_cclosure_marshal_VOID__STRING,
422                     G_TYPE_NONE, 0);
423       g_signal_new ("file_removed",
424                     iface_type,
425                     G_SIGNAL_RUN_LAST,
426                     G_STRUCT_OFFSET (GtkFileFolderIface, file_removed),
427                     NULL, NULL,
428                     g_cclosure_marshal_VOID__STRING,
429                     G_TYPE_NONE, 0);
430
431       initialized = TRUE;
432     }
433 }
434
435 gboolean
436 gtk_file_folder_list_children (GtkFileFolder    *folder,
437                                GSList          **children,
438                                GError          **error)
439 {
440   gboolean result;
441   GSList *tmp_children = NULL;
442   
443   g_return_val_if_fail (GTK_IS_FILE_FOLDER (folder), FALSE);
444   g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
445
446   result = GTK_FILE_FOLDER_GET_IFACE (folder)->list_children (folder, &tmp_children, error);
447   g_assert (result || tmp_children == NULL);
448
449   if (children)
450     *children = tmp_children;
451
452   return result;
453 }
454
455 GtkFileInfo *
456 gtk_file_folder_get_info (GtkFileFolder    *folder,
457                           const gchar      *uri,
458                           GError          **error)
459 {
460   g_return_val_if_fail (GTK_IS_FILE_FOLDER (folder), NULL);
461   g_return_val_if_fail (uri != NULL, NULL);
462   g_return_val_if_fail (error == NULL || *error == NULL, NULL);
463
464   return GTK_FILE_FOLDER_GET_IFACE (folder)->get_info (folder, uri, error);
465 }