📄 ptk-file-list.c
字号:
icon = vfs_file_info_get_small_thumbnail( info ); if( !icon ) icon = vfs_file_info_get_small_icon( info ); if( icon ) { g_value_set_object( value, icon ); gdk_pixbuf_unref( icon ); } break; case COL_FILE_NAME: g_value_set_string( value, vfs_file_info_get_disp_name(info) ); break; case COL_FILE_SIZE: g_value_set_string( value, vfs_file_info_get_disp_size(info) ); break; case COL_FILE_DESC: g_value_set_string( value, vfs_file_info_get_mime_type_desc( info ) ); break; case COL_FILE_PERM: g_value_set_string( value, vfs_file_info_get_disp_perm(info) ); break; case COL_FILE_OWNER: g_value_set_string( value, vfs_file_info_get_disp_owner(info) ); break; case COL_FILE_MTIME: g_value_set_string( value, vfs_file_info_get_disp_mtime(info) ); break; case COL_FILE_INFO: vfs_file_info_ref( info ); g_value_set_pointer( value, info ); break; }}gboolean ptk_file_list_iter_next ( GtkTreeModel *tree_model, GtkTreeIter *iter ){ GList* l; PtkFileList* list; g_return_val_if_fail (PTK_IS_FILE_LIST (tree_model), FALSE); if (iter == NULL || iter->user_data == NULL) return FALSE; list = PTK_FILE_LIST(tree_model); l = (GList *) iter->user_data; /* Is this the last l in the list? */ if ( ! l->next ) return FALSE; iter->stamp = list->stamp; iter->user_data = l->next; iter->user_data2 = l->next->data; return TRUE;}gboolean ptk_file_list_iter_children ( GtkTreeModel *tree_model, GtkTreeIter *iter, GtkTreeIter *parent ){ PtkFileList* list; g_return_val_if_fail ( parent == NULL || parent->user_data != NULL, FALSE ); /* this is a list, nodes have no children */ if ( parent ) return FALSE; /* parent == NULL is a special case; we need to return the first top-level row */ g_return_val_if_fail ( PTK_IS_FILE_LIST ( tree_model ), FALSE ); list = PTK_FILE_LIST( tree_model ); /* No rows => no first row */ if ( list->dir->n_files == 0 ) return FALSE; /* Set iter to first item in list */ iter->stamp = list->stamp; iter->user_data = list->files; iter->user_data2 = list->files->data; return TRUE;}gboolean ptk_file_list_iter_has_child ( GtkTreeModel *tree_model, GtkTreeIter *iter ){ return FALSE;}gint ptk_file_list_iter_n_children ( GtkTreeModel *tree_model, GtkTreeIter *iter ){ PtkFileList* list; g_return_val_if_fail ( PTK_IS_FILE_LIST ( tree_model ), -1 ); g_return_val_if_fail ( iter == NULL || iter->user_data != NULL, FALSE ); list = PTK_FILE_LIST( tree_model ); /* special case: if iter == NULL, return number of top-level rows */ if ( !iter ) return list->n_files; return 0; /* otherwise, this is easy again for a list */}gboolean ptk_file_list_iter_nth_child ( GtkTreeModel *tree_model, GtkTreeIter *iter, GtkTreeIter *parent, gint n ){ GList* l; PtkFileList* list; g_return_val_if_fail (PTK_IS_FILE_LIST (tree_model), FALSE); list = PTK_FILE_LIST(tree_model); /* a list has only top-level rows */ if(parent) return FALSE; /* special case: if parent == NULL, set iter to n-th top-level row */ if( n >= list->n_files || n < 0 ) return FALSE; l = g_list_nth( list->files, n ); g_assert( l != NULL ); iter->stamp = list->stamp; iter->user_data = l; iter->user_data2 = l->data; return TRUE;}gboolean ptk_file_list_iter_parent ( GtkTreeModel *tree_model, GtkTreeIter *iter, GtkTreeIter *child ){ return FALSE;}gboolean ptk_file_list_get_sort_column_id( GtkTreeSortable* sortable, gint* sort_column_id, GtkSortType* order ){ PtkFileList* list = (PtkFileList*)sortable; if( sort_column_id ) *sort_column_id = list->sort_col; if( order ) *order = list->sort_order; return TRUE;}void ptk_file_list_set_sort_column_id( GtkTreeSortable* sortable, gint sort_column_id, GtkSortType order ){ PtkFileList* list = (PtkFileList*)sortable; if( list->sort_col == sort_column_id && list->sort_order == order ) return; list->sort_col = sort_column_id; list->sort_order = order; gtk_tree_sortable_sort_column_changed (sortable); ptk_file_list_sort (list);}void ptk_file_list_set_sort_func( GtkTreeSortable *sortable, gint sort_column_id, GtkTreeIterCompareFunc sort_func, gpointer user_data, GtkDestroyNotify destroy ){ g_warning( "ptk_file_list_set_sort_func: Not supported\n" );}void ptk_file_list_set_default_sort_func( GtkTreeSortable *sortable, GtkTreeIterCompareFunc sort_func, gpointer user_data, GtkDestroyNotify destroy ){ g_warning( "ptk_file_list_set_default_sort_func: Not supported\n" );}static gint ptk_file_list_compare( gconstpointer a, gconstpointer b, gpointer user_data){ VFSFileInfo* file1 = (VFSFileInfo*)a; VFSFileInfo* file2 = (VFSFileInfo*)b; PtkFileList* list = (PtkFileList*)user_data; int ret; /* put folders before files */ ret = vfs_file_info_is_dir(file1) - vfs_file_info_is_dir(file2); if( ret ) return -ret; /* FIXME: strings should not be treated as ASCII when sorted */ switch( list->sort_col ) { case COL_FILE_NAME: ret = g_ascii_strcasecmp( vfs_file_info_get_disp_name(file1), vfs_file_info_get_disp_name(file2) ); break; case COL_FILE_SIZE: ret = file1->size - file2->size; break; case COL_FILE_DESC: ret = g_ascii_strcasecmp( vfs_file_info_get_mime_type_desc(file1), vfs_file_info_get_mime_type_desc(file2) ); break; case COL_FILE_PERM: ret = g_ascii_strcasecmp( vfs_file_info_get_disp_perm(file1), vfs_file_info_get_disp_perm(file2) ); break; case COL_FILE_OWNER: ret = g_ascii_strcasecmp( vfs_file_info_get_disp_owner(file1), vfs_file_info_get_disp_owner(file2) ); break; case COL_FILE_MTIME: ret = file1->mtime - file2->mtime; break; } return list->sort_order == GTK_SORT_ASCENDING ? ret : -ret;}void ptk_file_list_sort ( PtkFileList* list ){ GHashTable* old_order; gint *new_order; GtkTreePath *path; GList* l; int i; if( list->n_files <=1 ) return; old_order = g_hash_table_new( g_direct_hash, g_direct_equal ); /* save old order */ for( i = 0, l = list->files; l; l = l->next, ++i ) g_hash_table_insert( old_order, l, GINT_TO_POINTER(i) ); /* sort the list */ list->files = g_list_sort_with_data( list->files, ptk_file_list_compare, list ); /* save new order */ new_order = g_new( int, list->n_files ); for( i = 0, l = list->files; l; l = l->next, ++i ) new_order[i] = (guint)g_hash_table_lookup( old_order, l ); g_hash_table_destroy( old_order ); path = gtk_tree_path_new (); gtk_tree_model_rows_reordered (GTK_TREE_MODEL (list), path, NULL, new_order); gtk_tree_path_free (path); g_free( new_order );}void ptk_file_list_file_created( VFSDir* dir, VFSFileInfo* file, PtkFileList* list ){ GList* l; GtkTreeIter it; GtkTreePath* path; VFSFileInfo* file2; if( ! list->show_hidden && vfs_file_info_get_name(file)[0] == '.' ) return; for( l = list->files; l; l = l->next ) { file2 = (VFSFileInfo*)l->data; if( ptk_file_list_compare( file2, file, list ) >= 0 ) { break; } } list->files = g_list_insert_before( list->files, l, file ); vfs_file_info_ref( file ); ++list->n_files; if( l ) l = l->prev; else l = g_list_last( list->files ); it.stamp = list->stamp; it.user_data = l; it.user_data2 = file; path = gtk_tree_path_new_from_indices( g_list_index(list->files, l->data), -1 ); gtk_tree_model_row_inserted( GTK_TREE_MODEL(list), path, &it ); gtk_tree_path_free( path );}void ptk_file_list_file_deleted( VFSDir* dir, VFSFileInfo* file, PtkFileList* list ){ GList* l; GtkTreePath* path; if( ! list->show_hidden && vfs_file_info_get_name(file)[0] == '.' ) return; l = g_list_find( list->files, file ); if( ! l ) return; path = gtk_tree_path_new_from_indices( g_list_index(list->files, l->data), -1 ); gtk_tree_model_row_deleted( GTK_TREE_MODEL(list), path ); gtk_tree_path_free( path ); list->files = g_list_delete_link( list->files, l ); vfs_file_info_unref( file ); --list->n_files;}void ptk_file_list_file_changed( VFSDir* dir, VFSFileInfo* file, PtkFileList* list ){ GList* l; GtkTreeIter it; GtkTreePath* path; if( ! list->show_hidden && vfs_file_info_get_name(file)[0] == '.' ) return; l = g_list_find( list->files, file ); if( ! l ) return; it.stamp = list->stamp; it.user_data = l; it.user_data2 = l->data; path = gtk_tree_path_new_from_indices( g_list_index(list->files, l->data), -1 ); gtk_tree_model_row_changed( GTK_TREE_MODEL(list), path, &it ); gtk_tree_path_free( path );}void ptk_file_list_show_thumbnails( PtkFileList* list, gboolean big, int max_file_size ){ GList* l; VFSFileInfo* file; list->max_thumbnail = max_file_size; /* FIXME: This is extremely buggy!!! must be fixed before release Loading of big icons and small ones should be separate threads. */ if( 0 == max_file_size ) return; for( l = list->files; l; l = l->next ) { file = (VFSFileInfo*)l->data; if( vfs_file_info_is_image( file ) && vfs_file_info_get_size( file ) < list->max_thumbnail ) { if( vfs_file_info_is_thumbnail_loaded( file, big ) ) ptk_file_list_file_changed( list->dir, file, list ); else vfs_dir_request_thumbnail( list->dir, file, big ); } }}#if 0/* I still have doubt if this works */void ptk_file_list_show_hidden_files( PtkFileList* list ){ GList *l, *l2, *new_item; VFSFileInfo* info; int i = 0; GtkTreePath* path; GtkTreeIter it; if( list->show_hidden ) return; for( l = list->dir->file_list; l; l = l->next ) { info = (VFSFileInfo*)l->data; if( vfs_file_info_get_disp_name(info)[0] != '.' ) continue; for( i = 0, l2 = list->files; l2; l2 = l2->next, ++i ) { if( ptk_file_list_compare(info, l2->data, list) >= 0 ) { list->files = g_list_insert_before( list->files, info, l2 ); it.user_data = l2->prev; it.user_data2 = info; it.stamp = list->stamp; path = gtk_tree_path_new_from_indices(i, -1); gtk_tree_model_row_inserted( list, path, &it ); gtk_tree_path_free( path ); break; } } }}void ptk_file_list_hide_hidden_files( PtkFileList* list ){ GList* l; VFSFileInfo* info; GtkTreePath* path; if( ! list->show_hidden ) return; path = gtk_tree_path_new_first(); for( l = list->files; l; ) { info = (VFSFileInfo*)l->data; /* hidden file */ if( G_UNLIKELY(vfs_file_info_get_disp_name(info)[0] == '.') ) { l = l->next; list->files = g_list_delete_link( list->files, l->prev ); gtk_tree_model_row_deleted( GTK_TREE_MODEL(list), path ); } else { l = l->next; gtk_tree_path_next( path ); } } gtk_tree_path_free( path );}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -