31
#include <gio/gdesktopappinfo.h>
29
32
#include <glib/gprintf.h>
30
#include <libgnomevfs/gnome-vfs.h>
31
#include <libgnomevfs/gnome-vfs-mime-handlers.h>
32
#include <libgnome/gnome-desktop-item.h>
34
GtkIconTheme *icon_theme = NULL;
34
36
/******************************************************************************/
36
38
vfs_file_is_executable (const gchar *file_name) {
37
gchar *mime_type = gnome_vfs_get_mime_type (file_name);
38
gboolean is_executable = FALSE;
39
is_executable = g_file_test (file_name, G_FILE_TEST_IS_EXECUTABLE) &&
40
!g_file_test (file_name, G_FILE_TEST_IS_DIR) &&
41
(g_str_has_prefix (mime_type, "application/x-") ||
42
g_str_has_prefix (mime_type, "text/x-"));
39
if (DEBUG) g_printf ("In %s\n", __FUNCTION__);
41
GFileInfo* file_info = g_file_query_info (g_file_new_for_path (file_name),
42
G_FILE_ATTRIBUTE_ACCESS_CAN_EXECUTE,
47
return (g_file_info_get_attribute_boolean (file_info,
48
G_FILE_ATTRIBUTE_ACCESS_CAN_EXECUTE)) &&
49
!vfs_file_is_directory (file_name);
46
51
/******************************************************************************/
48
53
vfs_file_is_desktop (const gchar *file_name) {
49
return g_str_has_suffix (file_name, ".desktop");
51
/******************************************************************************/
54
if (DEBUG) g_printf ("In %s\n", __FUNCTION__);
56
return !(g_desktop_app_info_new_from_filename (file_name) == NULL);
58
/******************************************************************************/
60
vfs_file_is_directory (const gchar *file_name) {
61
if (DEBUG) g_printf ("In %s\n", __FUNCTION__);;
63
GFileInfo* file_info = g_file_query_info (g_file_new_for_path (file_name),
69
return (g_file_info_get_file_type (file_info) == G_FILE_TYPE_DIRECTORY);
71
/******************************************************************************/
72
/* Gets the executable file name of the application associated with the passed
53
75
vfs_get_mime_application (const gchar *file_name_and_path) {
54
GnomeVFSMimeApplication *mime_application = NULL;
55
gchar *mime_type = NULL;
56
gchar *file_mime_app_exec = NULL;
58
mime_type = gnome_vfs_get_mime_type (file_name_and_path);
59
mime_application = gnome_vfs_mime_get_default_application (mime_type);
61
if (mime_application) {
62
file_mime_app_exec = g_strdup ((gchar *)mime_application->command);
66
g_free (mime_application);
68
return file_mime_app_exec;
76
if (DEBUG) g_printf ("In %s\n", __FUNCTION__);
78
GFileInfo* file_info = g_file_query_info (g_file_new_for_path (file_name_and_path),
84
return (gchar *)g_app_info_get_executable (
85
g_app_info_get_default_for_type (
86
g_file_info_get_content_type (file_info), FALSE));
70
88
/******************************************************************************/
73
91
return g_file_test (file_name, G_FILE_TEST_EXISTS);
75
93
/******************************************************************************/
94
/* Gets the contents of a directory. Puts the files and directories in separate
95
* arrays, and sorts them both. */
77
vfs_get_dir_contents (GPtrArray *files,
97
vfs_get_dir_listings (GPtrArray *files,
79
99
gboolean show_hidden,
82
GnomeVFSDirectoryHandle *vfs_dir_handle = NULL;
83
GnomeVFSResult vfs_result;
84
GnomeVFSFileInfo *vfs_file_info = NULL;
87
/*make struct for getting file info, open the dir for reading and get the first entry*/
88
vfs_file_info = gnome_vfs_file_info_new();
90
vfs_result = gnome_vfs_directory_open (&vfs_dir_handle,
92
/* GNOME_VFS_FILE_INFO_GET_MIME_TYPE |*/
93
GNOME_VFS_FILE_INFO_FOLLOW_LINKS);
95
/* make sure the dir was opened OK. This fixes bug #3 */
96
if (vfs_result == GNOME_VFS_OK) {
97
/* get the first entry */
98
vfs_result = gnome_vfs_directory_read_next (vfs_dir_handle,
100
/* if it opened OK and while its not empty, keep reading items */
101
while (vfs_result == GNOME_VFS_OK) {
102
/*if it's not a hidden file or were showing hidden files...*/
103
if ((g_ascii_strncasecmp (vfs_file_info->name, ".", 1) != 0 || show_hidden) &&
104
g_ascii_strcasecmp (vfs_file_info->name, ".") != 0 &&
105
g_ascii_strcasecmp (vfs_file_info->name, "..") != 0) {
107
if (vfs_file_info->type == GNOME_VFS_FILE_TYPE_DIRECTORY) {
108
/*make an array that holds all the dirs in this dir*/
109
g_ptr_array_add (dirs, (gpointer)g_strdup (vfs_file_info->name));
111
if (vfs_file_info->type == GNOME_VFS_FILE_TYPE_REGULAR) {
112
/*make an array that holds all the files in this dir*/
113
g_ptr_array_add (files, (gpointer)g_strdup (vfs_file_info->name));
116
/*get the next entry*/
117
vfs_result = gnome_vfs_directory_read_next (vfs_dir_handle,
121
vfs_result = gnome_vfs_directory_close (vfs_dir_handle);
124
error = g_strdup_printf ("(%s)",gnome_vfs_result_to_string (vfs_result));
125
if (DEBUG) g_printf ("Error opening directory. GNOME_VFS error: %s\n",
128
/**************************** Finished reading dir contents ************************/
130
/*sort the arrays containing the directory and file listings*/
101
if (DEBUG) g_printf ("In %s\n", __FUNCTION__);
103
GError *error = NULL;
105
GFileInfo *file_info = NULL;
106
GFileEnumerator *enummerator = NULL;
108
file = g_file_new_for_path (path);
109
enummerator = g_file_enumerate_children (file,
114
/* did we read the dir correctly? */
116
gchar *error_msg = g_strdup (error->message);
117
g_error_free (error);
122
while ((file_info = g_file_enumerator_next_file (enummerator, NULL, &error)) != NULL) {
123
/* skip the file if it's hidden and we aren't showing hidden files */
124
if (g_file_info_get_is_hidden (file_info) && !show_hidden) {
128
/* get eh file's human readable name */
129
gchar *display_name = g_strdup (g_file_info_get_display_name (file_info));
131
/* add it to the array */
132
if (g_file_info_get_file_type (file_info) == G_FILE_TYPE_DIRECTORY) {
133
g_ptr_array_add (dirs, (gpointer)display_name);
136
g_ptr_array_add (files, (gpointer)display_name);
140
/* always check for errors */
142
gchar *error_msg = g_strdup (error->message);
143
g_error_free (error);
131
148
g_ptr_array_sort (dirs, (GCompareFunc)&utils_sort_alpha);
132
149
g_ptr_array_sort (files, (GCompareFunc)&utils_sort_alpha);
134
gnome_vfs_file_info_clear (vfs_file_info);
135
g_free (vfs_file_info);
153
/******************************************************************************/
155
vfs_launch_desktop_file (const gchar *file_name) {
156
if (DEBUG) g_printf ("In %s\n", __FUNCTION__);
158
if (!vfs_file_is_desktop (file_name)) {
162
GDesktopAppInfo *info = NULL;
163
if ((info = g_desktop_app_info_new_from_filename (file_name)) != NULL) {
164
return g_app_info_launch (G_APP_INFO (info),
171
/******************************************************************************/
173
vfs_launch_app (gchar **args, const gchar *working_dir) {
174
if (DEBUG) g_printf ("In %s\n", __FUNCTION__);
176
GError *error = NULL;
180
ret = g_spawn_async_with_pipes (working_dir,
192
if (utils_check_gerror (&error)) {
193
gchar *tmp = g_strdup_printf ("Error: Failed to launch \"%s\".", args[0]);
194
utils_show_dialog ("Error: Failed to launch application",
201
/******************************************************************************/
203
vfs_edit_file (const gchar *file_name_and_path, gchar *editor_bin) {
204
if (DEBUG) g_printf ("In %s\n", __FUNCTION__);
208
gchar *working_dir = NULL;
211
working_dir = g_path_get_dirname (file_name_and_path);
212
arg = g_strdelimit (editor_bin, " ", '\1');
213
arg = g_strconcat (arg, "\1", file_name_and_path, NULL);
214
args = g_strsplit (arg, "\1", 0);
215
vfs_launch_app (args, working_dir);
218
for (i = 0; args[i]; i++) {
222
g_free (working_dir);
224
/******************************************************************************/
226
vfs_launch_terminal (const gchar *path, gchar *terminal_bin) {
227
if (DEBUG) g_printf ("In %s\n", __FUNCTION__);
231
args = g_strsplit (terminal_bin, " ", 0);
233
vfs_launch_app (args, path);
237
/******************************************************************************/
239
vfs_open_file (const gchar *file_name_and_path, gint exec_action) {
240
if (DEBUG) g_printf ("In %s\n", __FUNCTION__);
244
gchar *file_mime_app_exec = NULL;
245
gchar *working_dir = NULL;
246
gboolean is_executable;
249
working_dir = g_path_get_dirname (file_name_and_path);
250
is_executable = vfs_file_is_executable (file_name_and_path);
252
file_mime_app_exec = vfs_get_mime_application (file_name_and_path);
254
/* if it's a binary file run it*/
256
arg = g_strdup_printf ("%s", file_name_and_path);
257
args = g_strsplit (arg, "\1", 0);
260
if (file_mime_app_exec) {
261
arg = g_strdelimit (file_mime_app_exec, " ", '\1');
262
arg = g_strconcat (arg, "\1", file_name_and_path, NULL);
263
args = g_strsplit (arg, "\1", 0);
264
if (DEBUG) g_printf ("%s ", file_mime_app_exec);
267
if (DEBUG) g_printf ("Error: failed to get mime application for %s\n", file_name_and_path);
268
gchar *message = g_strdup_printf ("Cannot open %s:\n"
269
"No application is known for this kind of file.",
272
utils_show_dialog ("Error: no application found",
279
if (DEBUG) g_printf ("%s\n", file_name_and_path);
280
vfs_launch_app (args, working_dir);
283
for (i = 0; args[i]; i++) {
287
g_free (file_mime_app_exec);
289
/******************************************************************************/
291
vfs_trash_file (gchar *file_name) {
292
if (DEBUG) g_printf ("In %s\n", __FUNCTION__);
294
GError *error = NULL;
295
GFile *file = g_file_new_for_path (file_name);
297
/* Try moving it to the trash */
302
/* Let the user know if we failed. */
303
if (utils_check_gerror (&error)) {
304
gchar *message = g_strdup_printf ("Error: Failed to move \"%s\" to Trash.",
306
utils_show_dialog ("Error: Failed to move tile to Trash",
312
/******************************************************************************/
313
/******************************************************************************/
314
/* Blatantly stolen (and modified) from nautilus-mime-application-chooser.c.
315
* Returns a pixmap of the image associated with the passed file. .desktop
316
* files will generally be handles by the G_IS_FILE_ICON section. Theme images
317
* are handles by the G_IS_THEMED_ICON section where we first do some shit I
318
* don't understand and if that fails, we ask gtk_icon_theme_choose_icon to
319
* figure out wat icon to use. */
321
vfs_get_pixbuf_for_icon (GIcon *icon) {
322
GdkPixbuf *pixbuf = NULL;
325
if (G_IS_THEMED_ICON (icon)) {
326
const gchar * const *names = g_themed_icon_get_names (G_THEMED_ICON (icon));
327
GtkIconInfo *icon_info = gtk_icon_theme_choose_icon (icon_theme,
328
(const gchar **)names,
331
pixbuf = gtk_icon_info_load_icon (icon_info, NULL);
333
if (pixbuf == NULL) {
334
if (names != NULL && names[0] != NULL) {
335
gchar *icon_no_extension = g_strdup (names[0]);
336
gchar *p = strrchr (icon_no_extension, '.');
338
(strcmp (p, ".png") == 0 ||
339
strcmp (p, ".xpm") == 0 ||
340
strcmp (p, ".svg") == 0)) {
344
pixbuf = gtk_icon_theme_load_icon (icon_theme,
349
g_free (icon_no_extension);
353
else if (G_IS_FILE_ICON (icon)) {
354
filename = g_file_get_path (g_file_icon_get_file (G_FILE_ICON (icon)));
356
pixbuf = gdk_pixbuf_new_from_file_at_size (filename,
365
/******************************************************************************/
366
/* Returns the image associated with a file. Works on both normal and desktop
369
vfs_get_icon_for_file (const gchar *file_name) {
370
if (icon_theme == NULL) {
371
icon_theme = gtk_icon_theme_get_default();
375
GdkPixbuf *icon_pixbuf = NULL;
377
/* try for desktop file */
378
if (vfs_file_is_desktop (file_name)) {
379
GDesktopAppInfo *info = g_desktop_app_info_new_from_filename (file_name);
380
icon = g_app_info_get_icon (G_APP_INFO (info));
381
} /* not a desktop file */
383
GFileInfo* file_info = g_file_query_info (g_file_new_for_path (file_name),
384
G_FILE_ATTRIBUTE_STANDARD_ICON,
388
icon = g_file_info_get_icon (file_info);
392
icon_pixbuf = vfs_get_pixbuf_for_icon (icon);
395
GtkWidget *icon_widget = gtk_image_new_from_pixbuf (icon_pixbuf);
396
g_object_unref (icon_pixbuf);
400
/******************************************************************************/
402
vfs_get_desktop_app_name (const gchar *file_name) {
403
GDesktopAppInfo *info = g_desktop_app_info_new_from_filename (file_name);
404
return g_app_info_get_name (G_APP_INFO (info));
138
406
/******************************************************************************/