Cast to (const char *) in strrchr calls
[elinks.git] / src / viewer / action.c
blob5eb47223026b58734a430da8438bd0a8838f10e6
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"
47 static void
48 goto_url_action(struct session *ses,
49 unsigned char *(*get_url)(struct session *, unsigned char *, size_t))
51 unsigned char url[MAX_STR_LEN];
53 if (!get_url || !get_url(ses, url, sizeof(url)))
54 url[0] = 0;
56 dialog_goto_url(ses, url);
59 /* This could gradually become some multiplexor / switch noodle containing
60 * most if not all default handling of actions (for the main mapping) that
61 * frame_ev() and/or send_event() could use as a backend. */
62 /* Many execution paths may lead to this code so it needs to take appropriate
63 * precausions to stuff like doc_view and doc_view->vs being NULL. */
64 enum frame_event_status
65 do_action(struct session *ses, enum main_action action_id, int verbose)
67 enum frame_event_status status = FRAME_EVENT_OK;
68 struct terminal *term = ses->tab->term;
69 struct document_view *doc_view = current_frame(ses);
70 struct link *link = NULL;
72 if (action_id == -1) goto unknown_action;
74 if (doc_view && doc_view->vs) {
75 if (action_prefix_is_link_number(KEYMAP_MAIN, action_id)
76 && !try_jump_to_link_number(ses, doc_view))
77 goto ignore_action;
79 link = get_current_link(doc_view);
81 } else if (action_requires_view_state(KEYMAP_MAIN, action_id)) {
82 goto ignore_action;
85 if (action_requires_location(KEYMAP_MAIN, action_id)
86 && !have_location(ses))
87 return FRAME_EVENT_OK;
89 if (action_requires_link(KEYMAP_MAIN, action_id)
90 && !link)
91 goto ignore_action;
93 if (action_requires_form(KEYMAP_MAIN, action_id)
94 && (!link || !link_is_form(link)))
95 goto ignore_action;
97 if (!action_is_anonymous_safe(KEYMAP_MAIN, action_id)
98 && get_cmd_opt_bool("anonymous"))
99 goto ignore_action;
101 /* Please keep in alphabetical order for now. Later we can sort by most
102 * used or something. */
103 switch (action_id) {
104 case ACT_MAIN_ABORT_CONNECTION:
105 abort_loading(ses, 1);
106 print_screen_status(ses);
107 break;
109 case ACT_MAIN_ADD_BOOKMARK:
110 #ifdef CONFIG_BOOKMARKS
111 launch_bm_add_doc_dialog(term, NULL, ses);
112 #endif
113 break;
114 case ACT_MAIN_ADD_BOOKMARK_LINK:
115 #ifdef CONFIG_BOOKMARKS
116 launch_bm_add_link_dialog(term, NULL, ses);
117 #endif
118 break;
119 case ACT_MAIN_ADD_BOOKMARK_TABS:
120 #ifdef CONFIG_BOOKMARKS
121 bookmark_terminal_tabs_dialog(term);
122 #endif
123 break;
125 case ACT_MAIN_AUTH_MANAGER:
126 auth_manager(ses);
127 break;
129 case ACT_MAIN_BACKSPACE_PREFIX:
131 if (!ses->kbdprefix.repeat_count) break;
133 set_kbd_repeat_count(ses,
134 ses->kbdprefix.repeat_count / 10);
136 /* Keep send_event from resetting repeat_count. */
137 status = FRAME_EVENT_SESSION_DESTROYED;
139 break;
141 case ACT_MAIN_BOOKMARK_MANAGER:
142 #ifdef CONFIG_BOOKMARKS
143 bookmark_manager(ses);
144 #endif
145 break;
147 case ACT_MAIN_CACHE_MANAGER:
148 cache_manager(ses);
149 break;
151 case ACT_MAIN_CACHE_MINIMIZE:
152 shrink_memory(1);
153 break;
155 case ACT_MAIN_COOKIES_LOAD:
156 #ifdef CONFIG_COOKIES
157 if (!get_opt_bool("cookies.save", NULL)) break;
158 load_cookies();
159 #endif
160 break;
162 case ACT_MAIN_COOKIE_MANAGER:
163 #ifdef CONFIG_COOKIES
164 cookie_manager(ses);
165 #endif
166 break;
168 case ACT_MAIN_COPY_CLIPBOARD:
169 status = copy_current_link_to_clipboard(ses, doc_view, 0);
170 break;
172 case ACT_MAIN_DOCUMENT_INFO:
173 document_info_dialog(ses);
174 break;
176 case ACT_MAIN_DOWNLOAD_MANAGER:
177 download_manager(ses);
178 break;
180 case ACT_MAIN_EXMODE:
181 #ifdef CONFIG_EXMODE
182 exmode_start(ses);
183 #endif
184 break;
186 case ACT_MAIN_FILE_MENU:
187 activate_bfu_technology(ses, 0);
188 break;
190 case ACT_MAIN_FIND_NEXT:
191 status = find_next(ses, doc_view, 1);
192 break;
194 case ACT_MAIN_FIND_NEXT_BACK:
195 status = find_next(ses, doc_view, -1);
196 break;
198 case ACT_MAIN_FORGET_CREDENTIALS:
199 free_auth();
200 shrink_memory(1); /* flush caches */
201 break;
203 case ACT_MAIN_FORMHIST_MANAGER:
204 #ifdef CONFIG_FORMHIST
205 formhist_manager(ses);
206 #endif
207 break;
209 case ACT_MAIN_FRAME_EXTERNAL_COMMAND:
210 status = pass_uri_to_command(ses, doc_view,
211 PASS_URI_FRAME);
212 break;
214 case ACT_MAIN_FRAME_NEXT:
215 next_frame(ses, 1);
216 draw_formatted(ses, 0);
217 break;
219 case ACT_MAIN_FRAME_MAXIMIZE:
220 status = set_frame(ses, doc_view, 0);
221 break;
223 case ACT_MAIN_FRAME_PREV:
224 next_frame(ses, -1);
225 draw_formatted(ses, 0);
226 break;
228 case ACT_MAIN_GOTO_URL:
229 goto_url_action(ses, NULL);
230 break;
232 case ACT_MAIN_GOTO_URL_CURRENT:
233 goto_url_action(ses, get_current_url);
234 break;
236 case ACT_MAIN_GOTO_URL_CURRENT_LINK:
237 goto_url_action(ses, get_current_link_url);
238 break;
240 case ACT_MAIN_GOTO_URL_HOME:
241 goto_url_home(ses);
242 break;
244 case ACT_MAIN_HEADER_INFO:
245 protocol_header_dialog(ses);
246 break;
248 case ACT_MAIN_HISTORY_MANAGER:
249 #ifdef CONFIG_GLOBHIST
250 history_manager(ses);
251 #endif
252 break;
254 case ACT_MAIN_HISTORY_MOVE_BACK:
256 int count = int_max(1, eat_kbd_repeat_count(ses));
258 go_history_by_n(ses, -count);
259 break;
261 case ACT_MAIN_HISTORY_MOVE_FORWARD:
263 int count = int_max(1, eat_kbd_repeat_count(ses));
265 go_history_by_n(ses, count);
266 break;
268 case ACT_MAIN_JUMP_TO_LINK:
269 break;
271 case ACT_MAIN_KEYBINDING_MANAGER:
272 keybinding_manager(ses);
273 break;
275 case ACT_MAIN_KILL_BACKGROUNDED_CONNECTIONS:
276 abort_background_connections();
277 break;
279 case ACT_MAIN_LINK_DIALOG:
280 open_link_dialog(ses);
281 break;
283 case ACT_MAIN_LINK_DOWNLOAD:
284 case ACT_MAIN_LINK_DOWNLOAD_IMAGE:
285 case ACT_MAIN_LINK_DOWNLOAD_RESUME:
286 status = download_link(ses, doc_view, action_id);
287 break;
289 case ACT_MAIN_LINK_EXTERNAL_COMMAND:
290 status = pass_uri_to_command(ses, doc_view,
291 PASS_URI_LINK);
292 break;
294 case ACT_MAIN_LINK_FOLLOW:
295 status = enter(ses, doc_view, 0);
296 break;
298 case ACT_MAIN_LINK_FOLLOW_RELOAD:
299 status = enter(ses, doc_view, 1);
300 break;
302 case ACT_MAIN_LINK_INFO:
303 link_info_dialog(ses);
304 break;
306 case ACT_MAIN_LINK_MENU:
307 link_menu(term, NULL, ses);
308 break;
310 case ACT_MAIN_LINK_FORM_MENU:
311 link_form_menu(ses);
312 break;
314 case ACT_MAIN_LUA_CONSOLE:
315 #ifdef CONFIG_SCRIPTING_LUA
316 trigger_event_name("dialog-lua-console", ses);
317 #endif
318 break;
320 case ACT_MAIN_MARK_SET:
321 #ifdef CONFIG_MARKS
322 ses->kbdprefix.mark = KP_MARK_SET;
323 status = FRAME_EVENT_REFRESH;
324 #endif
325 break;
327 case ACT_MAIN_MARK_GOTO:
328 #ifdef CONFIG_MARKS
329 /* TODO: Show promptly a menu (or even listbox?)
330 * with all the marks. But the next letter must
331 * still choose a mark directly! --pasky */
332 ses->kbdprefix.mark = KP_MARK_GOTO;
333 status = FRAME_EVENT_REFRESH;
334 #endif
335 break;
337 case ACT_MAIN_MENU:
338 activate_bfu_technology(ses, -1);
339 break;
341 case ACT_MAIN_MOVE_CURRENT_TOP:
342 status = move_current_top(ses, doc_view);
343 break;
345 case ACT_MAIN_MOVE_CURSOR_UP:
346 status = move_cursor_up(ses, doc_view);
347 break;
349 case ACT_MAIN_MOVE_CURSOR_DOWN:
350 status = move_cursor_down(ses, doc_view);
351 break;
353 case ACT_MAIN_MOVE_CURSOR_LEFT:
354 status = move_cursor_left(ses, doc_view);
355 break;
357 case ACT_MAIN_MOVE_CURSOR_RIGHT:
358 status = move_cursor_right(ses, doc_view);
359 break;
361 case ACT_MAIN_MOVE_CURSOR_LINE_START:
362 status = move_cursor_line_start(ses, doc_view);
363 break;
365 case ACT_MAIN_MOVE_HALF_PAGE_DOWN:
366 status = move_half_page_down(ses, doc_view);
367 break;
369 case ACT_MAIN_MOVE_HALF_PAGE_UP:
370 status = move_half_page_up(ses, doc_view);
371 break;
373 case ACT_MAIN_MOVE_LINK_DOWN:
374 status = move_link_down(ses, doc_view);
375 break;
377 case ACT_MAIN_MOVE_LINK_DOWN_LINE:
378 status = move_link_down_line(ses, doc_view);
379 break;
381 case ACT_MAIN_MOVE_LINK_LEFT:
382 status = move_link_left(ses, doc_view);
383 break;
385 case ACT_MAIN_MOVE_LINK_LEFT_LINE:
386 status = move_link_prev_line(ses, doc_view);
387 break;
389 case ACT_MAIN_MOVE_LINK_NEXT:
390 status = move_link_next(ses, doc_view);
391 break;
393 case ACT_MAIN_MOVE_LINK_PREV:
394 status = move_link_prev(ses, doc_view);
395 break;
397 case ACT_MAIN_MOVE_LINK_RIGHT:
398 status = move_link_right(ses, doc_view);
399 break;
401 case ACT_MAIN_MOVE_LINK_RIGHT_LINE:
402 status = move_link_next_line(ses, doc_view);
403 break;
405 case ACT_MAIN_MOVE_LINK_UP:
406 status = move_link_up(ses, doc_view);
407 break;
409 case ACT_MAIN_MOVE_LINK_UP_LINE:
410 status = move_link_up_line(ses, doc_view);
411 break;
413 case ACT_MAIN_MOVE_PAGE_DOWN:
414 status = move_page_down(ses, doc_view);
415 break;
417 case ACT_MAIN_MOVE_PAGE_UP:
418 status = move_page_up(ses, doc_view);
419 break;
421 case ACT_MAIN_MOVE_DOCUMENT_START:
422 status = move_document_start(ses, doc_view);
423 break;
425 case ACT_MAIN_MOVE_DOCUMENT_END:
426 status = move_document_end(ses, doc_view);
427 break;
429 case ACT_MAIN_OPEN_LINK_IN_NEW_TAB:
430 open_current_link_in_new_tab(ses, 0);
431 break;
433 case ACT_MAIN_OPEN_LINK_IN_NEW_TAB_IN_BACKGROUND:
434 open_current_link_in_new_tab(ses, 1);
435 break;
437 case ACT_MAIN_OPEN_LINK_IN_NEW_WINDOW:
438 open_in_new_window(term, send_open_in_new_window, ses);
439 break;
441 case ACT_MAIN_OPEN_NEW_TAB:
442 open_uri_in_new_tab(ses, NULL, 0, 1);
443 break;
445 case ACT_MAIN_OPEN_NEW_TAB_IN_BACKGROUND:
446 open_uri_in_new_tab(ses, NULL, 1, 1);
447 break;
449 case ACT_MAIN_OPEN_NEW_WINDOW:
450 open_in_new_window(term, send_open_new_window, ses);
451 break;
453 case ACT_MAIN_OPEN_OS_SHELL:
454 exec_shell(term);
455 break;
457 case ACT_MAIN_OPTIONS_MANAGER:
458 options_manager(ses);
459 break;
461 case ACT_MAIN_QUIT:
462 exit_prog(ses, 1);
463 break;
465 case ACT_MAIN_REALLY_QUIT:
466 exit_prog(ses, 0);
467 break;
469 case ACT_MAIN_REDRAW:
470 redraw_terminal_cls(term);
471 break;
473 case ACT_MAIN_RELOAD:
474 reload(ses, CACHE_MODE_INCREMENT);
475 break;
477 case ACT_MAIN_RERENDER:
478 draw_formatted(ses, 2);
479 break;
481 case ACT_MAIN_RESET_FORM:
482 status = reset_form(ses, doc_view, 0);
483 break;
485 case ACT_MAIN_RESOURCE_INFO:
486 resource_info(term);
487 break;
489 case ACT_MAIN_SAVE_AS:
490 status = save_as(ses, doc_view, 0);
491 break;
493 case ACT_MAIN_SAVE_FORMATTED:
494 status = save_formatted_dlg(ses, doc_view, 0);
495 break;
497 case ACT_MAIN_SAVE_OPTIONS:
498 write_config(term);
499 break;
501 case ACT_MAIN_SAVE_URL_AS:
502 save_url_as(ses);
503 break;
505 case ACT_MAIN_SCROLL_DOWN:
506 status = scroll_down(ses, doc_view);
507 break;
509 case ACT_MAIN_SCROLL_LEFT:
510 status = scroll_left(ses, doc_view);
511 break;
513 case ACT_MAIN_SCROLL_RIGHT:
514 status = scroll_right(ses, doc_view);
515 break;
517 case ACT_MAIN_SCROLL_UP:
518 status = scroll_up(ses, doc_view);
519 break;
521 case ACT_MAIN_SEARCH:
522 status = search_dlg(ses, doc_view, 1);
523 break;
525 case ACT_MAIN_SEARCH_BACK:
526 status = search_dlg(ses, doc_view, -1);
527 break;
529 case ACT_MAIN_SEARCH_TYPEAHEAD:
530 case ACT_MAIN_SEARCH_TYPEAHEAD_LINK:
531 case ACT_MAIN_SEARCH_TYPEAHEAD_TEXT:
532 case ACT_MAIN_SEARCH_TYPEAHEAD_TEXT_BACK:
533 status = search_typeahead(ses, doc_view, action_id);
534 break;
536 case ACT_MAIN_SHOW_TERM_OPTIONS:
537 terminal_options(term, NULL, ses);
538 break;
540 case ACT_MAIN_SUBMIT_FORM:
541 status = submit_form(ses, doc_view, 0);
542 break;
544 case ACT_MAIN_SUBMIT_FORM_RELOAD:
545 status = submit_form(ses, doc_view, 1);
546 break;
548 case ACT_MAIN_TAB_CLOSE:
549 close_tab(term, ses);
550 status = FRAME_EVENT_SESSION_DESTROYED;
551 break;
553 case ACT_MAIN_TAB_CLOSE_ALL_BUT_CURRENT:
554 close_all_tabs_but_current(ses);
555 break;
557 case ACT_MAIN_TAB_EXTERNAL_COMMAND:
558 status = pass_uri_to_command(ses, doc_view,
559 PASS_URI_TAB);
560 break;
562 case ACT_MAIN_TAB_MOVE_LEFT:
563 move_current_tab(ses, -1);
564 break;
566 case ACT_MAIN_TAB_MOVE_RIGHT:
567 move_current_tab(ses, 1);
568 break;
570 case ACT_MAIN_TAB_MENU:
571 assert(ses->tab == get_current_tab(term));
573 if (ses->status.show_tabs_bar)
574 tab_menu(ses, ses->tab->xpos,
575 term->height - 1
576 - ses->status.show_status_bar,
578 else
579 tab_menu(ses, 0, 0, 0);
581 break;
583 case ACT_MAIN_TAB_NEXT:
584 switch_current_tab(ses, 1);
585 break;
587 case ACT_MAIN_TAB_PREV:
588 switch_current_tab(ses, -1);
589 break;
591 case ACT_MAIN_TERMINAL_RESIZE:
592 resize_terminal_dialog(term);
593 break;
595 case ACT_MAIN_TOGGLE_CSS:
596 #ifdef CONFIG_CSS
597 toggle_document_option(ses, "document.css.enable");
598 #endif
599 break;
601 case ACT_MAIN_TOGGLE_DISPLAY_IMAGES:
602 toggle_document_option(ses, "document.browse.images.show_as_links");
603 break;
605 case ACT_MAIN_TOGGLE_DISPLAY_TABLES:
606 toggle_document_option(ses, "document.html.display_tables");
607 break;
609 case ACT_MAIN_TOGGLE_DOCUMENT_COLORS:
610 toggle_document_option(ses, "document.colors.use_document_colors");
611 break;
613 case ACT_MAIN_TOGGLE_HTML_PLAIN:
614 toggle_plain_html(ses, ses->doc_view, 0);
615 break;
617 case ACT_MAIN_TOGGLE_MOUSE:
618 #ifdef CONFIG_MOUSE
619 toggle_mouse();
620 #endif
621 break;
623 case ACT_MAIN_TOGGLE_NUMBERED_LINKS:
624 toggle_document_option(ses, "document.browse.links.numbering");
625 break;
627 case ACT_MAIN_TOGGLE_PLAIN_COMPRESS_EMPTY_LINES:
628 toggle_document_option(ses, "document.plain.compress_empty_lines");
629 break;
631 case ACT_MAIN_TOGGLE_WRAP_TEXT:
632 toggle_wrap_text(ses, ses->doc_view, 0);
633 break;
635 case ACT_MAIN_VIEW_IMAGE:
636 status = view_image(ses, doc_view, 0);
637 break;
639 case ACT_MAIN_SCRIPTING_FUNCTION:
640 case ACT_MAIN_NONE:
641 case MAIN_ACTIONS:
642 default:
643 unknown_action:
644 if (verbose) {
645 INTERNAL("No action handling defined for '%s'.",
646 get_action_name(KEYMAP_MAIN, action_id));
649 status = FRAME_EVENT_IGNORED;
652 ignore_action:
653 /* XXX: At this point the session may have been destroyed */
655 if (status != FRAME_EVENT_SESSION_DESTROYED
656 && ses->insert_mode == INSERT_MODE_ON
657 && link != get_current_link(doc_view))
658 ses->insert_mode = INSERT_MODE_OFF;
660 if (status == FRAME_EVENT_REFRESH && doc_view)
661 refresh_view(ses, doc_view, 0);
663 return status;