Python: Give goto_url_hook only one argument, like follow_url_hook.
[elinks.git] / src / viewer / action.c
blob3089a19f1d9010b8d8b86633fe2143120a0c9845
1 /* Sessions action management */
3 #ifdef HAVE_CONFIG_H
4 #include "config.h"
5 #endif
7 #include <stdlib.h>
9 #include "elinks.h"
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"
48 static void
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)))
55 url[0] = 0;
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))
78 goto ignore_action;
80 link = get_current_link(doc_view);
82 } else if (action_requires_view_state(KEYMAP_MAIN, action_id)) {
83 goto ignore_action;
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)
91 && !link)
92 goto ignore_action;
94 if (action_requires_form(KEYMAP_MAIN, action_id)
95 && (!link || !link_is_form(link)))
96 goto ignore_action;
98 if (!action_is_anonymous_safe(KEYMAP_MAIN, action_id)
99 && get_cmd_opt_bool("anonymous"))
100 goto ignore_action;
102 /* Please keep in alphabetical order for now. Later we can sort by most
103 * used or something. */
104 switch (action_id) {
105 case ACT_MAIN_ABORT_CONNECTION:
106 abort_loading(ses, 1);
107 print_screen_status(ses);
108 break;
110 case ACT_MAIN_ADD_BOOKMARK:
111 #ifdef CONFIG_BOOKMARKS
112 launch_bm_add_doc_dialog(term, NULL, ses);
113 #endif
114 break;
115 case ACT_MAIN_ADD_BOOKMARK_LINK:
116 #ifdef CONFIG_BOOKMARKS
117 launch_bm_add_link_dialog(term, NULL, ses);
118 #endif
119 break;
120 case ACT_MAIN_ADD_BOOKMARK_TABS:
121 #ifdef CONFIG_BOOKMARKS
122 bookmark_terminal_tabs_dialog(term);
123 #endif
124 break;
126 case ACT_MAIN_AUTH_MANAGER:
127 auth_manager(ses);
128 break;
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(
141 term, doc_view,
142 ses->kbdprefix.repeat_count);
144 print_screen_status(ses);
146 /* Keep send_event from resetting repeat_count. */
147 status = FRAME_EVENT_SESSION_DESTROYED;
149 break;
151 case ACT_MAIN_BOOKMARK_MANAGER:
152 #ifdef CONFIG_BOOKMARKS
153 bookmark_manager(ses);
154 #endif
155 break;
157 case ACT_MAIN_CACHE_MANAGER:
158 cache_manager(ses);
159 break;
161 case ACT_MAIN_CACHE_MINIMIZE:
162 shrink_memory(1);
163 break;
165 case ACT_MAIN_COOKIES_LOAD:
166 #ifdef CONFIG_COOKIES
167 if (!get_opt_bool("cookies.save")) break;
168 load_cookies();
169 #endif
170 break;
172 case ACT_MAIN_COOKIE_MANAGER:
173 #ifdef CONFIG_COOKIES
174 cookie_manager(ses);
175 #endif
176 break;
178 case ACT_MAIN_COPY_CLIPBOARD:
179 status = copy_current_link_to_clipboard(ses, doc_view, 0);
180 break;
182 case ACT_MAIN_DOCUMENT_INFO:
183 document_info_dialog(ses);
184 break;
186 case ACT_MAIN_DOWNLOAD_MANAGER:
187 download_manager(ses);
188 break;
190 case ACT_MAIN_EXMODE:
191 #ifdef CONFIG_EXMODE
192 exmode_start(ses);
193 #endif
194 break;
196 case ACT_MAIN_FILE_MENU:
197 activate_bfu_technology(ses, 0);
198 break;
200 case ACT_MAIN_FIND_NEXT:
201 status = find_next(ses, doc_view, 1);
202 break;
204 case ACT_MAIN_FIND_NEXT_BACK:
205 status = find_next(ses, doc_view, -1);
206 break;
208 case ACT_MAIN_FORGET_CREDENTIALS:
209 free_auth();
210 shrink_memory(1); /* flush caches */
211 break;
213 case ACT_MAIN_FORMHIST_MANAGER:
214 #ifdef CONFIG_FORMHIST
215 formhist_manager(ses);
216 #endif
217 break;
219 case ACT_MAIN_FRAME_EXTERNAL_COMMAND:
220 status = pass_uri_to_command(ses, doc_view,
221 PASS_URI_FRAME);
222 break;
224 case ACT_MAIN_FRAME_NEXT:
225 next_frame(ses, 1);
226 draw_formatted(ses, 0);
227 break;
229 case ACT_MAIN_FRAME_MAXIMIZE:
230 status = set_frame(ses, doc_view, 0);
231 break;
233 case ACT_MAIN_FRAME_PREV:
234 next_frame(ses, -1);
235 draw_formatted(ses, 0);
236 break;
238 case ACT_MAIN_GOTO_URL:
239 goto_url_action(ses, NULL);
240 break;
242 case ACT_MAIN_GOTO_URL_CURRENT:
243 goto_url_action(ses, get_current_url);
244 break;
246 case ACT_MAIN_GOTO_URL_CURRENT_LINK:
247 goto_url_action(ses, get_current_link_url);
248 break;
250 case ACT_MAIN_GOTO_URL_HOME:
251 goto_url_home(ses);
252 break;
254 case ACT_MAIN_HEADER_INFO:
255 protocol_header_dialog(ses);
256 break;
258 case ACT_MAIN_HISTORY_MANAGER:
259 #ifdef CONFIG_GLOBHIST
260 history_manager(ses);
261 #endif
262 break;
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);
269 break;
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);
276 break;
278 case ACT_MAIN_JUMP_TO_LINK:
279 break;
281 case ACT_MAIN_KEYBINDING_MANAGER:
282 keybinding_manager(ses);
283 break;
285 case ACT_MAIN_KILL_BACKGROUNDED_CONNECTIONS:
286 abort_background_connections();
287 break;
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);
293 break;
295 case ACT_MAIN_LINK_EXTERNAL_COMMAND:
296 status = pass_uri_to_command(ses, doc_view,
297 PASS_URI_LINK);
298 break;
300 case ACT_MAIN_LINK_FOLLOW:
301 status = enter(ses, doc_view, 0);
302 break;
304 case ACT_MAIN_LINK_FOLLOW_RELOAD:
305 status = enter(ses, doc_view, 1);
306 break;
308 case ACT_MAIN_LINK_MENU:
309 link_menu(term, NULL, ses);
310 break;
312 case ACT_MAIN_LINK_FORM_MENU:
313 link_form_menu(ses);
314 break;
316 case ACT_MAIN_LUA_CONSOLE:
317 #ifdef CONFIG_SCRIPTING_LUA
318 trigger_event_name("dialog-lua-console", ses);
319 #endif
320 break;
322 case ACT_MAIN_MARK_SET:
323 #ifdef CONFIG_MARKS
324 ses->kbdprefix.mark = KP_MARK_SET;
325 status = FRAME_EVENT_REFRESH;
326 #endif
327 break;
329 case ACT_MAIN_MARK_GOTO:
330 #ifdef CONFIG_MARKS
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;
336 #endif
337 break;
339 case ACT_MAIN_MENU:
340 activate_bfu_technology(ses, -1);
341 break;
343 case ACT_MAIN_MOVE_CURSOR_UP:
344 status = move_cursor_up(ses, doc_view);
345 break;
347 case ACT_MAIN_MOVE_CURSOR_DOWN:
348 status = move_cursor_down(ses, doc_view);
349 break;
351 case ACT_MAIN_MOVE_CURSOR_LEFT:
352 status = move_cursor_left(ses, doc_view);
353 break;
355 case ACT_MAIN_MOVE_CURSOR_RIGHT:
356 status = move_cursor_right(ses, doc_view);
357 break;
359 case ACT_MAIN_MOVE_LINK_DOWN:
360 status = move_link_down(ses, doc_view);
361 break;
363 case ACT_MAIN_MOVE_LINK_LEFT:
364 status = move_link_left(ses, doc_view);
365 break;
367 case ACT_MAIN_MOVE_LINK_NEXT:
368 status = move_link_next(ses, doc_view);
369 break;
371 case ACT_MAIN_MOVE_LINK_PREV:
372 status = move_link_prev(ses, doc_view);
373 break;
375 case ACT_MAIN_MOVE_LINK_RIGHT:
376 status = move_link_right(ses, doc_view);
377 break;
379 case ACT_MAIN_MOVE_LINK_UP:
380 status = move_link_up(ses, doc_view);
381 break;
383 case ACT_MAIN_MOVE_PAGE_DOWN:
384 status = move_page_down(ses, doc_view);
385 break;
387 case ACT_MAIN_MOVE_PAGE_UP:
388 status = move_page_up(ses, doc_view);
389 break;
391 case ACT_MAIN_MOVE_DOCUMENT_START:
392 status = move_document_start(ses, doc_view);
393 break;
395 case ACT_MAIN_MOVE_DOCUMENT_END:
396 status = move_document_end(ses, doc_view);
397 break;
399 case ACT_MAIN_OPEN_LINK_IN_NEW_TAB:
400 open_current_link_in_new_tab(ses, 0);
401 break;
403 case ACT_MAIN_OPEN_LINK_IN_NEW_TAB_IN_BACKGROUND:
404 open_current_link_in_new_tab(ses, 1);
405 break;
407 case ACT_MAIN_OPEN_LINK_IN_NEW_WINDOW:
408 open_in_new_window(term, send_open_in_new_window, ses);
409 break;
411 case ACT_MAIN_OPEN_NEW_TAB:
412 open_uri_in_new_tab(ses, NULL, 0, 1);
413 break;
415 case ACT_MAIN_OPEN_NEW_TAB_IN_BACKGROUND:
416 open_uri_in_new_tab(ses, NULL, 1, 1);
417 break;
419 case ACT_MAIN_OPEN_NEW_WINDOW:
420 open_in_new_window(term, send_open_new_window, ses);
421 break;
423 case ACT_MAIN_OPEN_OS_SHELL:
424 exec_shell(term);
425 break;
427 case ACT_MAIN_OPTIONS_MANAGER:
428 options_manager(ses);
429 break;
431 case ACT_MAIN_QUIT:
432 exit_prog(ses, 1);
433 break;
435 case ACT_MAIN_REALLY_QUIT:
436 exit_prog(ses, 0);
437 break;
439 case ACT_MAIN_REDRAW:
440 redraw_terminal_cls(term);
441 break;
443 case ACT_MAIN_RELOAD:
444 reload(ses, CACHE_MODE_INCREMENT);
445 break;
447 case ACT_MAIN_RERENDER:
448 draw_formatted(ses, 2);
449 break;
451 case ACT_MAIN_RESET_FORM:
452 status = reset_form(ses, doc_view, 0);
453 break;
455 case ACT_MAIN_RESOURCE_INFO:
456 resource_info(term);
457 break;
459 case ACT_MAIN_SAVE_AS:
460 status = save_as(ses, doc_view, 0);
461 break;
463 case ACT_MAIN_SAVE_FORMATTED:
464 status = save_formatted_dlg(ses, doc_view, 0);
465 break;
467 case ACT_MAIN_SAVE_OPTIONS:
468 write_config(term);
469 break;
471 case ACT_MAIN_SAVE_URL_AS:
472 save_url_as(ses);
473 break;
475 case ACT_MAIN_SCROLL_DOWN:
476 status = scroll_down(ses, doc_view);
477 break;
479 case ACT_MAIN_SCROLL_LEFT:
480 status = scroll_left(ses, doc_view);
481 break;
483 case ACT_MAIN_SCROLL_RIGHT:
484 status = scroll_right(ses, doc_view);
485 break;
487 case ACT_MAIN_SCROLL_UP:
488 status = scroll_up(ses, doc_view);
489 break;
491 case ACT_MAIN_SEARCH:
492 status = search_dlg(ses, doc_view, 1);
493 break;
495 case ACT_MAIN_SEARCH_BACK:
496 status = search_dlg(ses, doc_view, -1);
497 break;
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);
504 break;
506 case ACT_MAIN_SHOW_TERM_OPTIONS:
507 terminal_options(term, NULL, ses);
508 break;
510 case ACT_MAIN_SUBMIT_FORM:
511 status = submit_form(ses, doc_view, 0);
512 break;
514 case ACT_MAIN_SUBMIT_FORM_RELOAD:
515 status = submit_form(ses, doc_view, 1);
516 break;
518 case ACT_MAIN_TAB_CLOSE:
519 close_tab(term, ses);
520 status = FRAME_EVENT_SESSION_DESTROYED;
521 break;
523 case ACT_MAIN_TAB_CLOSE_ALL_BUT_CURRENT:
524 close_all_tabs_but_current(ses);
525 break;
527 case ACT_MAIN_TAB_EXTERNAL_COMMAND:
528 status = pass_uri_to_command(ses, doc_view,
529 PASS_URI_TAB);
530 break;
532 case ACT_MAIN_TAB_MOVE_LEFT:
533 move_current_tab(ses, -1);
534 break;
536 case ACT_MAIN_TAB_MOVE_RIGHT:
537 move_current_tab(ses, 1);
538 break;
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,
545 term->height - 1
546 - ses->status.show_status_bar,
548 else
549 tab_menu(ses, 0, 0, 0);
551 break;
553 case ACT_MAIN_TAB_NEXT:
554 switch_current_tab(ses, 1);
555 break;
557 case ACT_MAIN_TAB_PREV:
558 switch_current_tab(ses, -1);
559 break;
561 case ACT_MAIN_TERMINAL_RESIZE:
562 resize_terminal_dialog(term);
563 break;
565 case ACT_MAIN_TOGGLE_CSS:
566 #ifdef CONFIG_CSS
567 toggle_document_option(ses, "document.css.enable");
568 #endif
569 break;
571 case ACT_MAIN_TOGGLE_DISPLAY_IMAGES:
572 toggle_document_option(ses, "document.browse.images.show_as_links");
573 break;
575 case ACT_MAIN_TOGGLE_DISPLAY_TABLES:
576 toggle_document_option(ses, "document.html.display_tables");
577 break;
579 case ACT_MAIN_TOGGLE_DOCUMENT_COLORS:
580 toggle_document_option(ses, "document.colors.use_document_colors");
581 break;
583 case ACT_MAIN_TOGGLE_HTML_PLAIN:
584 toggle_plain_html(ses, ses->doc_view, 0);
585 break;
587 case ACT_MAIN_TOGGLE_MOUSE:
588 #ifdef CONFIG_MOUSE
589 toggle_mouse();
590 #endif
591 break;
593 case ACT_MAIN_TOGGLE_NUMBERED_LINKS:
594 toggle_document_option(ses, "document.browse.links.numbering");
595 break;
597 case ACT_MAIN_TOGGLE_PLAIN_COMPRESS_EMPTY_LINES:
598 toggle_document_option(ses, "document.plain.compress_empty_lines");
599 break;
601 case ACT_MAIN_TOGGLE_WRAP_TEXT:
602 toggle_wrap_text(ses, ses->doc_view, 0);
603 break;
605 case ACT_MAIN_VIEW_IMAGE:
606 status = view_image(ses, doc_view, 0);
607 break;
609 case ACT_MAIN_SCRIPTING_FUNCTION:
610 case ACT_MAIN_NONE:
611 case MAIN_ACTIONS:
612 default:
613 unknown_action:
614 if (verbose) {
615 INTERNAL("No action handling defined for '%s'.",
616 get_action_name(KEYMAP_MAIN, action_id));
619 status = FRAME_EVENT_IGNORED;
622 ignore_action:
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);
633 return status;