Dillo v3.2.0-143-gabad1053
Loading...
Searching...
No Matches
menu.cc
Go to the documentation of this file.
1/*
2 * File: menu.cc
3 *
4 * Copyright (C) 2005-2007 Jorge Arellano Cid <jcid@dillo.org>
5 * Copyright (C) 2024-2025 Rodrigo Arias Mallo <rodarima@gmail.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 3 of the License, or
10 * (at your option) any later version.
11 */
12
18#include <FL/Fl.H>
19#include <FL/Fl_Menu_Item.H>
20
21#include "lout/misc.hh" /* SimpleVector */
22#include "msg.h"
23#include "menu.hh"
24#include "actions.h"
25#include "uicmd.hh"
26#include "history.h"
27#include "html.hh"
28#include "ui.hh" // for (UI *)
29#include "keys.hh"
30#include "timeout.hh"
31
32#include <unistd.h>
33
34/*
35 * Local data types
36 */
37
38typedef struct {
39 const char *title;
40 const Fl_Menu_Item *picked;
41 const Fl_Menu_Item *menu;
42} Menu_popup_data_t;
43
44/*
45 * Local data
46 */
47
48// (This data can be encapsulated inside a class for each popup, but
49// as popups are modal, there's no need).
50static DilloUrl *popup_url = NULL;
51// Weak reference to the popup's bw
52static BrowserWindow *popup_bw = NULL;
53static void *popup_form = NULL;
54// Where to place the popup
55static int popup_x, popup_y;
56// History popup direction (-1 = back, 1 = forward).
57static int history_direction = -1;
58// History popup, list of URL-indexes.
59static int *history_list = NULL;
60
61
62//--------------------------------------------------------------------------
63static void Menu_nop_cb(Fl_Widget*, void*)
64{
65}
66
70static void filemenu_cb(Fl_Widget*, void *data)
71{
72 if (strcmp((char*)data, "nw") == 0) {
74 } else if (strcmp((char*)data, "nt") == 0) {
76 } else if (strcmp((char*)data, "of") == 0) {
78 } else if (strcmp((char*)data, "ou") == 0) {
80 } else if (strcmp((char*)data, "cw") == 0) {
82 } else if (strcmp((char*)data, "ed") == 0) {
84 }
85}
86
87
88static void Menu_copy_urlstr_cb(Fl_Widget*, void *user_data)
89{
90 if (user_data) {
91 DilloUrl *url = (DilloUrl *)user_data ;
93 }
94}
95
99static void Menu_open_url_cb(Fl_Widget*, void *user_data)
100{
101 DilloUrl *url = (DilloUrl *)user_data;
102 _MSG("Open URL cb: click! :-)\n");
104}
105
109static void Menu_open_url_nw_cb(Fl_Widget*, void *user_data)
110{
111 DilloUrl *url = (DilloUrl *)user_data;
112 _MSG("Open URL in new window cb: click! :-)\n");
114}
115
119static void Menu_open_url_nt_cb(Fl_Widget*, void *user_data)
120{
121 DilloUrl *url = (DilloUrl *)user_data;
122 int focus = prefs.focus_new_tab ? 1 : 0;
123 if (Fl::event_state(FL_SHIFT)) focus = !focus;
124 a_UIcmd_open_url_nt(popup_bw, url, focus);
125}
126
130static void Menu_add_bookmark_cb(Fl_Widget*, void *user_data)
131{
132 DilloUrl *url = (DilloUrl *)user_data;
134}
135
139static void Menu_find_text_cb(Fl_Widget*, void*)
140{
141 ((UI *)popup_bw->ui)->findbar_toggle(1);
142}
143
147static void Menu_save_link_cb(Fl_Widget*, void *user_data)
148{
149 DilloUrl *url = (DilloUrl *)user_data;
150 a_UIcmd_save_link(popup_bw, url, NULL);
151}
152
156static void Menu_save_page_cb(Fl_Widget*, void*)
157{
159}
160
164static void Menu_view_page_source_cb(Fl_Widget*, void *user_data)
165{
166 DilloUrl *url = (DilloUrl *)user_data;
168}
169
173static void Menu_view_page_bugs_cb(Fl_Widget*, void*)
174{
176}
177
181static void Menu_load_images_cb(Fl_Widget*, void *user_data)
182{
183 DilloUrl *page_url = (DilloUrl *) user_data;
184 void *doc = a_Bw_get_url_doc(popup_bw, page_url);
185
186 if (doc)
188}
189
193static void Menu_form_submit_cb(Fl_Widget*, void*)
194{
195 void *doc = a_Bw_get_url_doc(popup_bw, popup_url);
196
197 if (doc)
199}
200
204static void Menu_form_reset_cb(Fl_Widget*, void*)
205{
206 void *doc = a_Bw_get_url_doc(popup_bw, popup_url);
207
208 if (doc)
210}
211
215static void Menu_form_hiddens_cb(Fl_Widget*, void *user_data)
216{
217 bool visible = *((bool *) user_data);
218 void *doc = a_Bw_get_url_doc(popup_bw, popup_url);
219
220 if (doc)
222}
223
224static void Menu_stylesheet_cb(Fl_Widget*, void *vUrl)
225{
226 int mb = Fl::event_button();
227 const DilloUrl *url = (const DilloUrl *) vUrl;
228
229 if (mb == 1) {
231 } else if (mb == 2) {
233 int focus = prefs.focus_new_tab ? 1 : 0;
234 if (Fl::event_state(FL_SHIFT)) focus = !focus;
235 a_UIcmd_open_url_nt(popup_bw, url, focus);
236 } else {
238 }
239 }
240}
241
242static void Menu_bugmeter_validate(const char *validator_url)
243{
244 if (popup_url &&
246 const char *popup_str = URL_STR(popup_url),
247 *ptr = strrchr(popup_str, '#');
248 char *no_fragment = ptr ? dStrndup(popup_str, ptr - popup_str)
249 : dStrdup(popup_str);
250 char *encoded = a_Url_encode_hex_str(no_fragment);
251 Dstr *dstr = dStr_sized_new(128);
252
253 dStr_sprintf(dstr, validator_url, encoded);
255 dStr_free(dstr, 1);
256 dFree(encoded);
257 dFree(no_fragment);
258 }
259}
260
264static void Menu_bugmeter_validate_w3c_nu_cb(Fl_Widget*, void*)
265{
267 "https://validator.w3.org/nu/"
268 "?useragent=Validator.nu%%2FLV+https%%3A%%2F%%2Fvalidator.w3.org%%2Fservices"
269 "&acceptlanguage="
270 "&doc=%s");
271}
272
276static void Menu_bugmeter_validate_w3c_cb(Fl_Widget*, void*)
277{
279 "https://validator.w3.org/check?uri=%s"
280 "&charset=%%28detect+automatically%%29"
281 "&doctype=Inline&group=0"
282 "&user-agent=W3C_Validator%%2F1.3+");
283}
284
288static void Menu_bugmeter_about_cb(Fl_Widget*, void*)
289{
290 a_UIcmd_open_urlstr(popup_bw, "https://dillo-browser.github.io/old/help/bug_meter.html");
291}
292
297static void Menu_history_cb(Fl_Widget*, void *data)
298{
299 int mb = Fl::event_button();
300 int offset = history_direction * VOIDP2INT(data);
301 const DilloUrl *url = a_History_get_url(history_list[VOIDP2INT(data)-1]);
302
303 if (mb == 1) {
304 a_UIcmd_nav_jump(popup_bw, offset, 0);
305 } else if (mb == 2) {
306 // Middle button, open in a new window/tab
308 int focus = prefs.focus_new_tab ? 1 : 0;
309 if (Fl::event_state(FL_SHIFT)) focus = !focus;
310 a_UIcmd_open_url_nt(popup_bw, url, focus);
311 } else {
313 }
314 }
315}
316
317/*
318 * Menus are popped-up from this timeout callback so the events
319 * associated with the button are gone when it pops. This way we
320 * avoid a segfault when a new page replaces the page that issued
321 * the popup menu.
322 */
323static void Menu_simple_popup_cb(void *data)
324{
325 const Fl_Menu_Item *m;
326
327 ((UI*)popup_bw->ui)->window()->cursor(FL_CURSOR_DEFAULT);
328
329 m = ((Fl_Menu_Item *)data)->popup(popup_x, popup_y);
330
331 if (m && m->callback())
332 m->do_callback((Fl_Widget *)data);
334}
335
336static void Menu_popup_cb(void *data)
337{
338 const Fl_Menu_Item *picked;
339 Menu_popup_data_t *d = (Menu_popup_data_t *)data;
340
341 ((UI*)popup_bw->ui)->window()->cursor(FL_CURSOR_DEFAULT);
342
343 picked = d->menu->popup(popup_x, popup_y, d->title, d->picked);
344 if (picked) {
345 d->picked = picked;
346 if (picked->callback())
347 picked->do_callback((Fl_Widget *)(d->menu));
348 }
350}
351
352static Fl_Menu_Item page_menu_[] = {
353 {"View page source", 0, Menu_view_page_source_cb,0,0,0,0,0,0},
354 {"View page bugs", 0, Menu_view_page_bugs_cb,0,0,0,0,0,0},
355 {"View stylesheets", 0, Menu_nop_cb,0,FL_SUBMENU_POINTER|FL_MENU_DIVIDER,
356 0,0,0,0},
357 {"Bookmark this page", 0,Menu_add_bookmark_cb,0,FL_MENU_DIVIDER,0,0,0,0},
358 {"Find text", 0, Menu_find_text_cb,0,0,0,0,0,0},
359 {"Save page as...", 0, Menu_save_page_cb,0,FL_MENU_DIVIDER,0,0,0,0},
360 {0,0,0,0,0,0,0,0,0}
361};
362
363/* Keep a pointer to the current page url so that is available from the page
364 * action callback */
365static const DilloUrl *current_page_url = NULL;
366
370static void Menu_open_page_action_cb(Fl_Widget*, void *user_data)
371{
372 Action *action = (Action *) user_data;
373
375 setenv("url", URL_STR(current_page_url), 1);
376
377 a_Actions_run(action);
378
379 unsetenv("url");
380}
381
382static Fl_Menu_Item *get_page_menu(void)
383{
384 static Fl_Menu_Item *page_menu = NULL;
385
386 /* Already initialized */
387 if (page_menu != NULL)
388 return page_menu;
389
390 Dlist *actions = a_Actions_page_get();
391 int nactions = dList_length(actions);
392
393 /* Count static menu entries */
394 int nstatic = 0;
395 while (page_menu_[nstatic].text)
396 nstatic++;
397
398 int ntotal = nstatic + nactions;
399 page_menu = (Fl_Menu_Item *) calloc(ntotal + 1, sizeof(Fl_Menu_Item));
400
401 /* Just copy the static entries */
402 for (int i = 0; i < nstatic; i++) {
403 memcpy(&page_menu[i], &page_menu_[i], sizeof(Fl_Menu_Item));
404 }
405
406 /* And append the dynamic ones */
407 for (int i = 0; i < nactions; i++) {
408 Action *action = (Action *) dList_nth_data(actions, i);
409 Fl_Menu_Item *item = &page_menu[nstatic + i];
410 item->text = action->label;
411 item->callback_ = Menu_open_page_action_cb;
412 item->user_data_ = action;
413 }
414
415 return page_menu;
416}
417
422 bool_t has_bugs, void *v_cssUrls)
423{
424 lout::misc::SimpleVector <DilloUrl*> *cssUrls =
425 (lout::misc::SimpleVector <DilloUrl*> *) v_cssUrls;
426 int j = 0;
427
428 static Fl_Menu_Item *stylesheets = NULL;
429 static Menu_popup_data_t page_data = {"Page menu", NULL, NULL};
430 Fl_Menu_Item *pm = get_page_menu();
431 page_data.menu = pm;
432
433 current_page_url = url;
434
435 popup_x = Fl::event_x();
436 popup_y = Fl::event_y();
437 popup_bw = bw;
439 popup_url = a_Url_dup(url);
440
441 has_bugs == TRUE ? pm[1].activate() : pm[1].deactivate();
442
443 if (dStrAsciiCasecmp(URL_SCHEME(url), "dpi") == 0 &&
444 strncmp(URL_PATH(url), "/vsource/", 9) == 0)
445 pm[0].deactivate();
446 else {
447 pm[0].activate();
448 pm[0].user_data(popup_url);
449 }
450
451 if (stylesheets) {
452 while (stylesheets[j].text) {
453 dFree((char *) stylesheets[j].label());
454 a_Url_free((DilloUrl *) stylesheets[j].user_data());
455 j++;
456 }
457 delete [] stylesheets;
458 stylesheets = NULL;
459 }
460
461 if (cssUrls && cssUrls->size () > 0) {
462 stylesheets = new Fl_Menu_Item[cssUrls->size() + 1];
463 memset(stylesheets, '\0', (cssUrls->size() + 1) * sizeof(Fl_Menu_Item));
464
465 for (j = 0; j < cssUrls->size(); j++) {
466 DilloUrl *url = cssUrls->get(j);
467 const char *url_str = URL_STR(url);
468 const uint_t head_length = 30, tail_length = 40,
469 url_len = strlen(url_str);
470 char *label;
471
472 if (url_len > head_length + tail_length + 3) {
473 /* trim long URLs when making the label */
474 char *url_head = dStrndup(url_str, head_length);
475 const char *url_tail = url_str + (url_len - tail_length);
476 label = dStrconcat(url_head, "...", url_tail, NULL);
477 dFree(url_head);
478 } else {
479 label = dStrdup(url_str);
480 }
481
482 stylesheets[j].label(FL_NORMAL_LABEL, label);
483 stylesheets[j].callback(Menu_stylesheet_cb, a_Url_dup(url));
484 }
485
486 pm[2].user_data(stylesheets);
487 pm[2].activate();
488 } else {
489 pm[2].deactivate();
490 }
491 pm[3].user_data(popup_url);
492
493 a_Timeout_add(0.0, Menu_popup_cb, (void*)&page_data);
494}
495
496static Fl_Menu_Item link_menu_[] = {
497 {"Open link in new tab", 0, Menu_open_url_nt_cb,0,0,0,0,0,0},
498 {"Open link in new window", 0, Menu_open_url_nw_cb,0,FL_MENU_DIVIDER,0,0,
499 0,0},
500 {"Bookmark this link", 0, Menu_add_bookmark_cb,0,0,0,0,0,0},
501 {"Copy link location", 0, Menu_copy_urlstr_cb,0,FL_MENU_DIVIDER,0,0,0,0},
502 {"Save link as...", 0, Menu_save_link_cb,0,FL_MENU_DIVIDER,0,0,0,0},
503 {0,0,0,0,0,0,0,0,0}
504};
505
506/* As we can only provide a pointer to the link menu items, we need to
507 * create an auxiliary structure to hold the current URL and the program
508 * that should run on each item. */
509struct link_menu_item {
510 const DilloUrl *url;
511 const DilloUrl *origin;
512 Action *action;
513};
514
518static void Menu_open_url_action_cb(Fl_Widget*, void *user_data)
519{
520 /* Don't use popup_url because it is used for the image URL when coming from
521 * the image menu. We should get rid of the global variables and pass them
522 * via the user_data. */
523
524 struct link_menu_item *mitem = (struct link_menu_item *) user_data;
525 const DilloUrl *url = mitem->url;
526 const DilloUrl *origin = mitem->origin;
527 Action *action = mitem->action;
528
529 /* Set the environment variables */
530 setenv("url", URL_STR(url), 1);
531 setenv("origin", URL_STR(origin), 1);
532
533 a_Actions_run(action);
534}
535
536static Fl_Menu_Item *get_link_menu(void)
537{
538 static Fl_Menu_Item *link_menu = NULL;
539 static struct link_menu_item *link_menu_item = NULL;
540
541 /* Already initialized */
542 if (link_menu != NULL)
543 return link_menu;
544
545 Dlist *actions = a_Actions_link_get();
546 int nactions = dList_length(actions);
547
548 /* Count static menu entries */
549 int nstatic = 0;
550 while (link_menu_[nstatic].text)
551 nstatic++;
552
553 int ntotal = nstatic + nactions;
554 link_menu = (Fl_Menu_Item *) calloc(ntotal + 1, sizeof(Fl_Menu_Item));
555 link_menu_item = (struct link_menu_item *) calloc(nactions, sizeof(struct link_menu_item));
556
557 /* Just copy the static entries */
558 for (int i = 0; i < nstatic; i++) {
559 memcpy(&link_menu[i], &link_menu_[i], sizeof(Fl_Menu_Item));
560 }
561
562 /* And append the dynamic ones */
563 for (int i = 0; i < nactions; i++) {
564 Action *action = (Action *) dList_nth_data(actions, i);
565 struct link_menu_item *mitem = &link_menu_item[i];
566 mitem->url = NULL; /* Not known yet */
567 mitem->action = action;
568
569 Fl_Menu_Item *item = &link_menu[nstatic + i];
570 item->text = action->label;
571 item->callback_ = Menu_open_url_action_cb;
572 item->user_data_ = mitem;
573 }
574
575 return link_menu;
576}
577
578static void Menu_set_link_menu_user_data(const DilloUrl *url, const DilloUrl *page_url)
579{
580 Fl_Menu_Item *link_menu = get_link_menu();
581 for (int i = 0; link_menu[i].label(); i++) {
582 if (link_menu[i].callback_ == Menu_open_url_action_cb) {
583 struct link_menu_item *mitem = (struct link_menu_item *) link_menu[i].user_data_;
584 /* Set the url and origin */
585 mitem->url = url;
586 mitem->origin = page_url;
587 } else {
588 link_menu[i].user_data_ = (void *) url;
589 }
590 }
591}
592
596void a_Menu_link_popup(BrowserWindow *bw, const DilloUrl *url, const DilloUrl *page_url)
597{
598 static Menu_popup_data_t link_data = {"Link menu", NULL, NULL};
599
600 popup_x = Fl::event_x();
601 popup_y = Fl::event_y();
602 popup_bw = bw;
604 popup_url = a_Url_dup(url);
605
606 Fl_Menu_Item *link_menu = get_link_menu();
607 link_data.menu = link_menu;
608
610
611 a_Timeout_add(0.0, Menu_popup_cb, (void*)&link_data);
612}
613
618 bool_t loaded_img, DilloUrl *page_url,
619 DilloUrl *link_url)
620{
621 static DilloUrl *popup_page_url = NULL;
622 static DilloUrl *popup_link_url = NULL;
623 static Fl_Menu_Item pm[] = {
624 {"Isolate image", 0, Menu_open_url_cb,0,0,0,0,0,0},
625 {"Open image in new tab", 0, Menu_open_url_nt_cb,0,0,0,0,0,0},
626 {"Open image in new window", 0, Menu_open_url_nw_cb, 0, FL_MENU_DIVIDER,
627 0,0,0,0},
628 {"Load image", 0, Menu_load_images_cb,0,0,0,0,0,0},
629 {"Bookmark this image", 0, Menu_add_bookmark_cb,0,0,0,0,0,0},
630 {"Copy image location", 0,Menu_copy_urlstr_cb,0,FL_MENU_DIVIDER,0,0,0,0},
631 {"Save image as...", 0, Menu_save_link_cb, 0, FL_MENU_DIVIDER,0,0,0,0},
632 {"Link menu", 0, Menu_nop_cb, get_link_menu(), FL_SUBMENU_POINTER,0,0,0,0},
633 {0,0,0,0,0,0,0,0,0}
634 };
635 static Menu_popup_data_t image_data = {"Image menu", NULL, pm};
636
637 popup_x = Fl::event_x();
638 popup_y = Fl::event_y();
639 popup_bw = bw;
641 popup_url = a_Url_dup(url);
642 a_Url_free(popup_page_url);
643 popup_page_url = a_Url_dup(page_url);
644 a_Url_free(popup_link_url);
645 popup_link_url = a_Url_dup(link_url);
646
647
648 pm[0].user_data(popup_url);
649 pm[1].user_data(popup_url);
650 pm[2].user_data(popup_url);
651
652 if (loaded_img) {
653 pm[3].deactivate();
654 } else {
655 pm[3].activate();
656 pm[3].user_data(popup_page_url);
657 }
658
659 pm[4].user_data(popup_url);
660 pm[5].user_data(popup_url);
661 pm[6].user_data(popup_url);
662
663 if (link_url) {
664 pm[7].activate();
665 Menu_set_link_menu_user_data(popup_link_url, popup_page_url);
666 } else {
667 pm[7].deactivate();
668 }
669
670 a_Timeout_add(0.0, Menu_popup_cb, (void*)&image_data);
671}
672
676void a_Menu_form_popup(BrowserWindow *bw, const DilloUrl *page_url,
677 void *formptr, bool_t hidvis)
678{
679 static bool hiddens_visible;
680 static Fl_Menu_Item pm[] = {
681 {"Submit form", 0, Menu_form_submit_cb,0,0,0,0,0,0},
682 {"Reset form", 0, Menu_form_reset_cb,0,0,0,0,0,0},
683 {0, 0, Menu_form_hiddens_cb, &hiddens_visible, 0,0,0,0,0},
684 {0,0,0,0,0,0,0,0,0}
685 };
686 static Menu_popup_data_t form_data = {"Form menu", NULL, pm};
687
688 popup_x = Fl::event_x();
689 popup_y = Fl::event_y();
690 popup_bw = bw;
692 popup_url = a_Url_dup(page_url);
693 popup_form = formptr;
694
695 hiddens_visible = hidvis;
696 pm[2].label(hiddens_visible ? "Hide hiddens": "Show hiddens");
697
698 a_Timeout_add(0.0, Menu_popup_cb, (void*)&form_data);
699}
700
704void a_Menu_file_popup(BrowserWindow *bw, void *v_wid)
705{
706 Fl_Widget *wid = (Fl_Widget*)v_wid;
707
708 static Fl_Menu_Item pm[] = {
710 (void*)"nt",0,0,0,0,0},
712 (void*)"nw", FL_MENU_DIVIDER,0,0,0,0},
713 {"Open file...", Keys::getShortcut(KEYS_OPEN), filemenu_cb,
714 (void*)"of",0,0,0,0,0},
715 {"Open URL...", Keys::getShortcut(KEYS_GOTO), filemenu_cb,
716 (void*)"ou",0,0,0,0,0},
718 (void*)"cw", FL_MENU_DIVIDER,0,0,0,0},
720 (void*)"ed",0,0,0,0,0},
721 {0,0,0,0,0,0,0,0,0}
722 };
723
724 popup_bw = bw;
725 popup_x = wid->x();
726 popup_y = wid->y() + wid->h();
728 popup_url = NULL;
729
730 //pm->label(wid->visible() ? NULL : "File");
731 a_Timeout_add(0.0, Menu_simple_popup_cb, (void*)pm);
732}
733
738{
739 static Fl_Menu_Item pm[] = {
740 {"Validate URL with W3C Nu validator (HTML5 only)", 0,
742 {"Validate URL with W3C validator (HTML 4.01 and older)", 0,
743 Menu_bugmeter_validate_w3c_cb,0,FL_MENU_DIVIDER,0,0,0,0},
744 {"About bug meter", 0,
745 Menu_bugmeter_about_cb,0,0,0,0,0,0},
746 {0,0,0,0,0,0,0,0,0}
747 };
748
749 popup_x = Fl::event_x();
750 popup_y = Fl::event_y();
751 popup_bw = bw;
753 popup_url = a_Url_dup(url);
754
755 a_Timeout_add(0.0, Menu_simple_popup_cb, (void*)pm);
756}
757
763void a_Menu_history_popup(BrowserWindow *bw, int x, int y, int direction)
764{
765 static Fl_Menu_Item *pm = 0;
766 int i, n;
767
768 popup_bw = bw;
769 popup_x = x;
770 popup_y = y;
771 history_direction = direction;
772
773 // TODO: hook popdown event with delete or similar.
774 if (pm)
775 delete [] pm;
776 if (history_list)
778
779 // Get a list of URLs for this popup
780 history_list = a_UIcmd_get_history(bw, direction);
781
782 for (n = 0; history_list[n] != -1; n++)
783 ;
784
785 pm = new Fl_Menu_Item[n + 1];
786 memset(pm, '\0', (n + 1) * sizeof(Fl_Menu_Item));
787
788 for (i = 0; i < n; i++) {
789 pm[i].label(FL_NORMAL_LABEL, a_History_get_title(history_list[i], 1));
790 pm[i].callback(Menu_history_cb, INT2VOIDP(i+1));
791 }
792 a_Timeout_add(0.0, Menu_simple_popup_cb, (void*)pm);
793}
794
798static void Menu_remote_css_cb(Fl_Widget *wid, void*)
799{
800 Fl_Menu_Item *item = (Fl_Menu_Item*) wid;
801
802 item->flags ^= FL_MENU_VALUE;
803 prefs.load_stylesheets = item->flags & FL_MENU_VALUE ? 1 : 0;
805}
806
810static void Menu_embedded_css_cb(Fl_Widget *wid, void*)
811{
812 Fl_Menu_Item *item = (Fl_Menu_Item*) wid;
813
814 item->flags ^= FL_MENU_VALUE;
815 prefs.parse_embedded_css = item->flags & FL_MENU_VALUE ? 1 : 0;
817}
818
819
823static void Menu_force_https_cb(Fl_Widget *wid, void*)
824{
825 Fl_Menu_Item *item = (Fl_Menu_Item*) wid;
826
827 item->flags ^= FL_MENU_VALUE;
828 prefs.http_force_https = item->flags & FL_MENU_VALUE ? 1 : 0;
830}
831
832static void Menu_panel_change_cb(Fl_Widget*, void *user_data)
833{
834 UI *ui = (UI*)popup_bw->ui;
835
836 if (VOIDP2INT(user_data) == 10) /* small icons */
837 ui->change_panel(ui->get_panelsize(), !ui->get_smallicons());
838 else
839 ui->change_panel(VOIDP2INT(user_data), ui->get_smallicons());
840}
841
845static void Menu_imgload_toggle_cb(Fl_Widget *wid, void*)
846{
847 Fl_Menu_Item *item = (Fl_Menu_Item*) wid;
848
849 item->flags ^= FL_MENU_VALUE;
850
851 if ((prefs.load_images = item->flags & FL_MENU_VALUE ? 1 : 0)) {
852 void *doc = a_Bw_get_current_doc(popup_bw);
853
854 if (doc) {
855 DilloUrl *pattern = NULL;
856 a_Html_load_images(doc, pattern);
857 }
858 }
859}
860
864static void Menu_bgimg_load_toggle_cb(Fl_Widget *wid, void*)
865{
866 Fl_Menu_Item *item = (Fl_Menu_Item*) wid;
867
868 item->flags ^= FL_MENU_VALUE;
869 prefs.load_background_images = item->flags & FL_MENU_VALUE ? 1 : 0;
871}
872
876void a_Menu_tools_popup(BrowserWindow *bw, int x, int y)
877{
878 const Fl_Menu_Item *item;
879 UI *ui = (UI*)bw->ui;
880
881 static Fl_Menu_Item pm[] = {
882 {"Use remote CSS", 0, Menu_remote_css_cb, 0, FL_MENU_TOGGLE,0,0,0,0},
883 {"Use embedded CSS", 0, Menu_embedded_css_cb, 0,
884 FL_MENU_TOGGLE|FL_MENU_DIVIDER,0,0,0,0},
885 {"Load images", 0, Menu_imgload_toggle_cb, 0,
886 FL_MENU_TOGGLE,0,0,0,0},
887 {"Load background images", 0, Menu_bgimg_load_toggle_cb, 0,
888 FL_MENU_TOGGLE|FL_MENU_DIVIDER,0,0,0,0},
889 {"Force HTTPS", 0, Menu_force_https_cb, 0,
890 FL_MENU_TOGGLE|FL_MENU_DIVIDER,0,0,0,0},
891 {"Panel size", 0, Menu_nop_cb, (void*)"Submenu1", FL_SUBMENU,0,0,0,0},
892 {"tiny", 0,Menu_panel_change_cb,(void*)0,FL_MENU_RADIO,0,0,0,0},
893 {"small", 0,Menu_panel_change_cb,(void*)1,FL_MENU_RADIO,0,0,0,0},
894 {"medium",0,Menu_panel_change_cb,(void*)2,
895 FL_MENU_RADIO|FL_MENU_DIVIDER,0,0,0,0},
896 {"small icons", 0,Menu_panel_change_cb,(void*)10,
897 FL_MENU_TOGGLE,0,0,0,0},
898 {0,0,0,0,0,0,0,0,0},
899 {0,0,0,0,0,0,0,0,0}
900 };
901
902 popup_bw = bw;
903 int cur_panelsize = ui->get_panelsize();
904 int cur_smallicons = ui->get_smallicons();
905
907 pm[0].set();
909 pm[1].set();
910 if (prefs.load_images)
911 pm[2].set();
913 pm[3].set();
915 pm[4].set();
916 pm[6+cur_panelsize].setonly();
917 cur_smallicons ? pm[9].set() : pm[9].clear();
918
919 item = pm->popup(x, y);
920 if (item) {
921 ((Fl_Widget *)item)->do_callback();
922 }
923}
924
Dlist * a_Actions_page_get(void)
Definition actions.c:76
int a_Actions_run(Action *action)
Definition actions.c:82
Dlist * a_Actions_link_get(void)
Definition actions.c:70
#define _MSG(...)
Definition bookmarks.c:45
void * a_Bw_get_url_doc(BrowserWindow *bw, const DilloUrl *url)
Get document by URL.
Definition bw.c:252
void * a_Bw_get_current_doc(BrowserWindow *bw)
Get current document.
Definition bw.c:233
static int getShortcut(KeysCommand_t cmd)
Given a keys command, return a shortcut for it, or 0 if there is none (e.g., for KEYS_NEW_WINDOW,...
Definition keys.cc:331
Definition ui.hh:123
int get_panelsize()
Definition ui.hh:173
void change_panel(int new_size, int small_icons)
On-the-fly panel style change.
Definition ui.cc:1030
int get_smallicons()
Definition ui.hh:174
T get(int i) const
Return the one element, explicitly.
Definition misc.hh:222
int size() const
Return the number of elements put into this vector.
Definition misc.hh:162
unsigned int uint_t
Definition d_size.h:20
unsigned char bool_t
Definition d_size.h:21
char * dStrconcat(const char *s1,...)
Concatenate a NULL-terminated list of strings.
Definition dlib.c:102
void dFree(void *mem)
Definition dlib.c:68
int dStrAsciiCasecmp(const char *s1, const char *s2)
Definition dlib.c:203
char * dStrdup(const char *s)
Definition dlib.c:77
Dstr * dStr_sized_new(int sz)
Create a new string with a given size.
Definition dlib.c:254
int dList_length(Dlist *lp)
For completing the ADT.
Definition dlib.c:641
void * dList_nth_data(Dlist *lp, int n0)
Return the nth data item, NULL when not found or 'n0' is out of range.
Definition dlib.c:690
void dStr_free(Dstr *ds, int all)
Free a dillo string.
Definition dlib.c:337
char * dStrndup(const char *s, size_t sz)
Definition dlib.c:88
void dStr_sprintf(Dstr *ds, const char *format,...)
Printf-like function.
Definition dlib.c:450
#define VOIDP2INT(p)
Definition dlib.h:61
#define TRUE
Definition dlib.h:35
#define INT2VOIDP(i)
Definition dlib.h:62
const DilloUrl * a_History_get_url(int idx)
Return the DilloUrl field (by index)
Definition history.c:80
const char * a_History_get_title(int idx, int force)
Return the title field (by index) ('force' returns URL_STR when there's no title)
Definition history.c:94
void a_Html_form_display_hiddens(void *v_html, void *v_form, bool_t display)
Used by the "Show/Hide hiddens" form menuitem.
Definition html.cc:279
void a_Html_form_submit(void *v_html, void *v_form)
Used by the "Submit form" form menuitem.
Definition html.cc:253
void a_Html_load_images(void *v_html, DilloUrl *pattern)
Used by the "Load images" page menuitem.
Definition html.cc:230
void a_Html_form_reset(void *v_html, void *v_form)
Used by the "Reset form" form menuitem.
Definition html.cc:266
@ KEYS_CLOSE_ALL
Definition keys.hh:36
@ KEYS_GOTO
Definition keys.hh:39
@ KEYS_OPEN
Definition keys.hh:20
@ KEYS_NEW_WINDOW
Definition keys.hh:21
@ KEYS_NEW_TAB
Definition keys.hh:22
@ KEYS_CLOSE_TAB
Definition keys.hh:25
static void Menu_copy_urlstr_cb(Fl_Widget *, void *user_data)
Definition menu.cc:88
static int popup_y
Definition menu.cc:55
static Fl_Menu_Item page_menu_[]
Definition menu.cc:352
static void Menu_add_bookmark_cb(Fl_Widget *, void *user_data)
Add bookmark.
Definition menu.cc:130
void a_Menu_page_popup(BrowserWindow *bw, const DilloUrl *url, bool_t has_bugs, void *v_cssUrls)
Page popup menu (construction & popup)
Definition menu.cc:421
static void Menu_panel_change_cb(Fl_Widget *, void *user_data)
Definition menu.cc:832
static void Menu_popup_cb(void *data)
Definition menu.cc:336
void a_Menu_file_popup(BrowserWindow *bw, void *v_wid)
File popup menu (construction & popup)
Definition menu.cc:704
static void Menu_embedded_css_cb(Fl_Widget *wid, void *)
Toggle use of embedded CSS style.
Definition menu.cc:810
static void Menu_bugmeter_about_cb(Fl_Widget *, void *)
Show info page for the bug meter.
Definition menu.cc:288
static void Menu_bgimg_load_toggle_cb(Fl_Widget *wid, void *)
Toggle loading of background images.
Definition menu.cc:864
static void Menu_open_url_nw_cb(Fl_Widget *, void *user_data)
Open URL in new window.
Definition menu.cc:109
static void Menu_open_url_action_cb(Fl_Widget *, void *user_data)
Open URL following a custom action.
Definition menu.cc:518
void a_Menu_tools_popup(BrowserWindow *bw, int x, int y)
Tools popup menu (construction & popup).
Definition menu.cc:876
static void Menu_open_url_cb(Fl_Widget *, void *user_data)
Open URL.
Definition menu.cc:99
static void Menu_save_link_cb(Fl_Widget *, void *user_data)
Save link.
Definition menu.cc:147
static void Menu_view_page_bugs_cb(Fl_Widget *, void *)
View current page's bugs.
Definition menu.cc:173
static void Menu_bugmeter_validate_w3c_nu_cb(Fl_Widget *, void *)
Validate URL with the W3C Nu validator (for HTML 5)
Definition menu.cc:264
static void Menu_stylesheet_cb(Fl_Widget *, void *vUrl)
Definition menu.cc:224
static void Menu_bugmeter_validate_w3c_cb(Fl_Widget *, void *)
Validate URL with the W3C legacy validator (HTML 4.01 and older)
Definition menu.cc:276
static void Menu_force_https_cb(Fl_Widget *wid, void *)
Toggle use of force https mode.
Definition menu.cc:823
static void Menu_form_hiddens_cb(Fl_Widget *, void *user_data)
Toggle display of 'hidden' form controls.
Definition menu.cc:215
static void Menu_form_submit_cb(Fl_Widget *, void *)
Submit form.
Definition menu.cc:193
static void Menu_set_link_menu_user_data(const DilloUrl *url, const DilloUrl *page_url)
Definition menu.cc:578
static void Menu_save_page_cb(Fl_Widget *, void *)
Save current page.
Definition menu.cc:156
void a_Menu_link_popup(BrowserWindow *bw, const DilloUrl *url, const DilloUrl *page_url)
Link popup menu (construction & popup)
Definition menu.cc:596
static void Menu_simple_popup_cb(void *data)
Definition menu.cc:323
static Fl_Menu_Item * get_link_menu(void)
Definition menu.cc:536
static void Menu_open_page_action_cb(Fl_Widget *, void *user_data)
Open URL following a custom action.
Definition menu.cc:370
static Fl_Menu_Item * get_page_menu(void)
Definition menu.cc:382
static void filemenu_cb(Fl_Widget *, void *data)
Static function for File menu callbacks.
Definition menu.cc:70
static void Menu_bugmeter_validate(const char *validator_url)
Definition menu.cc:242
static void Menu_form_reset_cb(Fl_Widget *, void *)
Reset form.
Definition menu.cc:204
static const DilloUrl * current_page_url
Definition menu.cc:365
static void Menu_view_page_source_cb(Fl_Widget *, void *user_data)
View current page source.
Definition menu.cc:164
static void * popup_form
Definition menu.cc:53
static Fl_Menu_Item link_menu_[]
Definition menu.cc:496
static void Menu_open_url_nt_cb(Fl_Widget *, void *user_data)
Open URL in new Tab.
Definition menu.cc:119
static void Menu_find_text_cb(Fl_Widget *, void *)
Find text.
Definition menu.cc:139
static void Menu_history_cb(Fl_Widget *, void *data)
Navigation History callback.
Definition menu.cc:297
static void Menu_load_images_cb(Fl_Widget *, void *user_data)
Load images on current page that match URL pattern.
Definition menu.cc:181
static int popup_x
Definition menu.cc:55
void a_Menu_image_popup(BrowserWindow *bw, const DilloUrl *url, bool_t loaded_img, DilloUrl *page_url, DilloUrl *link_url)
Image popup menu (construction & popup)
Definition menu.cc:617
void a_Menu_bugmeter_popup(BrowserWindow *bw, const DilloUrl *url)
Bugmeter popup menu (construction & popup)
Definition menu.cc:737
static int * history_list
Definition menu.cc:59
static void Menu_imgload_toggle_cb(Fl_Widget *wid, void *)
Toggle loading of images – and load them if enabling.
Definition menu.cc:845
void a_Menu_history_popup(BrowserWindow *bw, int x, int y, int direction)
Navigation History popup menu (construction & popup).
Definition menu.cc:763
static BrowserWindow * popup_bw
Definition menu.cc:52
static void Menu_remote_css_cb(Fl_Widget *wid, void *)
Toggle use of remote stylesheets.
Definition menu.cc:798
void a_Menu_form_popup(BrowserWindow *bw, const DilloUrl *page_url, void *formptr, bool_t hidvis)
Form popup menu (construction & popup)
Definition menu.cc:676
static int history_direction
Definition menu.cc:57
static void Menu_nop_cb(Fl_Widget *, void *)
Definition menu.cc:63
static DilloUrl * popup_url
Definition menu.cc:50
DilloPrefs prefs
Global Data.
Definition prefs.c:33
char * label
Definition actions.h:22
Contains the specific data for a single window.
Definition bw.h:27
void * ui
Pointer to the UI object this bw belongs to.
Definition bw.h:29
bool_t parse_embedded_css
Definition prefs.h:104
bool_t load_images
Definition prefs.h:99
bool_t focus_new_tab
Definition prefs.h:74
bool_t load_background_images
Definition prefs.h:102
bool_t load_stylesheets
Definition prefs.h:103
bool_t http_force_https
Definition prefs.h:107
bool_t middle_click_opens_new_tab
Definition prefs.h:115
Definition url.h:88
Definition dlib.h:150
Definition dlib.h:120
Dstr_char_t * str
Definition dlib.h:123
void a_Timeout_add(float t, TimeoutCb_t cb, void *cbdata)
Hook a one-time timeout function 'cb' after 't' seconds with 'cbdata" as its data.
Definition timeout.cc:26
void a_Timeout_remove()
Stop running a timeout function.
Definition timeout.cc:42
void a_UIcmd_close_bw(void *vbw)
Definition uicmd.cc:686
int * a_UIcmd_get_history(BrowserWindow *bw, int direction)
Definition uicmd.cc:1434
void a_UIcmd_copy_urlstr(BrowserWindow *bw, const char *urlstr, int destination)
Definition uicmd.cc:1365
void a_UIcmd_open_file(void *vbw)
Definition uicmd.cc:1205
void a_UIcmd_focus_location(void *vbw)
Definition uicmd.cc:1743
void a_UIcmd_open_url_nw(BrowserWindow *bw, const DilloUrl *url)
Definition uicmd.cc:847
void a_UIcmd_view_page_source(BrowserWindow *bw, const DilloUrl *url)
Definition uicmd.cc:1374
void a_UIcmd_view_page_bugs(void *vbw)
Definition uicmd.cc:1409
void a_UIcmd_nav_jump(BrowserWindow *bw, int offset, int new_bw)
Definition uicmd.cc:1458
void a_UIcmd_close_all_bw(void *force)
Definition uicmd.cc:725
void a_UIcmd_open_urlstr(void *vbw, const char *urlstr)
Definition uicmd.cc:771
void a_UIcmd_save(void *vbw)
Definition uicmd.cc:1162
void a_UIcmd_repush(void *vbw)
Definition uicmd.cc:968
void a_UIcmd_add_bookmark(BrowserWindow *bw, const DilloUrl *url)
Definition uicmd.cc:1310
void a_UIcmd_open_url(BrowserWindow *bw, const DilloUrl *url)
Definition uicmd.cc:812
void a_UIcmd_save_link(BrowserWindow *bw, const DilloUrl *url, char *filename)
Definition uicmd.cc:1287
void a_UIcmd_open_url_nt(void *vbw, const DilloUrl *url, int focus)
Definition uicmd.cc:863
char * a_Url_encode_hex_str(const char *str)
Urlencode 'str'.
Definition url.c:620
void a_Url_free(DilloUrl *url)
Free a DilloUrl.
Definition url.c:208
DilloUrl * a_Url_dup(const DilloUrl *ori)
Duplicate a Url structure.
Definition url.c:477
#define URL_PATH(u)
Definition url.h:72
#define URL_STR(u)
Definition url.h:76
#define URL_SCHEME(u)
Definition url.h:70