示例#1
0
/*
* Run default action of specified file.
* Full path of the file is required by this function.
*/
gboolean vfs_file_info_open_file( VFSFileInfo* fi,
                                  const char* file_path,
                                  GError** err )
{
    VFSMimeType * mime_type;
    char* app_name;
    VFSAppDesktop* app;
    GList* files = NULL;
    gboolean ret = FALSE;
    char* argv[ 2 ];

    if ( vfs_file_info_is_executable( fi, file_path ) )
    {
        argv[ 0 ] = (char *) file_path;
        argv[ 1 ] = '\0';
        ret = g_spawn_async( NULL, argv, NULL, G_SPAWN_STDOUT_TO_DEV_NULL|
                             G_SPAWN_SEARCH_PATH, NULL, NULL, NULL, err );
    }
    else
    {
        mime_type = vfs_file_info_get_mime_type( fi );
        app_name = vfs_mime_type_get_default_action( mime_type );
        if ( app_name )
        {
            app = vfs_app_desktop_new( app_name );
            if ( ! vfs_app_desktop_get_exec( app ) )
                app->exec = g_strdup( app_name );   /* FIXME: app->exec */
            files = g_list_prepend( files, (gpointer) file_path );
            /* FIXME: working dir is needed */
            ret = vfs_app_desktop_open_files( gdk_screen_get_default(),
                                              NULL, app, files, err );
            g_list_free( files );
            vfs_app_desktop_unref( app );
            g_free( app_name );
        }
        vfs_mime_type_unref( mime_type );
    }
    return ret;
}
示例#2
0
/*
* Parse Exec command line of app desktop file, and translate
* it into a real command which can be passed to g_spawn_command_line_async().
* file_list is a null-terminated file list containing full
* paths of the files passed to app.
* returned char* should be freed when no longer needed.
*/
static char* translate_app_exec_to_command_line( VFSAppDesktop* app,
                                                 GList* file_list )
{
    const char* pexec = vfs_app_desktop_get_exec( app );
    char* file;
    GList* l;
    gchar *tmp;
    GString* cmd = g_string_new("");
    gboolean add_files = FALSE;

    for( ; *pexec; ++pexec )
    {
        if( *pexec == '%' )
        {
            ++pexec;
            switch( *pexec )
            {
            case 'U':
                for( l = file_list; l; l = l->next )
                {
                    tmp = g_filename_to_uri( (char*)l->data, NULL, NULL );
                    file = g_shell_quote( tmp );
                    g_free( tmp );
                    g_string_append( cmd, file );
                    g_string_append_c( cmd, ' ' );
                    g_free( file );
                }
                add_files = TRUE;
                break;
            case 'u':
                if( file_list && file_list->data )
                {
                    file = (char*)file_list->data;
                    tmp = g_filename_to_uri( file, NULL, NULL );
                    file = g_shell_quote( tmp );
                    g_free( tmp );
                    g_string_append( cmd, file );
                    g_free( file );
                    add_files = TRUE;
                }
                break;
            case 'F':
            case 'N':
                for( l = file_list; l; l = l->next )
                {
                    file = (char*)l->data;
                    tmp = g_shell_quote( file );
                    g_string_append( cmd, tmp );
                    g_string_append_c( cmd, ' ' );
                    g_free( tmp );
                }
                add_files = TRUE;
                break;
            case 'f':
            case 'n':
                if( file_list && file_list->data )
                {
                    file = (char*)file_list->data;
                    tmp = g_shell_quote( file );
                    g_string_append( cmd, tmp );
                    g_free( tmp );
                    add_files = TRUE;
                }
                break;
            case 'D':
                for( l = file_list; l; l = l->next )
                {
                    tmp = g_path_get_dirname( (char*)l->data );
                    file = g_shell_quote( tmp );
                    g_free( tmp );
                    g_string_append( cmd, file );
                    g_string_append_c( cmd, ' ' );
                    g_free( file );
                }
                add_files = TRUE;
                break;
            case 'd':
                if( file_list && file_list->data )
                {
                    tmp = g_path_get_dirname( (char*)file_list->data );
                    file = g_shell_quote( tmp );
                    g_free( tmp );
                    g_string_append( cmd, file );
                    g_free( tmp );
                    add_files = TRUE;
                }
                break;
            case 'c':
                g_string_append( cmd, vfs_app_desktop_get_disp_name( app ) );
                break;
            case 'i':
                /* Add icon name */
                if( vfs_app_desktop_get_icon_name( app ) )
                {
                    g_string_append( cmd, "--icon " );
                    g_string_append( cmd, vfs_app_desktop_get_icon_name( app ) );
                }
                break;
            case 'k':
                /* Location of the desktop file */
                break;
            case 'v':
                /* Device name */
                break;
            case '%':
                g_string_append_c ( cmd, '%' );
                break;
            case '\0':
                goto _finish;
                break;
            }
        }
        else  /* not % escaped part */
        {
            g_string_append_c ( cmd, *pexec );
        }
    }
_finish:
    if( ! add_files )
    {
        g_string_append_c ( cmd, ' ' );
        for( l = file_list; l; l = l->next )
        {
            file = (char*)l->data;
            tmp = g_shell_quote( file );
            g_string_append( cmd, tmp );
            g_string_append_c( cmd, ' ' );
            g_free( tmp );
        }
    }

    return g_string_free( cmd, FALSE );
}
示例#3
0
gboolean vfs_app_desktop_open_files( GdkScreen* screen,
                                     const char* working_dir,
                                     VFSAppDesktop* app,
                                     GList* file_paths,
                                     GError** err )
{
    char* exec = NULL;
    char* cmd;
    GList* l;
    gchar** argv = NULL;
    gint argc = 0;
    const char* sn_desc;

    if( vfs_app_desktop_get_exec( app ) )
    {
        if ( ! strchr( vfs_app_desktop_get_exec( app ), '%' ) )
        { /* No filename parameters */
            exec = g_strconcat( vfs_app_desktop_get_exec( app ), " %f", NULL );
        }
        else
        {
            exec = g_strdup( vfs_app_desktop_get_exec( app ) );
        }
    }

    if ( exec )
    {
        if( !screen )
            screen = gdk_screen_get_default();

        sn_desc = vfs_app_desktop_get_disp_name( app );
        if( !sn_desc )
            sn_desc = exec;

        if( vfs_app_desktop_open_multiple_files( app ) )
        {
            cmd = translate_app_exec_to_command_line( app, file_paths );
            if ( cmd )
            {
                if ( vfs_app_desktop_open_in_terminal( app ) )
                    exec_in_terminal( sn_desc,
                                      app->path && app->path[0] ? app->path :
                                                                  working_dir,
                                      cmd );
                else
                {
                    /* g_debug( "Execute %s\n", cmd ); */
                    if( g_shell_parse_argv( cmd, &argc, &argv, NULL ) )
                    {
                        vfs_exec_on_screen( screen,
                                            app->path && app->path[0] ?
                                                app->path : working_dir,
                                            argv, NULL,
                                            sn_desc,
                                            VFS_EXEC_DEFAULT_FLAGS,
                                            err );
                        g_strfreev( argv );
                    }
                }
                g_free( cmd );
            }
        }
        else
        {
            // app does not accept multiple files, so run multiple times
            GList* single;
            l = file_paths;
            do
            {
                if ( l )
                {
                    // just pass a single file path to translate
                    single = g_list_append( NULL, l->data );
                }
                else
                {
                    // there are no files being passed, just run once
                    single = NULL;
                }
                cmd = translate_app_exec_to_command_line( app, single );
                g_list_free( single );
                if ( cmd )
                {
                    if ( vfs_app_desktop_open_in_terminal( app ) )
                        exec_in_terminal( sn_desc, 
                                          app->path && app->path[0] ? app->path
                                                                    : working_dir,
                                          cmd );
                    else
                    {
                        /* g_debug( "Execute %s\n", cmd ); */
                        if( g_shell_parse_argv( cmd, &argc, &argv, NULL ) )
                        {
                            vfs_exec_on_screen( screen,
                                                app->path && app->path[0] ?
                                                    app->path : working_dir,
                                                argv, NULL, sn_desc,
                                                G_SPAWN_SEARCH_PATH|
                                                G_SPAWN_STDOUT_TO_DEV_NULL|
                                                G_SPAWN_STDERR_TO_DEV_NULL,
                                    err );
                            g_strfreev( argv );
                        }
                    }
                    g_free( cmd );
                }
            } while ( l = l ? l->next : NULL );
        }
        g_free( exec );
        return TRUE;
    }

    g_set_error( err, G_SPAWN_ERROR, G_SPAWN_ERROR_FAILED, _("Command not found") );
    return FALSE;
}