1 /* vi:set et ai sw=2 sts=2 ts=2: */
2 /*-
3  * Copyright (c) 2005-2006 Benedikt Meurer <benny@xfce.org>
4  * Copyright (c) 2009 Jannis Pohlmann <jannis@xfce.org>
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Library General Public
8  * License as published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Library General Public License for more details.
15  *
16  * You should have received a copy of the GNU Library General Public
17  * License along with this library; if not, write to the
18  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19  * Boston, MA 02111-1307, USA.
20  */
21 
22 #ifdef HAVE_CONFIG_H
23 #include <config.h>
24 #endif
25 
26 #include <thunarx/thunarx-file-info.h>
27 #include <thunarx/thunarx-private.h>
28 
29 
30 
31 /* Signal identifiers */
32 enum
33 {
34   CHANGED,
35   RENAMED,
36   LAST_SIGNAL,
37 };
38 
39 
40 
41 static guint file_info_signals[LAST_SIGNAL];
42 
43 /**
44  * SECTION: thunarx-file-info
45  * @short_description: Abstraction of a file handled within the file manager
46  * @title: ThunarxFileInfo
47  * @include: thunarx/thunarx.h
48  *
49  * The <interface>ThunarxFileInfo</interface> interface provides extensions with
50  * a way to access information about a file handled within the file manager.
51  */
52 
53 
54 GType
thunarx_file_info_get_type(void)55 thunarx_file_info_get_type (void)
56 {
57   static volatile gsize type__volatile = 0;
58   GType                 type;
59 
60   if (g_once_init_enter (&type__volatile))
61     {
62       type = g_type_register_static_simple (G_TYPE_INTERFACE,
63                                             I_("ThunarxFileInfo"),
64                                             sizeof (ThunarxFileInfoIface),
65                                             NULL,
66                                             0,
67                                             NULL,
68                                             0);
69 
70       g_type_interface_add_prerequisite (type, G_TYPE_OBJECT);
71 
72       /**
73        * ThunarxFileInfo::changed:
74        * @file_info : a #ThunarxFileInfo.
75        *
76        * Emitted whenever the system notices a change to @file_info.
77        *
78        * Thunar plugins should use this signal to stay informed about
79        * changes to a @file_info for which they currently display
80        * information (i.e. in a #ThunarxPropertyPage), and update
81        * it's user interface whenever a change is noticed on @file_info.
82        **/
83       file_info_signals[CHANGED] =
84         g_signal_new (I_("changed"),
85                       type,
86                       G_SIGNAL_RUN_FIRST,
87                       G_STRUCT_OFFSET (ThunarxFileInfoIface, changed),
88                       NULL, NULL,
89                       g_cclosure_marshal_VOID__VOID,
90                       G_TYPE_NONE, 0);
91 
92       /**
93        * ThunarxFileInfo::renamed:
94        * @file_info : a #ThunarxFileInfo
95        *
96        * Emitted when the @file_info is renamed to another
97        * name.
98        *
99        * For example, within Thunar, #ThunarFolder uses this
100        * signal to reregister it's VFS directory monitor, after
101        * the corresponding file was renamed.
102        **/
103       file_info_signals[RENAMED] =
104         g_signal_new (I_("renamed"),
105                       type,
106                       G_SIGNAL_RUN_FIRST,
107                       G_STRUCT_OFFSET (ThunarxFileInfoIface, renamed),
108                       NULL, NULL,
109                       g_cclosure_marshal_VOID__VOID,
110                       G_TYPE_NONE, 0);
111 
112       g_once_init_leave (&type__volatile, type);
113     }
114 
115   return type__volatile;
116 }
117 
118 
119 
120 /**
121  * thunarx_file_info_get_name:
122  * @file_info : a #ThunarxFileInfo.
123  *
124  * Returns the real name of the file represented
125  * by @file_info in the local file system encoding.
126  * You can use g_filename_display_name() or similar
127  * functions to generate an UTF-8 version of the
128  * name, which is suitable for use in the user
129  * interface.
130  *
131  * The caller is responsible to free the returned
132  * string using g_free() when no longer needed.
133  *
134  * Return value: the real name of the file represented
135  *               by @file_info.
136  **/
137 gchar*
thunarx_file_info_get_name(ThunarxFileInfo * file_info)138 thunarx_file_info_get_name (ThunarxFileInfo *file_info)
139 {
140   g_return_val_if_fail (THUNARX_IS_FILE_INFO (file_info), NULL);
141   return (*THUNARX_FILE_INFO_GET_IFACE (file_info)->get_name) (file_info);
142 }
143 
144 
145 
146 /**
147  * thunarx_file_info_get_uri:
148  * @file_info : a #ThunarxFileInfo.
149  *
150  * Returns the escaped, fully qualified URI
151  * of the file object represented by @file_info.
152  * You may use g_filename_from_uri() and similar
153  * functions to work with the returned URI.
154  *
155  * The caller is responsible to free the returned
156  * string using g_free() when no longer needed.
157  *
158  * Return value: the fully qualified URI of @file_info.
159  **/
160 gchar*
thunarx_file_info_get_uri(ThunarxFileInfo * file_info)161 thunarx_file_info_get_uri (ThunarxFileInfo *file_info)
162 {
163   g_return_val_if_fail (THUNARX_IS_FILE_INFO (file_info), NULL);
164   return (*THUNARX_FILE_INFO_GET_IFACE (file_info)->get_uri) (file_info);
165 }
166 
167 
168 
169 /**
170  * thunarx_file_info_get_parent_uri:
171  * @file_info : a #ThunarxFileInfo.
172  *
173  * Returns the URI to the parent file of
174  * @file_info or %NULL if @file_info has
175  * no parent. Note that the parent URI
176  * may be of a different type than the
177  * URI of @file_info. For example, the
178  * parent of "file:///" is "computer:///".
179  *
180  * The caller is responsible to free the
181  * returned string using g_free() when no
182  * longer needed.
183  *
184  * Return value: the parent URI for @file_info
185  *               or %NULL.
186  **/
187 gchar*
thunarx_file_info_get_parent_uri(ThunarxFileInfo * file_info)188 thunarx_file_info_get_parent_uri (ThunarxFileInfo *file_info)
189 {
190   g_return_val_if_fail (THUNARX_IS_FILE_INFO (file_info), NULL);
191   return (*THUNARX_FILE_INFO_GET_IFACE (file_info)->get_parent_uri) (file_info);
192 }
193 
194 
195 
196 /**
197  * thunarx_file_info_get_uri_scheme:
198  * @file_info : a #ThunarxFileInfo.
199  *
200  * Returns the URI scheme of the file represented
201  * by @file_info. E.g. if @file_info refers to the
202  * file "file:///usr/home", the return value will
203  * be "file".
204  *
205  * The caller is responsible to free the returned
206  * string using g_free() when no longer needed.
207  *
208  * Return value: the URI scheme for @file_info.
209  **/
210 gchar*
thunarx_file_info_get_uri_scheme(ThunarxFileInfo * file_info)211 thunarx_file_info_get_uri_scheme (ThunarxFileInfo *file_info)
212 {
213   g_return_val_if_fail (THUNARX_IS_FILE_INFO (file_info), NULL);
214   return (*THUNARX_FILE_INFO_GET_IFACE (file_info)->get_uri_scheme) (file_info);
215 }
216 
217 
218 
219 /**
220  * thunarx_file_info_get_mime_type:
221  * @file_info : a #ThunarxFileInfo.
222  *
223  * Returns the MIME-type of the file represented by
224  * @file_info or %NULL if no MIME-type is known for
225  * @file_info.
226  *
227  * The caller is responsible to free the returned
228  * string using g_free() when no longer needed.
229  *
230  * Return value: the MIME-type for @file_info or
231  *               %NULL.
232  **/
233 gchar*
thunarx_file_info_get_mime_type(ThunarxFileInfo * file_info)234 thunarx_file_info_get_mime_type (ThunarxFileInfo *file_info)
235 {
236   g_return_val_if_fail (THUNARX_IS_FILE_INFO (file_info), NULL);
237   return (*THUNARX_FILE_INFO_GET_IFACE (file_info)->get_mime_type) (file_info);
238 }
239 
240 
241 
242 /**
243  * thunarx_file_info_has_mime_type:
244  * @file_info : a #ThunarxFileInfo.
245  * @mime_type : a MIME-type (e.g. "text/plain").
246  *
247  * Checks whether @file_info is of the given @mime_type
248  * or whether the MIME-type of @file_info is a subclass
249  * of @mime_type.
250  *
251  * This is the preferred way for most extensions to check
252  * whether they support a given file or not, and you should
253  * consider using this method rather than
254  * thunarx_file_info_get_mime_type(). A simple example would
255  * be a menu extension that performs a certain action on
256  * text files. In this case you want to check whether a given
257  * #ThunarxFileInfo refers to any kind of text file, not only
258  * to "text/plain" (e.g. this also includes "text/xml" and
259  * "application/x-desktop").
260  *
261  * But you should be aware that this method may take some
262  * time to test whether @mime_type is valid for @file_info,
263  * so don't call it too often.
264  *
265  * Return value: %TRUE if @mime_type is valid for @file_info,
266  *               else %FALSE.
267  **/
268 gboolean
thunarx_file_info_has_mime_type(ThunarxFileInfo * file_info,const gchar * mime_type)269 thunarx_file_info_has_mime_type (ThunarxFileInfo *file_info,
270                                  const gchar     *mime_type)
271 {
272   g_return_val_if_fail (THUNARX_IS_FILE_INFO (file_info), FALSE);
273   g_return_val_if_fail (mime_type != NULL, FALSE);
274   return (*THUNARX_FILE_INFO_GET_IFACE (file_info)->has_mime_type) (file_info, mime_type);
275 }
276 
277 
278 
279 /**
280  * thunarx_file_info_is_directory:
281  * @file_info : a #ThunarxFileInfo.
282  *
283  * Checks whether @file_info refers to a directory.
284  *
285  * Return value: %TRUE if @file_info is a directory.
286  **/
287 gboolean
thunarx_file_info_is_directory(ThunarxFileInfo * file_info)288 thunarx_file_info_is_directory (ThunarxFileInfo *file_info)
289 {
290   g_return_val_if_fail (THUNARX_IS_FILE_INFO (file_info), FALSE);
291   return (*THUNARX_FILE_INFO_GET_IFACE (file_info)->is_directory) (file_info);
292 }
293 
294 
295 
296 /**
297  * thunarx_file_info_get_file_info:
298  * @file_info : a #ThunarxFileInfo.
299  *
300  * Returns the #GFileInfo associated with @file_info,
301  * which includes additional information about the @file_info
302  * as queried from GIO earlier. The caller is responsible to free the
303  * returned #GFileInfo object using g_object_unref() when
304  * no longer needed.
305  *
306  * Returns: (transfer full): the #GFileInfo object associated with @file_info,
307  *          which MUST be freed using g_object_unref().
308  **/
309 GFileInfo*
thunarx_file_info_get_file_info(ThunarxFileInfo * file_info)310 thunarx_file_info_get_file_info (ThunarxFileInfo *file_info)
311 {
312   g_return_val_if_fail (THUNARX_IS_FILE_INFO (file_info), NULL);
313   return (*THUNARX_FILE_INFO_GET_IFACE (file_info)->get_file_info) (file_info);
314 }
315 
316 
317 
318 /**
319  * thunarx_file_info_get_filesystem_info:
320  * @file_info : a #ThunarxFileInfo.
321  *
322  * Returns the #GFileInfo which includes additional information about
323  * the filesystem @file_info resides on. The caller is responsible to
324  * free the returned #GFileInfo object using g_object_unref() when
325  * no longer needed.
326  *
327  * Returns: (transfer full): the #GFileInfo containing information about the
328  *          filesystem of @file_info or %NULL if no filesystem information is
329  *          available. It MUST be released using g_object_unref().
330  **/
331 GFileInfo*
thunarx_file_info_get_filesystem_info(ThunarxFileInfo * file_info)332 thunarx_file_info_get_filesystem_info (ThunarxFileInfo *file_info)
333 {
334   g_return_val_if_fail (THUNARX_IS_FILE_INFO (file_info), NULL);
335   return (*THUNARX_FILE_INFO_GET_IFACE (file_info)->get_filesystem_info) (file_info);
336 }
337 
338 
339 
340 /**
341  * thunarx_file_info_get_location:
342  * @file_info : a #ThunarxFileInfo.
343  *
344  * Returns the #GFile @file_info points to. The #GFile is a more
345  * powerful tool than just the URI or the path. The caller
346  * is responsible to release the returned #GFile using g_object_unref()
347  * when no longer needed.
348  *
349  * Returns: (transfer full): the #GFile to which @file_info points. It MUST be
350  *          released using g_object_unref().
351  **/
352 GFile*
thunarx_file_info_get_location(ThunarxFileInfo * file_info)353 thunarx_file_info_get_location (ThunarxFileInfo *file_info)
354 {
355   g_return_val_if_fail (THUNARX_IS_FILE_INFO (file_info), NULL);
356   return (*THUNARX_FILE_INFO_GET_IFACE (file_info)->get_location) (file_info);
357 }
358 
359 
360 
361 /**
362  * thunarx_file_info_changed:
363  * @file_info : a #ThunarxFileInfo.
364  *
365  * Emits the ::changed signal on @file_info. This method should not
366  * be invoked by Thunar plugins, instead the file manager itself
367  * will use this method to emit ::changed whenever it notices a
368  * change on @file_info.
369  **/
370 void
thunarx_file_info_changed(ThunarxFileInfo * file_info)371 thunarx_file_info_changed (ThunarxFileInfo *file_info)
372 {
373   g_return_if_fail (THUNARX_IS_FILE_INFO (file_info));
374   g_signal_emit (G_OBJECT (file_info), file_info_signals[CHANGED], 0);
375 }
376 
377 
378 
379 /**
380  * thunarx_file_info_renamed:
381  * @file_info : a #ThunarxFileInfo.
382  *
383  * Emits the ::renamed signal on @file_info. This method should
384  * not be invoked by Thunar plugins, instead the file manager
385  * will emit this signal whenever the user renamed the @file_info.
386  *
387  * The plugins should instead connect to the ::renamed signal
388  * and update it's internal state and it's user interface
389  * after the file manager renamed a file.
390  **/
391 void
thunarx_file_info_renamed(ThunarxFileInfo * file_info)392 thunarx_file_info_renamed (ThunarxFileInfo *file_info)
393 {
394   g_return_if_fail (THUNARX_IS_FILE_INFO (file_info));
395   g_signal_emit (G_OBJECT (file_info), file_info_signals[RENAMED], 0);
396 }
397 
398 
399 
400 GType
thunarx_file_info_list_get_type(void)401 thunarx_file_info_list_get_type (void)
402 {
403   static GType type = G_TYPE_INVALID;
404 
405   if (G_UNLIKELY (type == G_TYPE_INVALID))
406     {
407       type = g_boxed_type_register_static (I_("ThunarxFileInfoList"),
408                                            (GBoxedCopyFunc) thunarx_file_info_list_copy,
409                                            (GBoxedFreeFunc) thunarx_file_info_list_free);
410     }
411 
412   return type;
413 }
414 
415 
416 
417 /**
418  * thunarx_file_info_list_copy:
419  * @file_infos: (element-type ThunarxFileInfo): a #GList of #ThunarxFileInfo<!---->s.
420  *
421  * Does a deep copy of @file_infos and returns the
422  * new list.
423  *
424  * Returns: (transfer full) (element-type ThunarxFileInfo): a copy of @file_infos.
425  **/
426 GList*
thunarx_file_info_list_copy(GList * file_infos)427 thunarx_file_info_list_copy (GList *file_infos)
428 {
429   return g_list_copy_deep (file_infos, (GCopyFunc) (void (*)(void)) g_object_ref, NULL);
430 }
431 
432 
433 
434 /**
435  * thunarx_file_info_list_free:
436  * @file_infos: (element-type ThunarxFileInfo): a #GList of #ThunarxFileInfo<!---->s.
437  *
438  * Frees the resources allocated for the @file_infos
439  * list and decreases the reference count on the
440  * #ThunarxFileInfo<!---->s contained within.
441  **/
442 void
thunarx_file_info_list_free(GList * file_infos)443 thunarx_file_info_list_free (GList *file_infos)
444 {
445   g_list_free_full (file_infos, g_object_unref);
446 }
447