Пример #1
0
void vfs_file_info_load_special_info( VFSFileInfo* fi,
                                      const char* file_path )
{
    /*if ( G_LIKELY(fi->type) && G_UNLIKELY(fi->type->name, "application/x-desktop") ) */
    if ( G_UNLIKELY( g_str_has_suffix( fi->name, ".desktop") ) )
    {    
        VFSAppDesktop * desktop;
        const char* icon_name;

        if ( !desktop_dir )
            desktop_dir = vfs_get_desktop_dir();
        char* file_dir = g_path_get_dirname( file_path );

        fi->flags |= VFS_FILE_INFO_DESKTOP_ENTRY;
        desktop = vfs_app_desktop_new( file_path );

        //MOD  display real filenames of .desktop files not in desktop folder
        if ( desktop_dir && !strcmp( file_dir, desktop_dir ) )
        {
            if ( vfs_app_desktop_get_disp_name( desktop ) )
            {
                vfs_file_info_set_disp_name(
                    fi, vfs_app_desktop_get_disp_name( desktop ) );
            }
        }

        if ( (icon_name = vfs_app_desktop_get_icon_name( desktop )) )
        {
            GdkPixbuf* icon;
            int big_size, small_size;
            vfs_mime_type_get_icon_size( &big_size, &small_size );
            if( ! fi->big_thumbnail )
            {
                icon = vfs_app_desktop_get_icon( desktop, big_size, FALSE );
                if( G_LIKELY(icon) )
                    fi->big_thumbnail =icon;
            }
            if( ! fi->small_thumbnail )
            {
                icon = vfs_app_desktop_get_icon( desktop, small_size, FALSE );
                if( G_LIKELY(icon) )
                    fi->small_thumbnail =icon;
            }
        }
        vfs_app_desktop_unref( desktop );
        g_free( file_dir );
    }
}
Пример #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
GtkWidget* file_properties_dlg_new( GtkWindow* parent,
                                    const char* dir_path,
                                    GList* sel_files, int page )
{
    GtkBuilder* builder = _gtk_builder_new_from_file( PACKAGE_UI_DIR "/file_properties.ui", NULL );

    GtkWidget * dlg = (GtkWidget*)gtk_builder_get_object( builder, "dlg" );
    GtkNotebook* notebook = (GtkNotebook*)gtk_builder_get_object( builder, "notebook" );

    FilePropertiesDialogData* data;
    gboolean need_calc_size = TRUE;

    VFSFileInfo *file, *file2;
    VFSMimeType* mime;

    const char* multiple_files = _( "( multiple files )" );
    const char* calculating;
    GtkWidget* name = (GtkWidget*)gtk_builder_get_object( builder, "file_name" );
    GtkWidget* location = (GtkWidget*)gtk_builder_get_object( builder, "location" );
    gtk_editable_set_editable ( GTK_EDITABLE( location ), FALSE );
    GtkWidget* mime_type = (GtkWidget*)gtk_builder_get_object( builder, "mime_type" );
    GtkWidget* open_with = (GtkWidget*)gtk_builder_get_object( builder, "open_with" );

    GtkWidget* mtime = (GtkWidget*)gtk_builder_get_object( builder, "mtime" );
    GtkWidget* atime = (GtkWidget*)gtk_builder_get_object( builder, "atime" );

    char buf[ 64 ];
    char buf2[ 32 ];
    const char* time_format = "%Y-%m-%d %H:%M";

    gchar* disp_path;
    gchar* file_type;

    int i;
    GList* l;
    gboolean same_type = TRUE;
    gboolean is_dirs = FALSE;
    char *owner_group, *tmp;

    gtk_dialog_set_alternative_button_order( GTK_DIALOG(dlg), GTK_RESPONSE_OK, GTK_RESPONSE_CANCEL, -1 );
    ptk_dialog_fit_small_screen( GTK_DIALOG(dlg) );

    int width = xset_get_int( "app_dlg", "s" );
    int height = xset_get_int( "app_dlg", "z" );
    if ( width && height )
        gtk_window_set_default_size( GTK_WINDOW( dlg ), width, height );

    data = g_slice_new0( FilePropertiesDialogData );
    /* FIXME: When will the data be freed??? */
    g_object_set_data( G_OBJECT( dlg ), "DialogData", data );
    data->file_list = sel_files;
    data->dlg = dlg;

    data->dir_path = g_strdup( dir_path );
    disp_path = g_filename_display_name( dir_path );
    //gtk_label_set_text( GTK_LABEL( location ), disp_path );
    gtk_entry_set_text( GTK_ENTRY( location ), disp_path );
    g_free( disp_path );

    data->total_size_label = GTK_LABEL( (GtkWidget*)gtk_builder_get_object( builder, "total_size" ) );
    data->size_on_disk_label = GTK_LABEL( (GtkWidget*)gtk_builder_get_object( builder, "size_on_disk" ) );
    data->count_label = GTK_LABEL( (GtkWidget*)gtk_builder_get_object( builder, "count" ) );
    data->owner = GTK_ENTRY( (GtkWidget*)gtk_builder_get_object( builder, "owner" ) );
    data->group = GTK_ENTRY( (GtkWidget*)gtk_builder_get_object( builder, "group" ) );

    for ( i = 0; i < N_CHMOD_ACTIONS; ++i )
    {
        data->chmod_btns[ i ] = GTK_TOGGLE_BUTTON( (GtkWidget*)gtk_builder_get_object( builder, chmod_names[ i ] ) );
    }

    //MOD
    VFSMimeType* type; 
    VFSMimeType* type2 = NULL;
    for ( l = sel_files; l ; l = l->next )
    {
        file = ( VFSFileInfo* ) l->data;
        type = vfs_file_info_get_mime_type( file );
        if ( !type2 )
            type2 = vfs_file_info_get_mime_type( file );
        if ( vfs_file_info_is_dir( file ) )
            is_dirs = TRUE;
        if ( type != type2 )
            same_type = FALSE;
        vfs_mime_type_unref( type );
        if ( is_dirs && !same_type )
            break;
    }
    if ( type2 )
        vfs_mime_type_unref( type2 );

    data->recurse = (GtkWidget*)gtk_builder_get_object( builder, "recursive" );
    gtk_widget_set_sensitive( data->recurse, is_dirs );

/*  //MOD
    for ( l = sel_files; l && l->next; l = l->next )
    {
        VFSMimeType *type, *type2;
        file = ( VFSFileInfo* ) l->data;
        file2 = ( VFSFileInfo* ) l->next->data;
        type = vfs_file_info_get_mime_type( file );
        type2 = vfs_file_info_get_mime_type( file2 );
        if ( type != type2 )
        {
            vfs_mime_type_unref( type );
            vfs_mime_type_unref( type2 );
            same_type = FALSE;
            break;
        }
        vfs_mime_type_unref( type );
        vfs_mime_type_unref( type2 );
    }
*/

    file = ( VFSFileInfo* ) sel_files->data;
    if ( same_type )
    {
        mime = vfs_file_info_get_mime_type( file );
        file_type = g_strdup_printf( "%s ( %s )",
                                     vfs_mime_type_get_description( mime ),
                                     vfs_mime_type_get_type( mime ) );
        gtk_label_set_text( GTK_LABEL( mime_type ), file_type );
        g_free( file_type );
        vfs_mime_type_unref( mime );
    }
    else
    {
        gtk_label_set_text( GTK_LABEL( mime_type ), _( "( multiple types )" ) );
    }

    /* Open with...
     * Don't show this option menu if files of different types are selected,
     * ,the selected file is a folder, or its type is unknown.
     */
    if( ! same_type ||
          vfs_file_info_is_dir( file ) ||
          vfs_file_info_is_desktop_entry( file ) ||
          vfs_file_info_is_unknown_type( file ) ||
          vfs_file_info_is_executable( file, NULL ) )
    {
        /* if open with shouldn't show, destroy it. */
        gtk_widget_destroy( open_with );
        open_with = NULL;
        gtk_widget_destroy( (GtkWidget*)gtk_builder_get_object( builder, "open_with_label" ) );
    }
    else /* Add available actions to the option menu */
    {
        GtkTreeIter it;
        char **action, **actions;

        mime = vfs_file_info_get_mime_type( file );
        actions = vfs_mime_type_get_actions( mime );
        GtkCellRenderer* renderer;
        GtkListStore* model;
        gtk_cell_layout_clear( GTK_CELL_LAYOUT(open_with) );
        renderer = gtk_cell_renderer_pixbuf_new();
        gtk_cell_layout_pack_start( GTK_CELL_LAYOUT(open_with), renderer, FALSE);
        gtk_cell_layout_set_attributes( GTK_CELL_LAYOUT(open_with), renderer,
                                        "pixbuf", 0, NULL );
        renderer = gtk_cell_renderer_text_new();
        gtk_cell_layout_pack_start( GTK_CELL_LAYOUT(open_with), renderer, TRUE);
        gtk_cell_layout_set_attributes( GTK_CELL_LAYOUT(open_with),renderer,
                                        "text", 1, NULL );
        model = gtk_list_store_new( 3, GDK_TYPE_PIXBUF,
                                    G_TYPE_STRING,
                                    G_TYPE_STRING,
                                    G_TYPE_STRING );
        if( actions )
        {
            for( action = actions; *action; ++action )
            {
                VFSAppDesktop* desktop;
                GdkPixbuf* icon;
                desktop = vfs_app_desktop_new( *action );
                gtk_list_store_append( model, &it );
                icon = vfs_app_desktop_get_icon(desktop, 20, TRUE);
                gtk_list_store_set( model, &it,
                                    0, icon,
                                    1, vfs_app_desktop_get_disp_name(desktop),
                                    2, *action, -1 );
                if( icon )
                    g_object_unref( icon );
                vfs_app_desktop_unref( desktop );
            }
        }
        else
        {
            g_object_set_data( G_OBJECT(open_with), "prev_sel", GINT_TO_POINTER(-1) );
        }

        /* separator */
        gtk_list_store_append( model, &it );

        gtk_list_store_append( model, &it );
        gtk_list_store_set( model, &it,
                            0, NULL,
                            1, _("Choose..."), -1 );
        gtk_combo_box_set_model( GTK_COMBO_BOX(open_with),
                                 GTK_TREE_MODEL(model) );
        gtk_combo_box_set_row_separator_func(
                GTK_COMBO_BOX(open_with), combo_sep,
                NULL, NULL );
        gtk_combo_box_set_active(GTK_COMBO_BOX(open_with), 0);
        g_signal_connect( open_with, "changed",
                          G_CALLBACK(on_combo_change), mime );

        /* vfs_mime_type_unref( mime ); */
        /* We can unref mime when combo box gets destroyed */
        g_object_weak_ref( G_OBJECT(open_with),
                           (GWeakNotify)vfs_mime_type_unref, mime );
    }
    g_object_set_data( G_OBJECT(dlg), "open_with", open_with );

    /* Multiple files are selected */
    if ( sel_files && sel_files->next )
    {
        gtk_widget_set_sensitive( name, FALSE );
        gtk_entry_set_text( GTK_ENTRY( name ), multiple_files );

        gtk_label_set_text( GTK_LABEL( mtime ), "-" );
        gtk_label_set_text( GTK_LABEL( atime ), "-" );

        for ( i = 0; i < N_CHMOD_ACTIONS; ++i )
        {
            gtk_toggle_button_set_inconsistent ( data->chmod_btns[ i ], TRUE );
            data->chmod_states[ i ] = 2; /* Don't touch this bit */
            g_signal_connect( G_OBJECT( data->chmod_btns[ i ] ), "toggled",
                              G_CALLBACK( on_chmod_btn_toggled ), data );
        }
    }
    else
    {
        /* special processing for files with special display names */
        if( vfs_file_info_is_desktop_entry( file ) )
        {
            char* disp_name = g_filename_display_name( file->name );
            gtk_entry_set_text( GTK_ENTRY( name ),
                                disp_name );
            g_free( disp_name );
        }
        else
            gtk_entry_set_text( GTK_ENTRY( name ),
                                vfs_file_info_get_disp_name( file ) );

        gtk_editable_set_editable ( GTK_EDITABLE( name ), FALSE );

        if ( ! vfs_file_info_is_dir( file ) )
        {
            /* Only single "file" is selected, so we don't need to
                caculate total file size */
            need_calc_size = FALSE;

            sprintf( buf, _("%s  ( %llu bytes )"),
                     vfs_file_info_get_disp_size( file ),
                     ( guint64 ) vfs_file_info_get_size( file ) );
            gtk_label_set_text( data->total_size_label, buf );

            vfs_file_size_to_string( buf2,
                                 vfs_file_info_get_blocks( file ) * 512 );
            sprintf( buf, _("%s  ( %llu bytes )"), buf2,
                     ( guint64 ) vfs_file_info_get_blocks( file ) * 512 );
            gtk_label_set_text( data->size_on_disk_label, buf );
            
            gtk_label_set_text( data->count_label, _("1 file") );
        }
        gtk_label_set_text( GTK_LABEL( mtime ),
                            vfs_file_info_get_disp_mtime( file ) );

        strftime( buf, sizeof( buf ),
                  time_format, localtime( vfs_file_info_get_atime( file ) ) );
        gtk_label_set_text( GTK_LABEL( atime ), buf );

        owner_group = (char *) vfs_file_info_get_disp_owner( file );
        tmp = strchr( owner_group, ':' );
        data->owner_name = g_strndup( owner_group, tmp - owner_group );
        gtk_entry_set_text( GTK_ENTRY( data->owner ), data->owner_name );
        data->group_name = g_strdup( tmp + 1 );
        gtk_entry_set_text( GTK_ENTRY( data->group ), data->group_name );

        for ( i = 0; i < N_CHMOD_ACTIONS; ++i )
        {
            if ( data->chmod_states[ i ] != 2 ) /* allow to touch this bit */
            {
                data->chmod_states[ i ] = ( vfs_file_info_get_mode( file ) & chmod_flags[ i ] ? 1 : 0 );
                gtk_toggle_button_set_active( data->chmod_btns[ i ], data->chmod_states[ i ] );
            }
        }
    }

    if ( need_calc_size )
    {
        /* The total file size displayed in "File Properties" is not
           completely calculated yet. So "Calculating..." is displayed. */
        calculating = _( "Calculating..." );
        gtk_label_set_text( data->total_size_label, calculating );
        gtk_label_set_text( data->size_on_disk_label, calculating );

        g_object_set_data( G_OBJECT( dlg ), "calc_size", data );
        data->calc_size_thread = g_thread_create ( ( GThreadFunc ) calc_size,
                                                   data, TRUE, NULL );
        data->update_label_timer = g_timeout_add( 250,
                                                  ( GSourceFunc ) on_update_labels,
                                                  data );
    }

    g_signal_connect( dlg, "response",
                        G_CALLBACK(on_dlg_response), dlg );
    g_signal_connect_swapped( gtk_builder_get_object(builder, "ok_button"),
                        "clicked",
                        G_CALLBACK(gtk_widget_destroy), dlg );
    g_signal_connect_swapped( gtk_builder_get_object(builder, "cancel_button"),
                        "clicked",
                        G_CALLBACK(gtk_widget_destroy), dlg );
    
    g_object_unref( builder );

    gtk_notebook_set_current_page( notebook, page );

    gtk_window_set_transient_for( GTK_WINDOW( dlg ), parent );
    return dlg;
}
Пример #4
0
static void on_combo_change( GtkComboBox* combo, gpointer user_data )
{
    GtkTreeIter it;
    if( gtk_combo_box_get_active_iter(combo, &it) )
    {
        const char* action;
        GtkTreeModel* model = gtk_combo_box_get_model( combo );
        gtk_tree_model_get( model, &it, 2, &action, -1 );
        if( ! action )
        {
            char* action;
            GtkWidget* parent;
            VFSMimeType* mime = (VFSMimeType*)user_data;
            parent = gtk_widget_get_toplevel( GTK_WIDGET( combo ) );
            action = (char *) ptk_choose_app_for_mime_type( GTK_WINDOW(parent),
                                                   mime );
            if( action )
            {
                gboolean exist = FALSE;
                /* check if the action is already in the list */
                if( gtk_tree_model_get_iter_first( model, &it ) )
                {
                    do
                    {
                        char* tmp;
                        gtk_tree_model_get( model, &it, 2, &tmp, -1 );
                        if( !tmp )
                            continue;
                        if( 0 == strcmp( tmp, action ) )
                        {
                            exist = TRUE;
                            g_free( tmp );
                            break;
                        }
                        g_free( tmp );
                    } while( gtk_tree_model_iter_next( model, &it ) );
                }

                if( ! exist ) /* It didn't exist */
                {
                    VFSAppDesktop* app = vfs_app_desktop_new( action );
                    if( app )
                    {
                        GdkPixbuf* icon;
                        icon = vfs_app_desktop_get_icon( app, 20, TRUE );
                        gtk_list_store_insert_with_values(
                                            GTK_LIST_STORE( model ), &it, 0,
                                            0, icon,
                                            1, vfs_app_desktop_get_disp_name(app),
                                            2, action, -1 );
                        if( icon )
                            g_object_unref( icon );
                        vfs_app_desktop_unref( app );
                        exist = TRUE;
                    }
                }

                if( exist )
                    gtk_combo_box_set_active_iter( combo, &it );
                g_free( action );
            }
            else
            {
                int prev_sel;
                prev_sel = GPOINTER_TO_INT( g_object_get_data( G_OBJECT(combo), "prev_sel") );
                gtk_combo_box_set_active( combo, prev_sel );
            }
        }
        else
        {
            int prev_sel = gtk_combo_box_get_active( combo );
            g_object_set_data( G_OBJECT(combo), "prev_sel", GINT_TO_POINTER(prev_sel) );
        }
    }
    else
    {
        g_object_set_data( G_OBJECT(combo), "prev_sel", GINT_TO_POINTER(-1) );
    }
}
Пример #5
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;
}