📄 menu.c
字号:
/* Menu system *//* $Id: menu.c,v 1.381.2.8 2005/05/01 21:32:11 jonas Exp $ */#ifdef HAVE_CONFIG_H#include "config.h"#endif#include <stdlib.h>#include <string.h>#include "elinks.h"#include "bfu/dialog.h"#include "bfu/leds.h"#include "bfu/menu.h"#include "config/options.h"#include "config/urlhist.h"#include "document/document.h"#include "document/view.h"#include "dialogs/exmode.h"#include "dialogs/info.h"#include "dialogs/menu.h"#include "dialogs/options.h"#include "intl/gettext/libintl.h"#include "lowlevel/select.h"#include "main.h"#include "mime/dialogs.h"#include "mime/mime.h"#include "osdep/osdep.h"#include "osdep/newwin.h"#include "protocol/protocol.h"#include "protocol/uri.h"#include "sched/connection.h"#include "sched/download.h"#include "sched/event.h"#include "sched/history.h"#include "sched/location.h"#include "sched/session.h"#include "sched/task.h"#include "terminal/tab.h"#include "terminal/terminal.h"#include "util/conv.h"#include "util/file.h"#include "util/memlist.h"#include "util/memory.h"#include "util/string.h"#include "viewer/text/link.h"#include "viewer/text/view.h"/* Helper for url items in help menu. */static voidmenu_url_shortcut(struct terminal *term, void *url_, void *ses_){ unsigned char *url = url_; struct session *ses = ses_; struct uri *uri = get_uri(url, 0); if (!uri) return; goto_uri(ses, uri); done_uri(uri);}static voidsave_url(struct session *ses, unsigned char *url){ struct document_view *doc_view; struct uri *uri; assert(ses && ses->tab && ses->tab->term && url); if_assert_failed return; if (!*url) return; uri = get_translated_uri(url, ses->tab->term->cwd); if (!uri) { print_error_dialog(ses, S_BAD_URL, NULL, PRI_CANCEL); return; } if (ses->download_uri) done_uri(ses->download_uri); ses->download_uri = uri; doc_view = current_frame(ses); assert(doc_view && doc_view->document && doc_view->document->uri); if_assert_failed return; set_session_referrer(ses, doc_view->document->uri); query_file(ses, ses->download_uri, ses, start_download, NULL, 1);}voidsave_url_as(struct session *ses){ input_dialog(ses->tab->term, NULL, N_("Save URL"), N_("Enter URL"), ses, &goto_url_history, MAX_STR_LEN, "", 0, 0, NULL, (void (*)(void *, unsigned char *)) save_url, NULL);}voidreally_exit_prog(struct session *ses){ register_bottom_half((void (*)(void *)) destroy_terminal, ses->tab->term);}static inline voiddont_exit_prog(struct session *ses){ ses->exit_query = 0;}voidquery_exit(struct session *ses){ ses->exit_query = 1; msg_box(ses->tab->term, NULL, 0, N_("Exit ELinks"), ALIGN_CENTER, (ses->tab->term->next == ses->tab->term->prev && are_there_downloads()) ? N_("Do you really want to exit ELinks " "(and terminate all downloads)?") : N_("Do you really want to exit ELinks?"), ses, 2, N_("~Yes"), (void (*)(void *)) really_exit_prog, B_ENTER, N_("~No"), (void (*)(void *)) dont_exit_prog, B_ESC);}voidexit_prog(struct session *ses, int query){ assert(ses); /* An exit query is in progress. */ if (ses->exit_query) return; /* Force a query if the last terminal is exiting with downloads still in * progress. */ if (query || (list_is_singleton(terminals) && are_there_downloads())) { query_exit(ses); return; } really_exit_prog(ses);}static voidgo_historywards(struct terminal *term, void *target_, void *ses_){ struct location *target = target_; struct session *ses = ses_; go_history(ses, target);}static struct menu_item no_hist_menu[] = { INIT_MENU_ITEM(N_("No history"), NULL, ACT_MAIN_NONE, NULL, NULL, NO_SELECT), NULL_MENU_ITEM};/* unhist == 0 => history * unhist == 1 => unhistory */static voidhistory_menu_common(struct terminal *term, struct session *ses, int unhist){ struct menu_item *mi = NULL; if (have_location(ses)) { struct location *loc; for (loc = unhist ? cur_loc(ses)->next : cur_loc(ses)->prev; loc != (struct location *) &ses->history.history; loc = unhist ? loc->next : loc->prev) { unsigned char *url; if (!mi) { mi = new_menu(FREE_LIST | FREE_TEXT | NO_INTL); if (!mi) return; } url = get_uri_string(loc->vs.uri, URI_PUBLIC); if (url) { add_to_menu(&mi, url, NULL, ACT_MAIN_NONE, go_historywards, (void *) loc, 0); } } } if (!mi) do_menu(term, no_hist_menu, ses, 0); else do_menu(term, mi, ses, 0);}static voidhistory_menu(struct terminal *term, void *xxx, void *ses_){ struct session *ses = ses_; history_menu_common(term, ses, 0);}static voidunhistory_menu(struct terminal *term, void *xxx, void *ses_){ struct session *ses = ses_; history_menu_common(term, ses, 1);}voidtab_menu(struct session *ses, int x, int y, int place_above_cursor){ struct menu_item *menu; int tabs;#ifdef CONFIG_BOOKMARKS int anonymous = get_cmd_opt_bool("anonymous");#endif assert(ses && ses->tab); if_assert_failed return; tabs = number_of_tabs(ses->tab->term); menu = new_menu(FREE_LIST); if (!menu) return; add_menu_action(&menu, N_("Go ~back"), ACT_MAIN_HISTORY_MOVE_BACK); add_menu_action(&menu, N_("Go for~ward"), ACT_MAIN_HISTORY_MOVE_FORWARD); if (have_location(ses)) { add_menu_separator(&menu);#ifdef CONFIG_BOOKMARKS if (!anonymous) { add_menu_action(&menu, N_("Bookm~ark document"), ACT_MAIN_ADD_BOOKMARK); }#endif add_menu_action(&menu, N_("Toggle ~html/plain"), ACT_MAIN_TOGGLE_HTML_PLAIN); add_menu_action(&menu, N_("~Reload"), ACT_MAIN_RELOAD); if (ses->doc_view && document_has_frames(ses->doc_view->document)) { add_menu_action(&menu, N_("Frame at ~full-screen"), ACT_MAIN_FRAME_MAXIMIZE); add_uri_command_to_menu(&menu, PASS_URI_FRAME); } } /* Keep tab related operations below this separator */ add_menu_separator(&menu); if (tabs > 1) { add_menu_action(&menu, N_("Nex~t tab"), ACT_MAIN_TAB_NEXT); add_menu_action(&menu, N_("Pre~v tab"), ACT_MAIN_TAB_PREV); } add_menu_action(&menu, N_("~Close tab"), ACT_MAIN_TAB_CLOSE); if (tabs > 1) { add_menu_action(&menu, N_("C~lose all tabs but the current"), ACT_MAIN_TAB_CLOSE_ALL_BUT_CURRENT);#ifdef CONFIG_BOOKMARKS if (!anonymous) { add_menu_action(&menu, N_("B~ookmark all tabs"), ACT_MAIN_ADD_BOOKMARK_TABS); }#endif } if (have_location(ses)) add_uri_command_to_menu(&menu, PASS_URI_TAB); /* Adjust the menu position taking the menu frame into account */ if (place_above_cursor) { int i = 0; while (menu[i].text) i++; y = int_max(y - i - 1, 0); } set_window_ptr(ses->tab, x, y); do_menu(ses->tab->term, menu, ses, 1);}static voiddo_submenu(struct terminal *term, void *menu_, void *ses_){ struct menu_item *menu = menu_; do_menu(term, menu, ses_, 1);}static struct menu_item file_menu11[] = { INIT_MENU_ACTION(N_("Open new ~tab"), ACT_MAIN_OPEN_NEW_TAB), INIT_MENU_ACTION(N_("Open new tab in backgroun~d"), ACT_MAIN_OPEN_NEW_TAB_IN_BACKGROUND), INIT_MENU_ACTION(N_("~Go to URL"), ACT_MAIN_GOTO_URL), INIT_MENU_ACTION(N_("Go ~back"), ACT_MAIN_HISTORY_MOVE_BACK), INIT_MENU_ACTION(N_("Go ~forward"), ACT_MAIN_HISTORY_MOVE_FORWARD), INIT_MENU_ITEM(N_("~History"), NULL, ACT_MAIN_NONE, history_menu, NULL, SUBMENU), INIT_MENU_ITEM(N_("~Unhistory"), NULL, ACT_MAIN_NONE, unhistory_menu, NULL, SUBMENU),};static struct menu_item file_menu21[] = { BAR_MENU_ITEM, INIT_MENU_ACTION(N_("~Save as"), ACT_MAIN_SAVE_AS), INIT_MENU_ACTION(N_("Save UR~L as"), ACT_MAIN_SAVE_URL_AS), INIT_MENU_ACTION(N_("Sa~ve formatted document"), ACT_MAIN_SAVE_FORMATTED),#ifdef CONFIG_BOOKMARKS INIT_MENU_ACTION(N_("Bookm~ark document"), ACT_MAIN_ADD_BOOKMARK),#endif};static struct menu_item file_menu22[] = { BAR_MENU_ITEM, INIT_MENU_ACTION(N_("~Kill background connections"), ACT_MAIN_KILL_BACKGROUNDED_CONNECTIONS), INIT_MENU_ACTION(N_("Flush all ~caches"), ACT_MAIN_CACHE_MINIMIZE), INIT_MENU_ACTION(N_("Resource ~info"), ACT_MAIN_RESOURCE_INFO), BAR_MENU_ITEM,};static struct menu_item file_menu3[] = { BAR_MENU_ITEM, INIT_MENU_ACTION(N_("E~xit"), ACT_MAIN_QUIT), NULL_MENU_ITEM,};static voiddo_file_menu(struct terminal *term, void *xxx, void *ses_){ struct menu_item *file_menu, *e, *f; int anonymous = get_cmd_opt_bool("anonymous"); int x, o; file_menu = mem_alloc(sizeof(file_menu11) + sizeof(file_menu21) + sizeof(file_menu22) + sizeof(file_menu3) + 3 * sizeof(struct menu_item)); if (!file_menu) return; e = file_menu; if (!anonymous && !get_cmd_opt_bool("no-connect") && !get_cmd_opt_bool("no-home")) o = can_open_in_new(term); else o = 0; if (o) { SET_MENU_ITEM(e, N_("Open ~new window"), NULL, ACT_MAIN_OPEN_NEW_WINDOW, open_in_new_window, send_open_new_window, (o - 1) ? SUBMENU : 0, 0, HKS_SHOW); e++; } memcpy(e, file_menu11, sizeof(file_menu11)); e += sizeof(file_menu11) / sizeof(struct menu_item); if (!anonymous) { memcpy(e, file_menu21, sizeof(file_menu21)); e += sizeof(file_menu21) / sizeof(struct menu_item); } memcpy(e, file_menu22, sizeof(file_menu22)); e += sizeof(file_menu22) / sizeof(struct menu_item); x = 1; if (!anonymous && can_open_os_shell(term->environment)) { SET_MENU_ITEM(e, N_("~OS shell"), NULL, ACT_MAIN_OPEN_OS_SHELL, NULL, NULL, 0, 0, HKS_SHOW); e++; x = 0; } if (can_resize_window(term->environment)) { SET_MENU_ITEM(e, N_("Resize t~erminal"), NULL, ACT_MAIN_TERMINAL_RESIZE, NULL, NULL, 0, 0, HKS_SHOW); e++; x = 0; } memcpy(e, file_menu3 + x, sizeof(file_menu3) - x * sizeof(struct menu_item)); e += sizeof(file_menu3) / sizeof(struct menu_item); for (f = file_menu; f < e; f++) f->flags |= FREE_LIST; do_menu(term, file_menu, ses_, 1);}static struct menu_item view_menu[] = { INIT_MENU_ACTION(N_("~Search"), ACT_MAIN_SEARCH), INIT_MENU_ACTION(N_("Search ~backward"), ACT_MAIN_SEARCH_BACK), INIT_MENU_ACTION(N_("Find ~next"), ACT_MAIN_FIND_NEXT), INIT_MENU_ACTION(N_("Find ~previous"), ACT_MAIN_FIND_NEXT_BACK), INIT_MENU_ACTION(N_("T~ypeahead search"), ACT_MAIN_SEARCH_TYPEAHEAD), BAR_MENU_ITEM, INIT_MENU_ACTION(N_("Toggle ~html/plain"), ACT_MAIN_TOGGLE_HTML_PLAIN), INIT_MENU_ACTION(N_("Toggle i~mages"), ACT_MAIN_TOGGLE_DISPLAY_IMAGES), INIT_MENU_ACTION(N_("Toggle ~link numbering"), ACT_MAIN_TOGGLE_NUMBERED_LINKS), INIT_MENU_ACTION(N_("Toggle ~document colors"), ACT_MAIN_TOGGLE_DOCUMENT_COLORS), INIT_MENU_ACTION(N_("~Wrap text on/off"), ACT_MAIN_TOGGLE_WRAP_TEXT), BAR_MENU_ITEM, INIT_MENU_ACTION(N_("Document ~info"), ACT_MAIN_DOCUMENT_INFO), INIT_MENU_ACTION(N_("H~eader info"), ACT_MAIN_HEADER_INFO), INIT_MENU_ACTION(N_("Rel~oad document"), ACT_MAIN_RELOAD), INIT_MENU_ACTION(N_("~Rerender document"), ACT_MAIN_RERENDER), INIT_MENU_ACTION(N_("Frame at ~full-screen"), ACT_MAIN_FRAME_MAXIMIZE), BAR_MENU_ITEM, INIT_MENU_ACTION(N_("Nex~t tab"), ACT_MAIN_TAB_NEXT), INIT_MENU_ACTION(N_("Pre~v tab"), ACT_MAIN_TAB_PREV), INIT_MENU_ACTION(N_("~Close tab"), ACT_MAIN_TAB_CLOSE), NULL_MENU_ITEM};static struct menu_item help_menu[] = { INIT_MENU_ITEM(N_("~ELinks homepage"), NULL, ACT_MAIN_NONE, menu_url_shortcut, ELINKS_HOMEPAGE, 0), INIT_MENU_ITEM(N_("~Documentation"), NULL, ACT_MAIN_NONE, menu_url_shortcut, ELINKS_DOC_URL, 0), INIT_MENU_ITEM(N_("~Keys"), NULL, ACT_MAIN_NONE, menu_keys, NULL, 0),#ifdef CONFIG_LEDS INIT_MENU_ITEM(N_("LED ~indicators"), NULL, ACT_MAIN_NONE, menu_leds_info, NULL, 0),#endif BAR_MENU_ITEM, INIT_MENU_ITEM(N_("~Bugs information"), NULL, ACT_MAIN_NONE, menu_url_shortcut, ELINKS_BUGS_URL, 0),#ifdef CONFIG_DEBUG INIT_MENU_ITEM(N_("ELinks C~vsWeb"), NULL, ACT_MAIN_NONE, menu_url_shortcut, ELINKS_CVSWEB_URL, 0), INIT_MENU_ITEM(N_("ELinks Cvs ~History"), NULL, ACT_MAIN_NONE, menu_url_shortcut, ELINKS_CVSHIST_URL, 0), INIT_MENU_ITEM(N_("ELinks ~LXR"), NULL, ACT_MAIN_NONE, menu_url_shortcut, ELINKS_LXR_URL, 0),#endif BAR_MENU_ITEM, INIT_MENU_ITEM(N_("~Copying"), NULL, ACT_MAIN_NONE, menu_copying, NULL, 0), INIT_MENU_ITEM(N_("~About"), NULL, ACT_MAIN_NONE, menu_about, NULL, 0), NULL_MENU_ITEM};static struct menu_item ext_menu[] = { INIT_MENU_ITEM(N_("~Add"), NULL, ACT_MAIN_NONE, menu_add_ext, NULL, 0), INIT_MENU_ITEM(N_("~Modify"), NULL, ACT_MAIN_NONE, menu_list_ext, menu_add_ext, SUBMENU), INIT_MENU_ITEM(N_("~Delete"), NULL, ACT_MAIN_NONE, menu_list_ext, menu_del_ext, SUBMENU), NULL_MENU_ITEM};static struct menu_item setup_menu[] = {#ifdef ENABLE_NLS INIT_MENU_ITEM(N_("~Language"), NULL, ACT_MAIN_NONE, menu_language_list, NULL, SUBMENU),#endif INIT_MENU_ITEM(N_("C~haracter set"), NULL, ACT_MAIN_NONE, charset_list, NULL, SUBMENU), INIT_MENU_ACTION(N_("~Terminal options"), ACT_MAIN_SHOW_TERM_OPTIONS), INIT_MENU_ITEM(N_("File ~extensions"), NULL, ACT_MAIN_NONE, do_submenu, ext_menu, SUBMENU), BAR_MENU_ITEM, INIT_MENU_ACTION(N_("~Options manager"), ACT_MAIN_OPTIONS_MANAGER), INIT_MENU_ACTION(N_("~Keybinding manager"), ACT_MAIN_KEYBINDING_MANAGER), INIT_MENU_ACTION(N_("~Save options"), ACT_MAIN_SAVE_OPTIONS), NULL_MENU_ITEM};static struct menu_item setup_menu_anon[] = { INIT_MENU_ITEM(N_("~Language"), NULL, ACT_MAIN_NONE, menu_language_list, NULL, SUBMENU), INIT_MENU_ITEM(N_("C~haracter set"), NULL, ACT_MAIN_NONE, charset_list, NULL, SUBMENU), INIT_MENU_ACTION(N_("~Terminal options"), ACT_MAIN_SHOW_TERM_OPTIONS), NULL_MENU_ITEM};static struct menu_item tools_menu[] = {#ifdef CONFIG_GLOBHIST INIT_MENU_ACTION(N_("Global ~history"), ACT_MAIN_HISTORY_MANAGER),#endif#ifdef CONFIG_BOOKMARKS INIT_MENU_ACTION(N_("~Bookmarks"), ACT_MAIN_BOOKMARK_MANAGER),#endif INIT_MENU_ACTION(N_("~Cache"), ACT_MAIN_CACHE_MANAGER), INIT_MENU_ACTION(N_("~Downloads"), ACT_MAIN_DOWNLOAD_MANAGER),#ifdef CONFIG_COOKIES INIT_MENU_ACTION(N_("Coo~kies"), ACT_MAIN_COOKIE_MANAGER),#endif#ifdef CONFIG_FORMHIST INIT_MENU_ACTION(N_("~Form history"), ACT_MAIN_FORMHIST_MANAGER),#endif INIT_MENU_ACTION(N_("~Authentication"), ACT_MAIN_AUTH_MANAGER), NULL_MENU_ITEM};static voiddo_setup_menu(struct terminal *term, void *xxx, void *ses_){ struct session *ses = ses_; if (!get_cmd_opt_bool("anonymous")) do_menu(term, setup_menu, ses, 1); else do_menu(term, setup_menu_anon, ses, 1);}static struct menu_item main_menu[] = { INIT_MENU_ITEM(N_("~File"), NULL, ACT_MAIN_NONE, do_file_menu, NULL, FREE_LIST | SUBMENU), INIT_MENU_ITEM(N_("~View"), NULL, ACT_MAIN_NONE, do_submenu, view_menu, FREE_LIST | SUBMENU), INIT_MENU_ITEM(N_("~Link"), NULL, ACT_MAIN_NONE, link_menu, NULL, FREE_LIST | SUBMENU), INIT_MENU_ITEM(N_("~Tools"), NULL, ACT_MAIN_NONE, do_submenu, tools_menu, FREE_LIST | SUBMENU), INIT_MENU_ITEM(N_("~Setup"), NULL, ACT_MAIN_NONE, do_setup_menu, NULL, FREE_LIST | SUBMENU), INIT_MENU_ITEM(N_("~Help"), NULL, ACT_MAIN_NONE, do_submenu, help_menu, FREE_LIST | SUBMENU), NULL_MENU_ITEM};voidactivate_bfu_technology(struct session *ses, int item){ do_mainmenu(ses->tab->term, main_menu, ses, item);}voiddialog_goto_url(struct session *ses, unsigned char *url){ input_dialog(ses->tab->term, NULL, N_("Go to URL"), N_("Enter URL"), ses, &goto_url_history, MAX_STR_LEN, url, 0, 0, NULL, (void (*)(void *, unsigned char *)) goto_url_with_hook, NULL);}static INIT_INPUT_HISTORY(file_history);voidquery_file(struct session *ses, struct uri *uri, void *data, void (*std)(void *, unsigned char *), void (*cancel)(void *), int interactive){
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -