ptk-file-menu.c
来自「台湾人开发的Linux下的文件管理器」· C语言 代码 · 共 641 行 · 第 1/2 页
C
641 行
/** C Implementation: ptk-file-menu** 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-menu.h"#include <glib.h>#include "glib-mem.h"#include <glib/gi18n.h>#include <gdk/gdkkeysyms.h>#include "vfs-app-desktop.h"#include "ptk-utils.h"#include "ptk-file-misc.h"typedef struct _PtkFileMenu PtkFileMenu;struct _PtkFileMenu{ PtkFileBrowser* browser; char* cwd; char* file_path; VFSFileInfo* info; GList* sel_files; GtkAccelGroup *accel_group;};/* Signal handlers for popup menu */static voidon_popup_open_activate ( GtkMenuItem *menuitem, PtkFileMenu* data );static voidon_popup_open_with_another_activate ( GtkMenuItem *menuitem, PtkFileMenu* data );static voidon_file_properties_activate ( GtkMenuItem *menuitem, PtkFileMenu* data );static voidon_popup_run_app ( GtkMenuItem *menuitem, PtkFileMenu* data );static voidon_popup_open_in_new_tab_activate ( GtkMenuItem *menuitem, PtkFileMenu* data );static voidon_popup_open_in_new_win_activate ( GtkMenuItem *menuitem, PtkFileMenu* data );static void on_popup_open_in_terminal_activate( GtkMenuItem *menuitem, PtkFileMenu* data );static voidon_popup_cut_activate ( GtkMenuItem *menuitem, PtkFileMenu* data );static voidon_popup_copy_activate ( GtkMenuItem *menuitem, PtkFileMenu* data );static voidon_popup_paste_activate ( GtkMenuItem *menuitem, PtkFileMenu* data );static voidon_popup_delete_activate ( GtkMenuItem *menuitem, PtkFileMenu* data );static voidon_popup_rename_activate ( GtkMenuItem *menuitem, PtkFileMenu* data );static voidon_popup_compress_activate ( GtkMenuItem *menuitem, PtkFileMenu* data );static voidon_popup_extract_here_activate ( GtkMenuItem *menuitem, PtkFileMenu* data );static voidon_popup_extract_to_activate ( GtkMenuItem *menuitem, PtkFileMenu* data );static voidon_popup_new_folder_activate ( GtkMenuItem *menuitem, PtkFileMenu* data );static voidon_popup_new_text_file_activate ( GtkMenuItem *menuitem, PtkFileMenu* data );static voidon_popup_file_properties_activate ( GtkMenuItem *menuitem, PtkFileMenu* data );static PtkMenuItemEntry create_new_menu[] = { PTK_IMG_MENU_ITEM( N_( "_Folder" ), "gtk-directory", on_popup_new_folder_activate, 0, 0 ), PTK_IMG_MENU_ITEM( N_( "_Text File" ), "gtk-edit", on_popup_new_text_file_activate, 0, 0 ), PTK_MENU_END };static PtkMenuItemEntry extract_menu[] = { PTK_MENU_ITEM( N_( "E_xtract Here" ), on_popup_extract_here_activate, 0, 0 ), PTK_IMG_MENU_ITEM( N_( "Extract _To" ), "gtk-directory", on_popup_extract_to_activate, 0, 0 ), PTK_MENU_END };static PtkMenuItemEntry basic_popup_menu[] = { PTK_MENU_ITEM( N_( "Open _with..." ), NULL, 0, 0 ), PTK_SEPARATOR_MENU_ITEM, PTK_STOCK_MENU_ITEM( "gtk-cut", on_popup_cut_activate ), PTK_STOCK_MENU_ITEM( "gtk-copy", on_popup_copy_activate ), PTK_STOCK_MENU_ITEM( "gtk-paste", on_popup_paste_activate ), PTK_IMG_MENU_ITEM( N_( "_Delete" ), "gtk-delete", on_popup_delete_activate, GDK_Delete, 0 ), PTK_IMG_MENU_ITEM( N_( "_Rename" ), "gtk-edit", on_popup_rename_activate, GDK_F2, 0 ), PTK_SEPARATOR_MENU_ITEM, PTK_MENU_ITEM( N_( "Compress" ), on_popup_compress_activate, 0, 0 ), PTK_POPUP_MENU( N_( "E_xtract" ), extract_menu ), PTK_POPUP_IMG_MENU( N_( "_Create New" ), "gtk-new", create_new_menu ), PTK_SEPARATOR_MENU_ITEM, PTK_IMG_MENU_ITEM( N_( "_Properties" ), "gtk-info", on_popup_file_properties_activate, GDK_Return, GDK_MOD1_MASK ), PTK_MENU_END };static PtkMenuItemEntry dir_popup_menu_items[] = { PTK_SEPARATOR_MENU_ITEM, PTK_MENU_ITEM( N_( "Open in New _Tab" ), on_popup_open_in_new_tab_activate, 0, 0 ), PTK_MENU_ITEM( N_( "Open in New _Window" ), on_popup_open_in_new_win_activate, 0, 0 ), PTK_IMG_MENU_ITEM( N_( "Open in Terminal" ), GTK_STOCK_EXECUTE, on_popup_open_in_terminal_activate, GDK_F4, 0 ), PTK_MENU_END };static gboolean same_file_type( GList* files ){ GList * l; VFSMimeType* mime_type; if ( ! files || ! files->next ) return TRUE; mime_type = vfs_file_info_get_mime_type( ( VFSFileInfo* ) l->data ); for ( l = files->next; l ; l = l->next ) { VFSMimeType * mime_type2; mime_type2 = vfs_file_info_get_mime_type( ( VFSFileInfo* ) l->data ); vfs_mime_type_unref( mime_type2 ); if ( mime_type != mime_type2 ) { vfs_mime_type_unref( mime_type ); return FALSE; } } vfs_mime_type_unref( mime_type ); return TRUE;}static void ptk_file_menu_free( PtkFileMenu* data ){ g_free( data->file_path ); vfs_file_info_unref( data->info ); g_free( data->cwd ); vfs_file_info_list_free( data->sel_files ); g_object_unref( data->accel_group ); g_slice_free( PtkFileMenu, data );}/* Retrive popup menu for selected file(s) */GtkWidget* ptk_file_menu_new( const char* file_path, VFSFileInfo* info, const char* cwd, GList* sel_files, PtkFileBrowser* browser ){ GtkWidget * popup = NULL; VFSMimeType* mime_type; GtkWidget *open; char* open_title; GtkWidget *open_with, *open_with_menu, *open_with_another; GtkWidget *seperator; GtkWidget *create_new; GtkWidget *extract; GtkWidget *paste; GtkAccelGroup *accel_group; GtkWidget *app_menu_item; gboolean is_dir; char **apps, **app; const char* app_name = NULL; const char* default_app_name = NULL; VFSAppDesktop* desktop_file; GdkPixbuf* app_icon, *open_icon = NULL; int icon_w, icon_h; GtkWidget* app_img; PtkFileMenu* data; data = g_slice_new0( PtkFileMenu ); data->cwd = g_strdup( cwd ); data->browser = browser; data->file_path = g_strdup( file_path ); data->info = info; vfs_file_info_ref( info ); data->sel_files = sel_files; data->accel_group = gtk_accel_group_new (); popup = gtk_menu_new (); g_object_weak_ref( G_OBJECT( popup ), ptk_file_menu_free, data ); g_signal_connect_after( ( gpointer ) popup, "selection-done", G_CALLBACK ( gtk_widget_destroy ), NULL ); /* Add some special menu items */ mime_type = vfs_file_info_get_mime_type( info ); if ( g_file_test( file_path, G_FILE_TEST_IS_DIR ) ) { ptk_menu_add_items_from_data( popup, dir_popup_menu_items, data, data->accel_group ); is_dir = TRUE; } else { is_dir = FALSE; } basic_popup_menu[ 0 ].ret = &open_with; basic_popup_menu[ 4 ].ret = &paste; basic_popup_menu[ 9 ].ret = &extract; basic_popup_menu[ 10 ].ret = &create_new; ptk_menu_add_items_from_data( popup, basic_popup_menu, data, data->accel_group ); gtk_widget_show_all( GTK_WIDGET( popup ) ); if ( ! is_dir ) { gtk_widget_destroy( paste ); gtk_widget_destroy( create_new ); } /* Add all of the apps */ open_with_menu = gtk_menu_new (); gtk_menu_item_set_submenu ( GTK_MENU_ITEM ( open_with ), open_with_menu ); apps = vfs_mime_type_get_actions( mime_type ); if ( vfs_file_info_is_text( info, file_path ) ) /* for text files */ { char **tmp, **txt_apps; VFSMimeType* txt_type; int len1, len2; txt_type = vfs_mime_type_get_from_type( XDG_MIME_TYPE_PLAIN_TEXT ); txt_apps = vfs_mime_type_get_actions( txt_type ); if ( txt_apps ) { len1 = apps ? g_strv_length( apps ) : 0; len2 = g_strv_length( txt_apps ); apps = vfs_mime_type_join_actions( apps, len1, txt_apps, len2 ); g_strfreev( txt_apps ); } vfs_mime_type_unref( txt_type ); } default_app_name = NULL; if ( apps ) { for ( app = apps; *app; ++app ) { if ( ( app - apps ) == 1 ) /* Add a separator after default app */ { seperator = gtk_separator_menu_item_new (); gtk_widget_show ( seperator ); gtk_container_add ( GTK_CONTAINER ( open_with_menu ), seperator ); } desktop_file = vfs_app_desktop_new( *app ); app_name = vfs_app_desktop_get_disp_name( desktop_file ); if ( app_name ) { app_menu_item = gtk_image_menu_item_new_with_label ( app_name ); if ( app == apps ) default_app_name = app_name; } else app_menu_item = gtk_image_menu_item_new_with_label ( *app ); g_object_set_data_full( G_OBJECT( app_menu_item ), "desktop_file", desktop_file, vfs_app_desktop_unref ); gtk_icon_size_lookup_for_settings( gtk_settings_get_default(), GTK_ICON_SIZE_MENU, &icon_w, &icon_h ); app_icon = vfs_app_desktop_get_icon( desktop_file, icon_w > icon_h ? icon_w : icon_h ); if ( app_icon ) { app_img = gtk_image_new_from_pixbuf( app_icon ); gtk_image_menu_item_set_image ( GTK_IMAGE_MENU_ITEM( app_menu_item ), app_img ); if ( app == apps ) /* Default app */ open_icon = app_icon; else gdk_pixbuf_unref( app_icon ); } gtk_container_add ( GTK_CONTAINER ( open_with_menu ), app_menu_item ); g_signal_connect( G_OBJECT( app_menu_item ), "activate", G_CALLBACK( on_popup_run_app ), ( gpointer ) data ); } seperator = gtk_separator_menu_item_new (); gtk_container_add ( GTK_CONTAINER ( open_with_menu ), seperator ); g_strfreev( apps ); } open_with_another = gtk_menu_item_new_with_mnemonic ( _( "_Open with another program" ) ); gtk_container_add ( GTK_CONTAINER ( open_with_menu ), open_with_another ); g_signal_connect ( ( gpointer ) open_with_another, "activate", G_CALLBACK ( on_popup_open_with_another_activate ), data ); gtk_widget_show_all( open_with_menu ); /* Create Open menu item */ open = NULL; if ( !is_dir ) /* Not a dir */ { if ( vfs_file_info_is_executable( info, file_path ) || info->flags & VFS_FILE_INFO_DESKTOP_ENTRY ) {
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?