~ubuntu-branches/ubuntu/raring/file-browser-applet/raring

« back to all changes in this revision

Viewing changes to src/vfs.c

  • Committer: Bazaar Package Importer
  • Author(s): Andrew Starr-Bochicchio
  • Date: 2009-02-13 21:33:45 UTC
  • mfrom: (1.1.3 upstream)
  • Revision ID: james.westby@ubuntu.com-20090213213345-gowiib2ifj0hmjb3
Tags: 0.6.1-0ubuntu1
* New upstream release. (LP: #329282)
 - Added mnemonic keyboard shortcut to menus for 
   faster keyboard navigation.
 - Added recent documents' support.
 - Improved menu browser focus after context menu close.
 - Fixed bugs #43, 44, 45, 49, 51, 56, 59, 60, 62.
* debian/control:
 - Update Vcs-Bzr field.

Show diffs side-by-side

added added

removed removed

Lines of Context:
23
23
 * Boston, MA 02110-1301, USA.
24
24
 */
25
25
 
 
26
#include <gio/gdesktopappinfo.h>
 
27
#include <glib/gprintf.h>
 
28
#include <glib/gstdio.h>
 
29
#include <gio/gio.h>
 
30
 
26
31
#include "vfs.h"
27
32
#include "utils.h"
28
 
 
29
 
#include <string.h>
30
 
#include <gio/gdesktopappinfo.h>
31
 
#include <glib/gprintf.h>
 
33
#include "config.h"
32
34
 
33
35
/******************************************************************************/
34
36
/* sort the structures based on the file's display_name */
48
50
 
49
51
        GFile*     file = g_file_new_for_path (file_name);
50
52
        GFileInfo* file_info =  g_file_query_info (file,
51
 
                                                                                           G_FILE_ATTRIBUTE_ACCESS_CAN_EXECUTE,
 
53
                                                                                           /*G_FILE_ATTRIBUTE_ACCESS_CAN_EXECUTE ,*/
 
54
                                                                                           "standard::content-type,"
 
55
                                                                                           "access::can-execute",
52
56
                                                                                           0,
53
57
                                                                                           NULL,
54
58
                                                                                           NULL);
55
59
 
56
60
        gboolean ret = g_file_info_get_attribute_boolean (file_info,
57
61
                                                                                                          G_FILE_ATTRIBUTE_ACCESS_CAN_EXECUTE) &&
58
 
                                                                                                          !vfs_file_is_directory (file_name);
 
62
                                                                                                          g_content_type_can_be_executable (g_file_info_get_content_type (file_info));
 
63
 
59
64
        g_object_unref (file_info);
60
65
        g_object_unref (file);
61
66
        return ret;     
183
188
        return app_infos;
184
189
}
185
190
/******************************************************************************/
 
191
/* Takes a null-terminated array of strings at least 2 items long. The first
 
192
 * item is always the application to execute, including if it is a script or
 
193
 * .desktop file. The second is the files to open. Either ARG_FILE or ARG_APP
 
194
 * can be NULL, but not both. If ARG_FILE is NULL, just launch ARG_APP. If
 
195
 * ARG_APP is NULL, open ARG_FILE with the default mime handler. */
186
196
gboolean
187
 
vfs_launch_application (LaunchInfo *launch_info) {
188
 
        if (DEBUG) g_printf ("In %s\n", __FUNCTION__);
189
 
 
190
 
        gboolean ret = TRUE;
191
 
        GError *error = NULL;
192
 
        gint child_pid;
193
 
        gchar *working_dir = NULL;
194
 
 
195
 
        if (launch_info->file) {
196
 
                working_dir = (vfs_file_is_directory (launch_info->file)) ? 
197
 
                                          g_strdup (launch_info->file) :
198
 
                                          g_path_get_dirname (launch_info->file);
199
 
        }
200
 
        else {
201
 
                working_dir = g_strdup (g_get_home_dir ());
202
 
        }
203
 
 
204
 
        g_strdelimit (launch_info->command, " ", '\1');
205
 
 
206
 
        /* only add the file name as an argument if one was specified */
207
 
        gchar *arg = (launch_info->file) ? 
208
 
                                 g_strconcat (launch_info->command, "\1", launch_info->file, NULL) :
209
 
                                 g_strdup (launch_info->command);
210
 
 
211
 
        gchar** args = g_strsplit (arg, "\1", 0);
212
 
 
213
 
        /* need to do this to convert the '\2's back into spaces. */
214
 
        g_strdelimit (args[0], "\2", ' ');
215
 
 
216
 
        /* remove trailing spaces from all args */
217
 
        int i = 0;
218
 
        while (args[i]) {
219
 
                g_strchomp (args[i]);
220
 
                i++;
221
 
        }
222
 
 
223
 
        g_spawn_async_with_pipes (working_dir,
224
 
                                                          args,
225
 
                                                          NULL,
226
 
                                                          G_SPAWN_SEARCH_PATH,
227
 
                                                          NULL,
228
 
                                                          NULL,
229
 
                                                          &child_pid,
230
 
                                                          NULL,
231
 
                                                          NULL,
232
 
                                                          NULL,
233
 
                                                          &error);
234
 
 
235
 
        ret = utils_gerror_ok (&error, TRUE) ? ret : FALSE;
236
 
        
237
 
        g_free (arg);
238
 
        g_strfreev (args);
 
197
vfs_launch_application (const gchar *const *args) {
 
198
 
 
199
        /* Can't have both arg[ARG_APP] and args[ARG_FILE} NULL */
 
200
        g_return_val_if_fail ((args[ARG_APP] != NULL || args[ARG_FILE] != NULL), FALSE);
 
201
 
 
202
        guint    i;
 
203
        gboolean ret       = FALSE;
 
204
        GError   *error    = NULL;
 
205
        GList    *files    = NULL;
 
206
        gchar    *command_line = NULL;
 
207
 
 
208
        /* Put the file(s) in a list (only of there is a file) for g_app_info_launch() */
 
209
        for (i = ARG_FILE; args[i]; i++) {
 
210
                files = g_list_append (files, (gpointer)g_file_new_for_path (args[i]));
 
211
        }
 
212
 
 
213
    gchar *uri = args[ARG_FILE] ? g_filename_to_uri(args[ARG_FILE], NULL, NULL) : g_filename_to_uri(args[ARG_APP], NULL, NULL);
 
214
    GtkRecentManager *recent = gtk_recent_manager_new ();
 
215
    gtk_recent_manager_add_item (recent, uri);
 
216
    g_object_unref (G_OBJECT(recent));
 
217
    g_free (uri);
 
218
 
 
219
        /* Set the current working dir. Do we use ARG_APP or ARG_FILE to set
 
220
         * cwd?  If ARG_FILE == NULL, use ARG_APP, otherwise use ARG_FILE */
 
221
        const gchar *cwd_root = args[ARG_FILE] == NULL ? args[ARG_APP] : args[ARG_FILE];
 
222
        gchar *working_dir = vfs_file_is_directory (cwd_root) ? g_strdup (cwd_root) : g_path_get_dirname (cwd_root);
 
223
        g_chdir (working_dir);
239
224
        g_free (working_dir);
240
225
 
 
226
        /* No agrs[ARG_APP] was NULL, open file with default mime handler */
 
227
        if (args[ARG_APP] == NULL) {
 
228
                GFile *file = g_file_new_for_path (args[ARG_FILE]);
 
229
                gchar *uri = g_file_get_uri (file);
 
230
                ret = g_app_info_launch_default_for_uri (uri, NULL, &error);
 
231
                utils_gerror_ok (&error, TRUE);
 
232
                g_free (uri);
 
233
                g_object_unref (file);
 
234
        }
 
235
        else {
 
236
                GAppInfo *app_info = NULL;
 
237
                if (vfs_file_is_desktop (args[ARG_APP])) {
 
238
                        app_info = G_APP_INFO (g_desktop_app_info_new_from_filename (args[ARG_APP]));
 
239
                }
 
240
                else {
 
241
                        command_line = vfs_file_is_executable (args[ARG_APP]) ?
 
242
                                utils_escape_str (args[ARG_APP], " ", "\\ ") : g_strdup (args[ARG_APP]);
 
243
                        app_info = g_app_info_create_from_commandline (command_line, NULL, 0, &error);
 
244
                        utils_gerror_ok (&error, TRUE);
 
245
                }
 
246
 
 
247
                if (app_info) {
 
248
                        ret = g_app_info_launch (app_info, files, NULL, &error);
 
249
                        utils_gerror_ok (&error, TRUE);
 
250
                        g_object_unref (app_info);
 
251
                }
 
252
                else {
 
253
                        gchar *msg = g_strdup_printf (_("Could not open \"%s\".\n"), args[ARG_FILE]);
 
254
                        utils_show_dialog (_("Error"), msg, GTK_MESSAGE_ERROR);
 
255
                        g_free (msg);
 
256
                }
 
257
        }
 
258
        g_list_foreach (files, (GFunc)g_object_unref, NULL);
 
259
        g_list_free (files);
 
260
        g_free (command_line);
 
261
 
 
262
        g_chdir (g_get_home_dir());
 
263
 
241
264
        return ret;
242
265
}
243
266
/******************************************************************************/
244
267
gboolean
245
268
vfs_file_do_default_action (const gchar *file_name) {
246
 
        if (DEBUG) g_printf ("In %s\n", __FUNCTION__);
247
 
 
248
 
        LaunchInfo *launch_info = g_new0 (LaunchInfo, 1);
249
 
 
250
 
        /*Try launching file as desktop file first*/
251
 
        if (vfs_file_is_desktop (file_name)) {
252
 
                GDesktopAppInfo *app_info = g_desktop_app_info_new_from_filename (file_name);
253
 
                launch_info->command = g_strdup (g_app_info_get_executable (G_APP_INFO (app_info)));
254
 
                launch_info->file = NULL;
255
 
                g_object_unref (app_info);
256
 
        }
257
 
        /* run it if its an executable */
258
 
        else if (vfs_file_is_executable (file_name)) {
259
 
                launch_info->command = g_strdup (file_name);
260
 
                /* need to do this in case the path or filename has spaces in it since
261
 
                 * the spaces are converted to '\1' in vfs_launch_application.
262
 
                 * vfs_launch_application will convert the '\2' back to a space. */
263
 
                g_strdelimit (launch_info->command, " ", '\2');
264
 
                launch_info->file = NULL;
 
269
        gchar **args = g_strv_new (ARGS_SIZE);
 
270
        gchar *_file_name = g_strdup (file_name);
 
271
 
 
272
        if (vfs_file_is_desktop (_file_name) ||
 
273
                vfs_file_is_executable (_file_name)) {
 
274
                args[ARG_APP] = _file_name;
265
275
        }
266
276
        /* open it with the default mime app */
267
277
        else {
268
 
                launch_info->command = vfs_get_default_mime_application (file_name);
269
 
                launch_info->file =  g_strdup (file_name);
270
 
        }
271
 
 
272
 
        gboolean ret = FALSE;
273
 
        if (launch_info->command) {
274
 
                ret = vfs_launch_application (launch_info);
275
 
        }
276
 
        else {
277
 
                gchar *msg = g_strdup_printf ("Could not display \"%s\".\n"
278
 
                                                                          "There is no application installed for this file type.", file_name);
279
 
                utils_show_dialog ("Error", msg, GTK_MESSAGE_ERROR);
280
 
                g_free (msg);
281
 
        }
282
 
 
283
 
        g_free (launch_info->command);
284
 
        g_free (launch_info->file);
285
 
        g_free (launch_info);
286
 
 
 
278
                args[ARG_FILE] = _file_name;
 
279
        }
 
280
        gboolean ret = vfs_launch_application ((const gchar*const*)args);
 
281
        g_strfreev (args);
287
282
        return ret;
288
283
}
289
284
/******************************************************************************/