📄 ptk-file-list.c
字号:
/** C Implementation: ptk-file-list** Description: *** Author: Hong Jen Yee (PCMan) <pcman.tw (AT) gmail.com>, (C) 2006** Copyright: See COPYING file that comes with this distribution**/#include "ptk-file-list.h"#include <gdk/gdk.h>#include "glib-mem.h"#include "vfs-file-info.h"static void ptk_file_list_init ( PtkFileList *list );static void ptk_file_list_class_init ( PtkFileListClass *klass );static void ptk_file_list_tree_model_init ( GtkTreeModelIface *iface );static void ptk_file_list_tree_sortable_init ( GtkTreeSortableIface *iface );static void ptk_file_list_drag_source_init ( GtkTreeDragSourceIface *iface );static void ptk_file_list_drag_dest_init ( GtkTreeDragDestIface *iface );static void ptk_file_list_finalize ( GObject *object );static GtkTreeModelFlags ptk_file_list_get_flags ( GtkTreeModel *tree_model );static gint ptk_file_list_get_n_columns ( GtkTreeModel *tree_model );static GType ptk_file_list_get_column_type ( GtkTreeModel *tree_model, gint index );static gboolean ptk_file_list_get_iter ( GtkTreeModel *tree_model, GtkTreeIter *iter, GtkTreePath *path );static GtkTreePath *ptk_file_list_get_path ( GtkTreeModel *tree_model, GtkTreeIter *iter );static void ptk_file_list_get_value ( GtkTreeModel *tree_model, GtkTreeIter *iter, gint column, GValue *value );static gboolean ptk_file_list_iter_next ( GtkTreeModel *tree_model, GtkTreeIter *iter );static gboolean ptk_file_list_iter_children ( GtkTreeModel *tree_model, GtkTreeIter *iter, GtkTreeIter *parent );static gboolean ptk_file_list_iter_has_child ( GtkTreeModel *tree_model, GtkTreeIter *iter );static gint ptk_file_list_iter_n_children ( GtkTreeModel *tree_model, GtkTreeIter *iter );static gboolean ptk_file_list_iter_nth_child ( GtkTreeModel *tree_model, GtkTreeIter *iter, GtkTreeIter *parent, gint n );static gboolean ptk_file_list_iter_parent ( GtkTreeModel *tree_model, GtkTreeIter *iter, GtkTreeIter *child );static gboolean ptk_file_list_get_sort_column_id( GtkTreeSortable* sortable, gint* sort_column_id, GtkSortType* order );static void ptk_file_list_set_sort_column_id( GtkTreeSortable* sortable, gint sort_column_id, GtkSortType order );static void ptk_file_list_set_sort_func( GtkTreeSortable *sortable, gint sort_column_id, GtkTreeIterCompareFunc sort_func, gpointer user_data, GtkDestroyNotify destroy );static void ptk_file_list_set_default_sort_func( GtkTreeSortable *sortable, GtkTreeIterCompareFunc sort_func, gpointer user_data, GtkDestroyNotify destroy );static void ptk_file_list_sort ( PtkFileList* list );/* signal handlers */static void ptk_file_list_file_created( VFSDir* dir, VFSFileInfo* file, PtkFileList* list );static void ptk_file_list_file_deleted( VFSDir* dir, VFSFileInfo* file, PtkFileList* list );static void ptk_file_list_file_changed( VFSDir* dir, VFSFileInfo* file, PtkFileList* list );static GObjectClass* parent_class = NULL;static GType column_types[ N_FILE_LIST_COLS ];typedef struct _ThumbThreadData{ PtkFileList* list; gboolean big;}ThumbThreadData;GType ptk_file_list_get_type ( void ){ static GType type = 0; if ( G_UNLIKELY( !type ) ) { static const GTypeInfo type_info = { sizeof ( PtkFileListClass ), NULL, /* base_init */ NULL, /* base_finalize */ ( GClassInitFunc ) ptk_file_list_class_init, NULL, /* class finalize */ NULL, /* class_data */ sizeof ( PtkFileList ), 0, /* n_preallocs */ ( GInstanceInitFunc ) ptk_file_list_init }; static const GInterfaceInfo tree_model_info = { ( GInterfaceInitFunc ) ptk_file_list_tree_model_init, NULL, NULL }; static const GInterfaceInfo tree_sortable_info = { ( GInterfaceInitFunc ) ptk_file_list_tree_sortable_init, NULL, NULL }; static const GInterfaceInfo drag_src_info = { ( GInterfaceInitFunc ) ptk_file_list_drag_source_init, NULL, NULL }; static const GInterfaceInfo drag_dest_info = { ( GInterfaceInitFunc ) ptk_file_list_drag_dest_init, NULL, NULL }; type = g_type_register_static ( G_TYPE_OBJECT, "PtkFileList", &type_info, ( GTypeFlags ) 0 ); g_type_add_interface_static ( type, GTK_TYPE_TREE_MODEL, &tree_model_info ); g_type_add_interface_static ( type, GTK_TYPE_TREE_SORTABLE, &tree_sortable_info ); g_type_add_interface_static ( type, GTK_TYPE_TREE_DRAG_SOURCE, &drag_src_info ); g_type_add_interface_static ( type, GTK_TYPE_TREE_DRAG_DEST, &drag_dest_info ); } return type;}void ptk_file_list_init ( PtkFileList *list ){ list->n_files = 0; list->files = NULL; list->sort_order = -1; list->sort_col = -1; /* Random int to check whether an iter belongs to our model */ list->stamp = g_random_int();}void ptk_file_list_class_init ( PtkFileListClass *klass ){ GObjectClass * object_class; parent_class = ( GObjectClass* ) g_type_class_peek_parent ( klass ); object_class = ( GObjectClass* ) klass; object_class->finalize = ptk_file_list_finalize;}void ptk_file_list_tree_model_init ( GtkTreeModelIface *iface ){ iface->get_flags = ptk_file_list_get_flags; iface->get_n_columns = ptk_file_list_get_n_columns; iface->get_column_type = ptk_file_list_get_column_type; iface->get_iter = ptk_file_list_get_iter; iface->get_path = ptk_file_list_get_path; iface->get_value = ptk_file_list_get_value; iface->iter_next = ptk_file_list_iter_next; iface->iter_children = ptk_file_list_iter_children; iface->iter_has_child = ptk_file_list_iter_has_child; iface->iter_n_children = ptk_file_list_iter_n_children; iface->iter_nth_child = ptk_file_list_iter_nth_child; iface->iter_parent = ptk_file_list_iter_parent; column_types [ COL_FILE_BIG_ICON ] = GDK_TYPE_PIXBUF; column_types [ COL_FILE_SMALL_ICON ] = GDK_TYPE_PIXBUF; column_types [ COL_FILE_NAME ] = G_TYPE_STRING; column_types [ COL_FILE_DESC ] = G_TYPE_STRING; column_types [ COL_FILE_SIZE ] = G_TYPE_STRING; column_types [ COL_FILE_DESC ] = G_TYPE_STRING; column_types [ COL_FILE_PERM ] = G_TYPE_STRING; column_types [ COL_FILE_OWNER ] = G_TYPE_STRING; column_types [ COL_FILE_MTIME ] = G_TYPE_STRING; column_types [ COL_FILE_INFO ] = G_TYPE_POINTER;}void ptk_file_list_tree_sortable_init ( GtkTreeSortableIface *iface ){ /* iface->sort_column_changed = ptk_file_list_sort_column_changed; */ iface->get_sort_column_id = ptk_file_list_get_sort_column_id; iface->set_sort_column_id = ptk_file_list_set_sort_column_id; iface->set_sort_func = ptk_file_list_set_sort_func; iface->set_default_sort_func = ptk_file_list_set_default_sort_func; iface->has_default_sort_func = (gboolean(*)(GtkTreeSortable *))gtk_false;}void ptk_file_list_drag_source_init ( GtkTreeDragSourceIface *iface ){ /* FIXME: Unused. Will this cause any problem? */}void ptk_file_list_drag_dest_init ( GtkTreeDragDestIface *iface ){ /* FIXME: Unused. Will this cause any problem? */}void ptk_file_list_finalize ( GObject *object ){ PtkFileList *list = ( PtkFileList* ) object; ptk_file_list_set_dir( list, NULL ); /* must chain up - finalize parent */ ( * parent_class->finalize ) ( object );}PtkFileList *ptk_file_list_new ( VFSDir* dir, gboolean show_hidden ){ PtkFileList * list; list = ( PtkFileList* ) g_object_new ( PTK_TYPE_FILE_LIST, NULL ); list->show_hidden = show_hidden; ptk_file_list_set_dir( list, dir ); return list;}void ptk_file_list_set_dir( PtkFileList* list, VFSDir* dir ){ GList* l; int i; VFSFileInfo* file; if( list->dir == dir ) return; if ( list->dir ) { if( list->max_thumbnail > 0 ) { 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 ) { /* FIXME: vfs_dir_cancel_thumbnail_request( ); */ } } } g_list_foreach( list->files, (GFunc)vfs_file_info_unref, NULL ); g_list_free( list->files ); g_signal_handlers_disconnect_by_func( list->dir, ptk_file_list_file_created, list ); g_signal_handlers_disconnect_by_func( list->dir, ptk_file_list_file_deleted, list ); g_signal_handlers_disconnect_by_func( list->dir, ptk_file_list_file_changed, list ); vfs_dir_unref( list->dir ); } list->dir = dir; list->files = NULL; list->n_files = 0; if( ! dir ) return; vfs_dir_ref( list->dir ); g_signal_connect( list->dir, "file-created", G_CALLBACK(ptk_file_list_file_created), list ); g_signal_connect( list->dir, "file-deleted", G_CALLBACK(ptk_file_list_file_deleted), list ); g_signal_connect( list->dir, "file-changed", G_CALLBACK(ptk_file_list_file_changed), list ); if( dir && dir->file_list ) { for( l = dir->file_list; l; l = l->next ) { if( list->show_hidden || ((VFSFileInfo*)l->data)->disp_name[0] != '.' ) { list->files = g_list_prepend( list->files, l->data ); vfs_file_info_ref( (VFSFileInfo*)l->data ); ++list->n_files; } } }}GtkTreeModelFlags ptk_file_list_get_flags ( GtkTreeModel *tree_model ){ g_return_val_if_fail ( PTK_IS_FILE_LIST( tree_model ), ( GtkTreeModelFlags ) 0 ); return ( GTK_TREE_MODEL_LIST_ONLY | GTK_TREE_MODEL_ITERS_PERSIST );}gint ptk_file_list_get_n_columns ( GtkTreeModel *tree_model ){ return N_FILE_LIST_COLS;}GType ptk_file_list_get_column_type ( GtkTreeModel *tree_model, gint index ){ g_return_val_if_fail ( PTK_IS_FILE_LIST( tree_model ), G_TYPE_INVALID ); g_return_val_if_fail ( index < G_N_ELEMENTS( column_types ) && index >= 0, G_TYPE_INVALID ); return column_types[ index ];}gboolean ptk_file_list_get_iter ( GtkTreeModel *tree_model, GtkTreeIter *iter, GtkTreePath *path ){ PtkFileList *list; gint *indices, n, depth; GList* l; g_assert(PTK_IS_FILE_LIST(tree_model)); g_assert(path!=NULL); list = PTK_FILE_LIST(tree_model); indices = gtk_tree_path_get_indices(path); depth = gtk_tree_path_get_depth(path); /* we do not allow children */ g_assert(depth == 1); /* depth 1 = top level; a list only has top level nodes and no children */ n = indices[0]; /* the 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); /* We simply store a pointer in the iter */ iter->stamp = list->stamp; iter->user_data = l; iter->user_data2 = l->data; iter->user_data3 = NULL; /* unused */ return TRUE;}GtkTreePath *ptk_file_list_get_path ( GtkTreeModel *tree_model, GtkTreeIter *iter ){ GtkTreePath* path; GList* l; PtkFileList* list = PTK_FILE_LIST(tree_model); g_return_val_if_fail (list, NULL); g_return_val_if_fail (iter->stamp == list->stamp, NULL); g_return_val_if_fail (iter != NULL, NULL); g_return_val_if_fail (iter->user_data != NULL, NULL); l = (GList*) iter->user_data; path = gtk_tree_path_new(); gtk_tree_path_append_index(path, g_list_index(list->files, l->data) ); return path;}void ptk_file_list_get_value ( GtkTreeModel *tree_model, GtkTreeIter *iter, gint column, GValue *value ){ GList* l; PtkFileList* list = PTK_FILE_LIST(tree_model); VFSFileInfo* info; GdkPixbuf* icon; g_return_if_fail (PTK_IS_FILE_LIST (tree_model)); g_return_if_fail (iter != NULL); g_return_if_fail (column < G_N_ELEMENTS(column_types) ); g_value_init (value, column_types[column] ); l = (GList*) iter->user_data; g_return_if_fail ( l != NULL ); info = (VFSFileInfo*)iter->user_data2; switch(column) { case COL_FILE_BIG_ICON: icon = NULL; /* special file can use special icons saved as thumbnails*/ if( list->max_thumbnail > vfs_file_info_get_size( info ) && info->flags == VFS_FILE_INFO_NONE ) icon = vfs_file_info_get_big_thumbnail( info ); if( ! icon ) icon = vfs_file_info_get_big_icon( info ); if( icon ) { g_value_set_object( value, icon ); gdk_pixbuf_unref( icon ); } break; case COL_FILE_SMALL_ICON: icon = NULL; /* special file can use special icons saved as thumbnails*/ if( list->max_thumbnail > vfs_file_info_get_size( info ) )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -