📄 ptk-file-browser.c
字号:
g_signal_connect_after ( ( gpointer ) folder_view, "selection-changed", G_CALLBACK ( on_folder_view_item_sel_change ), file_browser ); break; case FBVM_LIST_VIEW: folder_view = gtk_tree_view_new (); init_list_view( GTK_TREE_VIEW( folder_view ) ); tree_sel = gtk_tree_view_get_selection( GTK_TREE_VIEW( folder_view ) ); gtk_tree_selection_set_mode( tree_sel, GTK_SELECTION_MULTIPLE ); gtk_tree_view_enable_model_drag_source ( GTK_TREE_VIEW( folder_view ), ( GDK_CONTROL_MASK | GDK_BUTTON1_MASK | GDK_BUTTON3_MASK ), drag_targets, sizeof( drag_targets ) / sizeof( GtkTargetEntry ), GDK_ACTION_DEFAULT | GDK_ACTION_COPY | GDK_ACTION_MOVE | GDK_ACTION_LINK ); gtk_tree_view_enable_model_drag_dest ( GTK_TREE_VIEW( folder_view ), drag_targets, sizeof( drag_targets ) / sizeof( GtkTargetEntry ), GDK_ACTION_DEFAULT | GDK_ACTION_COPY | GDK_ACTION_MOVE | GDK_ACTION_LINK ); g_signal_connect ( ( gpointer ) folder_view, "row_activated", G_CALLBACK ( on_folder_view_row_activated ), file_browser ); g_signal_connect_after ( ( gpointer ) tree_sel, "changed", G_CALLBACK ( on_folder_view_item_sel_change ), file_browser ); gtk_tree_selection_set_select_function( tree_sel, can_sel_change, file_browser, NULL ); break; } g_signal_connect ( ( gpointer ) folder_view, "button-press-event", G_CALLBACK ( on_folder_view_button_press_event ), file_browser ); g_signal_connect ( ( gpointer ) folder_view, "button-release-event", G_CALLBACK ( on_folder_view_button_release_event ), file_browser ); g_signal_connect ( ( gpointer ) folder_view, "key_press_event", G_CALLBACK ( on_folder_view_key_press_event ), file_browser ); g_signal_connect ( ( gpointer ) folder_view, "popup-menu", G_CALLBACK ( on_folder_view_popup_menu ), file_browser ); /* init drag & drop support */ g_signal_connect ( ( gpointer ) folder_view, "drag-data-received", G_CALLBACK ( on_folder_view_drag_data_received ), file_browser ); g_signal_connect ( ( gpointer ) folder_view, "drag-data-get", G_CALLBACK ( on_folder_view_drag_data_get ), file_browser ); g_signal_connect ( ( gpointer ) folder_view, "drag-begin", G_CALLBACK ( on_folder_view_drag_begin ), file_browser ); g_signal_connect ( ( gpointer ) folder_view, "drag-motion", G_CALLBACK ( on_folder_view_drag_motion ), file_browser ); g_signal_connect ( ( gpointer ) folder_view, "drag-leave", G_CALLBACK ( on_folder_view_drag_leave ), file_browser ); g_signal_connect ( ( gpointer ) folder_view, "drag-drop", G_CALLBACK ( on_folder_view_drag_drop ), file_browser ); g_signal_connect ( ( gpointer ) folder_view, "drag-end", G_CALLBACK ( on_folder_view_drag_end ), file_browser ); return folder_view;}static void init_list_view( GtkTreeView* list_view ){ GtkTreeViewColumn * col; GtkCellRenderer *renderer; GtkCellRenderer *pix_renderer; int cols[] = { COL_FILE_NAME, COL_FILE_SIZE, COL_FILE_DESC, COL_FILE_PERM, COL_FILE_OWNER, COL_FILE_MTIME }; int i; const char* titles[] = { N_( "Name" ), N_( "Size" ), N_( "Type" ), N_( "Permission" ), N_( "Owner:Group" ), N_( "Last Modification" ) }; for ( i = 0; i < G_N_ELEMENTS( cols ); ++i ) { col = gtk_tree_view_column_new (); gtk_tree_view_column_set_resizable ( col, TRUE ); renderer = gtk_cell_renderer_text_new(); if ( i == 0 ) { /* First column */ gtk_object_set( GTK_OBJECT( renderer ), /* "editable", TRUE, */ "ellipsize", PANGO_ELLIPSIZE_END, NULL ); /* g_signal_connect( renderer, "editing-started", G_CALLBACK( on_filename_editing_started ), NULL ); */ pix_renderer = ptk_file_icon_renderer_new(); gtk_tree_view_column_pack_start( col, pix_renderer, FALSE ); gtk_tree_view_column_set_attributes( col, pix_renderer, "pixbuf", COL_FILE_SMALL_ICON, "info", COL_FILE_INFO, NULL ); gtk_tree_view_column_set_expand ( col, TRUE ); gtk_tree_view_column_set_min_width( col, 200 ); } gtk_tree_view_column_pack_start( col, renderer, TRUE ); gtk_tree_view_column_set_attributes( col, renderer, "text", cols[ i ], NULL ); gtk_tree_view_append_column ( list_view, col ); gtk_tree_view_column_set_title( col, _( titles[ i ] ) ); gtk_tree_view_column_set_sort_indicator( col, TRUE ); gtk_tree_view_column_set_sort_column_id( col, cols[ i ] ); gtk_tree_view_column_set_sort_order( col, GTK_SORT_DESCENDING ); } col = gtk_tree_view_get_column( list_view, 2 ); gtk_tree_view_column_set_sizing( col, GTK_TREE_VIEW_COLUMN_FIXED ); gtk_tree_view_column_set_fixed_width ( col, 120 ); gtk_tree_view_set_rules_hint ( list_view, TRUE );}void ptk_file_browser_refresh( PtkFileBrowser* file_browser ){ /* * FIXME: * Do nothing when there is unfinished task running in the * working thread. * This should be fixed with a better way in the future. */ if ( file_browser->busy ) return ; ptk_file_browser_chdir( file_browser, ptk_file_browser_get_cwd( file_browser ), FALSE );}guint ptk_file_browser_get_n_all_files( PtkFileBrowser* file_browser ){ return file_browser->dir ? file_browser->dir->n_files : 0;}guint ptk_file_browser_get_n_visible_files( PtkFileBrowser* file_browser ){ return file_browser->file_list ? gtk_tree_model_iter_n_children( file_browser->file_list, NULL ) : 0;}GList* folder_view_get_selected_items( PtkFileBrowser* file_browser, GtkTreeModel** model ){ GtkTreeSelection * tree_sel; if ( file_browser->view_mode == FBVM_ICON_VIEW ) { *model = ptk_icon_view_get_model( PTK_ICON_VIEW( file_browser->folder_view ) ); return ptk_icon_view_get_selected_items( PTK_ICON_VIEW( file_browser->folder_view ) ); } else if ( file_browser->view_mode == FBVM_LIST_VIEW ) { tree_sel = gtk_tree_view_get_selection( GTK_TREE_VIEW( file_browser->folder_view ) ); return gtk_tree_selection_get_selected_rows( tree_sel, model ); } return NULL;}static char* folder_view_get_drop_dir( PtkFileBrowser* file_browser, int x, int y ){ GtkTreePath * tree_path = NULL; GtkTreeModel *model; GtkTreeViewColumn* col; GtkTreeIter it; VFSFileInfo* file; char* dest_path; if ( file_browser->view_mode == FBVM_ICON_VIEW ) { ptk_icon_view_widget_to_icon_coords ( PTK_ICON_VIEW( file_browser->folder_view ), x, y, &x, &y ); tree_path = folder_view_get_tree_path_at_pos( file_browser, x, y ); model = ptk_icon_view_get_model( PTK_ICON_VIEW( file_browser->folder_view ) ); } else if ( file_browser->view_mode == FBVM_LIST_VIEW ) { gtk_tree_view_get_path_at_pos( GTK_TREE_VIEW( file_browser->folder_view ), x, y, NULL, &col, NULL, NULL ); if ( col == gtk_tree_view_get_column( GTK_TREE_VIEW( file_browser->folder_view ), 0 ) ) { gtk_tree_view_get_dest_row_at_pos ( GTK_TREE_VIEW( file_browser->folder_view ), x, y, &tree_path, NULL ); model = gtk_tree_view_get_model( GTK_TREE_VIEW( file_browser->folder_view ) ); } } if ( tree_path ) { if ( G_UNLIKELY( ! gtk_tree_model_get_iter( model, &it, tree_path ) ) ) return NULL; gtk_tree_model_get( model, &it, COL_FILE_INFO, &file, -1 ); if ( file ) { if ( vfs_file_info_is_dir( file ) ) { dest_path = g_build_filename( ptk_file_browser_get_cwd( file_browser ), vfs_file_info_get_name( file ), NULL ); } else /* Drop on a file, not folder */ { /* Return current directory */ dest_path = g_strdup( ptk_file_browser_get_cwd( file_browser ) ); } vfs_file_info_unref( file ); } gtk_tree_path_free( tree_path ); } else { dest_path = g_strdup( ptk_file_browser_get_cwd( file_browser ) ); } return dest_path;}void on_folder_view_drag_data_received ( GtkWidget *widget, GdkDragContext *drag_context, gint x, gint y, GtkSelectionData *sel_data, guint info, guint time, gpointer user_data ){ gchar **list, **puri; GList* files = NULL; PtkFileTask* task; VFSFileTaskType file_action = VFS_FILE_TASK_MOVE; PtkFileBrowser* file_browser = ( PtkFileBrowser* ) user_data; char* dest_dir; char* file_path; GtkWidget* parent_win; /* Don't call the default handler */ g_signal_stop_emission_by_name( widget, "drag-data-received" ); if ( ( sel_data->length >= 0 ) && ( sel_data->format == 8 ) ) { puri = list = gtk_selection_data_get_uris( sel_data ); if ( puri ) { if ( 0 == ( drag_context->action & ( GDK_ACTION_MOVE | GDK_ACTION_COPY | GDK_ACTION_LINK ) ) ) { drag_context->action = GDK_ACTION_MOVE; } gtk_drag_finish ( drag_context, TRUE, FALSE, time ); while ( *puri ) { if ( **puri == '/' ) { file_path = g_strdup( *puri ); } else { file_path = g_filename_from_uri( *puri, NULL, NULL ); } if ( file_path ) { files = g_list_prepend( files, file_path ); } ++puri; } g_strfreev( list ); switch ( drag_context->action ) { case GDK_ACTION_COPY: file_action = VFS_FILE_TASK_COPY; break; case GDK_ACTION_LINK: file_action = VFS_FILE_TASK_LINK; break; /* FIXME: GDK_ACTION_DEFAULT GDK_ACTION_MOVE GDK_ACTION_PRIVATE GDK_ACTION_ASK not handled */ default: break; } if ( files ) { dest_dir = folder_view_get_drop_dir( file_browser, x, y ); /* g_print( "dest_dir = %s\n", dest_dir ); */ parent_win = gtk_widget_get_toplevel( GTK_WIDGET( file_browser ) ); task = ptk_file_task_new( file_action, files, dest_dir, GTK_WINDOW( parent_win ) ); ptk_file_task_run( task ); g_free( dest_dir ); } gtk_drag_finish ( drag_context, TRUE, FALSE, time ); return ; } } gtk_drag_finish ( drag_context, FALSE, FALSE, time );}void on_folder_view_drag_data_get ( GtkWidget *widget, GdkDragContext *drag_context, GtkSelectionData *sel_data, guint info, guint time, PtkFileBrowser *file_browser ){ GdkAtom type = gdk_atom_intern( "text/uri-list", FALSE ); gchar* uri; GString* uri_list = g_string_sized_new( 8192 ); GList* sels = ptk_file_browser_get_selected_files( file_browser ); GList* sel; VFSFileInfo* file; char* full_path; /* Don't call the default handler */ g_signal_stop_emission_by_name( widget, "drag-data-get" ); drag_context->actions = GDK_ACTION_MOVE | GDK_ACTION_COPY | GDK_ACTION_LINK; drag_context->suggested_action = GDK_ACTION_MOVE; for ( sel = sels; sel; sel = g_list_next( sel ) ) { file = ( VFSFileInfo* ) sel->data;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -