⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 file-properties.c

📁 台湾人开发的Linux下的文件管理器
💻 C
📖 第 1 页 / 共 2 页
字号:
#ifdef HAVE_CONFIG_H#  include <config.h>#endif#include <gtk/gtk.h>#include "glib-mem.h"#include "file-properties.h"#include "file-properties-ui.h"#include "glade-support.h"#include "xdgmime.h"#include <sys/types.h>#include <pwd.h>#include <grp.h>#include <string.h>#include "ptk-file-task.h"#include "ptk-utils.h"#include "vfs-file-info.h"#include "vfs-app-desktop.h"const char* chmod_names[] =    {        "owner_r", "owner_w", "owner_x",        "group_r", "group_w", "group_x",        "others_r", "others_w", "others_x",        "set_uid", "set_gid", "sticky"    };typedef struct{    char* dir_path;    GList* file_list;    GtkWidget* dlg;    GtkEntry* owner;    GtkEntry* group;    char* owner_name;    char* group_name;    GtkToggleButton* chmod_btns[ N_CHMOD_ACTIONS ];    guchar chmod_states[ N_CHMOD_ACTIONS ];    GtkLabel* total_size_label;    GtkLabel* size_on_disk_label;    off_t total_size;    off_t size_on_disk;    guint total_count;    gboolean cancel;    gboolean done;    GThread* calc_size_thread;    guint update_label_timer;}FilePropertiesDialogData;/** void get_total_size_of_dir( const char* path, off_t* size )* Recursively count total size of all files in the specified directory.* If the path specified is a file, the size of the file is directly returned.* cancel is used to cancel the operation. This function will check the value* pointed by cancel in every iteration. If cancel is set to TRUE, the* calculation is cancelled.* NOTE: path is encoded in on-disk encoding and not necessarily UTF-8.*/static void calc_total_size_of_files( const char* path, FilePropertiesDialogData* data ){    GDir * dir;    const char* name;    char* full_path;    struct stat file_stat;    if ( data->cancel )        return ;    if ( lstat( path, &file_stat ) )        return ;    data->total_size += file_stat.st_size;    data->size_on_disk += ( file_stat.st_blocks << 9 ); /* block x 512 */    ++data->total_count;    dir = g_dir_open( path, 0, NULL );    if ( dir )    {        while ( !data->cancel && ( name = g_dir_read_name( dir ) ) )        {            full_path = g_build_filename( path, name, NULL );            lstat( full_path, &file_stat );            if ( S_ISDIR( file_stat.st_mode ) )            {                calc_total_size_of_files( full_path, data );            }            else            {                data->total_size += file_stat.st_size;                data->size_on_disk += ( file_stat.st_blocks << 9 );                ++data->total_count;            }            g_free( full_path );        }        g_dir_close( dir );    }}static gpointer calc_size( gpointer user_data ){    FilePropertiesDialogData * data = ( FilePropertiesDialogData* ) user_data;    GList* l;    char* path;    VFSFileInfo* file;    for ( l = data->file_list; l; l = l->next )    {        if ( data->cancel )            break;        file = ( VFSFileInfo* ) l->data;        path = g_build_filename( data->dir_path,                                 vfs_file_info_get_name( file ), NULL );        if ( path )        {            calc_total_size_of_files( path, data );            g_free( path );        }    }    data->done = TRUE;    return NULL;}gboolean on_update_labels( FilePropertiesDialogData* data ){    char buf[ 64 ];    char buf2[ 32 ];    gdk_threads_enter();    file_size_to_string( buf2, data->total_size );    sprintf( buf, "%s  (%llu Bytes)", buf2, ( guint64 ) data->total_size );    gtk_label_set_text( data->total_size_label, buf );    file_size_to_string( buf2, data->size_on_disk );    sprintf( buf, "%s  (%llu Bytes)", buf2, ( guint64 ) data->size_on_disk );    gtk_label_set_text( data->size_on_disk_label, buf );    gdk_threads_leave();    return !data->done;}static void on_chmod_btn_toggled( GtkToggleButton* btn,                                  FilePropertiesDialogData* data ){    /* Bypass the default handler */    g_signal_stop_emission_by_name( btn, "toggled" );    /* Block this handler while we are changing the state of buttons,      or this handler will be called recursively. */    g_signal_handlers_block_matched( btn, G_SIGNAL_MATCH_FUNC, 0,                                     0, NULL, on_chmod_btn_toggled, NULL );    if ( gtk_toggle_button_get_inconsistent( btn ) )    {        gtk_toggle_button_set_inconsistent( btn, FALSE );        gtk_toggle_button_set_active( btn, FALSE );    }    else if ( ! gtk_toggle_button_get_active( btn ) )    {        gtk_toggle_button_set_inconsistent( btn, TRUE );    }    g_signal_handlers_unblock_matched( btn, G_SIGNAL_MATCH_FUNC, 0,                                       0, NULL, on_chmod_btn_toggled, NULL );}static gboolean combo_sep( GtkTreeModel *model,                           GtkTreeIter* it,                           gpointer user_data ){    int i;    for( i = 2; i > 0; --i )    {        char* tmp;        gtk_tree_model_get( model, it, i, &tmp, -1 );        if( tmp )        {            g_free( tmp );            return FALSE;        }    }    return TRUE;}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 = 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 );                        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 )                            gdk_pixbuf_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( 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( combo, "prev_sel", GINT_TO_POINTER(prev_sel) );        }    }    else    {        g_object_set_data( combo, "prev_sel", GINT_TO_POINTER(-1) );    }}GtkWidget* file_properties_dlg_new( GtkWindow* parent,                                    const char* dir_path,                                    GList* sel_files ){    GtkWidget * dlg = create_filePropertiesDlg();    FilePropertiesDialogData* data;    gboolean need_calc_size = TRUE;    VFSFileInfo *file, *file2;    VFSMimeType* mime;    const char* multiple_files = _( "Multiple files are selected" );    const char* calculating;    GtkWidget* name = lookup_widget( dlg, "file_name" );    GtkWidget* location = lookup_widget( dlg, "location" );    GtkWidget* mime_type = lookup_widget( dlg, "mime_type" );    GtkWidget* open_with = lookup_widget( dlg, "open_with" );    GtkWidget* mtime = lookup_widget( dlg, "mtime" );    GtkWidget* atime = lookup_widget( dlg, "atime" );    char buf[ 64 ];    char buf2[ 32 ];    const char* time_format = "%Y-%m-%d %H:%M";    gchar* file_name;    gchar* disp_path;    gchar* file_path;    gchar* file_type;    int i;    GList* l;    gboolean same_type = TRUE;    char *owner_group, *tmp;    gtk_window_set_transient_for( GTK_WINDOW( dlg ), parent );    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 );    g_free( disp_path );    data->total_size_label = GTK_LABEL( lookup_widget( dlg, "total_size" ) );    data->size_on_disk_label = GTK_LABEL( lookup_widget( dlg, "size_on_disk" ) );    data->owner = GTK_ENTRY( lookup_widget( dlg, "owner" ) );    data->group = GTK_ENTRY( lookup_widget( dlg, "group" ) );    for ( i = 0; i < N_CHMOD_ACTIONS; ++i )    {        data->chmod_btns[ i ] = GTK_TOGGLE_BUTTON( lookup_widget( dlg, chmod_names[ i ] ) );    }    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 files of different 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_unknown_type( file ) ||          vfs_file_info_is_executable( file, NULL ) )    {        /* if open with shouldn't show, destroy it. */        gtk_widget_destroy( open_with );

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -