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/form.h"
43 #include "viewer/text/link.h"
44 #include "viewer/text/search.h"
45 #include "viewer/text/view.h"
49 goto_url_action(struct session
*ses
,
50 unsigned char *(*get_url
)(struct session
*, unsigned char *, size_t))
52 unsigned char url
[MAX_STR_LEN
];
54 if (!get_url
|| !get_url(ses
, url
, sizeof(url
)))
57 dialog_goto_url(ses
, url
);
60 /* This could gradually become some multiplexor / switch noodle containing
61 * most if not all default handling of actions (for the main mapping) that
62 * frame_ev() and/or send_event() could use as a backend. */
63 /* Many execution paths may lead to this code so it needs to take appropriate
64 * precausions to stuff like doc_view and doc_view->vs being NULL. */
65 enum frame_event_status
66 do_action(struct session
*ses
, enum main_action action_id
, int verbose
)
68 enum frame_event_status status
= FRAME_EVENT_OK
;
69 struct terminal
*term
= ses
->tab
->term
;
70 struct document_view
*doc_view
= current_frame(ses
);
71 struct link
*link
= NULL
;
73 if (action_id
== -1) goto unknown_action
;
75 if (doc_view
&& doc_view
->vs
) {
76 if (action_prefix_is_link_number(KEYMAP_MAIN
, action_id
)
77 && !try_jump_to_link_number(ses
, doc_view
))
80 link
= get_current_link(doc_view
);
82 } else if (action_requires_view_state(KEYMAP_MAIN
, action_id
)) {
86 if (action_requires_location(KEYMAP_MAIN
, action_id
)
87 && !have_location(ses
))
88 return FRAME_EVENT_OK
;
90 if (action_requires_link(KEYMAP_MAIN
, action_id
)
94 if (action_requires_form(KEYMAP_MAIN
, action_id
)
95 && (!link
|| !link_is_form(link
)))
98 if (!action_is_anonymous_safe(KEYMAP_MAIN
, action_id
)
99 && get_cmd_opt_bool("anonymous"))
102 /* Please keep in alphabetical order for now. Later we can sort by most
103 * used or something. */
105 case ACT_MAIN_ABORT_CONNECTION
:
106 abort_loading(ses
, 1);
107 print_screen_status(ses
);
110 case ACT_MAIN_ADD_BOOKMARK
:
111 #ifdef CONFIG_BOOKMARKS
112 launch_bm_add_doc_dialog(term
, NULL
, ses
);
115 case ACT_MAIN_ADD_BOOKMARK_LINK
:
116 #ifdef CONFIG_BOOKMARKS
117 launch_bm_add_link_dialog(term
, NULL
, ses
);
120 case ACT_MAIN_ADD_BOOKMARK_TABS
:
121 #ifdef CONFIG_BOOKMARKS
122 bookmark_terminal_tabs_dialog(term
);
126 case ACT_MAIN_AUTH_MANAGER
:
130 case ACT_MAIN_BACKSPACE_PREFIX
:
132 if (!ses
->kbdprefix
.repeat_count
) break;
134 /* Clear the highlighting. */
135 draw_formatted(ses
, 0);
137 ses
->kbdprefix
.repeat_count
/= 10;
139 if (ses
->kbdprefix
.repeat_count
)
140 highlight_links_with_prefixes_that_start_with_n(
142 ses
->kbdprefix
.repeat_count
);
144 print_screen_status(ses
);
146 /* Keep send_event from resetting repeat_count. */
147 status
= FRAME_EVENT_SESSION_DESTROYED
;
151 case ACT_MAIN_BOOKMARK_MANAGER
:
152 #ifdef CONFIG_BOOKMARKS
153 bookmark_manager(ses
);
157 case ACT_MAIN_CACHE_MANAGER
:
161 case ACT_MAIN_CACHE_MINIMIZE
:
165 case ACT_MAIN_COOKIES_LOAD
:
166 #ifdef CONFIG_COOKIES
167 if (!get_opt_bool("cookies.save")) break;
172 case ACT_MAIN_COOKIE_MANAGER
:
173 #ifdef CONFIG_COOKIES
178 case ACT_MAIN_COPY_CLIPBOARD
:
179 status
= copy_current_link_to_clipboard(ses
, doc_view
, 0);
182 case ACT_MAIN_DOCUMENT_INFO
:
183 document_info_dialog(ses
);
186 case ACT_MAIN_DOWNLOAD_MANAGER
:
187 download_manager(ses
);
190 case ACT_MAIN_EXMODE
:
196 case ACT_MAIN_FILE_MENU
:
197 activate_bfu_technology(ses
, 0);
200 case ACT_MAIN_FIND_NEXT
:
201 status
= find_next(ses
, doc_view
, 1);
204 case ACT_MAIN_FIND_NEXT_BACK
:
205 status
= find_next(ses
, doc_view
, -1);
208 case ACT_MAIN_FORGET_CREDENTIALS
:
210 shrink_memory(1); /* flush caches */
213 case ACT_MAIN_FORMHIST_MANAGER
:
214 #ifdef CONFIG_FORMHIST
215 formhist_manager(ses
);
219 case ACT_MAIN_FRAME_EXTERNAL_COMMAND
:
220 status
= pass_uri_to_command(ses
, doc_view
,
224 case ACT_MAIN_FRAME_NEXT
:
226 draw_formatted(ses
, 0);
229 case ACT_MAIN_FRAME_MAXIMIZE
:
230 status
= set_frame(ses
, doc_view
, 0);
233 case ACT_MAIN_FRAME_PREV
:
235 draw_formatted(ses
, 0);
238 case ACT_MAIN_GOTO_URL
:
239 goto_url_action(ses
, NULL
);
242 case ACT_MAIN_GOTO_URL_CURRENT
:
243 goto_url_action(ses
, get_current_url
);
246 case ACT_MAIN_GOTO_URL_CURRENT_LINK
:
247 goto_url_action(ses
, get_current_link_url
);
250 case ACT_MAIN_GOTO_URL_HOME
:
254 case ACT_MAIN_HEADER_INFO
:
255 protocol_header_dialog(ses
);
258 case ACT_MAIN_HISTORY_MANAGER
:
259 #ifdef CONFIG_GLOBHIST
260 history_manager(ses
);
264 case ACT_MAIN_HISTORY_MOVE_BACK
:
266 int count
= int_max(1, eat_kbd_repeat_count(ses
));
268 go_history_by_n(ses
, -count
);
271 case ACT_MAIN_HISTORY_MOVE_FORWARD
:
273 int count
= int_max(1, eat_kbd_repeat_count(ses
));
275 go_history_by_n(ses
, count
);
278 case ACT_MAIN_JUMP_TO_LINK
:
281 case ACT_MAIN_KEYBINDING_MANAGER
:
282 keybinding_manager(ses
);
285 case ACT_MAIN_KILL_BACKGROUNDED_CONNECTIONS
:
286 abort_background_connections();
289 case ACT_MAIN_LINK_DOWNLOAD
:
290 case ACT_MAIN_LINK_DOWNLOAD_IMAGE
:
291 case ACT_MAIN_LINK_DOWNLOAD_RESUME
:
292 status
= download_link(ses
, doc_view
, action_id
);
295 case ACT_MAIN_LINK_EXTERNAL_COMMAND
:
296 status
= pass_uri_to_command(ses
, doc_view
,
300 case ACT_MAIN_LINK_FOLLOW
:
301 status
= enter(ses
, doc_view
, 0);
304 case ACT_MAIN_LINK_FOLLOW_RELOAD
:
305 status
= enter(ses
, doc_view
, 1);
308 case ACT_MAIN_LINK_MENU
:
309 link_menu(term
, NULL
, ses
);
312 case ACT_MAIN_LINK_FORM_MENU
:
316 case ACT_MAIN_LUA_CONSOLE
:
317 #ifdef CONFIG_SCRIPTING_LUA
318 trigger_event_name("dialog-lua-console", ses
);
322 case ACT_MAIN_MARK_SET
:
324 ses
->kbdprefix
.mark
= KP_MARK_SET
;
325 status
= FRAME_EVENT_REFRESH
;
329 case ACT_MAIN_MARK_GOTO
:
331 /* TODO: Show promptly a menu (or even listbox?)
332 * with all the marks. But the next letter must
333 * still choose a mark directly! --pasky */
334 ses
->kbdprefix
.mark
= KP_MARK_GOTO
;
335 status
= FRAME_EVENT_REFRESH
;
340 activate_bfu_technology(ses
, -1);
343 case ACT_MAIN_MOVE_CURSOR_UP
:
344 status
= move_cursor_up(ses
, doc_view
);
347 case ACT_MAIN_MOVE_CURSOR_DOWN
:
348 status
= move_cursor_down(ses
, doc_view
);
351 case ACT_MAIN_MOVE_CURSOR_LEFT
:
352 status
= move_cursor_left(ses
, doc_view
);
355 case ACT_MAIN_MOVE_CURSOR_RIGHT
:
356 status
= move_cursor_right(ses
, doc_view
);
359 case ACT_MAIN_MOVE_LINK_DOWN
:
360 status
= move_link_down(ses
, doc_view
);
363 case ACT_MAIN_MOVE_LINK_LEFT
:
364 status
= move_link_left(ses
, doc_view
);
367 case ACT_MAIN_MOVE_LINK_NEXT
:
368 status
= move_link_next(ses
, doc_view
);
371 case ACT_MAIN_MOVE_LINK_PREV
:
372 status
= move_link_prev(ses
, doc_view
);
375 case ACT_MAIN_MOVE_LINK_RIGHT
:
376 status
= move_link_right(ses
, doc_view
);
379 case ACT_MAIN_MOVE_LINK_UP
:
380 status
= move_link_up(ses
, doc_view
);
383 case ACT_MAIN_MOVE_PAGE_DOWN
:
384 status
= move_page_down(ses
, doc_view
);
387 case ACT_MAIN_MOVE_PAGE_UP
:
388 status
= move_page_up(ses
, doc_view
);
391 case ACT_MAIN_MOVE_DOCUMENT_START
:
392 status
= move_document_start(ses
, doc_view
);
395 case ACT_MAIN_MOVE_DOCUMENT_END
:
396 status
= move_document_end(ses
, doc_view
);
399 case ACT_MAIN_OPEN_LINK_IN_NEW_TAB
:
400 open_current_link_in_new_tab(ses
, 0);
403 case ACT_MAIN_OPEN_LINK_IN_NEW_TAB_IN_BACKGROUND
:
404 open_current_link_in_new_tab(ses
, 1);
407 case ACT_MAIN_OPEN_LINK_IN_NEW_WINDOW
:
408 open_in_new_window(term
, send_open_in_new_window
, ses
);
411 case ACT_MAIN_OPEN_NEW_TAB
:
412 open_uri_in_new_tab(ses
, NULL
, 0, 1);
415 case ACT_MAIN_OPEN_NEW_TAB_IN_BACKGROUND
:
416 open_uri_in_new_tab(ses
, NULL
, 1, 1);
419 case ACT_MAIN_OPEN_NEW_WINDOW
:
420 open_in_new_window(term
, send_open_new_window
, ses
);
423 case ACT_MAIN_OPEN_OS_SHELL
:
427 case ACT_MAIN_OPTIONS_MANAGER
:
428 options_manager(ses
);
435 case ACT_MAIN_REALLY_QUIT
:
439 case ACT_MAIN_REDRAW
:
440 redraw_terminal_cls(term
);
443 case ACT_MAIN_RELOAD
:
444 reload(ses
, CACHE_MODE_INCREMENT
);
447 case ACT_MAIN_RERENDER
:
448 draw_formatted(ses
, 2);
451 case ACT_MAIN_RESET_FORM
:
452 status
= reset_form(ses
, doc_view
, 0);
455 case ACT_MAIN_RESOURCE_INFO
:
459 case ACT_MAIN_SAVE_AS
:
460 status
= save_as(ses
, doc_view
, 0);
463 case ACT_MAIN_SAVE_FORMATTED
:
464 status
= save_formatted_dlg(ses
, doc_view
, 0);
467 case ACT_MAIN_SAVE_OPTIONS
:
471 case ACT_MAIN_SAVE_URL_AS
:
475 case ACT_MAIN_SCROLL_DOWN
:
476 status
= scroll_down(ses
, doc_view
);
479 case ACT_MAIN_SCROLL_LEFT
:
480 status
= scroll_left(ses
, doc_view
);
483 case ACT_MAIN_SCROLL_RIGHT
:
484 status
= scroll_right(ses
, doc_view
);
487 case ACT_MAIN_SCROLL_UP
:
488 status
= scroll_up(ses
, doc_view
);
491 case ACT_MAIN_SEARCH
:
492 status
= search_dlg(ses
, doc_view
, 1);
495 case ACT_MAIN_SEARCH_BACK
:
496 status
= search_dlg(ses
, doc_view
, -1);
499 case ACT_MAIN_SEARCH_TYPEAHEAD
:
500 case ACT_MAIN_SEARCH_TYPEAHEAD_LINK
:
501 case ACT_MAIN_SEARCH_TYPEAHEAD_TEXT
:
502 case ACT_MAIN_SEARCH_TYPEAHEAD_TEXT_BACK
:
503 status
= search_typeahead(ses
, doc_view
, action_id
);
506 case ACT_MAIN_SHOW_TERM_OPTIONS
:
507 terminal_options(term
, NULL
, ses
);
510 case ACT_MAIN_SUBMIT_FORM
:
511 status
= submit_form(ses
, doc_view
, 0);
514 case ACT_MAIN_SUBMIT_FORM_RELOAD
:
515 status
= submit_form(ses
, doc_view
, 1);
518 case ACT_MAIN_TAB_CLOSE
:
519 close_tab(term
, ses
);
520 status
= FRAME_EVENT_SESSION_DESTROYED
;
523 case ACT_MAIN_TAB_CLOSE_ALL_BUT_CURRENT
:
524 close_all_tabs_but_current(ses
);
527 case ACT_MAIN_TAB_EXTERNAL_COMMAND
:
528 status
= pass_uri_to_command(ses
, doc_view
,
532 case ACT_MAIN_TAB_MOVE_LEFT
:
533 move_current_tab(ses
, -1);
536 case ACT_MAIN_TAB_MOVE_RIGHT
:
537 move_current_tab(ses
, 1);
540 case ACT_MAIN_TAB_MENU
:
541 assert(ses
->tab
== get_current_tab(term
));
543 if (ses
->status
.show_tabs_bar
)
544 tab_menu(ses
, ses
->tab
->xpos
,
546 - ses
->status
.show_status_bar
,
549 tab_menu(ses
, 0, 0, 0);
553 case ACT_MAIN_TAB_NEXT
:
554 switch_current_tab(ses
, 1);
557 case ACT_MAIN_TAB_PREV
:
558 switch_current_tab(ses
, -1);
561 case ACT_MAIN_TERMINAL_RESIZE
:
562 resize_terminal_dialog(term
);
565 case ACT_MAIN_TOGGLE_CSS
:
567 toggle_document_option(ses
, "document.css.enable");
571 case ACT_MAIN_TOGGLE_DISPLAY_IMAGES
:
572 toggle_document_option(ses
, "document.browse.images.show_as_links");
575 case ACT_MAIN_TOGGLE_DISPLAY_TABLES
:
576 toggle_document_option(ses
, "document.html.display_tables");
579 case ACT_MAIN_TOGGLE_DOCUMENT_COLORS
:
580 toggle_document_option(ses
, "document.colors.use_document_colors");
583 case ACT_MAIN_TOGGLE_HTML_PLAIN
:
584 toggle_plain_html(ses
, ses
->doc_view
, 0);
587 case ACT_MAIN_TOGGLE_MOUSE
:
593 case ACT_MAIN_TOGGLE_NUMBERED_LINKS
:
594 toggle_document_option(ses
, "document.browse.links.numbering");
597 case ACT_MAIN_TOGGLE_PLAIN_COMPRESS_EMPTY_LINES
:
598 toggle_document_option(ses
, "document.plain.compress_empty_lines");
601 case ACT_MAIN_TOGGLE_WRAP_TEXT
:
602 toggle_wrap_text(ses
, ses
->doc_view
, 0);
605 case ACT_MAIN_VIEW_IMAGE
:
606 status
= view_image(ses
, doc_view
, 0);
609 case ACT_MAIN_SCRIPTING_FUNCTION
:
615 INTERNAL("No action handling defined for '%s'.",
616 get_action_name(KEYMAP_MAIN
, action_id
));
619 status
= FRAME_EVENT_IGNORED
;
623 /* XXX: At this point the session may have been destroyed */
625 if (status
!= FRAME_EVENT_SESSION_DESTROYED
626 && ses
->insert_mode
== INSERT_MODE_ON
627 && link
!= get_current_link(doc_view
))
628 ses
->insert_mode
= INSERT_MODE_OFF
;
630 if (status
== FRAME_EVENT_REFRESH
&& doc_view
)
631 refresh_view(ses
, doc_view
, 0);