diff options
author | Richard Wilson <rjw@netsurf-browser.org> | 2005-04-07 20:46:22 +0000 |
---|---|---|
committer | Richard Wilson <rjw@netsurf-browser.org> | 2005-04-07 20:46:22 +0000 |
commit | 610fca368b4b438fd2868f8a4d6a39a45f823e6b (patch) | |
tree | f31e0cbf961196522727043cef55fb76c122bddb /riscos/menus.c | |
parent | 75e7c01b1f23b9b03f32c2eaf7399f12a9a20272 (diff) | |
download | netsurf-610fca368b4b438fd2868f8a4d6a39a45f823e6b.tar.gz netsurf-610fca368b4b438fd2868f8a4d6a39a45f823e6b.tar.bz2 |
[project @ 2005-04-07 20:46:22 by rjw]
Update to the way menus are handled. Various GUI bug fixes.
svn path=/import/netsurf/; revision=1603
Diffstat (limited to 'riscos/menus.c')
-rw-r--r-- | riscos/menus.c | 3528 |
1 files changed, 1654 insertions, 1874 deletions
diff --git a/riscos/menus.c b/riscos/menus.c index e354ee8cc..01191b03f 100644 --- a/riscos/menus.c +++ b/riscos/menus.c @@ -14,18 +14,16 @@ #include <stdlib.h> #include <string.h> -#include "oslib/font.h" #include "oslib/os.h" #include "oslib/osgbpb.h" #include "oslib/wimp.h" -#include "oslib/wimpspriteop.h" -#include "netsurf/content/url_store.h" #include "netsurf/desktop/gui.h" #include "netsurf/render/box.h" #include "netsurf/render/form.h" #include "netsurf/riscos/gui.h" #include "netsurf/riscos/global_history.h" #include "netsurf/riscos/help.h" +#include "netsurf/riscos/menus.h" #include "netsurf/riscos/options.h" #include "netsurf/riscos/tinct.h" #include "netsurf/riscos/theme.h" @@ -33,627 +31,362 @@ #include "netsurf/riscos/wimp.h" #include "netsurf/utils/log.h" #include "netsurf/utils/messages.h" -#include "netsurf/utils/url.h" #include "netsurf/utils/utils.h" -/* Menu index definitions used by menu decoding code so that entries can - be quickly commented out. Use -ve numbers below -1 to hide an entry. -*/ -#define MENU_PAGE 0 -#define MENU_OBJECT 1 -#define MENU_SELECTION -2 -#define MENU_NAVIGATE 2 -#define MENU_VIEW 3 -#define MENU_UTILITIES 4 -#define MENU_HELP 5 - -static void translate_menu(wimp_menu *menu); -static void build_languages_menu(void); -static void ro_gui_menu_toolbar_submenu_selection(int index); -static void ro_gui_menu_prepare_images(void); -static void ro_gui_menu_prepare_window(void); -static void ro_gui_menu_prepare_toolbars(struct toolbar *toolbar); -static void ro_gui_menu_prepare_render(void); -static void ro_gui_menu_prepare_help(int forced); -static void ro_gui_menu_prepare_view(void); -static void ro_gui_menu_objectinfo(wimp_message_menu_warning *warning); -static void ro_gui_menu_object_reload(void); -static void ro_gui_menu_browser_warning(wimp_message_menu_warning *warning); -static void ro_gui_menu_hotlist_warning(wimp_message_menu_warning *warning); -static void ro_gui_menu_global_history_warning(wimp_message_menu_warning *warning); - -struct gui_window *current_gui; -wimp_menu *current_menu; -static int current_menu_x, current_menu_y; -static char select_null_text_string[] = "\0"; - -/** Box for object under menu, or 0 if no object. */ -static struct box *gui_menu_object_box = 0; - -/** Menu of options for form select controls. */ -static wimp_menu *gui_form_select_menu = 0; -/** Form control which gui_form_select_menu is for. */ -static struct form_control *gui_form_select_control; - - -/* Default menu item flags -*/ -#define DEFAULT_FLAGS (wimp_ICON_TEXT | wimp_ICON_FILLED | \ - (wimp_COLOUR_BLACK << wimp_ICON_FG_COLOUR_SHIFT) | \ - (wimp_COLOUR_WHITE << wimp_ICON_BG_COLOUR_SHIFT)) - - -/* Iconbar menu -*/ -static wimp_MENU(4) ibar_menu = { - { "NetSurf" }, 7,2,7,0, 200, 44, 0, - { - { 0, wimp_NO_SUB_MENU, DEFAULT_FLAGS, { "Info" } }, - { 0, wimp_NO_SUB_MENU, DEFAULT_FLAGS, { "AppHelp" } }, - { 0, wimp_NO_SUB_MENU, DEFAULT_FLAGS, { "Choices" } }, - { wimp_MENU_LAST, wimp_NO_SUB_MENU, DEFAULT_FLAGS, { "Quit" } } - } -}; -int iconbar_menu_height = 4 * 44; -wimp_menu *iconbar_menu = (wimp_menu *)&ibar_menu; - - -/* Export submenu -*/ -static wimp_MENU(2) export_menu = { - { "ExportAs" }, 7,2,7,0, 200, 44, 0, - { - { wimp_MENU_GIVE_WARNING, (wimp_menu *)1, DEFAULT_FLAGS, { "Draw" } }, - { wimp_MENU_LAST | wimp_MENU_GIVE_WARNING, (wimp_menu *)1, DEFAULT_FLAGS, { "Text" } } - } -}; - -static wimp_MENU(3) link_menu = { - { "SaveLink" }, 7,2,7,0, 200, 44, 0, - { - { wimp_MENU_GIVE_WARNING, (wimp_menu*)1, DEFAULT_FLAGS, { "URI" } }, - { wimp_MENU_GIVE_WARNING, (wimp_menu*)1, DEFAULT_FLAGS, { "URL" } }, - { wimp_MENU_LAST | wimp_MENU_GIVE_WARNING, (wimp_menu*)1, DEFAULT_FLAGS, { "LinkText" } } - } -}; - - -/* Page submenu -*/ -static wimp_MENU(8) page_menu = { - { "Page" }, 7,2,7,0, 200, 44, 0, - { - { wimp_MENU_GIVE_WARNING, (wimp_menu *)1, DEFAULT_FLAGS, { "PageInfo" } }, - { wimp_MENU_GIVE_WARNING, (wimp_menu *)1, DEFAULT_FLAGS, { "Save" } }, - { wimp_MENU_GIVE_WARNING, (wimp_menu *)1, DEFAULT_FLAGS, { "SaveComp" } }, - { 0, (wimp_menu *)&export_menu, DEFAULT_FLAGS, { "Export" } }, - { 0, (wimp_menu *)&link_menu, DEFAULT_FLAGS, { "SaveURL" } }, - { wimp_MENU_GIVE_WARNING | wimp_MENU_SEPARATE, (wimp_menu *)1, DEFAULT_FLAGS, { "Print" } }, - { 0, wimp_NO_SUB_MENU, DEFAULT_FLAGS, { "NewWindow" } }, - { wimp_MENU_LAST, wimp_NO_SUB_MENU, DEFAULT_FLAGS, { "ViewSrc" } } - } -}; - - -/* Object export submenu -*/ -static wimp_MENU(2) object_export_menu = { - { "ExportAs" }, 7,2,7,0, 200, 44, 0, - { - { wimp_MENU_LAST | wimp_MENU_GIVE_WARNING, (wimp_menu *)1, DEFAULT_FLAGS, { "Sprite" } } - } -}; - - -/* Object submenu -*/ -static wimp_MENU(5) object_menu = { - { "Object" }, 7,2,7,0, 300, 44, 0, - { - { wimp_MENU_GIVE_WARNING, (wimp_menu *)1, DEFAULT_FLAGS, { "ObjInfo" } }, - { wimp_MENU_GIVE_WARNING, (wimp_menu *)1, DEFAULT_FLAGS, { "ObjSave" } }, - { 0, (wimp_menu *)&object_export_menu, DEFAULT_FLAGS, { "Export" } }, - { wimp_MENU_SEPARATE, (wimp_menu *)&link_menu, DEFAULT_FLAGS, { "SaveURL" } }, - { wimp_MENU_LAST, wimp_NO_SUB_MENU, DEFAULT_FLAGS, { "ObjReload" } } - } -}; - - -/* Selection submenu -*/ -static wimp_MENU(3) selection_menu = { - { "Selection" }, 7,2,7,0, 300, 44, 0, - { - { wimp_MENU_SEPARATE, wimp_NO_SUB_MENU, DEFAULT_FLAGS | wimp_ICON_SHADED, { "Copy" } }, - { 0, wimp_NO_SUB_MENU, DEFAULT_FLAGS | wimp_ICON_SHADED, { "SelectAll" } }, - { wimp_MENU_LAST, wimp_NO_SUB_MENU, DEFAULT_FLAGS | wimp_ICON_SHADED, { "Clear" } } - } -}; - - -/* Navigate submenu -*/ -static wimp_MENU(5) navigate_menu = { - { "Navigate" }, 7,2,7,0, 300, 44, 0, - { - { 0, wimp_NO_SUB_MENU, DEFAULT_FLAGS, { "Home" } }, - { 0, wimp_NO_SUB_MENU, DEFAULT_FLAGS, { "Back" } }, - { wimp_MENU_SEPARATE, wimp_NO_SUB_MENU, DEFAULT_FLAGS, { "Forward" } }, - { 0, wimp_NO_SUB_MENU, DEFAULT_FLAGS, { "Reload" } }, - { wimp_MENU_LAST, wimp_NO_SUB_MENU, DEFAULT_FLAGS, { "Stop" } } - } -}; - - -/* Image submenu -*/ -static wimp_MENU(3) image_menu = { - { "Images" }, 7,2,7,0, 300, 44, 0, - { - { 0, wimp_NO_SUB_MENU, DEFAULT_FLAGS | wimp_ICON_SHADED, { "ForeImg" } }, - { wimp_MENU_LAST, wimp_NO_SUB_MENU, DEFAULT_FLAGS, { "BackImg" } }, - } -}; - - -/* Toolbar submenu -*/ -static wimp_MENU(4) show_toolbar_menu = { - { "Toolbars" }, 7,2,7,0, 300, 44, 0, - { - { 0, wimp_NO_SUB_MENU, DEFAULT_FLAGS, { "ToolButtons" } }, - { 0, wimp_NO_SUB_MENU, DEFAULT_FLAGS, { "ToolAddress" } }, - { wimp_MENU_SEPARATE, wimp_NO_SUB_MENU, DEFAULT_FLAGS, { "ToolThrob" } }, - { wimp_MENU_LAST, wimp_NO_SUB_MENU, DEFAULT_FLAGS, { "ToolStatus" } } - } -}; - - -/* Render submenu -*/ -static wimp_MENU(3) render_menu = { - { "Render" }, 7,2,7,0, 300, 44, 0, - { - { wimp_MENU_SEPARATE, wimp_NO_SUB_MENU, DEFAULT_FLAGS, { "RenderText" } }, - { 0, wimp_NO_SUB_MENU, DEFAULT_FLAGS, { "RenderAnims" } }, - { wimp_MENU_LAST, wimp_NO_SUB_MENU, DEFAULT_FLAGS, { "RenderAll" } } - } -}; - - -/* Window submenu -*/ -static wimp_MENU(4) window_menu = { - { "Window" }, 7,2,7,0, 300, 44, 0, - { - { 0, wimp_NO_SUB_MENU, DEFAULT_FLAGS, { "WindowSave" } }, - { 0, wimp_NO_SUB_MENU, DEFAULT_FLAGS, { "WindowStagr" } }, - { wimp_MENU_SEPARATE, wimp_NO_SUB_MENU, DEFAULT_FLAGS, { "WindowSize" } }, - { wimp_MENU_LAST, wimp_NO_SUB_MENU, DEFAULT_FLAGS, { "WindowReset" } } - } -}; - - -/* View submenu -*/ -static wimp_MENU(5) view_menu = { - { "View" }, 7,2,7,0, 300, 44, 0, - { - { wimp_MENU_GIVE_WARNING, (wimp_menu *)1, DEFAULT_FLAGS, { "ScaleView" } }, - { wimp_MENU_GIVE_WARNING, (wimp_menu *)&image_menu, DEFAULT_FLAGS, { "Images" } }, - { wimp_MENU_GIVE_WARNING, (wimp_menu *)&show_toolbar_menu, DEFAULT_FLAGS, { "Toolbars" } }, - { wimp_MENU_GIVE_WARNING | wimp_MENU_SEPARATE, (wimp_menu *)&render_menu, DEFAULT_FLAGS, { "Render" } }, - { wimp_MENU_LAST, wimp_NO_SUB_MENU, DEFAULT_FLAGS, { "OptDefault" } } - } -}; - - -/* Hotlist submenu -*/ -static wimp_MENU(2) hotlist_util_menu = { - { "Hotlist" }, 7,2,7,0, 300, 44, 0, - { - { 0, wimp_NO_SUB_MENU, DEFAULT_FLAGS, { "HotlistAdd" } }, - { wimp_MENU_LAST, wimp_NO_SUB_MENU, DEFAULT_FLAGS, { "HotlistShow" } } - } -}; - - -/* History submenu -*/ -static wimp_MENU(2) history_util_menu = { - { "History" }, 7,2,7,0, 300, 44, 0, - { - { 0, wimp_NO_SUB_MENU, DEFAULT_FLAGS, { "HistLocal" } }, - { wimp_MENU_LAST, wimp_NO_SUB_MENU, DEFAULT_FLAGS, { "HistGlobal" } } - } -}; - - -/* Utilities submenu -*/ -static wimp_MENU(4) utilities_menu = { - { "Utilities" }, 7,2,7,0, 300, 44, 0, - { - { 0, (wimp_menu *)&hotlist_util_menu, DEFAULT_FLAGS, { "Hotlist" } }, - { 0, (wimp_menu *)&history_util_menu, DEFAULT_FLAGS, { "History" } }, - { wimp_MENU_GIVE_WARNING, (wimp_menu *)1, DEFAULT_FLAGS, { "FindText" } }, - { wimp_MENU_GIVE_WARNING | wimp_MENU_LAST, (wimp_menu *)&window_menu, DEFAULT_FLAGS, { "Window" } }, - } -}; - - -/* Help submenu -*/ -static wimp_MENU(5) help_menu = { - { "Help" }, 7,2,7,0, 300, 44, 0, - { - { 0, wimp_NO_SUB_MENU, DEFAULT_FLAGS, { "HelpContent" } }, - { 0, wimp_NO_SUB_MENU, DEFAULT_FLAGS, { "HelpGuide" } }, - { wimp_MENU_SEPARATE, wimp_NO_SUB_MENU, DEFAULT_FLAGS, { "HelpInfo" } }, - { wimp_MENU_SEPARATE, wimp_NO_SUB_MENU, DEFAULT_FLAGS, { "HelpAbout" } }, - { wimp_MENU_LAST, wimp_NO_SUB_MENU, DEFAULT_FLAGS, { "HelpInter" } } - } -}; - - -/* Main browser menu -*/ -static wimp_MENU(6) menu = { - { "NetSurf" }, 7,2,7,0, 200, 44, 0, - { - { 0, (wimp_menu *)&page_menu, DEFAULT_FLAGS, { "Page" } }, - { 0, (wimp_menu *)&object_menu, DEFAULT_FLAGS, { "Object" } }, -// { 0, (wimp_menu *)&selection_menu, DEFAULT_FLAGS, { "Selection" } }, - { wimp_MENU_GIVE_WARNING, (wimp_menu *)&navigate_menu, DEFAULT_FLAGS, { "Navigate" } }, - { wimp_MENU_GIVE_WARNING, (wimp_menu *)&view_menu, DEFAULT_FLAGS, { "View" } }, - { 0, (wimp_menu *)&utilities_menu, DEFAULT_FLAGS, { "Utilities" } }, - { wimp_MENU_LAST | wimp_MENU_GIVE_WARNING, (wimp_menu *)&help_menu, DEFAULT_FLAGS, { "Help" } } - } -}; -wimp_menu *browser_menu = (wimp_menu *) &menu; - - - -/* Hotlist new submenu -*/ -static wimp_MENU(2) hotlist_new = { - { "New" }, 7,2,7,0, 300, 44, 0, - { - { wimp_MENU_GIVE_WARNING, (wimp_menu *)1, DEFAULT_FLAGS, { "Folder" } }, - { wimp_MENU_LAST | wimp_MENU_GIVE_WARNING, (wimp_menu *)1, DEFAULT_FLAGS, { "Link" } }, - } -}; - - -/* Hotlist expand submenu -*/ -static wimp_MENU(3) hotlist_expand = { - { "Expand" }, 7,2,7,0, 300, 44, 0, - { - { 0, wimp_NO_SUB_MENU, DEFAULT_FLAGS, { "All" } }, - { 0, wimp_NO_SUB_MENU, DEFAULT_FLAGS, { "Folders" } }, - { wimp_MENU_LAST, wimp_NO_SUB_MENU, DEFAULT_FLAGS, { "Links" } } - } -}; - -/* Hotlist collapse submenu -*/ -static wimp_MENU(3) hotlist_collapse = { - { "Collapse" }, 7,2,7,0, 300, 44, 0, - { - { 0, wimp_NO_SUB_MENU, DEFAULT_FLAGS, { "All" } }, - { 0, wimp_NO_SUB_MENU, DEFAULT_FLAGS, { "Folders" } }, - { wimp_MENU_LAST, wimp_NO_SUB_MENU, DEFAULT_FLAGS, { "Links" } } - } +struct ns_menu_entry { + const char *text; /**< menu text (from messages) */ + menu_action action; /**< associated action */ + wimp_w sub_window; /**< sub-window if any */ }; -/* Hotlist file submenu -*/ -static wimp_MENU(5) hotlist_file = { - { "Hotlist" }, 7,2,7,0, 300, 44, 0, - { - { 0, (wimp_menu *)&hotlist_new, DEFAULT_FLAGS, { "New" } }, - { wimp_MENU_GIVE_WARNING | wimp_MENU_SEPARATE, (wimp_menu *)1, DEFAULT_FLAGS, { "Export" } }, - { 0, (wimp_menu *)&hotlist_expand, DEFAULT_FLAGS, { "Expand" } }, - { 0, (wimp_menu *)&hotlist_collapse, DEFAULT_FLAGS, { "Collapse" } }, - { wimp_MENU_LAST | wimp_MENU_GIVE_WARNING, (wimp_menu *)&show_toolbar_menu, DEFAULT_FLAGS, { "Toolbars" } } - } +struct ns_menu { + const char *title; + struct ns_menu_entry entries[1]; }; -/* History file submenu -*/ -static wimp_MENU(4) history_file = { - { "History" }, 7,2,7,0, 300, 44, 0, - { - { wimp_MENU_GIVE_WARNING | wimp_MENU_SEPARATE, (wimp_menu *)1, DEFAULT_FLAGS, { "Export" } }, - { 0, (wimp_menu *)&hotlist_expand, DEFAULT_FLAGS, { "Expand" } }, - { 0, (wimp_menu *)&hotlist_collapse, DEFAULT_FLAGS, { "Collapse" } }, - { wimp_MENU_LAST | wimp_MENU_GIVE_WARNING, (wimp_menu *)&show_toolbar_menu, DEFAULT_FLAGS, { "Toolbars" } } - } -}; - -/* Hotlist file submenu -*/ -static wimp_MENU(4) hotlist_select = { - { "Selection" }, 7,2,7,0, 300, 44, 0, - { - { wimp_MENU_GIVE_WARNING, (wimp_menu *)1, DEFAULT_FLAGS, { "Edit" } }, - { 0, wimp_NO_SUB_MENU, DEFAULT_FLAGS, { "Launch" } }, - { 0, wimp_NO_SUB_MENU, DEFAULT_FLAGS, { "Delete" } }, - { wimp_MENU_LAST, wimp_NO_SUB_MENU, DEFAULT_FLAGS, { "ResetUsage" } } - } -}; - -/* History file submenu -*/ -static wimp_MENU(4) history_select = { - { "Selection" }, 7,2,7,0, 300, 44, 0, - { - { 0, wimp_NO_SUB_MENU, DEFAULT_FLAGS, { "Launch" } }, - { wimp_MENU_LAST, wimp_NO_SUB_MENU, DEFAULT_FLAGS, { "Delete" } }, - } -}; +#define NS_MENU(N) \ + struct { \ + const char *title; \ + struct ns_menu_entry entries[N]; \ + } -/* Hotlist menu -*/ -static wimp_MENU(4) hotlist_root = { - { "Hotlist" }, 7,2,7,0, 200, 44, 0, - { - { 0, (wimp_menu *)&hotlist_file, DEFAULT_FLAGS, { "Hotlist" } }, - { wimp_MENU_GIVE_WARNING, (wimp_menu *)&hotlist_select, DEFAULT_FLAGS, { "Selection" } }, - { 0, wimp_NO_SUB_MENU, DEFAULT_FLAGS, { "SelectAll" } }, - { wimp_MENU_LAST, wimp_NO_SUB_MENU, DEFAULT_FLAGS, { "Clear" } } - } -}; -wimp_menu *hotlist_menu = (wimp_menu *)&hotlist_root; - -/* History menu -*/ -static wimp_MENU(4) history_root = { - { "History" }, 7,2,7,0, 200, 44, 0, - { - { 0, (wimp_menu *)&history_file, DEFAULT_FLAGS, { "History" } }, - { wimp_MENU_GIVE_WARNING, (wimp_menu *)&history_select, DEFAULT_FLAGS, { "Selection" } }, - { 0, wimp_NO_SUB_MENU, DEFAULT_FLAGS, { "SelectAll" } }, - { wimp_MENU_LAST, wimp_NO_SUB_MENU, DEFAULT_FLAGS, { "Clear" } } - } -}; -wimp_menu *global_history_menu = (wimp_menu *)&history_root; - - -/* Proxy auth popup menu (used in proxy Choices dialog) -*/ -static wimp_MENU(3) proxy_menu = { - { "ProxyAuth" }, 7,2,7,0, 200, 44, 0, - { - { 0, wimp_NO_SUB_MENU, DEFAULT_FLAGS, { "ProxyNone" } }, - { 0, wimp_NO_SUB_MENU, DEFAULT_FLAGS, { "ProxyBasic" } }, - { wimp_MENU_LAST, wimp_NO_SUB_MENU, DEFAULT_FLAGS, { "ProxyNTLM" } } - } +struct menu_definition_entry { + menu_action action; /**< menu action */ + wimp_menu_entry *menu_entry; /**< corresponding menu entry */ + struct menu_definition_entry *next; /**< next menu entry */ }; -wimp_menu *proxyauth_menu = (wimp_menu *) &proxy_menu; - - -/* Image display quality popup menu (used in image Choices dialog) -*/ -static wimp_MENU(4) imageq_menu = { - { "Display" }, 7,2,7,0, 200, 44, 0, - { - { 0, wimp_NO_SUB_MENU, DEFAULT_FLAGS, { "ImgStyle0" } }, - { 0, wimp_NO_SUB_MENU, DEFAULT_FLAGS, { "ImgStyle1" } }, - { 0, wimp_NO_SUB_MENU, DEFAULT_FLAGS, { "ImgStyle2" } }, - { wimp_MENU_LAST, wimp_NO_SUB_MENU, DEFAULT_FLAGS, { "ImgStyle3" } } - } -}; -wimp_menu *image_quality_menu = (wimp_menu *) &imageq_menu; - -/* Toolbar icon menu -*/ -static wimp_MENU(5) toolbar = { - { "Toolbar" }, 7,2,7,0, 200, 44, 0, - { - { 0, (wimp_menu *)&show_toolbar_menu, DEFAULT_FLAGS, { "Toolbars" } }, - { wimp_MENU_LAST, wimp_NO_SUB_MENU, DEFAULT_FLAGS, { "EditToolbar" } } - } +struct menu_definition { + wimp_menu *menu; /**< corresponding menu */ + struct menu_definition_entry *entries; /**< menu entries */ + struct menu_definition *next; /**< next menu */ }; -wimp_menu *toolbar_menu = (wimp_menu *)&toolbar; - -/* Current toolbar -*/ -struct toolbar *current_toolbar; -/* Languages popup menu (used in browser choices dialog) -*/ -wimp_menu *languages_menu = NULL; +static wimp_menu *ro_gui_menu_define_menu(struct ns_menu *menu); +static void ro_gui_menu_define_menu_add(struct menu_definition *definition, + struct ns_menu *menu, int depth, wimp_menu_entry *link, + int first, int last, const char *prefix, int prefix_length); +static struct menu_definition *ro_gui_menu_find_menu(wimp_menu *menu); +static struct menu_definition_entry *ro_gui_menu_find_entry(wimp_menu *menu, + menu_action action); +static menu_action ro_gui_menu_find_action(wimp_menu *menu, + wimp_menu_entry *menu_entry); +static void ro_gui_menu_set_entry_shaded(wimp_menu *menu, menu_action action, + bool shaded); +static void ro_gui_menu_set_entry_ticked(wimp_menu *menu, menu_action action, + bool ticked); +static void ro_gui_menu_get_window_details(wimp_w w, struct gui_window **g, + struct browser_window **bw, struct content **content, + struct toolbar **toolbar, struct tree **tree); +static int ro_gui_menu_get_checksum(void); +static bool ro_gui_menu_prepare_url_suggest(void); +static void ro_gui_menu_prepare_pageinfo(struct gui_window *g); +static void ro_gui_menu_prepare_objectinfo(struct box *box); +static void ro_gui_menu_refresh_toolbar(struct toolbar *toolbar); + + +/* default menu item flags */ +#define DEFAULT_FLAGS (wimp_ICON_TEXT | wimp_ICON_FILLED | \ + (wimp_COLOUR_BLACK << wimp_ICON_FG_COLOUR_SHIFT) | \ + (wimp_COLOUR_WHITE << wimp_ICON_BG_COLOUR_SHIFT)) -/* Toolbar menu -*/ -wimp_menu *toolbar_icon_menu = NULL; -/* URL suggestion menu -*/ +/** The currently defined menus to perform actions for */ +static struct menu_definition *ro_gui_menu_definitions; +/** The current menu being worked with (may not be open) */ +wimp_menu *current_menu; +/** Whether a menu is currently open */ +static bool current_menu_open = false; +/** Box for object under menu, or 0 if no object. */ +static struct box *current_menu_object_box = 0; +/** Menu of options for form select controls. */ +static wimp_menu *gui_form_select_menu = 0; +/** Form control which gui_form_select_menu is for. */ +static struct form_control *gui_form_select_control; +/** Window that owns the current menu */ +static wimp_w current_menu_window; +/** The height of the iconbar menu */ +int iconbar_menu_height = 5 * 44; +/** The available menus */ +wimp_menu *iconbar_menu, *browser_menu, *hotlist_menu, *global_history_menu, + *image_quality_menu, *browser_toolbar_menu, + *tree_toolbar_menu, *proxy_auth_menu, *languages_menu; +/** URL suggestion menu */ static wimp_MENU(GLOBAL_HISTORY_RECENT_URLS) url_suggest; wimp_menu *url_suggest_menu = (wimp_menu *)&url_suggest; -static wimp_menu *browser_page_menu = (wimp_menu *)&page_menu; -static wimp_menu *browser_export_menu = (wimp_menu *)&export_menu; -static wimp_menu *browser_object_menu = (wimp_menu *)&object_menu; -static wimp_menu *browser_link_menu = (wimp_menu *)&link_menu; -static wimp_menu *browser_object_export_menu = (wimp_menu *)&object_export_menu; -static wimp_menu *browser_selection_menu = (wimp_menu *)&selection_menu; -static wimp_menu *browser_navigate_menu = (wimp_menu *)&navigate_menu; -static wimp_menu *browser_view_menu = (wimp_menu *)&view_menu; -static wimp_menu *browser_image_menu = (wimp_menu *)&image_menu; -static wimp_menu *browser_toolbar_menu = (wimp_menu *)&show_toolbar_menu; -static wimp_menu *browser_render_menu = (wimp_menu *)&render_menu; -static wimp_menu *browser_window_menu = (wimp_menu *)&window_menu; -static wimp_menu *browser_utilities_menu = (wimp_menu *)&utilities_menu; -static wimp_menu *browser_hotlist_menu = (wimp_menu *)&hotlist_util_menu; -static wimp_menu *browser_history_menu = (wimp_menu *)&history_util_menu; -static wimp_menu *browser_help_menu = (wimp_menu *)&help_menu; - -static wimp_menu *hotlist_new_menu = (wimp_menu *)&hotlist_new; -static wimp_menu *hotlist_expand_menu = (wimp_menu *)&hotlist_expand; -static wimp_menu *hotlist_collapse_menu = (wimp_menu *)&hotlist_collapse; -static wimp_menu *hotlist_file_menu = (wimp_menu *)&hotlist_file; -static wimp_menu *hotlist_select_menu = (wimp_menu *)&hotlist_select; - -static wimp_menu *history_file_menu = (wimp_menu *)&history_file; -static wimp_menu *history_select_menu = (wimp_menu *)&history_select; - /** * Create menu structures. */ - -void ro_gui_menus_init(void) -{ - translate_menu(iconbar_menu); - - translate_menu(browser_menu); - translate_menu(browser_page_menu); - translate_menu(browser_export_menu); - translate_menu(browser_object_menu); - translate_menu(browser_link_menu); - translate_menu(browser_object_export_menu); - translate_menu(browser_selection_menu); - translate_menu(browser_navigate_menu); - translate_menu(browser_view_menu); - translate_menu(browser_image_menu); - translate_menu(browser_toolbar_menu); - translate_menu(browser_render_menu); - translate_menu(browser_window_menu); - translate_menu(browser_utilities_menu); - translate_menu(browser_hotlist_menu); - translate_menu(browser_history_menu); - translate_menu(browser_help_menu); - - translate_menu(hotlist_menu); - translate_menu(hotlist_new_menu); - translate_menu(hotlist_expand_menu); - translate_menu(hotlist_collapse_menu); - translate_menu(hotlist_file_menu); - translate_menu(hotlist_select_menu); - - translate_menu(global_history_menu); - translate_menu(history_file_menu); - translate_menu(history_select_menu); - - - translate_menu(toolbar_menu); - - translate_menu(proxyauth_menu); - - translate_menu(image_quality_menu); - - build_languages_menu(); - - url_suggest_menu->title_data.indirected_text.text = strdup(messages_get("URLSuggest")); - - iconbar_menu->entries[0].sub_menu = (wimp_menu *) dialog_info; - browser_page_menu->entries[0].sub_menu = (wimp_menu*) dialog_pageinfo; - browser_object_menu->entries[0].sub_menu = (wimp_menu*) dialog_objinfo; -// browser_page_menu->entries[1].sub_menu = (wimp_menu *) dialog_saveas; -// browser_page_menu->entries[2].sub_menu = (wimp_menu *) dialog_saveas; -// browser_export_menu->entries[0].sub_menu = (wimp_menu *) dialog_saveas; -// browser_export_menu->entries[1].sub_menu = (wimp_menu *) dialog_saveas; -// browser_view_menu->entries[0].sub_menu = (wimp_menu *) dialog_zoom; -} - - -/** - * Replace text in a menu with message values. - */ - -void translate_menu(wimp_menu *menu) -{ - unsigned int i = 0; - const char *indirected_text; - - /* We can't just blindly set something as indirected as if we use - the fallback messages text (ie the pointer we gave), we overwrite - this data when setting the pointer to the indirected text we - already had. - */ - indirected_text = messages_get(menu->title_data.text); - if (indirected_text != menu->title_data.text) { - menu->title_data.indirected_text.text = strdup(indirected_text); - menu->entries[0].menu_flags |= wimp_MENU_TITLE_INDIRECTED; - - } - - /* items */ - do { - indirected_text = messages_get(menu->entries[i].data.text); - if (indirected_text != menu->entries[i].data.text) { - menu->entries[i].icon_flags |= wimp_ICON_INDIRECTED; - menu->entries[i].data.indirected_text.text = strdup(indirected_text); - menu->entries[i].data.indirected_text.validation = select_null_text_string; - menu->entries[i].data.indirected_text.size = strlen(indirected_text) + 1; - } - i++; - } while ((menu->entries[i - 1].menu_flags & wimp_MENU_LAST) == 0); -} - -/** - * Builds the languages menu based on available translations - */ -void build_languages_menu(void) -{ +void ro_gui_menu_init(void) { int context = 0, read_count, entries = 0; - os_error *e; + os_error *error; osgbpb_INFO(100) info; char lang[8] = {0}; char *lang_name; void *temp; + /* iconbar menu */ + NS_MENU(9) iconbar_definition = { + "NetSurf", { + { "Info", NO_ACTION, dialog_info }, + { "AppHelp", HELP_OPEN_CONTENTS, 0 }, + { "Open", NO_ACTION, 0 }, + { "Open.OpenURL", BROWSER_NAVIGATE_URL, dialog_openurl }, + { "Open.HotlistShow", HOTLIST_SHOW, 0 }, + { "Open.HistGlobal", HISTORY_SHOW_GLOBAL, 0 }, + { "Choices", CHOICES_SHOW, 0 }, + { "Quit", APPLICATION_QUIT, 0 }, + {NULL, 0, 0} + } + }; + iconbar_menu = ro_gui_menu_define_menu( + (struct ns_menu *)&iconbar_definition); + + /* browser menu */ + NS_MENU(66) browser_definition = { + "NetSurf", { + { "Page", BROWSER_PAGE, 0 }, + { "Page.PageInfo",BROWSER_PAGE_INFO, dialog_pageinfo }, + { "Page.Save", BROWSER_SAVE, dialog_saveas }, + { "Page.SaveComp", BROWSER_SAVE_COMPLETE, dialog_saveas }, + { "Page.Export", NO_ACTION, 0 }, + { "Page.Export.Draw", BROWSER_EXPORT_DRAW, dialog_saveas }, + { "Page.Export.Text", BROWSER_EXPORT_TEXT, dialog_saveas }, + { "Page.SaveURL", NO_ACTION, 0 }, + { "Page.SaveURL.URI", BROWSER_SAVE_URL_URI, dialog_saveas }, + { "Page.SaveURL.URL", BROWSER_SAVE_URL_URL, dialog_saveas }, + { "Page.SaveURL.LinkText", BROWSER_SAVE_URL_TEXT, dialog_saveas }, + { "Page.Print_", BROWSER_PRINT, dialog_print }, + { "Page.NewWindow", BROWSER_NEW_WINDOW, 0 }, + { "Page.ViewSrc", BROWSER_VIEW_SOURCE, 0 }, + { "Object", BROWSER_OBJECT, 0 }, + { "Object.ObjInfo", BROWSER_OBJECT_INFO, dialog_objinfo }, + { "Object.ObjSave", BROWSER_OBJECT_SAVE, dialog_saveas }, + { "Object.Export", NO_ACTION, 0 }, + { "Object.Export.Sprite", BROWSER_OBJECT_EXPORT_SPRITE, dialog_saveas }, + { "Object.SaveURL_", NO_ACTION, 0 }, + { "Object.SaveURL.URI", BROWSER_OBJECT_SAVE_URL_URI, dialog_saveas }, + { "Object.SaveURL.URL", BROWSER_OBJECT_SAVE_URL_URL, dialog_saveas }, + { "Object.SaveURL.LinkText", BROWSER_OBJECT_SAVE_URL_TEXT, dialog_saveas }, + { "Object.ObjReload", BROWSER_OBJECT_RELOAD, 0 }, + { "Navigate", NO_ACTION, 0 }, + { "Navigate.Home", BROWSER_NAVIGATE_HOME, 0 }, + { "Navigate.Back", BROWSER_NAVIGATE_BACK, 0 }, + { "Navigate.Forward_", BROWSER_NAVIGATE_FORWARD, 0 }, + { "Navigate.Reload", BROWSER_NAVIGATE_RELOAD_ALL, 0 }, + { "Navigate.Stop", BROWSER_NAVIGATE_STOP, 0 }, + { "View", NO_ACTION, 0 }, + { "View.ScaleView", BROWSER_SCALE_VIEW, dialog_zoom }, + { "View.Images", NO_ACTION, 0 }, + { "View.Images.ForeImg", BROWSER_IMAGES_FOREGROUND, 0 }, + { "View.Images.BackImg", BROWSER_IMAGES_BACKGROUND, 0 }, + { "View.Toolbars", NO_ACTION, 0 }, + { "View.Toolbars.ToolButtons", TOOLBAR_BUTTONS, 0 }, + { "View.Toolbars.ToolAddress", TOOLBAR_ADDRESS_BAR, 0 }, + { "View.Toolbars.ToolThrob", TOOLBAR_THROBBER, 0 }, + { "View.Toolbars.ToolStatus_", TOOLBAR_STATUS_BAR, 0 }, + { "View.Toolbars.EditToolbar", TOOLBAR_EDIT, 0 }, + { "View.Render_", NO_ACTION, 0 }, + { "View.Render.RenderText_", BROWSER_BLEND_TEXT, 0 }, + { "View.Render.RenderAnims", BROWSER_BUFFER_ANIMS, 0 }, + { "View.Render.RenderAll", BROWSER_BUFFER_ALL, 0 }, + { "View.OptDefault", BROWSER_SAVE_VIEW, 0 }, + { "Utilities", NO_ACTION, 0 }, + { "Utilities.Hotlist", HOTLIST_SHOW, 0 }, + { "Utilities.Hotlist.HotlistAdd", HOTLIST_ADD_URL, 0 }, + { "Utilities.Hotlist.HotlistShow", HOTLIST_SHOW, 0 }, + { "Utilities.History", HISTORY_SHOW_GLOBAL, 0 }, + { "Utilities.History.HistLocal", HISTORY_SHOW_LOCAL, 0 }, + { "Utilities.History.HistGlobal", HISTORY_SHOW_GLOBAL, 0 }, + { "Utilities.FindText", BROWSER_FIND_TEXT, dialog_search }, + { "Utilities.Window", NO_ACTION, 0 }, + { "Utilities.Window.WindowSave", BROWSER_WINDOW_DEFAULT, 0 }, + { "Utilities.Window.WindowStagr", BROWSER_WINDOW_STAGGER, 0 }, + { "Utilities.Window.WindowSize_", BROWSER_WINDOW_COPY, 0 }, + { "Utilities.Window.WindowReset", BROWSER_WINDOW_RESET, 0 }, + { "Help", HELP_OPEN_CONTENTS, 0 }, + { "Help.HelpContent", HELP_OPEN_CONTENTS, 0 }, + { "Help.HelpGuide", HELP_OPEN_GUIDE, 0 }, + { "Help.HelpInfo_", HELP_OPEN_INFORMATION, 0 }, + { "Help.HelpAbout_", HELP_OPEN_ABOUT, 0 }, + { "Help.HelpInter", HELP_LAUNCH_INTERACTIVE, 0 }, + {NULL, 0, 0} + } + }; + browser_menu = ro_gui_menu_define_menu( + (struct ns_menu *)&browser_definition); + + /* hotlist menu */ + NS_MENU(24) hotlist_definition = { + "Hotlist", { + { "Hotlist", NO_ACTION, 0 }, + { "Hotlist.New", NO_ACTION, 0 }, + { "Hotlist.New.Folder", TREE_NEW_FOLDER, dialog_folder }, + { "Hotlist.New.Link", TREE_NEW_LINK, dialog_entry }, + { "Hotlist.Export_", HOTLIST_EXPORT, dialog_saveas }, + { "Hotlist.Expand", TREE_EXPAND_ALL, 0 }, + { "Hotlist.Expand.All", TREE_EXPAND_ALL, 0 }, + { "Hotlist.Expand.Folders", TREE_EXPAND_FOLDERS, 0 }, + { "Hotlist.Expand.Links", TREE_EXPAND_LINKS, 0 }, + { "Hotlist.Collapse", TREE_COLLAPSE_ALL, 0 }, + { "Hotlist.Collapse.All", TREE_COLLAPSE_ALL, 0 }, + { "Hotlist.Collapse.Folders", TREE_COLLAPSE_FOLDERS, 0 }, + { "Hotlist.Collapse.Links", TREE_COLLAPSE_LINKS, 0 }, + { "Hotlist.Toolbars", NO_ACTION, 0 }, + { "Hotlist.Toolbars.ToolButtons_", TOOLBAR_BUTTONS, 0 }, + { "Hotlist.Toolbars.EditToolbar", TOOLBAR_EDIT, 0 }, + { "Selection", TREE_SELECTION, 0 }, + { "Selection.Edit", TREE_SELECTION_EDIT, (wimp_w)1 }, + { "Selection.Launch", TREE_SELECTION_LAUNCH, 0 }, + { "Selection.Delete", TREE_SELECTION_DELETE, 0 }, + { "Selection.ResetUsage", TREE_SELECTION_RESET, 0 }, + { "SelectAll", TREE_SELECT_ALL, 0 }, + { "Clear", TREE_CLEAR_SELECTION, 0 }, + {NULL, 0, 0} + } + }; + hotlist_menu = ro_gui_menu_define_menu( + (struct ns_menu *)&hotlist_definition); + + /* history menu */ + NS_MENU(19) global_history_definition = { + "History", { + { "History", NO_ACTION, 0 }, + { "History.Export_", HISTORY_EXPORT, dialog_saveas }, + { "History.Expand", TREE_EXPAND_ALL, 0 }, + { "History.Expand.All", TREE_EXPAND_ALL, 0 }, + { "History.Expand.Folders", TREE_EXPAND_FOLDERS, 0 }, + { "History.Expand.Links", TREE_EXPAND_LINKS, 0 }, + { "History.Collapse", TREE_COLLAPSE_ALL, 0 }, + { "History.Collapse.All", TREE_COLLAPSE_ALL, 0 }, + { "History.Collapse.Folders", TREE_COLLAPSE_FOLDERS, 0 }, + { "History.Collapse.Links", TREE_COLLAPSE_LINKS, 0 }, + { "History.Toolbars", NO_ACTION, 0 }, + { "History.Toolbars.ToolButtons_", TOOLBAR_BUTTONS, 0 }, + { "History.Toolbars.EditToolbar",TOOLBAR_EDIT, 0 }, + { "Selection", TREE_SELECTION, 0 }, + { "Selection.Launch", TREE_SELECTION_LAUNCH, 0 }, + { "Selection.Delete", TREE_SELECTION_DELETE, 0 }, + { "SelectAll", TREE_SELECT_ALL, 0 }, + { "Clear", TREE_CLEAR_SELECTION, 0 }, + {NULL, 0, 0} + } + }; + global_history_menu = ro_gui_menu_define_menu( + (struct ns_menu *)&global_history_definition); + + /* image quality menu */ + NS_MENU(5) images_definition = { + "Display", { + { "ImgStyle0", NO_ACTION, 0 }, + { "ImgStyle1", NO_ACTION, 0 }, + { "ImgStyle2", NO_ACTION, 0 }, + { "ImgStyle3", NO_ACTION, 0 }, + {NULL, 0, 0} + } + }; + image_quality_menu = ro_gui_menu_define_menu( + (struct ns_menu *)&images_definition); + + /* browser toolbar menu */ + NS_MENU(7) browser_toolbar_definition = { + "Toolbar", { + { "Toolbars", NO_ACTION, 0 }, + { "Toolbars.ToolButtons", TOOLBAR_BUTTONS, 0 }, + { "Toolbars.ToolAddress", TOOLBAR_ADDRESS_BAR, 0 }, + { "Toolbars.ToolThrob", TOOLBAR_THROBBER, 0 }, + { "Toolbars.ToolStatus", TOOLBAR_STATUS_BAR, 0 }, + { "EditToolbar", TOOLBAR_EDIT, 0 }, + {NULL, 0, 0} + } + }; + browser_toolbar_menu = ro_gui_menu_define_menu( + (struct ns_menu *)&browser_toolbar_definition); + + /* tree toolbar menu */ + NS_MENU(4) tree_toolbar_definition = { + "Toolbar", { + { "Toolbars", NO_ACTION, 0 }, + { "Toolbars.ToolButtons", TOOLBAR_BUTTONS, 0 }, + { "EditToolbar", TOOLBAR_EDIT, 0 }, + {NULL, 0, 0} + } + }; + tree_toolbar_menu = ro_gui_menu_define_menu( + (struct ns_menu *)&tree_toolbar_definition); + + /* proxy menu */ + NS_MENU(4) proxy_auth_definition = { + "ProxyAuth", { + { "ProxyNone", NO_ACTION, 0 }, + { "ProxyBasic", NO_ACTION, 0 }, + { "ProxyNTLM", NO_ACTION, 0 }, + {NULL, 0, 0} + } + }; + proxy_auth_menu = ro_gui_menu_define_menu( + (struct ns_menu *)&proxy_auth_definition); + + /* special case menus */ + url_suggest_menu->title_data.indirected_text.text = + messages_get("URLSuggest"); + url_suggest_menu->title_fg = wimp_COLOUR_BLACK; + url_suggest_menu->title_bg = wimp_COLOUR_LIGHT_GREY; + url_suggest_menu->work_fg = wimp_COLOUR_BLACK; + url_suggest_menu->work_bg = wimp_COLOUR_WHITE; + url_suggest_menu->width = 200; + url_suggest_menu->height = wimp_MENU_ITEM_HEIGHT; + url_suggest_menu->gap = wimp_MENU_ITEM_GAP; + + /* language menu */ languages_menu = calloc(1, wimp_SIZEOF_MENU(1)); - if (!languages_menu) { - LOG(("No memory for languages menu")); - die("Insufficient memory for languages menu"); - } - languages_menu->title_data.indirected_text.text = strdup(messages_get("Languages")); + if (!languages_menu) + die("Insufficient memory for languages menu."); + languages_menu->title_data.indirected_text.text = + messages_get("Languages"); languages_menu->title_fg = wimp_COLOUR_BLACK; languages_menu->title_bg = wimp_COLOUR_LIGHT_GREY; languages_menu->work_fg = wimp_COLOUR_BLACK; languages_menu->work_bg = wimp_COLOUR_WHITE; - languages_menu->width = 300; - languages_menu->height = 44; - languages_menu->gap = 0; + languages_menu->width = 200; + languages_menu->height = wimp_MENU_ITEM_HEIGHT; + languages_menu->gap = wimp_MENU_ITEM_GAP; while (context != -1) { - e = xosgbpb_dir_entries_info("<NetSurf$Dir>.Resources", (osgbpb_info_list*)&info, 1, - context, sizeof(info), 0, &read_count, &context); - if (e) - die(e->errmess); - - if (read_count == 0) - continue; - - if (info.obj_type != fileswitch_IS_DIR) + error = xosgbpb_dir_entries_info("<NetSurf$Dir>.Resources", + (osgbpb_info_list*)&info, 1, context, + sizeof(info), 0, &read_count, &context); + if (error) + die(error->errmess); + if ((read_count == 0) || (info.obj_type != fileswitch_IS_DIR)) continue; snprintf(lang, sizeof lang, "lang_%2s", info.name); - if ((lang_name = strdup(messages_get(lang))) == NULL || - strlen(info.name) != 2) + /* we can't duplicate the string returned from our messages as + * it causes value->key lookups to fail */ + lang_name = messages_get(lang); + if ((lang_name == lang) || (strlen(info.name) != 2)) continue; - temp = realloc(languages_menu, wimp_SIZEOF_MENU(entries+1)); + temp = realloc(languages_menu, wimp_SIZEOF_MENU(entries + 1)); if (!temp) die("Insufficient memory for languages menu"); languages_menu = temp; languages_menu->entries[entries].menu_flags = 0; languages_menu->entries[entries].sub_menu = wimp_NO_SUB_MENU; - languages_menu->entries[entries].icon_flags = DEFAULT_FLAGS | wimp_ICON_INDIRECTED; - languages_menu->entries[entries].data.indirected_text.text = lang_name; - languages_menu->entries[entries].data.indirected_text.validation = (char *)-1; - languages_menu->entries[entries].data.indirected_text.size = strlen(lang_name) + 1; - + languages_menu->entries[entries].icon_flags = DEFAULT_FLAGS | + wimp_ICON_INDIRECTED; + languages_menu->entries[entries].data.indirected_text.text = + lang_name; + languages_menu->entries[entries].data.indirected_text. + validation = (char *)-1; + languages_menu->entries[entries].data.indirected_text.size = + strlen(lang_name) + 1; entries++; } @@ -663,55 +396,19 @@ void build_languages_menu(void) /** - * Builds the URL suggestion menu - */ -bool ro_gui_menu_prepare_url_suggest(void) { - char **suggest_text; - int suggestions; - int i; - - suggest_text = global_history_get_recent(&suggestions); - if (suggestions < 1) - return false; - - url_suggest_menu->title_fg = wimp_COLOUR_BLACK; - url_suggest_menu->title_bg = wimp_COLOUR_LIGHT_GREY; - url_suggest_menu->work_fg = wimp_COLOUR_BLACK; - url_suggest_menu->work_bg = wimp_COLOUR_WHITE; - url_suggest_menu->width = 300; - url_suggest_menu->height = 44; - url_suggest_menu->gap = 0; - - for (i = 0; i < suggestions; i++) { - url_suggest_menu->entries[i].menu_flags = 0; - url_suggest_menu->entries[i].sub_menu = wimp_NO_SUB_MENU; - url_suggest_menu->entries[i].icon_flags = DEFAULT_FLAGS | wimp_ICON_INDIRECTED; - url_suggest_menu->entries[i].data.indirected_text.text = suggest_text[i]; - url_suggest_menu->entries[i].data.indirected_text.validation = (char *)-1; - url_suggest_menu->entries[i].data.indirected_text.size = strlen(suggest_text[i]) + 1; - } - - url_suggest_menu->entries[0].menu_flags |= wimp_MENU_TITLE_INDIRECTED; - url_suggest_menu->entries[suggestions - 1].menu_flags |= wimp_MENU_LAST; - return true; -} - - -/** * Display a menu. */ -void ro_gui_create_menu(wimp_menu *menu, int x, int y, struct gui_window *g) -{ +void ro_gui_menu_create(wimp_menu *menu, int x, int y, wimp_w w) { int doc_x, doc_y; wimp_window_state state; + struct gui_window *g; os_error *error; + int i; + menu_action action; - current_gui = g; - - if (menu == browser_menu) { - assert(g); - - state.w = g->window; + /* read the object under the pointer for a new gui_window menu */ + if ((!current_menu) && (menu == browser_menu)) { + state.w = w; error = xwimp_get_window_state(&state); if (error) { LOG(("xwimp_get_window_state: 0x%x: %s", @@ -720,55 +417,45 @@ void ro_gui_create_menu(wimp_menu *menu, int x, int y, struct gui_window *g) return; } + g = ro_gui_window_lookup(w); + assert(g); + doc_x = window_x_units(x, &state) / 2 / g->option.scale; doc_y = -window_y_units(y, &state) / 2 / g->option.scale; - gui_menu_object_box = 0; + current_menu_object_box = NULL; if (g->bw->current_content && - g->bw->current_content->type == CONTENT_HTML) { - gui_menu_object_box = box_object_at_point( + g->bw->current_content->type == CONTENT_HTML) + current_menu_object_box = box_object_at_point( g->bw->current_content, doc_x, doc_y); - } + } - if (!hotlist_tree) - browser_utilities_menu->entries[0].icon_flags |= - wimp_ICON_SHADED; - if (gui_menu_object_box) - menu->entries[1].icon_flags &= ~wimp_ICON_SHADED; - else - menu->entries[1].icon_flags |= wimp_ICON_SHADED; - if ((current_gui->bw) && (current_gui->bw->current_content)) { - menu->entries[0].icon_flags &= ~wimp_ICON_SHADED; - } else { - menu->entries[0].icon_flags |= wimp_ICON_SHADED; - } - current_toolbar = g->toolbar; - - } else if (menu == toolbar_menu) { - ro_gui_menu_prepare_toolbars(current_toolbar); - toolbar_menu->entries[1].menu_flags &= ~wimp_MENU_TICKED; - if (current_toolbar->editor) - toolbar_menu->entries[1].menu_flags |= wimp_MENU_TICKED; - } else if (menu == hotlist_menu) { - ro_gui_menu_prepare_hotlist(); - current_toolbar = hotlist_tree->toolbar; - } else if (menu == global_history_menu) { - ro_gui_menu_prepare_global_history(); - current_toolbar = global_history_tree->toolbar; - } else if (menu == url_suggest_menu) { + /* store the menu characteristics */ + current_menu = menu; + current_menu_window = w; + + /* prepare the menu state */ + if (menu == url_suggest_menu) { if (!ro_gui_menu_prepare_url_suggest()) return; + } else { + i = 0; + do { + action = ro_gui_menu_find_action(menu, + &menu->entries[i]); + if (action != NO_ACTION) + ro_gui_menu_prepare_action(w, action, false); + } while (!(menu->entries[i++].menu_flags & wimp_MENU_LAST)); } + /* create the menu */ + current_menu_open = true; error = xwimp_create_menu(menu, x - 64, y); if (error) { LOG(("xwimp_create_menu: 0x%x: %s", error->errnum, error->errmess)); warn_user("MenuError", error->errmess); - } else { - current_menu = menu; - current_menu_x = x; - current_menu_y = y; + ro_gui_menu_closed(); } } @@ -777,12 +464,10 @@ void ro_gui_create_menu(wimp_menu *menu, int x, int y, struct gui_window *g) * Display a pop-up menu next to the specified icon. * * \param menu menu to open - * \param w window handle - * \param i icon handle + * \param w window handle + * \param i icon handle */ - -void ro_gui_popup_menu(wimp_menu *menu, wimp_w w, wimp_i i) -{ +void ro_gui_popup_menu(wimp_menu *menu, wimp_w w, wimp_i i) { wimp_window_state state; wimp_icon_state icon_state; os_error *error; @@ -806,798 +491,203 @@ void ro_gui_popup_menu(wimp_menu *menu, wimp_w w, wimp_i i) return; } - ro_gui_create_menu(menu, + ro_gui_menu_create(menu, state.visible.x0 + icon_state.icon.extent.x1 + 64, state.visible.y1 + icon_state.icon.extent.y1 - - state.yscroll, current_gui); + state.yscroll, w); } /** - * Handle menu selection. + * Clean up after a menu has been closed, or forcible close an open menu. */ - -void ro_gui_menu_selection(wimp_selection *selection) -{ - struct node *node; - char url[80]; - wimp_pointer pointer; - wimp_window_state state; +void ro_gui_menu_closed(void) { + struct gui_window *g; + struct browser_window *bw; + struct content *c; + struct toolbar *t; + struct tree *tree; os_error *error; - wimp_get_pointer_info(&pointer); - - if (current_menu == gui_form_select_menu && 0 <= selection->items[0]) { - browser_window_form_select(current_gui->bw, - gui_form_select_control, - selection->items[0]); - - } else if (current_menu == iconbar_menu) { - switch (selection->items[0]) { - case 0: /* Info */ - ro_gui_create_menu((wimp_menu *) dialog_info, - pointer.pos.x, pointer.pos.y, 0); - break; - case 1: /* Help */ - ro_gui_open_help_page("docs"); - break; - case 2: /* Choices */ - ro_gui_dialog_open_config(); - break; - case 3: /* Quit */ - netsurf_quit = true; - break; - } - - } else if (current_menu == url_suggest_menu) { - if (!current_gui) - LOG(("No current GUI")); - else if (selection->items[0] >= 0) { - browser_window_go(current_gui->bw, - url_suggest_menu->entries[selection->items[0]].data.indirected_text.text, 0); - global_history_add_recent(url_suggest_menu->entries[selection->items[0]].data.indirected_text.text); - } - } else if (current_menu == toolbar_menu) { - switch (selection->items[0]) { - case 0: /* Toolbars-> */ - ro_gui_menu_toolbar_submenu_selection(selection->items[1]); - break; - case 1: /* Edit toolbar */ - ro_gui_theme_toggle_edit(current_toolbar); - ro_gui_menu_prepare_toolbars(current_toolbar); - break; - } - } else if (current_menu == hotlist_menu) { - switch (selection->items[0]) { - case 0: /* Hotlist-> */ - switch (selection->items[1]) { - case 0: /* New */ - break; - case 1: /* Export */ - break; - case 2: /* Expand */ - tree_handle_expansion(hotlist_tree, hotlist_tree->root, true, - (selection->items[2] != 2), (selection->items[2] != 1)); - break; - case 3: /* Collapse */ - tree_handle_expansion(hotlist_tree, hotlist_tree->root, false, - (selection->items[2] != 2), (selection->items[2] != 1)); - break; - case 4: /* Toolbars-> */ - ro_gui_menu_toolbar_submenu_selection(selection->items[2]); - break; - } - break; - case 1: /* Selection-> */ - switch (selection->items[1]) { - case 0: /* Edit-> */ - break; - case 1: /* Launch */ - ro_gui_tree_launch_selected(hotlist_tree); - break; - case 2: /* Delete */ - tree_delete_selected_nodes(hotlist_tree, hotlist_tree->root); - break; - case 3: /* Reset usage */ - tree_reset_URL_nodes(hotlist_tree, hotlist_tree->root, true); - break; - } - break; - case 2: /* Select all */ - ro_gui_tree_keypress(1, hotlist_tree); - ro_gui_menu_prepare_hotlist(); - break; - case 3: /* Clear */ - ro_gui_tree_keypress(26, hotlist_tree); - ro_gui_menu_prepare_hotlist(); - break; - } - } else if (current_menu == global_history_menu) { - switch (selection->items[0]) { - case 0: /* Hotlist-> */ - switch (selection->items[1]) { - case 0: /* Export */ - break; - case 1: /* Expand */ - tree_handle_expansion(global_history_tree, global_history_tree->root, true, - (selection->items[2] != 2), (selection->items[2] != 1)); - break; - case 2: /* Collapse */ - tree_handle_expansion(global_history_tree, global_history_tree->root, false, - (selection->items[2] != 2), (selection->items[2] != 1)); - break; - case 3: /* Toolbars-> */ - ro_gui_menu_toolbar_submenu_selection(selection->items[2]); - break; - } - break; - case 1: /* Selection-> */ - switch (selection->items[1]) { - case 0: /* Launch */ - ro_gui_tree_launch_selected(global_history_tree); - break; - case 1: /* Delete */ - tree_delete_selected_nodes(global_history_tree, global_history_tree->root); - break; - } - break; - case 2: /* Select all */ - ro_gui_tree_keypress(1, global_history_tree); - ro_gui_menu_prepare_global_history(); - break; - case 3: /* Clear */ - ro_gui_tree_keypress(26, global_history_tree); - ro_gui_menu_prepare_global_history(); - break; - } - } else if (current_menu == browser_menu) { - struct content *c = current_gui->bw->current_content; - switch (selection->items[0]) { - case MENU_PAGE: - switch (selection->items[1]) { - case 0: /* Info */ - break; - case 1: /* Save */ - break; - case 2: /* Full save */ - break; - case 3: /* Export */ - break; - case 4: /* Save location */ - switch (selection->items[2]) { - case 0: /* URI */ - break; - case 1: /* URL */ - break; - case 2: /* Text */ - break; - } - break; - case 5: /* Print */ - break; - case 6: /* New window */ - browser_window_create(current_gui->bw->current_content->url, - current_gui->bw, 0); - break; - case 7: /* Page source */ - ro_gui_view_source(c); - break; - } - break; - case MENU_OBJECT: - if (!gui_menu_object_box) - break; - switch (selection->items[1]) { - case 0: /* Info */ - break; - case 1: /* Save */ - break; - case 2: /* Export */ - break; - case 3: /* Save Link */ - switch (selection->items[2]) { - case 0: /* URI */ - break; - case 1: /* URL */ - break; - case 2: /* Text */ - break; - } - break; - case 4: /* Reload */ - ro_gui_menu_object_reload(); - break; - } - break; - case MENU_SELECTION: - switch (selection->items[1]) { - case 0: /* Copy to clipboard */ - ro_gui_copy_selection(current_gui); - break; - case 1: /* Select all */ - break; - case 2: /* Clear */ - break; - } - break; - case MENU_NAVIGATE: - switch (selection->items[1]) { - case 0: /* Home */ - if (option_homepage_url && option_homepage_url[0]) { - browser_window_go(current_gui->bw, option_homepage_url, 0); - } else { - snprintf(url, sizeof url, - "file:/<NetSurf$Dir>/Docs/intro_%s", - option_language); - browser_window_go(current_gui->bw, url, 0); - } - break; - case 1: /* Back */ - history_back(current_gui->bw, - current_gui->bw->history); - ro_gui_prepare_navigate(current_gui); - break; - case 2: /* Forward */ - history_forward(current_gui->bw, - current_gui->bw->history); - ro_gui_prepare_navigate(current_gui); - break; - case 3: /* Reload */ - browser_window_reload(current_gui->bw, false); - break; - case 4: /* Stop */ - browser_window_stop(current_gui->bw); - break; - } - break; - case MENU_VIEW: - switch (selection->items[1]) { - case 0: /* Scale view */ - ro_gui_menu_prepare_scale(); - ro_gui_dialog_open_persistant(current_gui->window, dialog_zoom, false); - break; - case 1: /* Images -> */ - switch (selection->items[2]) { - case 0: - break; - case 1: - current_gui->option.background_images = - !current_gui->option.background_images; - break; - } - ro_gui_menu_prepare_images(); - gui_window_redraw_window(current_gui); - break; - case 2: /* Toolbars-> */ - ro_gui_menu_toolbar_submenu_selection(selection->items[2]); - break; - case 3: /* Render -> */ - switch (selection->items[2]) { - case 0: - current_gui->option.background_blending = - !current_gui->option.background_blending; - gui_window_redraw_window(current_gui); - break; - case 1: - current_gui->option.buffer_animations = - !current_gui->option.buffer_animations; - break; - case 2: - current_gui->option.buffer_everything = - !current_gui->option.buffer_everything; - break; - } - ro_gui_menu_prepare_render(); - break; - case 4: /* Make default */ - ro_gui_window_default_options(current_gui->bw); - ro_gui_save_options(); - break; - } - break; - case MENU_UTILITIES: - switch (selection->items[1]) { - case 0: /* Hotlist -> */ - switch (selection->items[2]) { - case 0: /* Add to hotlist */ - node = tree_create_URL_node(hotlist_tree->root, - messages_get(current_gui->title), - current_gui->bw->current_content->url, - ro_content_filetype(current_gui->bw->current_content), - time(NULL), -1, 0); - tree_redraw_area(hotlist_tree, node->box.x - NODE_INSTEP, 0, - NODE_INSTEP, 16384); - tree_handle_node_changed(hotlist_tree, node, false, true); - ro_gui_tree_scroll_visible(hotlist_tree, &node->data); - break; - case -1: - case 1: /* Show hotlist */ - ro_gui_hotlist_show(); - break; - } - break; - case 1: /* History -> */ - switch (selection->items[2]) { - case -1: - case 0: /* Local history */ - ro_gui_history_open(current_gui->bw, - current_gui->bw->history, false); - break; - case 1: /* Global history */ - ro_gui_global_history_show(); - break; - } - break; - case 2: /* Find Text -> */ -#ifdef WITH_SEARCH - ro_gui_search_open(current_gui, 0, 0, false, true); -#endif - break; - case 3: /* Window -> */ - switch (selection->items[2]) { - case 0: - ro_gui_screen_size(&option_window_screen_width, - &option_window_screen_height); - state.w = current_gui->window; - error = xwimp_get_window_state(&state); - if (error) { - LOG(("xwimp_get_window_state: 0x%x: %s", - error->errnum, error->errmess)); - warn_user("WimpError", error->errmess); - } - option_window_x = state.visible.x0; - option_window_y = state.visible.y0; - option_window_width = state.visible.x1 - state.visible.x0; - option_window_height = state.visible.y1 - state.visible.y0; - break; - case 1: - option_window_stagger = !option_window_stagger; - break; - case 2: - option_window_size_clone = !option_window_size_clone; - break; - case 3: - option_window_screen_width = 0; - option_window_screen_height = 0; - break; - } - if (selection->items[2] >= 0) - ro_gui_save_options(); - ro_gui_menu_prepare_window(); - break; - } - break; - case MENU_HELP: - switch (selection->items[1]) { - case -1: /* No sub-item */ - case 0: /* Contents */ - ro_gui_open_help_page("docs"); - break; - case 1: /* User guide -> */ - ro_gui_open_help_page("guide"); - break; - case 2: /* User information */ - ro_gui_open_help_page("info"); - break; - case 3: /* About NetSurf */ - browser_window_create("file:/" - "<NetSurf$Dir>/Docs/about", 0, 0); - break; - case 4: /* Interactive help */ - xos_cli("Filer_Run Resources:$.Apps.!Help"); - ro_gui_menu_prepare_help(true); - break; - } - break; - } - } else if (current_menu == proxyauth_menu) { - ro_gui_dialog_proxyauth_menu_selection(selection->items[0]); - } else if (current_menu == image_quality_menu) { - ro_gui_dialog_image_menu_selection(selection->items[0]); - } else if (current_menu == languages_menu) { - ro_gui_dialog_languages_menu_selection(languages_menu-> - entries[selection->items[0]]. - data.indirected_text.text); - } else if (current_menu == font_menu) { - ro_gui_dialog_font_menu_selection(selection->items[0]); + error = xwimp_create_menu(wimp_CLOSE_MENU, 0, 0); + if (error) { + LOG(("xwimp_create_menu: 0x%x: %s", + error->errnum, error->errmess)); + warn_user("MenuError", error->errmess); } - if (pointer.buttons == wimp_CLICK_ADJUST) { - if (current_menu == gui_form_select_menu) - gui_create_form_select_menu(current_gui->bw, - gui_form_select_control); - else - ro_gui_create_menu(current_menu, - current_menu_x, current_menu_y, - current_gui); - } else { - if (current_menu == hotlist_menu) - ro_gui_hotlist_menu_closed(); - else if (current_menu == global_history_menu) - ro_gui_global_history_menu_closed(); - current_menu = NULL; - current_gui = NULL; - } -} + if (!current_menu) + return; + ro_gui_menu_get_window_details(current_menu_window, &g, &bw, &c, &t, &tree); -/** - * Handle a selection for a toolbar submenu - */ -void ro_gui_menu_toolbar_submenu_selection(int index) { - int height; + current_menu = NULL; + current_menu_window = NULL; + current_menu_open = false; - if ((index < 0) || (!current_toolbar)) - return; - switch (index) { - case 0: - current_toolbar->display_buttons = !current_toolbar->display_buttons; - break; - case 1: - current_toolbar->display_url = !current_toolbar->display_url; - break; - case 2: - current_toolbar->display_throbber = !current_toolbar->display_throbber; - break; - case 3: - current_toolbar->display_status = !current_toolbar->display_status; - break; - } - ro_gui_menu_prepare_toolbars(current_toolbar); - current_toolbar->reformat_buttons = true; - height = current_toolbar->height; - ro_gui_theme_process_toolbar(current_toolbar, -1); - if ((index == 1) && (current_toolbar->display_url)) - ro_gui_set_caret_first(current_toolbar->toolbar_handle); - if (current_toolbar->type == THEME_BROWSER_TOOLBAR) { - if ((height != current_toolbar->height) && (current_gui)) - ro_gui_window_update_dimensions(current_gui, - height - current_toolbar->height); - } else if (current_toolbar->type == THEME_HOTLIST_TOOLBAR) { - tree_resized(hotlist_tree); - xwimp_force_redraw((wimp_w)hotlist_tree->handle, 0,-16384, 16384, 16384); - } else if (current_toolbar->type == THEME_HISTORY_TOOLBAR) { - tree_resized(global_history_tree); - xwimp_force_redraw((wimp_w)global_history_tree->handle, 0,-16384, 16384, 16384); - } + if (tree) + ro_gui_tree_menu_closed(tree); + } - /** - * Handle Message_MenuWarning. + * The content has changed, reset object references */ - -void ro_gui_menu_warning(wimp_message_menu_warning *warning) -{ - if (current_menu == browser_menu) - ro_gui_menu_browser_warning(warning); - else if (current_menu == hotlist_menu) - ro_gui_menu_hotlist_warning(warning); - else if (current_menu == global_history_menu) - ro_gui_menu_global_history_warning(warning); +void ro_gui_menu_objects_moved(void) { + gui_form_select_control = NULL; + current_menu_object_box = NULL; + + ro_gui_menu_prepare_action(0, BROWSER_OBJECT, false); + if (current_menu == gui_form_select_menu) + ro_gui_menu_closed(); } /** - * Handle Message_MenuWarning for the browser menu. + * Handle menu selection. */ +void ro_gui_menu_selection(wimp_selection *selection) { + int i, j; + wimp_menu_entry *menu_entry; + menu_action action; + wimp_pointer pointer; + struct gui_window *g = NULL; + wimp_menu *menu; + os_error *error; -void ro_gui_menu_browser_warning(wimp_message_menu_warning *warning) -{ - struct content *c; - struct box *box; - os_error *error = 0; - - c = current_gui->bw->current_content; - - switch (warning->selection.items[0]) { - case MENU_PAGE: /* Page -> */ - switch (warning->selection.items[1]) { - case 0: /* Page info */ - ro_gui_menu_prepare_pageinfo(); - error = xwimp_create_sub_menu( - (wimp_menu *) dialog_pageinfo, - warning->pos.x, warning->pos.y); - break; - - case 1: /* Save */ - ro_gui_save_open(GUI_SAVE_SOURCE, c, true, - warning->pos.x, warning->pos.y, 0, false); - break; - - case 2: /* Save complete */ - ro_gui_save_open(GUI_SAVE_COMPLETE, c, true, - warning->pos.x, warning->pos.y, 0, false); - break; - - case 3: /* Export as -> */ - switch (warning->selection.items[2]) { - case 0: /* Draw */ - ro_gui_save_open(GUI_SAVE_DRAW, c, true, - warning->pos.x, warning->pos.y, - 0, false); - break; - - case 1: /* Text */ - ro_gui_save_open(GUI_SAVE_TEXT, c, true, - warning->pos.x, warning->pos.y, - 0, false); - break; - } - break; - - case 4: /* Save Link */ - switch (warning->selection.items[2]) { - case 0: /* URI */ - ro_gui_save_open(GUI_SAVE_LINK_URI, c, true, - warning->pos.x, warning->pos.y, - 0, false); - break; - - case 1: /* URL */ - ro_gui_save_open(GUI_SAVE_LINK_URL, c, true, - warning->pos.x, warning->pos.y, - 0, false); - break; - - case 2: /* Text */ - ro_gui_save_open(GUI_SAVE_LINK_TEXT, c, true, - warning->pos.x, warning->pos.y, - 0, false); - break; - } - break; - - case 5: /* Print -> */ -#ifdef WITH_PRINT - ro_gui_print_open(current_gui, warning->pos.x, - warning->pos.y, true, false); -#endif - break; - } - break; - - case MENU_OBJECT: /* Object -> */ - /** \todo this is really dumb, the object should be the one - * that the user clicked menu over, not the one that happens to - * be under the menu now */ - box = gui_menu_object_box; - if (!box) - break; - - switch (warning->selection.items[1]) { - case 0: /* Object info */ - ro_gui_menu_objectinfo(warning); - return; - - case 1: /* Save */ - ro_gui_save_open(GUI_SAVE_OBJECT_ORIG, box->object, - true, - warning->pos.x, warning->pos.y, 0, false); - break; - - case 2: /* Export */ - switch (warning->selection.items[2]) { - case 0: /* Sprite */ - ro_gui_save_open(GUI_SAVE_OBJECT_NATIVE, - box->object, true, - warning->pos.x, warning->pos.y, - 0, false); - break; - } - break; - - case 3: /* Save Link */ - switch (warning->selection.items[2]) { - case 0: /* URI */ - ro_gui_save_open(GUI_SAVE_LINK_URI, - box->object, true, - warning->pos.x, warning->pos.y, - 0, false); - break; - - case 1: /* URL */ - ro_gui_save_open(GUI_SAVE_LINK_URL, - box->object, true, - warning->pos.x, warning->pos.y, - 0, false); - break; + assert(current_menu); + assert(current_menu_window); - case 2: /* Text */ - ro_gui_save_open(GUI_SAVE_LINK_TEXT, - box->object, true, - warning->pos.x, warning->pos.y, - 0, false); - break; - } - break; - } - break; - - case MENU_NAVIGATE: /* Navigate -> */ - ro_gui_prepare_navigate(current_gui); - error = xwimp_create_sub_menu(browser_navigate_menu, - warning->pos.x, warning->pos.y); - break; - - case MENU_VIEW: /* View -> */ - switch (warning->selection.items[1]) { - case -1: /* View-> */ - ro_gui_menu_prepare_view(); - if (current_gui->toolbar) - view_menu.entries[2].icon_flags &= ~wimp_ICON_SHADED; - else - view_menu.entries[2].icon_flags |= wimp_ICON_SHADED; - error = xwimp_create_sub_menu((wimp_menu *) browser_view_menu, - warning->pos.x, warning->pos.y); - break; - case 0: /* Scale view -> */ - ro_gui_menu_prepare_scale(); - error = xwimp_create_sub_menu((wimp_menu *) dialog_zoom, - warning->pos.x, warning->pos.y); - break; + /* get the menu entry and associated action */ + menu_entry = ¤t_menu->entries[selection->items[0]]; + for (i = 1; selection->items[i] != -1; i++) + menu_entry = &menu_entry->sub_menu-> + entries[selection->items[i]]; + action = ro_gui_menu_find_action(current_menu, menu_entry); - case 1: /* Images -> */ - ro_gui_menu_prepare_images(); - error = xwimp_create_sub_menu(browser_image_menu, - warning->pos.x, warning->pos.y); - break; - case 2: /* Toolbars -> */ - ro_gui_menu_prepare_toolbars(current_gui->toolbar); - error = xwimp_create_sub_menu(browser_toolbar_menu, - warning->pos.x, warning->pos.y); - break; - case 3: /* Render -> */ - ro_gui_menu_prepare_render(); - error = xwimp_create_sub_menu(browser_render_menu, - warning->pos.x, warning->pos.y); - break; - } - break; + /* perform menu action */ + if (action != NO_ACTION) + ro_gui_menu_handle_action(current_menu_window, action, false); - case MENU_UTILITIES: - switch (warning->selection.items[1]) { - case 0: /* Hotlist -> */ - case 1: /* History -> */ - break; - case 2: /* Find text -> */ -#ifdef WITH_SEARCH - ro_gui_search_open(current_gui, - warning->pos.x, - warning->pos.y, - true, - false); - break; -#endif - case 3: /* Window -> */ - ro_gui_menu_prepare_window(); - error = xwimp_create_sub_menu(browser_window_menu, - warning->pos.x, warning->pos.y); - break; - } - break; - case MENU_HELP: /* Help -> */ - ro_gui_menu_prepare_help(false); - error = xwimp_create_sub_menu(browser_help_menu, - warning->pos.x, warning->pos.y); + /* perform non-automated actions */ + if (current_menu == url_suggest_menu) { + g = ro_gui_toolbar_lookup(current_menu_window); + assert(g); + browser_window_go(g->bw, + url_suggest_menu->entries[selection->items[0]]. + data.indirected_text.text, 0); + global_history_add_recent(url_suggest_menu-> + entries[selection->items[0]]. + data.indirected_text.text); + } else if (current_menu == proxy_auth_menu) { + ro_gui_dialog_proxyauth_menu_selection(selection->items[0]); + } else if (current_menu == image_quality_menu) { + ro_gui_dialog_image_menu_selection(selection->items[0]); + } else if (current_menu == languages_menu) { + ro_gui_dialog_languages_menu_selection(languages_menu-> + entries[selection->items[0]]. + data.indirected_text.text); + } else if (current_menu == font_menu) { + ro_gui_dialog_font_menu_selection(selection->items[0]); + } else if ((current_menu == gui_form_select_menu) && + (selection->items[0] >= 0)) { + g = ro_gui_window_lookup(current_menu_window); + assert(g); + browser_window_form_select(g->bw, + gui_form_select_control, + selection->items[0]); } + /* re-open the menu for Adjust clicks */ + error = xwimp_get_pointer_info(&pointer); if (error) { - LOG(("xwimp_create_sub_menu: 0x%x: %s", + LOG(("xwimp_get_pointer_info: 0x%x: %s", error->errnum, error->errmess)); - warn_user("MenuError", error->errmess); + warn_user("WimpError", error->errmess); + ro_gui_menu_closed(); + return; } -} - - -/** - * Handle Message_MenuWarning for the hotlist menu. - */ -void ro_gui_menu_hotlist_warning(wimp_message_menu_warning *warning) -{ - os_error *error = NULL; - struct node *node; - - switch (warning->selection.items[0]) { - case 0: /* Hotlist-> */ - switch (warning->selection.items[1]) { - case 0: /* New-> */ - switch (warning->selection.items[2]) { - case 0: /* Folder */ - ro_gui_hotlist_prepare_folder_dialog(NULL); - error = xwimp_create_sub_menu( - (wimp_menu *) dialog_folder, - warning->pos.x, warning->pos.y); - break; - case 1: /* Entry */ - ro_gui_hotlist_prepare_entry_dialog(NULL); - error = xwimp_create_sub_menu( - (wimp_menu *) dialog_entry, - warning->pos.x, warning->pos.y); - break; - } - break; - case 1: /* Export-> */ - ro_gui_save_open(GUI_SAVE_HOTLIST_EXPORT_HTML, 0, true, - warning->pos.x, warning->pos.y, 0, false); - break; - case 4: /* Toolbars -> */ - ro_gui_menu_prepare_toolbars(hotlist_tree->toolbar); - error = xwimp_create_sub_menu(browser_toolbar_menu, - warning->pos.x, warning->pos.y); - break; - } - break; - case 1: /* Selection-> */ - switch (warning->selection.items[1]) { - case -1: /* Root */ - ro_gui_menu_prepare_hotlist(); - error = xwimp_create_sub_menu(hotlist_select_menu, - warning->pos.x, warning->pos.y); - break; - case 0: /* Edit-> */ - node = tree_get_selected_node(hotlist_tree->root); - if (!node) - break; - if (node->folder) { - ro_gui_hotlist_prepare_folder_dialog(node); - error = xwimp_create_sub_menu( - (wimp_menu *) dialog_folder, - warning->pos.x, warning->pos.y); - } else { - ro_gui_hotlist_prepare_entry_dialog(node); - error = xwimp_create_sub_menu( - (wimp_menu *) dialog_entry, - warning->pos.x, warning->pos.y); - } - break; - } - break; + if (pointer.buttons != wimp_CLICK_ADJUST) { + ro_gui_menu_closed(); + return; } - if (error) { - LOG(("xwimp_create_sub_menu: 0x%x: %s", - error->errnum, error->errmess)); - warn_user("MenuError", error->errmess); - } + /* re-prepare all the visible enties */ + i = 0; + menu = current_menu; + do { + j = 0; + do { + action = ro_gui_menu_find_action(current_menu, + &menu->entries[j]); + if (action != NO_ACTION) + ro_gui_menu_prepare_action(current_menu_window, + action, false); + } while (!(menu->entries[j++].menu_flags & wimp_MENU_LAST)); + j = selection->items[i++]; + if (j != -1) + menu = menu->entries[j].sub_menu; + } while (j != -1); + + if (current_menu == gui_form_select_menu) + gui_create_form_select_menu(g->bw, + gui_form_select_control); + else + ro_gui_menu_create(current_menu, 0, 0, current_menu_window); } /** - * Handle Message_MenuWarning for the global history menu. + * Handle Message_MenuWarning. */ +void ro_gui_menu_warning(wimp_message_menu_warning *warning) { + int i; + menu_action action; + wimp_menu_entry *menu_entry; + wimp_menu *sub_menu; + os_error *error; + int menu_check; -void ro_gui_menu_global_history_warning(wimp_message_menu_warning *warning) -{ - os_error *error = NULL; - - switch (warning->selection.items[0]) { - case 0: /* History-> */ - switch (warning->selection.items[1]) { - case 0: /* Export-> */ - ro_gui_save_open(GUI_SAVE_HISTORY_EXPORT_HTML, 0, true, - warning->pos.x, warning->pos.y, 0, false); - break; - case 3: /* Toolbars -> */ - ro_gui_menu_prepare_toolbars(hotlist_tree->toolbar); - error = xwimp_create_sub_menu(browser_toolbar_menu, - warning->pos.x, warning->pos.y); - break; - } - break; - case 1: /* Selection-> */ - switch (warning->selection.items[1]) { - case -1: /* Root */ - ro_gui_menu_prepare_global_history(); - error = xwimp_create_sub_menu(history_select_menu, - warning->pos.x, warning->pos.y); - break; - } - break; + assert(current_menu); + assert(current_menu_window); + + /* get the sub-menu of the warning */ + if (warning->selection.items[0] == -1) + return; + menu_entry = ¤t_menu->entries[warning->selection.items[0]]; + for (i = 1; warning->selection.items[i] != -1; i++) + menu_entry = &menu_entry->sub_menu-> + entries[warning->selection.items[i]]; + + /* the values given in PRM 3-157 for how to check menus/windows are + * incorrect so we use a hack of checking if the sub-menu is within + * 256KB of its parent */ + menu_check = abs((int)menu_entry->sub_menu - (int)menu_entry); + if (menu_check < 0x40000) { + sub_menu = menu_entry->sub_menu; + i = 0; + do { + action = ro_gui_menu_find_action(current_menu, + &sub_menu->entries[i]); + if (action != NO_ACTION) + ro_gui_menu_prepare_action(current_menu_window, + action, false); + } while (!(sub_menu->entries[i++].menu_flags & wimp_MENU_LAST)); + } else { + action = ro_gui_menu_find_action(current_menu, menu_entry); + if (action != NO_ACTION) + ro_gui_menu_prepare_action(current_menu_window, + action, true); + /* remove the close icon */ + ro_gui_wimp_update_window_furniture((wimp_w)menu_entry->sub_menu, + wimp_WINDOW_CLOSE_ICON | wimp_WINDOW_BACK_ICON, 0); } + /* open the sub-menu */ + error = xwimp_create_sub_menu(menu_entry->sub_menu, + warning->pos.x, warning->pos.y); if (error) { LOG(("xwimp_create_sub_menu: 0x%x: %s", error->errnum, error->errmess)); @@ -1605,459 +695,120 @@ void ro_gui_menu_global_history_warning(wimp_message_menu_warning *warning) } } -/** - * Update navigate menu status and toolbar icons. - * - * /param gui_window the gui_window to update - */ -void ro_gui_prepare_navigate(struct gui_window *gui) { - struct browser_window *bw; - struct history *h; - struct content *c; - struct toolbar *t; - bool update_menu = ((current_menu == browser_menu) && (current_gui == gui)); - int menu_changed = 0; - unsigned int i; - int suggestions; - wimp_selection selection; - - if (!gui) { - LOG(("Attempt to update a NULL gui_window icon status")); - return; - } - - /* Get the data we need to work with - */ - bw = gui->bw; - h = bw->history; - c = bw->current_content; - t = gui->toolbar; - - /* Get the initial menu state to check for changes - */ - if (update_menu) { - for (i = 0; i < 4; i++) { - if (browser_navigate_menu->entries[i].icon_flags & wimp_ICON_SHADED) { - menu_changed += (1 << i); - } - } - if (menu.entries[0].icon_flags & wimp_ICON_SHADED) menu_changed += (1 << 4); - } - - /* Update the back/forwards icons/buttons - */ - if (update_menu) { - if (history_back_available(h)) { - browser_navigate_menu->entries[1].icon_flags &= ~wimp_ICON_SHADED; - } else { - browser_navigate_menu->entries[1].icon_flags |= wimp_ICON_SHADED; - } - if (history_forward_available(h)) { - browser_navigate_menu->entries[2].icon_flags &= ~wimp_ICON_SHADED; - } else { - browser_navigate_menu->entries[2].icon_flags |= wimp_ICON_SHADED; - } - } - if (t) { - if ((h) && (!t->editor)) { - ro_gui_set_icon_shaded_state(t->toolbar_handle, ICON_TOOLBAR_BACK, - !history_back_available(h)); - ro_gui_set_icon_shaded_state(t->toolbar_handle, ICON_TOOLBAR_FORWARD, - !history_forward_available(h)); - ro_gui_set_icon_shaded_state(t->toolbar_handle, ICON_TOOLBAR_HISTORY, - !(c || history_back_available(h) || history_forward_available(h))); - } else { - ro_gui_set_icon_shaded_state(t->toolbar_handle, ICON_TOOLBAR_BACK, !t->editor); - ro_gui_set_icon_shaded_state(t->toolbar_handle, ICON_TOOLBAR_FORWARD, !t->editor); - ro_gui_set_icon_shaded_state(t->toolbar_handle, ICON_TOOLBAR_HISTORY, !t->editor); - } - ro_gui_set_icon_shaded_state(t->toolbar_handle, ICON_TOOLBAR_BOOKMARK, (!hotlist_tree && !t->editor)); - global_history_get_recent(&suggestions); - ro_gui_set_icon_shaded_state(t->toolbar_handle, ICON_TOOLBAR_SUGGEST, (suggestions <= 0)); - } - - /* Update the stop/refresh icons/buttons - */ - if (bw->current_content && !bw->loading_content) { - if (update_menu) browser_navigate_menu->entries[3].icon_flags &= ~wimp_ICON_SHADED; - if (t) ro_gui_set_icon_shaded_state(t->toolbar_handle, ICON_TOOLBAR_RELOAD, false); - } else { - if (update_menu) browser_navigate_menu->entries[3].icon_flags |= wimp_ICON_SHADED; - if (t) ro_gui_set_icon_shaded_state(t->toolbar_handle, ICON_TOOLBAR_RELOAD, !t->editor); - } - if (bw->loading_content || (bw->current_content && - bw->current_content->status != CONTENT_STATUS_DONE)) { - if (update_menu) browser_navigate_menu->entries[4].icon_flags &= ~wimp_ICON_SHADED; - if (t) ro_gui_set_icon_shaded_state(t->toolbar_handle, ICON_TOOLBAR_STOP, false); - } else { - if (update_menu) browser_navigate_menu->entries[4].icon_flags |= wimp_ICON_SHADED; - if (t) ro_gui_set_icon_shaded_state(t->toolbar_handle, ICON_TOOLBAR_STOP, !t->editor); - } - - /* Set the scale view icon - */ - if (update_menu) { - if (c) - menu.entries[0].icon_flags &= ~wimp_ICON_SHADED; - else - menu.entries[0].icon_flags |= wimp_ICON_SHADED; - } - if (t) { - ro_gui_set_icon_shaded_state(t->toolbar_handle, ICON_TOOLBAR_SEARCH, (!c && !t->editor)); - ro_gui_set_icon_shaded_state(t->toolbar_handle, ICON_TOOLBAR_SCALE, (!c && !t->editor)); - ro_gui_set_icon_shaded_state(t->toolbar_handle, ICON_TOOLBAR_SAVE, (!c && !t->editor)); - ro_gui_set_icon_shaded_state(t->toolbar_handle, ICON_TOOLBAR_PRINT, (!c && !t->editor)); - } - - /* Check if we've changed our menu state - */ - if (update_menu) { - for (i = 0; i < 4; i++) { - if (browser_navigate_menu->entries[i].icon_flags & wimp_ICON_SHADED) { - menu_changed -= (1 << i); - } - } - if (menu.entries[0].icon_flags & wimp_ICON_SHADED) menu_changed -= (1 << 4); - - /* Re-open the submenu - */ - if (menu_changed != 0) { - if (!xwimp_get_menu_state((wimp_menu_state_flags)0, &selection, - (wimp_w)0, (wimp_i)0)) { - if (selection.items[0] == MENU_NAVIGATE) { - ro_gui_create_menu(current_menu, 0, 0, current_gui); - } - - } - } - } -} - /** - * Update image menu status + * Refresh a toolbar after it has been updated + * + * \param toolbar the toolbar to update */ -static void ro_gui_menu_prepare_images(void) { - if (current_menu != browser_menu) return; - - /* Set the options according to the local values - */ - browser_image_menu->entries[1].menu_flags &= ~wimp_MENU_TICKED; - if (current_gui->option.background_images) browser_image_menu->entries[1].menu_flags |= wimp_MENU_TICKED; - browser_image_menu->entries[2].menu_flags &= ~wimp_MENU_TICKED; -} +void ro_gui_menu_refresh_toolbar(struct toolbar *toolbar) { + int height; + assert(toolbar); -/** - * Update render menu status - */ -static void ro_gui_menu_prepare_render(void) { - if (current_menu != browser_menu) return; - - /* Set the options according to the local values - */ - browser_render_menu->entries[1].menu_flags &= ~wimp_MENU_TICKED; - browser_render_menu->entries[1].icon_flags &= ~wimp_ICON_SHADED; - browser_render_menu->entries[2].menu_flags &= ~wimp_MENU_TICKED; - if (current_gui->option.background_blending) { - browser_render_menu->entries[0].menu_flags |= wimp_MENU_TICKED; - } else { - browser_render_menu->entries[0].menu_flags &= ~wimp_MENU_TICKED; - } - if (current_gui->option.buffer_everything) { - browser_render_menu->entries[1].icon_flags |= wimp_ICON_SHADED; - browser_render_menu->entries[1].menu_flags |= wimp_MENU_TICKED; - browser_render_menu->entries[2].menu_flags |= wimp_MENU_TICKED; - } else { - browser_render_menu->entries[1].icon_flags &= ~wimp_ICON_SHADED; - browser_render_menu->entries[2].menu_flags &= ~wimp_MENU_TICKED; - if (current_gui->option.buffer_animations) { - browser_render_menu->entries[1].menu_flags |= wimp_MENU_TICKED; - } else { - browser_render_menu->entries[1].menu_flags &= ~wimp_MENU_TICKED; - } + toolbar->reformat_buttons = true; + height = toolbar->height; + ro_gui_theme_process_toolbar(toolbar, -1); + if (toolbar->type == THEME_BROWSER_TOOLBAR) { + ro_gui_window_update_dimensions( + ro_gui_window_lookup(current_menu_window), + height - toolbar->height); + } else if (toolbar->type == THEME_HOTLIST_TOOLBAR) { + tree_resized(hotlist_tree); + xwimp_force_redraw((wimp_w)hotlist_tree->handle, + 0,-16384, 16384, 16384); + } else if (toolbar->type == THEME_HISTORY_TOOLBAR) { + tree_resized(global_history_tree); + xwimp_force_redraw((wimp_w)global_history_tree->handle, + 0,-16384, 16384, 16384); } } /** - * Update window menu status + * Builds the URL suggestion menu */ -static void ro_gui_menu_prepare_window(void) { - if (current_menu != browser_menu) return; - - /* Check if we can reset - */ - if ((option_window_screen_width != 0) && (option_window_screen_height != 0)) { - browser_window_menu->entries[1].icon_flags &= ~wimp_ICON_SHADED; - browser_window_menu->entries[3].icon_flags &= ~wimp_ICON_SHADED; - - /* Check if we are staggered - */ - if (option_window_stagger) { - browser_window_menu->entries[1].menu_flags |= wimp_MENU_TICKED; - } else { - browser_window_menu->entries[1].menu_flags &= ~wimp_MENU_TICKED; - } - } else { - browser_window_menu->entries[1].menu_flags |= wimp_MENU_TICKED; - browser_window_menu->entries[1].icon_flags |= wimp_ICON_SHADED; - browser_window_menu->entries[3].icon_flags |= wimp_ICON_SHADED; - } - - /* Set if we are cloing the window size - */ - if (option_window_size_clone) { - browser_window_menu->entries[2].menu_flags |= wimp_MENU_TICKED; - } else { - browser_window_menu->entries[2].menu_flags &= ~wimp_MENU_TICKED; - } -} +bool ro_gui_menu_prepare_url_suggest(void) { + char **suggest_text; + int suggestions; + int i; + suggest_text = global_history_get_recent(&suggestions); + if (suggestions < 1) + return false; -/** - * Update toolbar menu status - */ -static void ro_gui_menu_prepare_toolbars(struct toolbar *toolbar) { - int index; - - /* Set our ticks, or shade everything if there's no toolbar - */ - if (toolbar) { - for (index = 0; index < 4; index++) { - browser_toolbar_menu->entries[index].icon_flags &= ~wimp_ICON_SHADED; - browser_toolbar_menu->entries[index].menu_flags &= ~wimp_MENU_TICKED; - } - if (toolbar->editor) { - browser_toolbar_menu->entries[0].icon_flags |= wimp_ICON_SHADED; - browser_toolbar_menu->entries[0].menu_flags |= wimp_MENU_TICKED; - } - if ((toolbar->descriptor) && (toolbar->descriptor->theme)) { - if (toolbar->display_buttons) browser_toolbar_menu->entries[0].menu_flags |= wimp_MENU_TICKED; - if (toolbar->display_throbber) browser_toolbar_menu->entries[2].menu_flags |= wimp_MENU_TICKED; - } else { - for (index = 0; index < 3; index += 2) { - browser_toolbar_menu->entries[index].icon_flags |= wimp_ICON_SHADED; - browser_toolbar_menu->entries[index].menu_flags &= ~wimp_MENU_TICKED; - } - } - if (toolbar->display_url) - browser_toolbar_menu->entries[1].menu_flags |= wimp_MENU_TICKED; - if (toolbar->display_status) - browser_toolbar_menu->entries[3].menu_flags |= wimp_MENU_TICKED; - if (toolbar->type == THEME_BROWSER_TOOLBAR) - browser_toolbar_menu->entries[0].menu_flags &= ~wimp_MENU_LAST; - else - browser_toolbar_menu->entries[0].menu_flags |= wimp_MENU_LAST; - } else { - for (index = 0; index < 4; index++) { - browser_toolbar_menu->entries[index].icon_flags |= wimp_ICON_SHADED; - browser_toolbar_menu->entries[index].menu_flags &= ~wimp_MENU_TICKED; - } - browser_toolbar_menu->entries[0].menu_flags &= ~wimp_MENU_LAST; + for (i = 0; i < suggestions; i++) { + url_suggest_menu->entries[i].menu_flags = 0; + url_suggest_menu->entries[i].sub_menu = wimp_NO_SUB_MENU; + url_suggest_menu->entries[i].icon_flags = + DEFAULT_FLAGS | wimp_ICON_INDIRECTED; + url_suggest_menu->entries[i].data.indirected_text.text = + suggest_text[i]; + url_suggest_menu->entries[i].data.indirected_text.validation = + (char *)-1; + url_suggest_menu->entries[i].data.indirected_text.size = + strlen(suggest_text[i]) + 1; } -} - -/** - * Update scale to current document value - */ -void ro_gui_menu_prepare_scale(void) { - char scale_buffer[8]; - sprintf(scale_buffer, "%.0f", current_gui->option.scale * 100); - ro_gui_set_icon_string(dialog_zoom, ICON_ZOOM_VALUE, scale_buffer); - ro_gui_current_zoom_gui = current_gui; + url_suggest_menu->entries[0].menu_flags |= wimp_MENU_TITLE_INDIRECTED; + url_suggest_menu->entries[suggestions - 1].menu_flags |= wimp_MENU_LAST; + return true; } /** - * Update hotlist menu (all of) + * Update navigate menu status and toolbar icons. + * + * /param gui the gui_window to update */ -void ro_gui_menu_prepare_hotlist(void) { - os_error *error; - bool reopen = false; - bool selection = false; - struct node *single = NULL; - struct toolbar *hotlist_toolbar; - - if (!hotlist_tree) - return; - hotlist_toolbar = hotlist_tree->toolbar; - - if (hotlist_tree->root->child) { - single = tree_get_selected_node(hotlist_tree->root->child); - selection = tree_has_selection(hotlist_tree->root->child); - hotlist_menu->entries[2].icon_flags &= ~wimp_ICON_SHADED; - hotlist_file_menu->entries[2].icon_flags &= ~wimp_ICON_SHADED; - hotlist_file_menu->entries[3].icon_flags &= ~wimp_ICON_SHADED; - } else { - hotlist_menu->entries[2].icon_flags |= wimp_ICON_SHADED; - hotlist_file_menu->entries[2].icon_flags |= wimp_ICON_SHADED; - hotlist_file_menu->entries[3].icon_flags &= wimp_ICON_SHADED; - } - - if (hotlist_toolbar) { - if (hotlist_toolbar->editor) { - ro_gui_set_icon_shaded_state(hotlist_toolbar->toolbar_handle, - ICON_TOOLBAR_OPEN, false); - ro_gui_set_icon_shaded_state(hotlist_toolbar->toolbar_handle, - ICON_TOOLBAR_EXPAND, false); - ro_gui_set_icon_shaded_state(hotlist_toolbar->toolbar_handle, - ICON_TOOLBAR_DELETE, false); - ro_gui_set_icon_shaded_state(hotlist_toolbar->toolbar_handle, - ICON_TOOLBAR_LAUNCH, false); - } else { - ro_gui_set_icon_shaded_state(hotlist_toolbar->toolbar_handle, - ICON_TOOLBAR_OPEN, !hotlist_tree->root->child); - ro_gui_set_icon_shaded_state(hotlist_toolbar->toolbar_handle, - ICON_TOOLBAR_EXPAND, !hotlist_tree->root->child); - ro_gui_set_icon_shaded_state(hotlist_toolbar->toolbar_handle, - ICON_TOOLBAR_DELETE, !selection); - ro_gui_set_icon_shaded_state(hotlist_toolbar->toolbar_handle, - ICON_TOOLBAR_LAUNCH, !selection); - } - } - - if (selection) { - reopen |= (hotlist_menu->entries[1].icon_flags & wimp_ICON_SHADED); - hotlist_menu->entries[1].icon_flags &= ~wimp_ICON_SHADED; - hotlist_menu->entries[3].icon_flags &= ~wimp_ICON_SHADED; - } else { - reopen |= !(hotlist_menu->entries[1].icon_flags & wimp_ICON_SHADED); - hotlist_menu->entries[1].icon_flags |= wimp_ICON_SHADED; - hotlist_menu->entries[3].icon_flags |= wimp_ICON_SHADED; - } - - if (single) { - reopen |= (hotlist_select_menu->entries[0].icon_flags & wimp_ICON_SHADED); - hotlist_select_menu->entries[0].icon_flags &= ~wimp_ICON_SHADED; - } else { - reopen |= !(hotlist_select_menu->entries[0].icon_flags & wimp_ICON_SHADED); - hotlist_select_menu->entries[0].icon_flags |= wimp_ICON_SHADED; - } +void ro_gui_prepare_navigate(struct gui_window *gui) { + int suggestions; - if ((reopen) && (current_menu == hotlist_menu)) { - error = xwimp_create_menu(hotlist_menu, 0, 0); - if (error) { - LOG(("xwimp_create_menu: 0x%x: %s", - error->errnum, error->errmess)); - warn_user("MenuError", error->errmess); - } + ro_gui_menu_prepare_action(gui->window, HOTLIST_SHOW, false); + ro_gui_menu_prepare_action(gui->window, BROWSER_NAVIGATE_STOP, false); + ro_gui_menu_prepare_action(gui->window, BROWSER_NAVIGATE_RELOAD_ALL, false); + ro_gui_menu_prepare_action(gui->window, BROWSER_NAVIGATE_BACK, false); + ro_gui_menu_prepare_action(gui->window, BROWSER_NAVIGATE_FORWARD, false); + ro_gui_menu_prepare_action(gui->window, HOTLIST_SHOW, false); + ro_gui_menu_prepare_action(gui->window, BROWSER_SAVE, false); + ro_gui_menu_prepare_action(gui->window, BROWSER_PRINT, false); + ro_gui_menu_prepare_action(gui->window, BROWSER_SCALE_VIEW, false); + ro_gui_menu_prepare_action(gui->window, BROWSER_FIND_TEXT, false); + + if (gui->toolbar) { + global_history_get_recent(&suggestions); + ro_gui_set_icon_shaded_state(gui->toolbar->toolbar_handle, + ICON_TOOLBAR_SUGGEST, (suggestions <= 0)); } } /** - * Update global history menu (all of) + * Prepare the image quality menu for use + * + * \param tinct_options the options to set the menu status for */ -void ro_gui_menu_prepare_global_history(void) { - os_error *error; - bool reopen = false; - bool selection = false; - struct toolbar *global_history_toolbar; - - if (!global_history_tree) - return; - global_history_toolbar = global_history_tree->toolbar; - - if (global_history_tree->root->child) { - selection = tree_has_selection(global_history_tree->root->child); - global_history_menu->entries[2].icon_flags &= ~wimp_ICON_SHADED; - history_file_menu->entries[1].icon_flags &= ~wimp_ICON_SHADED; - history_file_menu->entries[2].icon_flags &= ~wimp_ICON_SHADED; - } else { - global_history_menu->entries[2].icon_flags |= wimp_ICON_SHADED; - history_file_menu->entries[1].icon_flags |= wimp_ICON_SHADED; - history_file_menu->entries[2].icon_flags |= wimp_ICON_SHADED; - } - - if (global_history_toolbar) { - if (global_history_toolbar->editor) { - ro_gui_set_icon_shaded_state(global_history_toolbar->toolbar_handle, - ICON_TOOLBAR_OPEN, false); - ro_gui_set_icon_shaded_state(global_history_toolbar->toolbar_handle, - ICON_TOOLBAR_EXPAND, false); - ro_gui_set_icon_shaded_state(global_history_toolbar->toolbar_handle, - ICON_TOOLBAR_DELETE, false); - ro_gui_set_icon_shaded_state(global_history_toolbar->toolbar_handle, - ICON_TOOLBAR_LAUNCH, false); - } else { - ro_gui_set_icon_shaded_state(global_history_toolbar->toolbar_handle, - ICON_TOOLBAR_OPEN, !global_history_tree->root->child); - ro_gui_set_icon_shaded_state(global_history_toolbar->toolbar_handle, - ICON_TOOLBAR_EXPAND, !global_history_tree->root->child); - ro_gui_set_icon_shaded_state(global_history_toolbar->toolbar_handle, - ICON_TOOLBAR_DELETE, !selection); - ro_gui_set_icon_shaded_state(global_history_toolbar->toolbar_handle, - ICON_TOOLBAR_LAUNCH, !selection); - } - } - - if (selection) { - reopen |= (global_history_menu->entries[1].icon_flags & wimp_ICON_SHADED); - global_history_menu->entries[1].icon_flags &= ~wimp_ICON_SHADED; - global_history_menu->entries[3].icon_flags &= ~wimp_ICON_SHADED; - } else { - reopen |= !(global_history_menu->entries[1].icon_flags & wimp_ICON_SHADED); - global_history_menu->entries[1].icon_flags |= wimp_ICON_SHADED; - global_history_menu->entries[3].icon_flags |= wimp_ICON_SHADED; - } - - if ((reopen) && (current_menu == global_history_menu)) { - error = xwimp_create_menu(global_history_menu, 0, 0); - if (error) { - LOG(("xwimp_create_menu: 0x%x: %s", - error->errnum, error->errmess)); - warn_user("MenuError", error->errmess); - } - } +void ro_gui_menu_prepare_image_quality(unsigned int tinct_options) { + for (int i = 0; i < 4; i++) + image_quality_menu->entries[i].menu_flags &= ~wimp_MENU_TICKED; + if (tinct_options & tinct_USE_OS_SPRITE_OP) + image_quality_menu->entries[0].menu_flags |= wimp_MENU_TICKED; + else if (tinct_options & tinct_ERROR_DIFFUSE) + image_quality_menu->entries[3].menu_flags |= wimp_MENU_TICKED; + else if (tinct_options & tinct_DITHER) + image_quality_menu->entries[2].menu_flags |= wimp_MENU_TICKED; + else + image_quality_menu->entries[1].menu_flags |= wimp_MENU_TICKED; } /** - * Update the Interactive Help status + * Prepare the page info window for use * - * \parmam force force the status to be disabled + * \param g the gui_window to set the display icons for */ -void ro_gui_menu_prepare_help(int forced) { - if (ro_gui_interactive_help_available() || (forced)) { - browser_help_menu->entries[4].icon_flags |= wimp_ICON_SHADED; - } else { - browser_help_menu->entries[4].icon_flags &= ~wimp_ICON_SHADED; - } -} - -void ro_gui_menu_prepare_view(void) { - if (current_gui->toolbar) { - view_menu.entries[2].icon_flags &= ~wimp_ICON_SHADED; - } else { - view_menu.entries[2].icon_flags |= wimp_ICON_SHADED; - } - if ((current_gui->bw) && (current_gui->bw->current_content)) { - view_menu.entries[0].icon_flags &= ~wimp_ICON_SHADED; - } else { - view_menu.entries[0].icon_flags |= wimp_ICON_SHADED; - } -} - -void ro_gui_menu_prepare_image_quality(unsigned int tinct_options) { - for (int i = 0; i < 4; i++) - image_quality_menu->entries[i].menu_flags &= ~wimp_MENU_TICKED; - if (tinct_options & tinct_USE_OS_SPRITE_OP) { - image_quality_menu->entries[0].menu_flags |= wimp_MENU_TICKED; - } else if (tinct_options & tinct_ERROR_DIFFUSE) { - image_quality_menu->entries[3].menu_flags |= wimp_MENU_TICKED; - } else if (tinct_options & tinct_DITHER) { - image_quality_menu->entries[2].menu_flags |= wimp_MENU_TICKED; - } else { - image_quality_menu->entries[1].menu_flags |= wimp_MENU_TICKED; - } -} - - -void ro_gui_menu_prepare_pageinfo(void) -{ - struct content *c = current_gui->bw->current_content; +void ro_gui_menu_prepare_pageinfo(struct gui_window *g) { + struct content *c = g->bw->current_content; char icon_buf[20] = "file_xxx"; char enc_buf[40]; char enc_token[10] = "Encoding0"; @@ -2067,17 +818,18 @@ void ro_gui_menu_prepare_pageinfo(void) const char *enc = "-"; const char *mime = "-"; - if (c->title != 0) title = c->title; - if (c->url != 0) url = c->url; - if (c->mime_type != 0) mime = c->mime_type; + assert(c); - sprintf(icon_buf, "file_%x", ro_content_filetype(c)); + if (c->title) + title = c->title; + if (c->url) + url = c->url; + if (c->mime_type) + mime = c->mime_type; - /* Ensure the correct icon exists - */ - if (xwimpspriteop_read_sprite_info(icon_buf, 0, 0, 0, 0)) { + sprintf(icon_buf, "file_%x", ro_content_filetype(c)); + if (!ro_gui_wimp_sprite_exists(icon_buf)) sprintf(icon_buf, "file_xxx"); - } if (c->type == CONTENT_HTML) { if (c->data.html.encoding) { @@ -2099,45 +851,33 @@ void ro_gui_menu_prepare_pageinfo(void) } -void ro_gui_menu_objectinfo(wimp_message_menu_warning *warning) -{ +/** + * Prepare the object info window for use + * + * \param box the box to set the display icons for + */ +void ro_gui_menu_prepare_objectinfo(struct box *box) { char icon_buf[20] = "file_xxx"; const char *url = "-"; const char *target = "-"; const char *mime = "-"; - os_error *error; sprintf(icon_buf, "file_%.3x", - ro_content_filetype(gui_menu_object_box->object)); + ro_content_filetype(box->object)); if (!ro_gui_wimp_sprite_exists(icon_buf)) sprintf(icon_buf, "file_xxx"); - if (gui_menu_object_box->object->url) - url = gui_menu_object_box->object->url; - if (gui_menu_object_box->href) - target = gui_menu_object_box->href; - if (gui_menu_object_box->object->mime_type) - mime = gui_menu_object_box->object->mime_type; + if (box->object->url) + url = box->object->url; + if (box->href) + target = box->href; + if (box->object->mime_type) + mime = box->object->mime_type; ro_gui_set_icon_string(dialog_objinfo, ICON_OBJINFO_ICON, icon_buf); ro_gui_set_icon_string(dialog_objinfo, ICON_OBJINFO_URL, url); ro_gui_set_icon_string(dialog_objinfo, ICON_OBJINFO_TARGET, target); ro_gui_set_icon_string(dialog_objinfo, ICON_OBJINFO_TYPE, mime); - - error = xwimp_create_sub_menu((wimp_menu *) dialog_objinfo, - warning->pos.x, warning->pos.y); - if (error) { - LOG(("xwimp_create_sub_menu: 0x%x: %s", - error->errnum, error->errmess)); - warn_user("MenuError", error->errmess); - } -} - - -void ro_gui_menu_object_reload(void) -{ - gui_menu_object_box->object->fresh = false; - browser_window_reload(current_gui->bw, false); } @@ -2147,24 +887,21 @@ void ro_gui_menu_object_reload(void) * \param bw browser window containing form control * \param control form control of type GADGET_SELECT */ - void gui_create_form_select_menu(struct browser_window *bw, - struct form_control *control) -{ + struct form_control *control) { unsigned int i = 0, j; char *text_convert; struct form_option *option; wimp_pointer pointer; os_error *error; + gui_form_select_control = NULL; for (option = control->data.select.items; option; option = option->next) i++; - if (i == 0) return; if (gui_form_select_menu) { - free(gui_form_select_menu->title_data.indirected_text.text); for (j = 0; ; j++) { free(gui_form_select_menu->entries[j].data. indirected_text.text); @@ -2179,11 +916,12 @@ void gui_create_form_select_menu(struct browser_window *bw, gui_form_select_menu = malloc(wimp_SIZEOF_MENU(i)); if (!gui_form_select_menu) { warn_user("NoMemory", 0); + ro_gui_menu_closed(); return; } gui_form_select_menu->title_data.indirected_text.text = - strdup(messages_get("SelectMenu")); + messages_get("SelectMenu"); gui_form_select_menu->title_fg = wimp_COLOUR_BLACK; gui_form_select_menu->title_bg = wimp_COLOUR_LIGHT_GREY; gui_form_select_menu->work_fg = wimp_COLOUR_BLACK; @@ -2208,14 +946,16 @@ void gui_create_form_select_menu(struct browser_window *bw, /* \todo can cnv_str_local_enc() fail? */ gui_form_select_menu->entries[i].data.indirected_text.text = cnv_str_local_enc(option->text); - /* convert spaces to hard spaces to stop things like 'Go Home' being treated - as if 'Home' is a keyboard shortcut and right aligned in the menu. */ - text_convert = gui_form_select_menu->entries[i].data.indirected_text.text - 1; + /* convert spaces to hard spaces to stop things like 'Go Home' + * being treated as if 'Home' is a keyboard shortcut and right + * aligned in the menu. */ + text_convert = gui_form_select_menu->entries[i]. + data.indirected_text.text - 1; while (*++text_convert != '\0') if (*text_convert == 0x20) *text_convert = 0xa0; gui_form_select_menu->entries[i].data.indirected_text. - validation = select_null_text_string; + validation = (char *)-1; gui_form_select_menu->entries[i].data.indirected_text.size = strlen(gui_form_select_menu->entries[i]. data.indirected_text.text) + 1; @@ -2230,10 +970,1050 @@ void gui_create_form_select_menu(struct browser_window *bw, LOG(("xwimp_get_pointer_info: 0x%x: %s", error->errnum, error->errmess)); warn_user("WimpError", error->errmess); + ro_gui_menu_closed(); + return; } - current_gui = bw->window; gui_form_select_control = control; - ro_gui_create_menu(gui_form_select_menu, - pointer.pos.x, pointer.pos.y, bw->window); + ro_gui_menu_create(gui_form_select_menu, + pointer.pos.x, pointer.pos.y, bw->window->window); +} + + +/** + * Creates a wimp_menu and adds it to the list to handle actions for. + * + * \param menu the data to create the menu with + * \return the menu created, or NULL on failure + */ +wimp_menu *ro_gui_menu_define_menu(struct ns_menu *menu) { + struct menu_definition *definition; + int entry; + + definition = calloc(sizeof(struct menu_definition), 1); + if (!definition) + die("No memory to create menu definition."); + + /* link in the menu to our list */ + definition->next = ro_gui_menu_definitions; + ro_gui_menu_definitions = definition; + + /* create our definitions */ + for (entry = 0; menu->entries[entry].text; entry++); + ro_gui_menu_define_menu_add(definition, menu, 0, NULL, + 0, entry, NULL, 0); + return definition->menu; +} + +void ro_gui_menu_define_menu_add(struct menu_definition *definition, + struct ns_menu *menu, int depth, wimp_menu_entry *link, + int first, int last, const char *prefix, int prefix_length) { + int entry, id, cur_depth, new_prefix_length; + int entries = 0; + int matches[last - first + 1]; + const char *match; + char *text, *menu_text, *search; + char *title, *translated; + wimp_menu *new_menu; + struct menu_definition_entry *definition_entry; + + /* step 1: store the matches for depth and subset string */ + for (entry = first; entry < last; entry++) { + cur_depth = 0; + match = menu->entries[entry].text; + if ((prefix) && (strncmp(match, prefix, prefix_length))) + continue; + while (*match) + if (*match++ == '.') + cur_depth++; + if (depth == cur_depth) + matches[entries++] = entry; + } + matches[entries] = last; + + /* step 2: build and link the menu. we must use realloc to stop + * our memory fragmenting so we can test for sub-menus easily */ + if (entries == 0) + return; + new_menu = (wimp_menu *)malloc(wimp_SIZEOF_MENU(entries)); + if (!new_menu) + die("No memory to create menu."); + if (link) { + title = link->data.indirected_text.text; + link->sub_menu = new_menu; + } else { + title = messages_get(menu->title); + if (!title) + die("No memory to translate root menu title"); + definition->menu = new_menu; + } + new_menu->title_data.indirected_text.text = title; + new_menu->title_fg = wimp_COLOUR_BLACK; + new_menu->title_bg = wimp_COLOUR_LIGHT_GREY; + new_menu->work_fg = wimp_COLOUR_BLACK; + new_menu->work_bg = wimp_COLOUR_WHITE; + new_menu->width = 200; + new_menu->height = wimp_MENU_ITEM_HEIGHT; + new_menu->gap = wimp_MENU_ITEM_GAP; + for (entry = 0; entry < entries; entry++) { + /* add the entry */ + id = matches[entry]; + text = strdup(menu->entries[id].text); + if (!text) + die("No memory to examine menu text"); + search = menu_text = text; + while (*search) + if (*search++ == '.') + menu_text = search; + new_menu->entries[entry].menu_flags = 0; + search = menu_text; + while (*search) + if (*search++ == '_') { + new_menu->entries[entry].menu_flags |= + wimp_MENU_SEPARATE; + search[-1] = 0; + break; + } + if (menu->entries[id].sub_window) + new_menu->entries[entry].sub_menu = (wimp_menu *)menu-> + entries[id].sub_window; + else + new_menu->entries[entry].sub_menu = wimp_NO_SUB_MENU; + new_menu->entries[entry].icon_flags = DEFAULT_FLAGS | + wimp_ICON_INDIRECTED; + translated = messages_get(menu_text); + if (translated != menu_text) + free(text); + new_menu->entries[entry].data.indirected_text.text = translated; + new_menu->entries[entry].data.indirected_text.validation = + (char *)-1; + new_menu->entries[entry].data.indirected_text.size = + strlen(translated); + + /* store action */ + if (menu->entries[id].action != NO_ACTION) { + definition_entry = malloc( + sizeof(struct menu_definition_entry)); + if (!definition_entry) + die("Unable to create menu definition entry"); + definition_entry->action = menu->entries[id].action; + definition_entry->menu_entry = + &new_menu->entries[entry]; + definition_entry->next = definition->entries; + definition->entries = definition_entry; + } + + /* recurse */ + if (new_menu->entries[entry].sub_menu == wimp_NO_SUB_MENU) { + new_prefix_length = strlen(menu->entries[id].text); + if (menu->entries[id].text[new_prefix_length - 1] == '_') + new_prefix_length--; + ro_gui_menu_define_menu_add(definition, menu, depth + 1, + &new_menu->entries[entry], + matches[entry], matches[entry + 1], + menu->entries[id].text, + new_prefix_length); + } + + /* give menu warnings */ + if (new_menu->entries[entry].sub_menu != wimp_NO_SUB_MENU) + new_menu->entries[entry].menu_flags |= + wimp_MENU_GIVE_WARNING; + } + new_menu->entries[0].menu_flags |= wimp_MENU_TITLE_INDIRECTED; + new_menu->entries[entries - 1].menu_flags |= wimp_MENU_LAST; +} + + +/** + * Finds the menu_definition corresponding to a wimp_menu. + * + * \param menu the menu to find the definition for + * \return the associated definition, or NULL if one could not be found + */ +struct menu_definition *ro_gui_menu_find_menu(wimp_menu *menu) { + struct menu_definition *definition; + + if (!menu) + return NULL; + + for (definition = ro_gui_menu_definitions; definition; + definition = definition->next) + if (definition->menu == menu) + return definition; + return NULL; +} + + +/** + * Finds the menu_definition_entry corresponding to an action for a wimp_menu. + * + * \param menu the menu to search for an action within + * \param action the action to find + * \return the associated menu entry, or NULL if one could not be found + */ +struct menu_definition_entry *ro_gui_menu_find_entry(wimp_menu *menu, + menu_action action) { + struct menu_definition_entry *entry; + struct menu_definition *definition = ro_gui_menu_find_menu(menu); + + if (!definition) + return NULL; + + for (entry = definition->entries; entry; entry = entry->next) + if (entry->action == action) + return entry; + return NULL; +} + + +/** + * Finds the action corresponding to a wimp_menu_entry for a wimp_menu. + * + * \param menu the menu to search for an action within + * \param menu_entry the menu_entry to find + * \return the associated action, or 0 if one could not be found + */ +menu_action ro_gui_menu_find_action(wimp_menu *menu, wimp_menu_entry *menu_entry) { + struct menu_definition_entry *entry; + struct menu_definition *definition = ro_gui_menu_find_menu(menu); + + if (!definition) + return NO_ACTION; + + for (entry = definition->entries; entry; entry = entry->next) { + if (entry->menu_entry == menu_entry) + return entry->action; + } + return NO_ACTION; +} + + +/** + * Sets an action within a menu as having a specific ticked status. + * + * \param menu the menu containing the action + * \param action the action to tick/untick + * \param ticked whether to set the item as ticked + */ +void ro_gui_menu_set_entry_shaded(wimp_menu *menu, menu_action action, + bool shaded) { + struct menu_definition_entry *entry = + ro_gui_menu_find_entry(menu, action); + if (entry) { + if (shaded) + entry->menu_entry->icon_flags |= wimp_ICON_SHADED; + else + entry->menu_entry->icon_flags &= ~wimp_ICON_SHADED; + } +} + + +/** + * Sets an action within a menu as having a specific ticked status. + * + * \param menu the menu containing the action + * \param action the action to tick/untick + * \param ticked whether to set the item as ticked + */ +void ro_gui_menu_set_entry_ticked(wimp_menu *menu, menu_action action, + bool ticked) { + struct menu_definition_entry *entry = + ro_gui_menu_find_entry(menu, action); + if (entry) { + if (ticked) + entry->menu_entry->menu_flags |= wimp_MENU_TICKED; + else + entry->menu_entry->menu_flags &= ~wimp_MENU_TICKED; + } +} + + +/** + * Handles an action. + * + * \param owner the window to handle the action for + * \param action the action to handle + * \param windows_at_pointer whether to open any windows at the pointer location + */ +bool ro_gui_menu_handle_action(wimp_w owner, menu_action action, + bool windows_at_pointer) { + wimp_window_state state; + struct gui_window *g = NULL; + struct browser_window *bw = NULL; + struct content *c = NULL; + struct toolbar *t = NULL; + struct tree *tree; + struct node *node; + os_error *error; + char url[80]; + + ro_gui_menu_get_window_details(owner, &g, &bw, &c, &t, &tree); + + switch (action) { + + /* help actions */ + case HELP_OPEN_CONTENTS: + ro_gui_open_help_page("docs"); + return true; + case HELP_OPEN_GUIDE: + ro_gui_open_help_page("guide"); + return true; + case HELP_OPEN_INFORMATION: + ro_gui_open_help_page("info"); + return true; + case HELP_OPEN_ABOUT: + browser_window_create("file:/<NetSurf$Dir>/Docs/about", + 0, 0); + return true; + case HELP_LAUNCH_INTERACTIVE: + ro_gui_interactive_help_start(); + return true; + + /* history actions */ + case HISTORY_SHOW_LOCAL: + if ((!bw) || (!bw->history)) + return false; + ro_gui_history_open(bw, bw->history, windows_at_pointer); + return true; + case HISTORY_SHOW_GLOBAL: + ro_gui_tree_show(global_history_tree); + return true; + + /* hotlist actions */ + case HOTLIST_ADD_URL: + if ((!hotlist_tree) || (!c)) + return false; + node = tree_create_URL_node(hotlist_tree->root, + c->title, c->url, ro_content_filetype(c), + time(NULL), -1, 0); + if (node) { + tree_redraw_area(hotlist_tree, + node->box.x - NODE_INSTEP, 0, + NODE_INSTEP, 16384); + tree_handle_node_changed(hotlist_tree, node, + false, true); + ro_gui_tree_scroll_visible(hotlist_tree, + &node->data); + } + return true; + case HOTLIST_SHOW: + ro_gui_tree_show(hotlist_tree); + return true; + + /* page actions */ + case BROWSER_PAGE_INFO: + if (!c) + return false; + ro_gui_menu_prepare_action(owner, action, true); + ro_gui_dialog_open_persistant(g->window, dialog_pageinfo, + windows_at_pointer); + return true; + case BROWSER_PRINT: + if (!c) + return false; + ro_gui_menu_prepare_action(owner, action, true); + ro_gui_dialog_open_persistant(g->window, dialog_print, + windows_at_pointer); + return true; + case BROWSER_NEW_WINDOW: + if (!c) + return false; + browser_window_create(c->url, bw, 0); + return true; + case BROWSER_VIEW_SOURCE: + if (!c) + return false; + ro_gui_view_source(c); + return true; + + /* object actions */ + case BROWSER_OBJECT_INFO: + if (!current_menu_object_box) + return false; + ro_gui_menu_prepare_action(owner, action, true); + ro_gui_dialog_open_persistant(g->window, dialog_objinfo, + windows_at_pointer); + return true; + case BROWSER_OBJECT_RELOAD: + if (!current_menu_object_box) + return false; + current_menu_object_box->object->fresh = false; + browser_window_reload(bw, false); + return true; + + /* save actions */ + case BROWSER_OBJECT_SAVE: + case BROWSER_OBJECT_EXPORT_SPRITE: + case BROWSER_OBJECT_SAVE_URL_URI: + case BROWSER_OBJECT_SAVE_URL_URL: + case BROWSER_OBJECT_SAVE_URL_TEXT: + c = current_menu_object_box ? + current_menu_object_box->object : NULL; + case BROWSER_SAVE: + case BROWSER_SAVE_COMPLETE: + case BROWSER_EXPORT_DRAW: + case BROWSER_EXPORT_TEXT: + case BROWSER_SAVE_URL_URI: + case BROWSER_SAVE_URL_URL: + case BROWSER_SAVE_URL_TEXT: + if (!c) + return false; + case HOTLIST_EXPORT: + case HISTORY_EXPORT: + ro_gui_menu_prepare_action(owner, action, true); + ro_gui_dialog_open_persistant(owner, dialog_saveas, + windows_at_pointer); + return true; + + /* navigation actions */ + case BROWSER_NAVIGATE_HOME: + if (!bw) + return false; + if ((option_homepage_url) && (option_homepage_url[0])) { + browser_window_go(g->bw, option_homepage_url, 0); + } else { + snprintf(url, sizeof url, + "file:/<NetSurf$Dir>/Docs/intro_%s", + option_language); + browser_window_go(g->bw, url, 0); + } + return true; + case BROWSER_NAVIGATE_BACK: + if ((!bw) || (!bw->history)) + return false; + history_back(bw, bw->history); + return true; + case BROWSER_NAVIGATE_FORWARD: + if ((!bw) || (!bw->history)) + return false; + history_forward(bw, bw->history); + return true; + case BROWSER_NAVIGATE_RELOAD: + case BROWSER_NAVIGATE_RELOAD_ALL: + if (!bw) + return false; + browser_window_reload(bw, + (action == BROWSER_NAVIGATE_RELOAD_ALL)); + return true; + case BROWSER_NAVIGATE_STOP: + if (!bw) + return false; + browser_window_stop(bw); + return true; + case BROWSER_NAVIGATE_URL: + ro_gui_menu_prepare_action(owner, action, true); + ro_gui_dialog_open_persistant(NULL, dialog_openurl, + windows_at_pointer); + return true; + + /* browser window/display actions */ + case BROWSER_SCALE_VIEW: + if (!c) + return false; + ro_gui_menu_prepare_action(owner, action, true); + ro_gui_dialog_open_persistant(g->window, dialog_zoom, + windows_at_pointer); + return true; + case BROWSER_FIND_TEXT: + if (!c) + return false; + ro_gui_menu_prepare_action(owner, action, true); + ro_gui_dialog_open_persistant(g->window, dialog_search, + windows_at_pointer); + return true; + case BROWSER_IMAGES_BACKGROUND: + if (!g) + return false; + g->option.background_images = !g->option.background_images; + gui_window_redraw_window(g); + return true; + case BROWSER_BLEND_TEXT: + if (!g) + return false; + g->option.background_blending = !g->option.background_blending; + break; + case BROWSER_BUFFER_ANIMS: + if (!g) + return false; + g->option.buffer_animations = !g->option.buffer_animations; + break; + case BROWSER_BUFFER_ALL: + if (!g) + return false; + g->option.buffer_everything = !g->option.buffer_everything; + break; + case BROWSER_SAVE_VIEW: + if (!bw) + return false; + ro_gui_window_default_options(bw); + ro_gui_save_options(); + return true; + case BROWSER_WINDOW_DEFAULT: + if (!g) + return false; + ro_gui_screen_size(&option_window_screen_width, + &option_window_screen_height); + state.w = current_menu_window; + error = xwimp_get_window_state(&state); + if (error) { + LOG(("xwimp_get_window_state: 0x%x: %s", + error->errnum, error->errmess)); + warn_user("WimpError", error->errmess); + } + option_window_x = state.visible.x0; + option_window_y = state.visible.y0; + option_window_width = state.visible.x1 - state.visible.x0; + option_window_height = state.visible.y1 - state.visible.y0; + return true; + case BROWSER_WINDOW_STAGGER: + option_window_stagger = !option_window_stagger; + ro_gui_save_options(); + return true; + case BROWSER_WINDOW_COPY: + option_window_size_clone = !option_window_size_clone; + ro_gui_save_options(); + return true; + case BROWSER_WINDOW_RESET: + option_window_screen_width = 0; + option_window_screen_height = 0; + ro_gui_save_options(); + return true; + + /* tree actions */ + case TREE_NEW_FOLDER: + ro_gui_menu_prepare_action(owner, action, true); + ro_gui_dialog_open_persistant(g->window, dialog_folder, + windows_at_pointer); + return true; + case TREE_NEW_LINK: + ro_gui_menu_prepare_action(owner, action, true); + ro_gui_dialog_open_persistant(g->window, dialog_entry, + windows_at_pointer); + return true; + case TREE_EXPAND_ALL: + case TREE_EXPAND_FOLDERS: + case TREE_EXPAND_LINKS: + tree_handle_expansion(tree, tree->root, true, + (action != TREE_EXPAND_LINKS), + (action != TREE_EXPAND_FOLDERS)); + return true; + case TREE_COLLAPSE_ALL: + case TREE_COLLAPSE_FOLDERS: + case TREE_COLLAPSE_LINKS: + tree_handle_expansion(tree, tree->root, false, + (action != TREE_COLLAPSE_LINKS), + (action != TREE_COLLAPSE_FOLDERS)); + return true; + case TREE_SELECTION_EDIT: + return true; + case TREE_SELECTION_LAUNCH: + ro_gui_tree_launch_selected(tree); + return true; + case TREE_SELECTION_DELETE: + tree_delete_selected_nodes(tree, tree->root); + return true; + case TREE_SELECTION_RESET: + tree_reset_URL_nodes(tree, tree->root, true); + return true; + case TREE_SELECT_ALL: + ro_gui_tree_keypress(1, tree); /* CTRL-A */ + return true; + case TREE_CLEAR_SELECTION: + ro_gui_tree_keypress(26, tree); /* CTRL-Z */ + return true; + + /* toolbar actions */ + case TOOLBAR_BUTTONS: + assert(t); + t->display_buttons = !t->display_buttons; + ro_gui_menu_refresh_toolbar(t); + return true; + case TOOLBAR_ADDRESS_BAR: + assert(t); + t->display_url = !t->display_url; + ro_gui_menu_refresh_toolbar(t); + if (t->display_url) + ro_gui_set_caret_first(t->toolbar_handle); + return true; + case TOOLBAR_THROBBER: + assert(t); + t->display_throbber = !t->display_throbber; + ro_gui_menu_refresh_toolbar(t); + return true; + case TOOLBAR_STATUS_BAR: + assert(t); + t->display_status = !t->display_status; + ro_gui_menu_refresh_toolbar(t); + return true; + case TOOLBAR_EDIT: + assert(t); + ro_gui_theme_toggle_edit(t); + return true; + + /* misc actions */ + case APPLICATION_QUIT: + netsurf_quit = true; + return true; + case CHOICES_SHOW: + ro_gui_dialog_open_config(); + return true; + + /* unknown action */ + default: + return false; + } + return false; +} + + +/** + * Prepares an action for use. + * + * \param owner the window to prepare the action for + * \param action the action to prepare + * \param windows whether to update sub-windows + */ +void ro_gui_menu_prepare_action(wimp_w owner, menu_action action, bool windows) { + struct menu_definition_entry *entry; + struct gui_window *g; + struct browser_window *bw; + struct content *c; + struct toolbar *t; + struct tree *tree; + struct node *node; + bool result = false; + int checksum = 0; + os_error *error; + + ro_gui_menu_get_window_details(owner, &g, &bw, &c, &t, &tree); + if (current_menu_open) + checksum = ro_gui_menu_get_checksum(); + + switch (action) { + + /* help actions */ + case HELP_LAUNCH_INTERACTIVE: + result = ro_gui_interactive_help_available(); + ro_gui_menu_set_entry_shaded(current_menu, action, result); + ro_gui_menu_set_entry_ticked(current_menu, action, result); + break; + + /* history actions */ + case HISTORY_SHOW_LOCAL: + ro_gui_menu_set_entry_shaded(current_menu, action, + (!bw || (!bw->history) || + !(c || history_back_available(bw->history) || + history_forward_available(bw->history)))); + break; + case HISTORY_SHOW_GLOBAL: + ro_gui_menu_set_entry_shaded(current_menu, action, + !global_history_tree); + break; + + /* hotlist actions */ + case HOTLIST_ADD_URL: + ro_gui_menu_set_entry_shaded(current_menu, action, + (!c || !hotlist_tree)); + break; + case HOTLIST_SHOW: + ro_gui_menu_set_entry_shaded(current_menu, action, + !hotlist_tree); + if ((t) && (!t->editor) && (t->type == THEME_BROWSER_TOOLBAR)) + ro_gui_set_icon_shaded_state(t->toolbar_handle, + ICON_TOOLBAR_BOOKMARK, !hotlist_tree); + break; + + /* page actions */ + case BROWSER_PAGE_INFO: + ro_gui_menu_set_entry_shaded(current_menu, action, !c); + if ((windows) && (c)) + ro_gui_menu_prepare_pageinfo(g); + break; + case BROWSER_PRINT: + ro_gui_menu_set_entry_shaded(current_menu, action, !c); + if ((t) && (t->type == THEME_BROWSER_TOOLBAR)) + ro_gui_set_icon_shaded_state(t->toolbar_handle, + ICON_TOOLBAR_PRINT, !c); + if ((windows) && (c)) + ro_gui_print_prepare(g); + if ((t) && (!t->editor) && (t->type == THEME_BROWSER_TOOLBAR)) + ro_gui_set_icon_shaded_state(t->toolbar_handle, + ICON_TOOLBAR_PRINT, !c); + break; + case BROWSER_PAGE: + case BROWSER_NEW_WINDOW: + case BROWSER_VIEW_SOURCE: + ro_gui_menu_set_entry_shaded(current_menu, action, !c); + break; + + /* object actions */ + case BROWSER_OBJECT: + c = current_menu_object_box ? + current_menu_object_box->object : NULL; + ro_gui_menu_set_entry_shaded(current_menu, action, !c); + break; + case BROWSER_OBJECT_INFO: + if ((windows) && (current_menu_object_box)) + ro_gui_menu_prepare_objectinfo( + current_menu_object_box); + case BROWSER_OBJECT_RELOAD: + ro_gui_menu_set_entry_shaded(current_menu, action, + !current_menu_object_box); + break; + + /* save actions (browser, hotlist, history) */ + case BROWSER_OBJECT_SAVE: + c = current_menu_object_box ? + current_menu_object_box->object : NULL; + ro_gui_menu_set_entry_shaded(current_menu, action, !c); + if ((c) && (windows)) + ro_gui_save_prepare(GUI_SAVE_OBJECT_ORIG, c); + break; + case BROWSER_OBJECT_EXPORT_SPRITE: + c = current_menu_object_box ? + current_menu_object_box->object : NULL; + ro_gui_menu_set_entry_shaded(current_menu, action, !c); + if ((c) && (windows)) + ro_gui_save_prepare(GUI_SAVE_OBJECT_NATIVE, c); + break; + case BROWSER_SAVE: + ro_gui_menu_set_entry_shaded(current_menu, action, !c); + if ((c) && (windows)) + ro_gui_save_prepare(GUI_SAVE_SOURCE, c); + if ((t) && (!t->editor) && (t->type == THEME_BROWSER_TOOLBAR)) + ro_gui_set_icon_shaded_state(t->toolbar_handle, + ICON_TOOLBAR_SAVE, !c); + break; + case BROWSER_SAVE_COMPLETE: + ro_gui_menu_set_entry_shaded(current_menu, action, !c); + if ((c) && (windows)) + ro_gui_save_prepare(GUI_SAVE_COMPLETE, c); + break; + case BROWSER_EXPORT_DRAW: + ro_gui_menu_set_entry_shaded(current_menu, action, !c); + if ((c) && (windows)) + ro_gui_save_prepare(GUI_SAVE_DRAW, c); + break; + case BROWSER_EXPORT_TEXT: + ro_gui_menu_set_entry_shaded(current_menu, action, !c); + if ((c) && (windows)) + ro_gui_save_prepare(GUI_SAVE_TEXT, c); + break; + case BROWSER_OBJECT_SAVE_URL_URI: + c = current_menu_object_box ? + current_menu_object_box->object : NULL; + case BROWSER_SAVE_URL_URI: + ro_gui_menu_set_entry_shaded(current_menu, action, !c); + if ((c) && (windows)) + ro_gui_save_prepare(GUI_SAVE_LINK_URI, c); + break; + case BROWSER_OBJECT_SAVE_URL_URL: + c = current_menu_object_box ? + current_menu_object_box->object : NULL; + case BROWSER_SAVE_URL_URL: + ro_gui_menu_set_entry_shaded(current_menu, action, !c); + if ((c) && (windows)) + ro_gui_save_prepare(GUI_SAVE_LINK_URL, c); + break; + case BROWSER_OBJECT_SAVE_URL_TEXT: + c = current_menu_object_box ? + current_menu_object_box->object : NULL; + case BROWSER_SAVE_URL_TEXT: + ro_gui_menu_set_entry_shaded(current_menu, action, !c); + if ((c) && (windows)) + ro_gui_save_prepare(GUI_SAVE_LINK_TEXT, c); + break; + case HOTLIST_EXPORT: + if ((tree) && (windows)) + ro_gui_save_prepare(GUI_SAVE_HOTLIST_EXPORT_HTML, + NULL); + break; + case HISTORY_EXPORT: + if ((tree) && (windows)) + ro_gui_save_prepare(GUI_SAVE_HISTORY_EXPORT_HTML, + NULL); + break; + + /* navigation actions */ + case BROWSER_NAVIGATE_BACK: + result = (!bw || !bw->history || + !history_back_available(bw->history)); + ro_gui_menu_set_entry_shaded(current_menu, action, result); + if ((t) && (!t->editor) && (t->type == THEME_BROWSER_TOOLBAR)) + ro_gui_set_icon_shaded_state(t->toolbar_handle, + ICON_TOOLBAR_BACK, result); + break; + case BROWSER_NAVIGATE_FORWARD: + result = (!bw || !bw->history || + !history_forward_available(bw->history)); + ro_gui_menu_set_entry_shaded(current_menu, action, result); + if ((t) && (!t->editor) && (t->type == THEME_BROWSER_TOOLBAR)) + ro_gui_set_icon_shaded_state(t->toolbar_handle, + ICON_TOOLBAR_FORWARD, result); + break; + case BROWSER_NAVIGATE_RELOAD: + case BROWSER_NAVIGATE_RELOAD_ALL: + result = (bw->current_content && !bw->loading_content); + ro_gui_menu_set_entry_shaded(current_menu, action, !result); + if ((t) && (!t->editor) && (t->type == THEME_BROWSER_TOOLBAR)) + ro_gui_set_icon_shaded_state(t->toolbar_handle, + ICON_TOOLBAR_RELOAD, !result); + break; + case BROWSER_NAVIGATE_STOP: + result = (bw->loading_content || (bw->current_content && + (bw->current_content->status != + CONTENT_STATUS_DONE))); + ro_gui_menu_set_entry_shaded(current_menu, action, !result); + if ((t) && (!t->editor) && (t->type == THEME_BROWSER_TOOLBAR)) + ro_gui_set_icon_shaded_state(t->toolbar_handle, + ICON_TOOLBAR_STOP, !result); + break; + case BROWSER_NAVIGATE_URL: + if (windows) + ro_gui_dialog_prepare_open_url(); + break; + + /* display actions */ + case BROWSER_SCALE_VIEW: + ro_gui_menu_set_entry_shaded(current_menu, action, !c); + if ((c) && (windows)) + ro_gui_dialog_prepare_zoom(g); + if ((t) && (!t->editor) && (t->type == THEME_BROWSER_TOOLBAR)) + ro_gui_set_icon_shaded_state(t->toolbar_handle, + ICON_TOOLBAR_SCALE, !c); + break; + case BROWSER_FIND_TEXT: + if ((c) && (windows)) + ro_gui_search_prepare(g); + if ((t) && (!t->editor) && (t->type == THEME_BROWSER_TOOLBAR)) + ro_gui_set_icon_shaded_state(t->toolbar_handle, + ICON_TOOLBAR_SEARCH, !c); + break; + case BROWSER_IMAGES_FOREGROUND: + ro_gui_menu_set_entry_shaded(current_menu, action, true); + ro_gui_menu_set_entry_ticked(current_menu, action, true); + break; + case BROWSER_IMAGES_BACKGROUND: + if (g) + ro_gui_menu_set_entry_ticked(current_menu, action, + g->option.background_images); + break; + case BROWSER_BLEND_TEXT: + if (g) + ro_gui_menu_set_entry_ticked(current_menu, action, + g->option.background_blending); + break; + case BROWSER_BUFFER_ANIMS: + if (g) { + ro_gui_menu_set_entry_shaded(current_menu, action, + g->option.buffer_everything); + ro_gui_menu_set_entry_ticked(current_menu, action, + g->option.buffer_animations || + g->option.buffer_everything); + } + break; + case BROWSER_BUFFER_ALL: + if (g) + ro_gui_menu_set_entry_ticked(current_menu, action, + g->option.buffer_everything); + break; + case BROWSER_WINDOW_STAGGER: + ro_gui_menu_set_entry_shaded(current_menu, action, + option_window_screen_width == 0); + ro_gui_menu_set_entry_ticked(current_menu, action, + ((option_window_screen_width == 0) || + option_window_stagger)); + break; + case BROWSER_WINDOW_COPY: + ro_gui_menu_set_entry_ticked(current_menu, action, + option_window_size_clone); + break; + case BROWSER_WINDOW_RESET: + ro_gui_menu_set_entry_shaded(current_menu, action, + option_window_screen_width == 0); + break; + + /* tree actions */ + case TREE_NEW_FOLDER: + ro_gui_hotlist_prepare_folder_dialog(NULL); + break; + case TREE_NEW_LINK: + ro_gui_hotlist_prepare_entry_dialog(NULL); + break; + case TREE_EXPAND_ALL: + case TREE_EXPAND_FOLDERS: + case TREE_EXPAND_LINKS: + case TREE_COLLAPSE_ALL: + case TREE_COLLAPSE_FOLDERS: + case TREE_COLLAPSE_LINKS: + if ((tree) && (tree->root)) + ro_gui_menu_set_entry_shaded(current_menu, action, + !tree->root->child); + break; + case TREE_SELECTION: + if ((!tree) || (!tree->root)) + break; + if (tree->root->child) + result = tree_has_selection(tree->root->child); + ro_gui_menu_set_entry_shaded(current_menu, action, !result); + if ((t) && (!t->editor) && (t->type != THEME_BROWSER_TOOLBAR)) { + ro_gui_set_icon_shaded_state(t->toolbar_handle, + ICON_TOOLBAR_DELETE, !result); + ro_gui_set_icon_shaded_state(t->toolbar_handle, + ICON_TOOLBAR_LAUNCH, !result); + } + break; + case TREE_SELECTION_EDIT: + node = tree_get_selected_node(tree->root); + entry = ro_gui_menu_find_entry(current_menu, action); + if ((!node) || (!entry)) + break; + if (node->folder) { + entry->menu_entry->sub_menu = + (wimp_menu *)dialog_folder; + if (windows) + ro_gui_hotlist_prepare_folder_dialog(node); + } else { + entry->menu_entry->sub_menu = + (wimp_menu *)dialog_entry; + if (windows) + ro_gui_hotlist_prepare_entry_dialog(node); + } + break; + case TREE_SELECTION_LAUNCH: + case TREE_SELECTION_DELETE: + case TREE_SELECTION_RESET: + if ((!tree) || (!tree->root)) + break; + if (tree->root->child) + result = tree_has_selection(tree->root->child); + ro_gui_menu_set_entry_shaded(current_menu, action, !result); + break; + case TREE_SELECT_ALL: + ro_gui_menu_set_entry_shaded(current_menu, action, + !tree->root->child); + break; + case TREE_CLEAR_SELECTION: + if ((!tree) || (!tree->root)) + break; + if (tree->root->child) + result = tree_has_selection(tree->root->child); + ro_gui_menu_set_entry_shaded(current_menu, action, !result); + break; + + /* toolbar actions */ + case TOOLBAR_BUTTONS: + ro_gui_menu_set_entry_shaded(current_menu, action, (!t || + (t->editor))); + ro_gui_menu_set_entry_ticked(current_menu, action, (t && + ((t->display_buttons) || (t->editor)))); + break; + case TOOLBAR_ADDRESS_BAR: + ro_gui_menu_set_entry_shaded(current_menu, action, !t); + ro_gui_menu_set_entry_ticked(current_menu, action, + (t && t->display_url)); + break; + case TOOLBAR_THROBBER: + ro_gui_menu_set_entry_shaded(current_menu, action, !t); + ro_gui_menu_set_entry_ticked(current_menu, action, + (t && t->display_throbber)); + break; + case TOOLBAR_STATUS_BAR: + ro_gui_menu_set_entry_shaded(current_menu, action, !t); + ro_gui_menu_set_entry_ticked(current_menu, action, + (t && t->display_status)); + break; + case TOOLBAR_EDIT: + ro_gui_menu_set_entry_shaded(current_menu, action, !t); + ro_gui_menu_set_entry_ticked(current_menu, action, + (t && t->editor)); + break; + + /* unknown action */ + default: + return; + } + + /* update open menus */ + if ((current_menu_open) && + (checksum != ro_gui_menu_get_checksum())) { + error = xwimp_create_menu(current_menu, 0, 0); + if (error) { + LOG(("xwimp_create_menu: 0x%x: %s", + error->errnum, error->errmess)); + warn_user("MenuError", error->errmess); + } + } +} + + +/** + * Gets various details relating to a window + * + * \param w the window to complete information for + */ +void ro_gui_menu_get_window_details(wimp_w w, struct gui_window **g, + struct browser_window **bw, struct content **content, + struct toolbar **toolbar, struct tree **tree) { + *g = ro_gui_window_lookup(w); + if (*g) { + *bw = (*g)->bw; + *toolbar = (*g)->toolbar; + if (*bw) + *content = (*bw)->current_content; + *tree = NULL; + } else { + *bw = NULL; + *content = NULL; + if ((hotlist_tree) && (w == (wimp_w)hotlist_tree->handle)) + *tree = hotlist_tree; + else if ((global_history_tree) && + (w == (wimp_w)global_history_tree->handle)) + *tree = global_history_tree; + else + *tree = NULL; + if (*tree) + *toolbar = (*tree)->toolbar; + else + *toolbar = NULL; + } +} + + +/** + * Calculates a simple checksum for the current menu state + */ +int ro_gui_menu_get_checksum(void) { + wimp_selection menu_tree; + int i = 0, j, checksum = 0; + os_error *error; + wimp_menu *menu; + + if (!current_menu_open) + return 0; + + error = xwimp_get_menu_state((wimp_menu_state_flags)0, + &menu_tree, 0, 0); + if (error) { + LOG(("xwimp_get_menu_state: 0x%x: %s", + error->errnum, error->errmess)); + warn_user("MenuError", error->errmess); + return 0; + } + + menu = current_menu; + do { + j = 0; + do { + if (menu->entries[j].icon_flags & wimp_ICON_SHADED) + checksum ^= (1 << (i + j * 2)); + if (menu->entries[j].menu_flags & wimp_MENU_TICKED) + checksum ^= (2 << (i + j * 2)); + } while (!(menu->entries[j++].menu_flags & wimp_MENU_LAST)); + j = menu_tree.items[i++]; + if (j != -1) + menu = menu->entries[j].sub_menu; + } while (j != -1); + return checksum; } |