1 /* Sessions action management */
11 #include "bookmarks/dialogs.h"
12 #include "cache/dialogs.h"
13 #include "config/conf.h"
14 #include "config/dialogs.h"
15 #include "config/kbdbind.h"
16 #include "config/options.h"
17 #include "cookies/cookies.h"
18 #include "cookies/dialogs.h"
19 #include "dialogs/document.h"
20 #include "dialogs/download.h"
21 #include "dialogs/exmode.h"
22 #include "dialogs/info.h"
23 #include "dialogs/menu.h"
24 #include "dialogs/options.h"
25 #include "dialogs/status.h"
26 #include "document/document.h"
27 #include "document/view.h"
28 #include "formhist/dialogs.h"
29 #include "globhist/dialogs.h"
30 #include "main/main.h"
31 #include "network/connection.h"
32 #include "protocol/auth/auth.h"
33 #include "protocol/auth/dialogs.h"
34 #include "terminal/tab.h"
35 #include "terminal/terminal.h"
36 #include "terminal/window.h"
37 #include "session/history.h"
38 #include "session/session.h"
39 #include "session/task.h"
40 #include "viewer/action.h"
41 #include "viewer/text/draw.h"
42 #include "viewer/text/festival.h"
43 #include "viewer/text/form.h"
44 #include "viewer/text/link.h"
45 #include "viewer/text/search.h"
46 #include "viewer/text/view.h"
50 goto_url_action(struct session
*ses
,
51 unsigned char *(*get_url
)(struct session
*, unsigned char *, size_t))
53 unsigned char url
[MAX_STR_LEN
];
55 if (!get_url
|| !get_url(ses
, url
, sizeof(url
)))
58 dialog_goto_url(ses
, url
);
61 /* This could gradually become some multiplexor / switch noodle containing
62 * most if not all default handling of actions (for the main mapping) that
63 * frame_ev() and/or send_event() could use as a backend. */
64 /* Many execution paths may lead to this code so it needs to take appropriate
65 * precausions to stuff like doc_view and doc_view->vs being NULL. */
66 enum frame_event_status
67 do_action(struct session
*ses
, enum main_action action_id
, int verbose
)
69 enum frame_event_status status
= FRAME_EVENT_OK
;
70 struct terminal
*term
= ses
->tab
->term
;
71 struct document_view
*doc_view
= current_frame(ses
);
72 struct link
*link
= NULL
;
74 if (action_id
== -1) goto unknown_action
;
76 if (doc_view
&& doc_view
->vs
) {
77 if (action_prefix_is_link_number(KEYMAP_MAIN
, action_id
)
78 && !try_jump_to_link_number(ses
, doc_view
))
81 link
= get_current_link(doc_view
);
83 } else if (action_requires_view_state(KEYMAP_MAIN
, action_id
)) {
87 if (action_requires_location(KEYMAP_MAIN
, action_id
)
88 && !have_location(ses
))
89 return FRAME_EVENT_OK
;
91 if (action_requires_link(KEYMAP_MAIN
, action_id
)
95 if (action_requires_form(KEYMAP_MAIN
, action_id
)
96 && (!link
|| !link_is_form(link
)))
99 if (!action_is_anonymous_safe(KEYMAP_MAIN
, action_id
)
100 && get_cmd_opt_bool("anonymous"))
103 /* Please keep in alphabetical order for now. Later we can sort by most
104 * used or something. */
106 case ACT_MAIN_ABORT_CONNECTION
:
107 abort_loading(ses
, 1);
108 print_screen_status(ses
);
111 case ACT_MAIN_ADD_BOOKMARK
:
112 #ifdef CONFIG_BOOKMARKS
113 launch_bm_add_doc_dialog(term
, NULL
, ses
);
116 case ACT_MAIN_ADD_BOOKMARK_LINK
:
117 #ifdef CONFIG_BOOKMARKS
118 launch_bm_add_link_dialog(term
, NULL
, ses
);
121 case ACT_MAIN_ADD_BOOKMARK_TABS
:
122 #ifdef CONFIG_BOOKMARKS
123 bookmark_terminal_tabs_dialog(term
);
127 case ACT_MAIN_AUTH_MANAGER
:
131 case ACT_MAIN_BACKSPACE_PREFIX
:
133 if (!ses
->kbdprefix
.repeat_count
) break;
135 /* Clear the highlighting. */
136 draw_formatted(ses
, 0);
138 ses
->kbdprefix
.repeat_count
/= 10;
140 if (ses
->kbdprefix
.repeat_count
)
141 highlight_links_with_prefixes_that_start_with_n(
143 ses
->kbdprefix
.repeat_count
);
145 print_screen_status(ses
);
147 /* Keep send_event from resetting repeat_count. */
148 status
= FRAME_EVENT_SESSION_DESTROYED
;
152 case ACT_MAIN_BOOKMARK_MANAGER
:
153 #ifdef CONFIG_BOOKMARKS
154 bookmark_manager(ses
);
158 case ACT_MAIN_CACHE_MANAGER
:
162 case ACT_MAIN_CACHE_MINIMIZE
:
166 case ACT_MAIN_COOKIES_LOAD
:
167 #ifdef CONFIG_COOKIES
168 if (!get_opt_bool("cookies.save")) break;
173 case ACT_MAIN_COOKIE_MANAGER
:
174 #ifdef CONFIG_COOKIES
179 case ACT_MAIN_COPY_CLIPBOARD
:
180 status
= copy_current_link_to_clipboard(ses
, doc_view
, 0);
183 case ACT_MAIN_DOCUMENT_INFO
:
184 document_info_dialog(ses
);
187 case ACT_MAIN_DOWNLOAD_MANAGER
:
188 download_manager(ses
);
191 case ACT_MAIN_EXMODE
:
197 case ACT_MAIN_FILE_MENU
:
198 activate_bfu_technology(ses
, 0);
201 case ACT_MAIN_FIND_NEXT
:
202 status
= find_next(ses
, doc_view
, 1);
205 case ACT_MAIN_FIND_NEXT_BACK
:
206 status
= find_next(ses
, doc_view
, -1);
209 case ACT_MAIN_FORGET_CREDENTIALS
:
211 shrink_memory(1); /* flush caches */
214 case ACT_MAIN_FORMHIST_MANAGER
:
215 #ifdef CONFIG_FORMHIST
216 formhist_manager(ses
);
220 case ACT_MAIN_FRAME_EXTERNAL_COMMAND
:
221 status
= pass_uri_to_command(ses
, doc_view
,
225 case ACT_MAIN_FRAME_NEXT
:
227 draw_formatted(ses
, 0);
230 case ACT_MAIN_FRAME_MAXIMIZE
:
231 status
= set_frame(ses
, doc_view
, 0);
234 case ACT_MAIN_FRAME_PREV
:
236 draw_formatted(ses
, 0);
239 case ACT_MAIN_GOTO_URL
:
240 goto_url_action(ses
, NULL
);
243 case ACT_MAIN_GOTO_URL_CURRENT
:
244 goto_url_action(ses
, get_current_url
);
247 case ACT_MAIN_GOTO_URL_CURRENT_LINK
:
248 goto_url_action(ses
, get_current_link_url
);
251 case ACT_MAIN_GOTO_URL_HOME
:
255 case ACT_MAIN_HEADER_INFO
:
256 protocol_header_dialog(ses
);
259 case ACT_MAIN_HISTORY_MANAGER
:
260 #ifdef CONFIG_GLOBHIST
261 history_manager(ses
);
265 case ACT_MAIN_HISTORY_MOVE_BACK
:
267 int count
= int_max(1, eat_kbd_repeat_count(ses
));
269 go_history_by_n(ses
, -count
);
272 case ACT_MAIN_HISTORY_MOVE_FORWARD
:
274 int count
= int_max(1, eat_kbd_repeat_count(ses
));
276 go_history_by_n(ses
, count
);
279 case ACT_MAIN_JUMP_TO_LINK
:
282 case ACT_MAIN_KEYBINDING_MANAGER
:
283 keybinding_manager(ses
);
286 case ACT_MAIN_KILL_BACKGROUNDED_CONNECTIONS
:
287 abort_background_connections();
290 case ACT_MAIN_LINK_DOWNLOAD
:
291 case ACT_MAIN_LINK_DOWNLOAD_IMAGE
:
292 case ACT_MAIN_LINK_DOWNLOAD_RESUME
:
293 status
= download_link(ses
, doc_view
, action_id
);
296 case ACT_MAIN_LINK_EXTERNAL_COMMAND
:
297 status
= pass_uri_to_command(ses
, doc_view
,
301 case ACT_MAIN_LINK_FOLLOW
:
302 status
= enter(ses
, doc_view
, 0);
305 case ACT_MAIN_LINK_FOLLOW_RELOAD
:
306 status
= enter(ses
, doc_view
, 1);
309 case ACT_MAIN_LINK_MENU
:
310 link_menu(term
, NULL
, ses
);
313 case ACT_MAIN_LINK_FORM_MENU
:
317 case ACT_MAIN_LUA_CONSOLE
:
318 #ifdef CONFIG_SCRIPTING_LUA
319 trigger_event_name("dialog-lua-console", ses
);
323 case ACT_MAIN_MARK_SET
:
325 ses
->kbdprefix
.mark
= KP_MARK_SET
;
326 status
= FRAME_EVENT_REFRESH
;
330 case ACT_MAIN_MARK_GOTO
:
332 /* TODO: Show promptly a menu (or even listbox?)
333 * with all the marks. But the next letter must
334 * still choose a mark directly! --pasky */
335 ses
->kbdprefix
.mark
= KP_MARK_GOTO
;
336 status
= FRAME_EVENT_REFRESH
;
341 activate_bfu_technology(ses
, -1);
344 case ACT_MAIN_MOVE_CURSOR_UP
:
345 status
= move_cursor_up(ses
, doc_view
);
348 case ACT_MAIN_MOVE_CURSOR_DOWN
:
349 status
= move_cursor_down(ses
, doc_view
);
352 case ACT_MAIN_MOVE_CURSOR_LEFT
:
353 status
= move_cursor_left(ses
, doc_view
);
356 case ACT_MAIN_MOVE_CURSOR_RIGHT
:
357 status
= move_cursor_right(ses
, doc_view
);
360 case ACT_MAIN_MOVE_CURSOR_LINE_START
:
361 status
= move_cursor_line_start(ses
, doc_view
);
364 case ACT_MAIN_MOVE_LINK_DOWN
:
365 status
= move_link_down(ses
, doc_view
);
368 case ACT_MAIN_MOVE_LINK_DOWN_LINE
:
369 status
= move_link_down_line(ses
, doc_view
);
372 case ACT_MAIN_MOVE_LINK_LEFT
:
373 status
= move_link_left(ses
, doc_view
);
376 case ACT_MAIN_MOVE_LINK_LEFT_LINE
:
377 status
= move_link_prev_line(ses
, doc_view
);
380 case ACT_MAIN_MOVE_LINK_NEXT
:
381 status
= move_link_next(ses
, doc_view
);
384 case ACT_MAIN_MOVE_LINK_PREV
:
385 status
= move_link_prev(ses
, doc_view
);
388 case ACT_MAIN_MOVE_LINK_RIGHT
:
389 status
= move_link_right(ses
, doc_view
);
392 case ACT_MAIN_MOVE_LINK_RIGHT_LINE
:
393 status
= move_link_next_line(ses
, doc_view
);
396 case ACT_MAIN_MOVE_LINK_UP
:
397 status
= move_link_up(ses
, doc_view
);
400 case ACT_MAIN_MOVE_LINK_UP_LINE
:
401 status
= move_link_up_line(ses
, doc_view
);
404 case ACT_MAIN_MOVE_PAGE_DOWN
:
405 status
= move_page_down(ses
, doc_view
);
408 case ACT_MAIN_MOVE_PAGE_UP
:
409 status
= move_page_up(ses
, doc_view
);
412 case ACT_MAIN_MOVE_DOCUMENT_START
:
413 status
= move_document_start(ses
, doc_view
);
416 case ACT_MAIN_MOVE_DOCUMENT_END
:
417 status
= move_document_end(ses
, doc_view
);
420 case ACT_MAIN_OPEN_LINK_IN_NEW_TAB
:
421 open_current_link_in_new_tab(ses
, 0);
424 case ACT_MAIN_OPEN_LINK_IN_NEW_TAB_IN_BACKGROUND
:
425 open_current_link_in_new_tab(ses
, 1);
428 case ACT_MAIN_OPEN_LINK_IN_NEW_WINDOW
:
429 open_in_new_window(term
, send_open_in_new_window
, ses
);
432 case ACT_MAIN_OPEN_NEW_TAB
:
433 open_uri_in_new_tab(ses
, NULL
, 0, 1);
436 case ACT_MAIN_OPEN_NEW_TAB_IN_BACKGROUND
:
437 open_uri_in_new_tab(ses
, NULL
, 1, 1);
440 case ACT_MAIN_OPEN_NEW_WINDOW
:
441 open_in_new_window(term
, send_open_new_window
, ses
);
444 case ACT_MAIN_OPEN_OS_SHELL
:
448 case ACT_MAIN_OPTIONS_MANAGER
:
449 options_manager(ses
);
456 case ACT_MAIN_REALLY_QUIT
:
460 case ACT_MAIN_REDRAW
:
461 redraw_terminal_cls(term
);
464 case ACT_MAIN_RELOAD
:
465 reload(ses
, CACHE_MODE_INCREMENT
);
468 case ACT_MAIN_RERENDER
:
469 draw_formatted(ses
, 2);
472 case ACT_MAIN_RESET_FORM
:
473 status
= reset_form(ses
, doc_view
, 0);
476 case ACT_MAIN_RESOURCE_INFO
:
480 case ACT_MAIN_SAVE_AS
:
481 status
= save_as(ses
, doc_view
, 0);
484 case ACT_MAIN_SAVE_FORMATTED
:
485 status
= save_formatted_dlg(ses
, doc_view
, 0);
488 case ACT_MAIN_SAVE_OPTIONS
:
492 case ACT_MAIN_SAVE_URL_AS
:
496 case ACT_MAIN_SAY_TEXT
:
498 run_festival(ses
, doc_view
);
502 case ACT_MAIN_SCROLL_DOWN
:
503 status
= scroll_down(ses
, doc_view
);
506 case ACT_MAIN_SCROLL_LEFT
:
507 status
= scroll_left(ses
, doc_view
);
510 case ACT_MAIN_SCROLL_RIGHT
:
511 status
= scroll_right(ses
, doc_view
);
514 case ACT_MAIN_SCROLL_UP
:
515 status
= scroll_up(ses
, doc_view
);
518 case ACT_MAIN_SEARCH
:
519 status
= search_dlg(ses
, doc_view
, 1);
522 case ACT_MAIN_SEARCH_BACK
:
523 status
= search_dlg(ses
, doc_view
, -1);
526 case ACT_MAIN_SEARCH_TYPEAHEAD
:
527 case ACT_MAIN_SEARCH_TYPEAHEAD_LINK
:
528 case ACT_MAIN_SEARCH_TYPEAHEAD_TEXT
:
529 case ACT_MAIN_SEARCH_TYPEAHEAD_TEXT_BACK
:
530 status
= search_typeahead(ses
, doc_view
, action_id
);
533 case ACT_MAIN_SHOW_TERM_OPTIONS
:
534 terminal_options(term
, NULL
, ses
);
537 case ACT_MAIN_SUBMIT_FORM
:
538 status
= submit_form(ses
, doc_view
, 0);
541 case ACT_MAIN_SUBMIT_FORM_RELOAD
:
542 status
= submit_form(ses
, doc_view
, 1);
545 case ACT_MAIN_TAB_CLOSE
:
546 close_tab(term
, ses
);
547 status
= FRAME_EVENT_SESSION_DESTROYED
;
550 case ACT_MAIN_TAB_CLOSE_ALL_BUT_CURRENT
:
551 close_all_tabs_but_current(ses
);
554 case ACT_MAIN_TAB_EXTERNAL_COMMAND
:
555 status
= pass_uri_to_command(ses
, doc_view
,
559 case ACT_MAIN_TAB_MOVE_LEFT
:
560 move_current_tab(ses
, -1);
563 case ACT_MAIN_TAB_MOVE_RIGHT
:
564 move_current_tab(ses
, 1);
567 case ACT_MAIN_TAB_MENU
:
568 assert(ses
->tab
== get_current_tab(term
));
570 if (ses
->status
.show_tabs_bar
)
571 tab_menu(ses
, ses
->tab
->xpos
,
573 - ses
->status
.show_status_bar
,
576 tab_menu(ses
, 0, 0, 0);
580 case ACT_MAIN_TAB_NEXT
:
581 switch_current_tab(ses
, 1);
584 case ACT_MAIN_TAB_PREV
:
585 switch_current_tab(ses
, -1);
588 case ACT_MAIN_TERMINAL_RESIZE
:
589 resize_terminal_dialog(term
);
592 case ACT_MAIN_TOGGLE_CSS
:
594 toggle_document_option(ses
, "document.css.enable");
598 case ACT_MAIN_TOGGLE_DISPLAY_IMAGES
:
599 toggle_document_option(ses
, "document.browse.images.show_as_links");
602 case ACT_MAIN_TOGGLE_DISPLAY_TABLES
:
603 toggle_document_option(ses
, "document.html.display_tables");
606 case ACT_MAIN_TOGGLE_DOCUMENT_COLORS
:
607 toggle_document_option(ses
, "document.colors.use_document_colors");
610 case ACT_MAIN_TOGGLE_HTML_PLAIN
:
611 toggle_plain_html(ses
, ses
->doc_view
, 0);
614 case ACT_MAIN_TOGGLE_MOUSE
:
620 case ACT_MAIN_TOGGLE_NUMBERED_LINKS
:
621 toggle_document_option(ses
, "document.browse.links.numbering");
624 case ACT_MAIN_TOGGLE_PLAIN_COMPRESS_EMPTY_LINES
:
625 toggle_document_option(ses
, "document.plain.compress_empty_lines");
628 case ACT_MAIN_TOGGLE_WRAP_TEXT
:
629 toggle_wrap_text(ses
, ses
->doc_view
, 0);
632 case ACT_MAIN_VIEW_IMAGE
:
633 status
= view_image(ses
, doc_view
, 0);
636 case ACT_MAIN_SCRIPTING_FUNCTION
:
642 INTERNAL("No action handling defined for '%s'.",
643 get_action_name(KEYMAP_MAIN
, action_id
));
646 status
= FRAME_EVENT_IGNORED
;
650 /* XXX: At this point the session may have been destroyed */
652 if (status
!= FRAME_EVENT_SESSION_DESTROYED
653 && ses
->insert_mode
== INSERT_MODE_ON
654 && link
!= get_current_link(doc_view
))
655 ses
->insert_mode
= INSERT_MODE_OFF
;
657 if (status
== FRAME_EVENT_REFRESH
&& doc_view
)
658 refresh_view(ses
, doc_view
, 0);