From af3a78060fc18d1544b0d411d2d7584fcac9f3df Mon Sep 17 00:00:00 2001 From: Vincent Sanders Date: Mon, 26 Dec 2016 13:22:42 +0000 Subject: [PATCH] Update RISC OS hotlist to use core window interface --- frontends/riscos/dialog.c | 2 +- frontends/riscos/gui.c | 5 +- frontends/riscos/gui/button_bar.h | 8 - frontends/riscos/hotlist.c | 913 ++++++++++++++++-------------- frontends/riscos/hotlist.h | 59 +- frontends/riscos/iconbar.c | 7 +- frontends/riscos/window.c | 6 +- 7 files changed, 562 insertions(+), 438 deletions(-) diff --git a/frontends/riscos/dialog.c b/frontends/riscos/dialog.c index e58a61dbe..64f1dba1e 100644 --- a/frontends/riscos/dialog.c +++ b/frontends/riscos/dialog.c @@ -184,7 +184,7 @@ void ro_gui_dialog_init(void) ro_gui_cert_preinitialise(); /* hotlist window */ - ro_gui_hotlist_preinitialise(); + ro_gui_hotlist_initialise(); /* global history window */ ro_gui_global_history_preinitialise(); diff --git a/frontends/riscos/gui.c b/frontends/riscos/gui.c index f5126f8b4..4834396d6 100644 --- a/frontends/riscos/gui.c +++ b/frontends/riscos/gui.c @@ -1271,9 +1271,6 @@ static nserror gui_init(int argc, char** argv) /* certificate verification window */ ro_gui_cert_postinitialise(); - /* hotlist window */ - ro_gui_hotlist_postinitialise(); - /* global history window */ ro_gui_global_history_postinitialise(); @@ -1565,7 +1562,7 @@ static void gui_quit(void) urldb_save(nsoption_charp(url_save)); ro_gui_window_quit(); ro_gui_global_history_destroy(); - ro_gui_hotlist_destroy(); + ro_gui_hotlist_finalise(); ro_gui_cookies_finalise(); ro_gui_saveas_quit(); ro_gui_url_bar_fini(); diff --git a/frontends/riscos/gui/button_bar.h b/frontends/riscos/gui/button_bar.h index fb8ee790a..eb8f18bfe 100644 --- a/frontends/riscos/gui/button_bar.h +++ b/frontends/riscos/gui/button_bar.h @@ -103,14 +103,6 @@ static const struct button_bar_buttons global_history_toolbar_buttons[] = { {NULL, TOOLBAR_BUTTON_NONE, TOOLBAR_BUTTON_NONE, '\0', ""} }; -static const struct button_bar_buttons hotlist_toolbar_buttons[] = { - {"delete", TOOLBAR_BUTTON_DELETE, TOOLBAR_BUTTON_NONE, '0', "0"}, - {"expand", TOOLBAR_BUTTON_EXPAND, TOOLBAR_BUTTON_COLLAPSE, '1', "1"}, - {"open", TOOLBAR_BUTTON_OPEN, TOOLBAR_BUTTON_CLOSE, '2', "2"}, - {"launch", TOOLBAR_BUTTON_LAUNCH, TOOLBAR_BUTTON_NONE, '3', "3"}, - {"create", TOOLBAR_BUTTON_CREATE, TOOLBAR_BUTTON_NONE, '4', "4"}, - {NULL, TOOLBAR_BUTTON_NONE, TOOLBAR_BUTTON_NONE, '\0', ""} -}; struct button_bar; diff --git a/frontends/riscos/hotlist.c b/frontends/riscos/hotlist.c index d47702082..24ced69b5 100644 --- a/frontends/riscos/hotlist.c +++ b/frontends/riscos/hotlist.c @@ -1,6 +1,6 @@ /* - * Copyright 2004, 2005 Richard Wilson * Copyright 2010, 2013 Stephen Fryatt + * Copyright 2016 Vincent Sanders * * This file is part of NetSurf, http://www.netsurf-browser.org/ * @@ -19,16 +19,11 @@ /** * \file - * Hotlist implementation for RISC OS. + * Implementation of RISC OS hotlist manager. */ -#include -#include -#include -#include +#include #include -#include -#include #include #include @@ -38,222 +33,145 @@ #include "utils/nsurl.h" #include "netsurf/url_db.h" #include "netsurf/window.h" +#include "netsurf/plotters.h" #include "netsurf/keypress.h" #include "desktop/hotlist.h" -#include "desktop/tree.h" #include "riscos/gui.h" #include "riscos/dialog.h" -#include "riscos/hotlist.h" -#include "riscos/menus.h" #include "riscos/message.h" #include "riscos/save.h" #include "riscos/toolbar.h" -#include "riscos/treeview.h" #include "riscos/wimp.h" #include "riscos/wimp_event.h" #include "riscos/query.h" +#include "riscos/menus.h" +#include "riscos/corewindow.h" +#include "riscos/hotlist.h" -static void ro_gui_hotlist_toolbar_update_buttons(void); -static void ro_gui_hotlist_toolbar_save_buttons(char *config); -static bool ro_gui_hotlist_menu_prepare(wimp_w w, wimp_i i, wimp_menu *menu, - wimp_pointer *pointer); -static void ro_gui_hotlist_menu_warning(wimp_w w, wimp_i i, wimp_menu *menu, - wimp_selection *selection, menu_action action); -static bool ro_gui_hotlist_menu_select(wimp_w w, wimp_i i, wimp_menu *menu, - wimp_selection *selection, menu_action action); -static void ro_gui_hotlist_toolbar_click(button_bar_action action); -static void ro_gui_hotlist_addurl_bounce(wimp_message *message); -static void ro_gui_hotlist_scheduled_callback(void *p); -static void ro_gui_hotlist_remove_confirmed(query_id id, - enum query_response res, void *p); -static void ro_gui_hotlist_remove_cancelled(query_id id, - enum query_response res, void *p); - -static const query_callback remove_funcs = { - ro_gui_hotlist_remove_confirmed, - ro_gui_hotlist_remove_cancelled +/** + * Hotlist window container for RISC OS. + */ +struct ro_hotlist_window { + struct ro_corewindow core; + wimp_menu *menu; }; -struct ro_treeview_callbacks ro_hotlist_treeview_callbacks = { - ro_gui_hotlist_toolbar_click, - ro_gui_hotlist_toolbar_update_buttons, - ro_gui_hotlist_toolbar_save_buttons -}; +/** hotlist window singleton */ +static struct ro_hotlist_window *hotlist_window = NULL; -/* Hotlist Protocol Message Blocks, which are currently not in OSLib. */ - -struct ro_hotlist_message_hotlist_addurl { - wimp_MESSAGE_HEADER_MEMBERS /**< The standard message header. */ - char *url; /**< Pointer to the URL in RMA. */ - char *title; /**< Pointer to the title in RMA. */ - char appname[32]; /**< The application name. */ -}; - -struct ro_hotlist_message_hotlist_changed { - wimp_MESSAGE_HEADER_MEMBERS /**< The standard message header. */ -}; - -static char *hotlist_url = NULL; /**< URL area claimed from RMA. */ -static char *hotlist_title = NULL; /**< Title area claimed from RMA. */ +/** riscos template for hotlist window */ +static wimp_window *dialog_hotlist_template; /** Hotlist Query Handler. */ - static query_id hotlist_query = QUERY_INVALID; -static nsurl *hotlist_delete_url = NULL; - -/* The RISC OS hotlist window, toolbar and treeview data. */ - -static struct ro_hotlist { - wimp_w window; /**< The hotlist RO window handle. */ - struct toolbar *toolbar; /**< The hotlist toolbar handle. */ - ro_treeview *tv; /**< The hotlist treeview handle. */ - wimp_menu *menu; /**< The hotlist window menu. */ -} hotlist_window; +static nsurl *hotlist_delete_url = NULL; /** - * Pre-Initialise the hotlist tree. This is called for things that need to - * be done at the gui_init() stage, such as loading templates. + * URL adding hotlist protocol message block. + * + * Message block is not currently in OSLib. */ - -void ro_gui_hotlist_preinitialise(void) -{ - /* Create our window. */ - - hotlist_window.window = ro_gui_dialog_create("tree"); - ro_gui_set_window_title(hotlist_window.window, - messages_get("Hotlist")); -} +struct ro_hotlist_message_hotlist_addurl { + wimp_MESSAGE_HEADER_MEMBERS /**< The standard message header. */ + char *url; /**< Pointer to the URL in RMA. */ + char *title; /**< Pointer to the title in RMA. */ + char appname[32]; /**< The application name. */ +}; /** - * Initialise the hotlist tree, at the gui_init2() stage. + * change hotlist protocol message block. + * + * Message block is not currently in OSLib. */ +struct ro_hotlist_message_hotlist_changed { + wimp_MESSAGE_HEADER_MEMBERS /**< The standard message header. */ +}; -void ro_gui_hotlist_postinitialise(void) +/** URL area claimed from RMA. */ +static char *hotlist_url = NULL; +/** Title area claimed from RMA. */ +static char *hotlist_title = NULL; + + +/** + * callback to draw on drawable area of ro hotlist window + * + * \param ro_cw The riscos core window structure. + * \param r The rectangle of the window that needs updating. + * \param originx The risc os plotter x origin. + * \param originy The risc os plotter y origin. + * \return NSERROR_OK on success otherwise apropriate error code + */ +static nserror +hotlist_draw(struct ro_corewindow *ro_cw, + int originx, + int originy, + struct rect *r) { - /* Create our toolbar. */ - - hotlist_window.toolbar = ro_toolbar_create(NULL, hotlist_window.window, - THEME_STYLE_HOTLIST_TOOLBAR, TOOLBAR_FLAGS_NONE, - ro_treeview_get_toolbar_callbacks(), NULL, - "HelpHotToolbar"); - if (hotlist_window.toolbar != NULL) { - ro_toolbar_add_buttons(hotlist_window.toolbar, - hotlist_toolbar_buttons, - nsoption_charp(toolbar_hotlist)); - ro_toolbar_rebuild(hotlist_window.toolbar); - } - - /* Create the treeview with the window and toolbar. */ - tree_hotlist_path = nsoption_charp(hotlist_path); - hotlist_window.tv = ro_treeview_create(hotlist_window.window, - hotlist_window.toolbar, &ro_hotlist_treeview_callbacks, - TREE_HOTLIST); - if (hotlist_window.tv == NULL) { - LOG("Failed to allocate treeview"); - return; - } - - ro_toolbar_update_client_data(hotlist_window.toolbar, - hotlist_window.tv); - - /* Build the hotlist window menu. */ - - static const struct ns_menu hotlist_definition = { - "Hotlist", { - { "Hotlist", NO_ACTION, 0 }, - { "Hotlist.New", NO_ACTION, 0 }, - { "Hotlist.New.Folder", TREE_NEW_FOLDER, 0 }, - { "Hotlist.New.Link", TREE_NEW_LINK, 0 }, - { "_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, 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} - } + struct redraw_context ctx = { + .interactive = true, + .background_images = true, + .plot = &ro_plotters }; - hotlist_window.menu = ro_gui_menu_define_menu(&hotlist_definition); + ro_plot_origin_x = originx; + ro_plot_origin_y = originy; + no_font_blending = true; + hotlist_redraw(0, 0, r, &ctx); + no_font_blending = false; - ro_gui_wimp_event_register_menu(hotlist_window.window, - hotlist_window.menu, false, false); - ro_gui_wimp_event_register_menu_prepare(hotlist_window.window, - ro_gui_hotlist_menu_prepare); - ro_gui_wimp_event_register_menu_selection(hotlist_window.window, - ro_gui_hotlist_menu_select); - ro_gui_wimp_event_register_menu_warning(hotlist_window.window, - ro_gui_hotlist_menu_warning); -} - -/** - * Destroy the hotlist window. - */ - -void ro_gui_hotlist_destroy(void) -{ - if (hotlist_window.tv == NULL) - return; - - tree_hotlist_path = nsoption_charp(hotlist_save); - ro_treeview_destroy(hotlist_window.tv); + return NSERROR_OK; } /** - * Open the hotlist window. + * callback for keypress on ro hotlist window * + * \param ro_cw The ro core window structure. + * \param nskey The netsurf key code. + * \return NSERROR_OK if key processed, + * NSERROR_NOT_IMPLEMENTED if key not processed + * otherwise apropriate error code */ - -void ro_gui_hotlist_open(void) +static nserror hotlist_key(struct ro_corewindow *ro_cw, uint32_t nskey) { - if (nsoption_bool(external_hotlists) && - nsoption_charp(external_hotlist_app) != NULL && - *nsoption_charp(external_hotlist_app) != '\0') { - char command[2048]; - os_error *error; - - snprintf(command, sizeof(command), "Filer_Run %s", - nsoption_charp(external_hotlist_app)); - error = xos_cli(command); - - if (error == NULL) - return; - - LOG("xos_cli: 0x%x: %s", error->errnum, error->errmess); - ro_warn_user("Failed to launch external hotlist: %s", - error->errmess); - } - - ro_gui_hotlist_toolbar_update_buttons(); - - if (!ro_gui_dialog_open_top(hotlist_window.window, - hotlist_window.toolbar, 600, 800)) { - ro_treeview_set_origin(hotlist_window.tv, 0, - -(ro_toolbar_height(hotlist_window.toolbar))); + if (hotlist_keypress(nskey)) { + return NSERROR_OK; } + return NSERROR_NOT_IMPLEMENTED; } -/** - * Handle toolbar button clicks. - * - * \param action The action to handle - */ -void ro_gui_hotlist_toolbar_click(button_bar_action action) +/** + * callback for mouse event on ro hotlist window + * + * \param ro_cw The ro core window structure. + * \param mouse_state mouse state + * \param x location of event + * \param y location of event + * \return NSERROR_OK on sucess otherwise apropriate error code. + */ +static nserror +hotlist_mouse(struct ro_corewindow *ro_cw, + browser_mouse_state mouse_state, + int x, int y) +{ + hotlist_mouse_action(mouse_state, x, y); + + return NSERROR_OK; +} + + +/** + * handle clicks in ro hotlist window toolbar. + * + * \param ro_cw The ro core window structure. + * \param action The button bar action. + * \return NSERROR_OK if config saved, otherwise apropriate error code + */ +static nserror +hotlist_toolbar_click(struct ro_corewindow *ro_cw, button_bar_action action) { switch (action) { case TOOLBAR_BUTTON_DELETE: @@ -288,76 +206,90 @@ void ro_gui_hotlist_toolbar_click(button_bar_action action) default: break; } + + return NSERROR_OK; } /** - * Update the button state in the hotlist toolbar. - */ - -void ro_gui_hotlist_toolbar_update_buttons(void) -{ - ro_toolbar_set_button_shaded_state(hotlist_window.toolbar, - TOOLBAR_BUTTON_DELETE, - !hotlist_has_selection()); - - ro_toolbar_set_button_shaded_state(hotlist_window.toolbar, - TOOLBAR_BUTTON_LAUNCH, - !hotlist_has_selection()); -} - - -/** - * Save a new button arrangement in the hotlist toolbar. + * Handle updating state of buttons in ro core window toolbar. * - * \param *config The new button configuration string. + * \param ro_cw The ro core window structure. + * \return NSERROR_OK if config saved, otherwise apropriate error code */ +static nserror hotlist_toolbar_update(struct ro_corewindow *ro_cw) +{ + bool has_selection; -void ro_gui_hotlist_toolbar_save_buttons(char *config) + has_selection = hotlist_has_selection(); + + ro_toolbar_set_button_shaded_state(ro_cw->toolbar, + TOOLBAR_BUTTON_DELETE, + !has_selection); + + ro_toolbar_set_button_shaded_state(ro_cw->toolbar, + TOOLBAR_BUTTON_LAUNCH, + !has_selection); + + return NSERROR_OK; +} + + +/** + * callback for saving of toolbar state in ro hotlist window + * + * \param ro_cw The ro core window structure. + * \param config The new toolbar configuration. + * \return NSERROR_OK if config saved, otherwise apropriate error code + */ +static nserror hotlist_toolbar_save(struct ro_corewindow *ro_cw, char *config) { nsoption_set_charp(toolbar_hotlist, config); ro_gui_save_options(); + + return NSERROR_OK; } /** - * Prepare the hotlist menu for opening + * Prepare the hotlist menu for display * - * \param w The window owning the menu. - * \param i A wimp icon - * \param menu The menu about to be opened. - * \param pointer Pointer to the relevant wimp event block, or - * NULL for an Adjust click. - * \return true if the event was handled; else false. + * \param w The window owning the menu. + * \param i The icon owning the menu. + * \param menu The menu from which the selection was made. + * \param pointer The pointer shape + * \return true if action accepted; else false. */ - -bool ro_gui_hotlist_menu_prepare(wimp_w w, wimp_i i, wimp_menu *menu, - wimp_pointer *pointer) +static bool +hotlist_menu_prepare(wimp_w w, wimp_i i, wimp_menu *menu, wimp_pointer *pointer) { bool selection; + struct ro_hotlist_window *hotlistw; - if (menu != hotlist_window.menu) + hotlistw = (struct ro_hotlist_window *)ro_gui_wimp_event_get_user_data(w); + + if ((hotlistw == NULL) || + (menu != hotlistw->menu)) { return false; + } selection = hotlist_has_selection(); - ro_gui_menu_set_entry_shaded(hotlist_window.menu, - TREE_SELECTION, !selection); - ro_gui_menu_set_entry_shaded(hotlist_window.menu, - TREE_CLEAR_SELECTION, !selection); + ro_gui_menu_set_entry_shaded(menu, TREE_SELECTION, !selection); + ro_gui_menu_set_entry_shaded(menu, TREE_CLEAR_SELECTION, !selection); ro_gui_save_prepare(GUI_SAVE_HOTLIST_EXPORT_HTML, - NULL, NULL, NULL, NULL); + NULL, NULL, NULL, NULL); ro_gui_menu_set_entry_shaded(menu, TOOLBAR_BUTTONS, - ro_toolbar_menu_option_shade(hotlist_window.toolbar)); + ro_toolbar_menu_option_shade(hotlistw->core.toolbar)); ro_gui_menu_set_entry_ticked(menu, TOOLBAR_BUTTONS, - ro_toolbar_menu_buttons_tick(hotlist_window.toolbar)); + ro_toolbar_menu_buttons_tick(hotlistw->core.toolbar)); ro_gui_menu_set_entry_shaded(menu, TOOLBAR_EDIT, - ro_toolbar_menu_edit_shade(hotlist_window.toolbar)); + ro_toolbar_menu_edit_shade(hotlistw->core.toolbar)); ro_gui_menu_set_entry_ticked(menu, TOOLBAR_EDIT, - ro_toolbar_menu_edit_tick(hotlist_window.toolbar)); + ro_toolbar_menu_edit_tick(hotlistw->core.toolbar)); return true; } @@ -366,85 +298,116 @@ bool ro_gui_hotlist_menu_prepare(wimp_w w, wimp_i i, wimp_menu *menu, /** * Handle submenu warnings for the hotlist menu * - * \param w The window owning the menu. - * \param i The icon owning the menu. - * \param *menu The menu to which the warning applies. - * \param *selection The wimp menu selection data. - * \param action The selected menu action. + * \param w The window owning the menu. + * \param i The icon owning the menu. + * \param menu The menu to which the warning applies. + * \param selection The wimp menu selection data. + * \param action The selected menu action. */ - -void ro_gui_hotlist_menu_warning(wimp_w w, wimp_i i, wimp_menu *menu, - wimp_selection *selection, menu_action action) +static void +hotlist_menu_warning(wimp_w w, + wimp_i i, + wimp_menu *menu, + wimp_selection *selection, + menu_action action) { /* Do nothing */ } + /** * Handle selections from the hotlist menu * - * \param w The window owning the menu. - * \param i The icon owning the menu. - * \param *menu The menu from which the selection was made. - * \param *selection The wimp menu selection data. - * \param action The selected menu action. - * \return true if action accepted; else false. + * \param w The window owning the menu. + * \param i The icon owning the menu. + * \param menu The menu from which the selection was made. + * \param selection The wimp menu selection data. + * \param action The selected menu action. + * \return true if action accepted; else false. */ - -bool ro_gui_hotlist_menu_select(wimp_w w, wimp_i i, wimp_menu *menu, - wimp_selection *selection, menu_action action) +static bool +hotlist_menu_select(wimp_w w, + wimp_i i, + wimp_menu *menu, + wimp_selection *selection, + menu_action action) { + struct ro_hotlist_window *hotlistw; + + hotlistw = (struct ro_hotlist_window *)ro_gui_wimp_event_get_user_data(w); + + if ((hotlistw == NULL) || + (menu != hotlistw->menu)) { + return false; + } + switch (action) { case HOTLIST_EXPORT: ro_gui_dialog_open_persistent(w, dialog_saveas, true); return true; + case TREE_NEW_FOLDER: hotlist_add_folder(NULL, false, 0); return true; + case TREE_NEW_LINK: hotlist_add_entry(NULL, NULL, false, 0); return true; + case TREE_EXPAND_ALL: hotlist_expand(false); return true; + case TREE_EXPAND_FOLDERS: hotlist_expand(true); return true; + case TREE_EXPAND_LINKS: hotlist_expand(false); return true; + case TREE_COLLAPSE_ALL: hotlist_contract(true); return true; + case TREE_COLLAPSE_FOLDERS: hotlist_contract(true); return true; + case TREE_COLLAPSE_LINKS: hotlist_contract(false); return true; + case TREE_SELECTION_EDIT: hotlist_edit_selection(); return true; + case TREE_SELECTION_LAUNCH: hotlist_keypress(NS_KEY_CR); return true; + case TREE_SELECTION_DELETE: hotlist_keypress(NS_KEY_DELETE_LEFT); ro_toolbar_update_all_hotlists(); return true; + case TREE_SELECT_ALL: hotlist_keypress(NS_KEY_SELECT_ALL); return true; + case TREE_CLEAR_SELECTION: hotlist_keypress(NS_KEY_CLEAR_SELECTION); return true; + case TOOLBAR_BUTTONS: - ro_toolbar_set_display_buttons(hotlist_window.toolbar, - !ro_toolbar_get_display_buttons( - hotlist_window.toolbar)); + ro_toolbar_set_display_buttons(hotlistw->core.toolbar, + !ro_toolbar_get_display_buttons(hotlistw->core.toolbar)); return true; + case TOOLBAR_EDIT: - ro_toolbar_toggle_edit(hotlist_window.toolbar); + ro_toolbar_toggle_edit(hotlistw->core.toolbar); return true; + default: return false; } @@ -452,58 +415,262 @@ bool ro_gui_hotlist_menu_select(wimp_w w, wimp_i i, wimp_menu *menu, return false; } + /** - * Check if a particular window handle is the hotlist window + * Creates the window for the hotlist tree. * - * \param window The window in question - * \return true if this window is the hotlist + * \return NSERROR_OK on success else appropriate error code on faliure. */ -bool ro_gui_hotlist_check_window(wimp_w window) +static nserror ro_hotlist_init(void) { - if (hotlist_window.window == window) - return true; - else - return false; + struct ro_hotlist_window *ncwin; + nserror res; + static const struct ns_menu hotlist_menu_def = { + "Hotlist", { + { "Hotlist", NO_ACTION, 0 }, + { "Hotlist.New", NO_ACTION, 0 }, + { "Hotlist.New.Folder", TREE_NEW_FOLDER, 0 }, + { "Hotlist.New.Link", TREE_NEW_LINK, 0 }, + { "_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, 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} + } + }; + + static const struct button_bar_buttons hotlist_toolbar_buttons[] = { + { "delete", TOOLBAR_BUTTON_DELETE, TOOLBAR_BUTTON_NONE, '0', "0" }, + { "expand", TOOLBAR_BUTTON_EXPAND, TOOLBAR_BUTTON_COLLAPSE, '1', "1" }, + { "open", TOOLBAR_BUTTON_OPEN, TOOLBAR_BUTTON_CLOSE, '2', "2" }, + { "launch", TOOLBAR_BUTTON_LAUNCH, TOOLBAR_BUTTON_NONE, '3', "3" }, + { "create", TOOLBAR_BUTTON_CREATE, TOOLBAR_BUTTON_NONE, '4', "4" }, + { NULL, TOOLBAR_BUTTON_NONE, TOOLBAR_BUTTON_NONE, '\0', "" } + }; + + if (hotlist_window != NULL) { + return NSERROR_OK; + } + + ncwin = malloc(sizeof(struct ro_hotlist_window)); + if (ncwin == NULL) { + return NSERROR_NOMEM; + } + + /* create window from template */ + ncwin->core.wh = wimp_create_window(dialog_hotlist_template); + + ro_gui_set_window_title(ncwin->core.wh, messages_get("Hotlist")); + + /* Set up callback handlers */ + ncwin->core.draw = hotlist_draw; + ncwin->core.key = hotlist_key; + ncwin->core.mouse = hotlist_mouse; + ncwin->core.toolbar_click = hotlist_toolbar_click; + ncwin->core.toolbar_save = hotlist_toolbar_save; + /* update is not valid untill hotlist manager is initialised */ + ncwin->core.toolbar_update = NULL; + + /* initialise core window */ + res = ro_corewindow_init(&ncwin->core, + hotlist_toolbar_buttons, + nsoption_charp(toolbar_hotlist), + THEME_STYLE_HOTLIST_TOOLBAR, + "HelpHotToolbar"); + if (res != NSERROR_OK) { + free(ncwin); + return res; + } + + res = hotlist_init(ncwin->core.cb_table, + (struct core_window *)ncwin, + nsoption_charp(hotlist_path)); + if (res != NSERROR_OK) { + free(ncwin); + return res; + } + + /* setup toolbar update post hotlist manager initialisation */ + ncwin->core.toolbar_update = hotlist_toolbar_update; + hotlist_toolbar_update(&ncwin->core); + + /* Build the hotlist window menu. */ + ncwin->menu = ro_gui_menu_define_menu(&hotlist_menu_def); + + ro_gui_wimp_event_register_menu(ncwin->core.wh, + ncwin->menu, false, false); + ro_gui_wimp_event_register_menu_prepare(ncwin->core.wh, + hotlist_menu_prepare); + ro_gui_wimp_event_register_menu_selection(ncwin->core.wh, + hotlist_menu_select); + ro_gui_wimp_event_register_menu_warning(ncwin->core.wh, + hotlist_menu_warning); + + /* memoise window so it can be re-presented when necessary + * instead of recreating every time. + */ + hotlist_window = ncwin; + + return NSERROR_OK; } -/** - * Check if a particular menu handle is the hotlist menu - * - * \param *menu The menu in question. - * \return true if this menu is the hotlist menu - */ +/* exported interface documented in riscos/hotlist.h */ +nserror ro_gui_hotlist_present(void) +{ + nserror res; + + /* deal with external hotlist handler */ + if (nsoption_bool(external_hotlists) && + (nsoption_charp(external_hotlist_app) != NULL) && + (*nsoption_charp(external_hotlist_app) != '\0')) { + char command[2048]; + os_error *error; + + snprintf(command, sizeof(command), "Filer_Run %s", + nsoption_charp(external_hotlist_app)); + error = xos_cli(command); + + if (error == NULL) { + return NSERROR_OK; + } + + LOG("xos_cli: 0x%x: %s", error->errnum, error->errmess); + ro_warn_user("Failed to launch external hotlist: %s", + error->errmess); + } + + res = ro_hotlist_init(); + if (res == NSERROR_OK) { + LOG("Presenting"); + ro_gui_dialog_open_top(hotlist_window->core.wh, + hotlist_window->core.toolbar, + 600, 800); + } else { + LOG("Failed presenting code %d", res); + } + + return res; +} + + +/* exported interface documented in riscos/hotlist.h */ +void ro_gui_hotlist_initialise(void) +{ + dialog_hotlist_template = ro_gui_dialog_load_template("tree"); +} + + +/* exported interface documented in riscos/hotlist.h */ +nserror ro_gui_hotlist_finalise(void) +{ + nserror res; + + if (hotlist_window == NULL) { + return NSERROR_OK; + } + + res = hotlist_fini(nsoption_charp(hotlist_path)); + if (res == NSERROR_OK) { + res = ro_corewindow_fini(&hotlist_window->core); + + free(hotlist_window); + hotlist_window = NULL; + } + + return res; +} + + +/* exported interface documented in riscos/hotlist.h */ +bool ro_gui_hotlist_check_window(wimp_w wh) +{ + if ((hotlist_window != NULL) && + (hotlist_window->core.wh == wh)) { + return true; + } + return false; +} + + +/* exported interface documented in riscos/hotlist.h */ bool ro_gui_hotlist_check_menu(wimp_menu *menu) { - if (hotlist_window.menu == menu) + if ((hotlist_window != NULL) && + (hotlist_window->menu == menu)) { return true; - else - return false; + } + return false; } /** - * Add a URL to the hotlist. This will be passed on to the core hotlist, then - * Message_HotlistAddURL will broadcast to any bookmark applications via the - * Hotlist Protocol. + * Callback to schedule for the next available Null poll, by which point + * a hotlist client will have claimed the Message_HotlistAddURL and any + * details in RMA can safely be discarded. * - * \param *url The URL to be added. + * \param p Unused data pointer. */ +static void ro_gui_hotlist_scheduled_callback(void *p) +{ + ro_gui_hotlist_add_cleanup(); +} + +/** + * Handle bounced Message_HotlistAddURL, so that RMA storage can be freed. + * + * \param message The bounced message content. + */ +static void ro_gui_hotlist_addurl_bounce(wimp_message *message) +{ + if (hotlist_url != NULL) { + nsurl *nsurl; + + if (nsurl_create(hotlist_url, &nsurl) != NSERROR_OK) + return; + + hotlist_add_url(nsurl); + nsurl_unref(nsurl); + } + + ro_gui_hotlist_add_cleanup(); + + /* There's no longer any need to listen for the next Null poll. */ + + riscos_schedule(-1, ro_gui_hotlist_scheduled_callback, NULL); +} + + +/* exported interface documented in riscos/hotlist.h */ void ro_gui_hotlist_add_page(nsurl *url) { - const struct url_data *data; - wimp_message message; - struct ro_hotlist_message_hotlist_addurl *add_url = - (struct ro_hotlist_message_hotlist_addurl *) &message; + const struct url_data *data; + wimp_message message; + struct ro_hotlist_message_hotlist_addurl *add_url = + (struct ro_hotlist_message_hotlist_addurl *) &message; - if (url == NULL) + if (url == NULL) { return; + } /* If we're not using external hotlists, add the page to NetSurf's * own hotlist and return... */ - if (!nsoption_bool(external_hotlists)) { hotlist_add_url(url); return; @@ -538,62 +705,21 @@ void ro_gui_hotlist_add_page(nsurl *url) add_url->title = hotlist_title; strcpy(add_url->appname, "NetSurf"); - if (!ro_message_send_message(wimp_USER_MESSAGE_RECORDED, &message, 0, - ro_gui_hotlist_addurl_bounce)) + if (!ro_message_send_message(wimp_USER_MESSAGE_RECORDED, + &message, + 0, + ro_gui_hotlist_addurl_bounce)) { ro_gui_hotlist_add_cleanup(); + } /* Listen for the next Null poll, as an indication that the * message didn't bounce. */ - riscos_schedule(0, ro_gui_hotlist_scheduled_callback, NULL); } -/** - * Handle bounced Message_HotlistAddURL, so that RMA storage can be freed. - * - * \param *message The bounced message content. - */ - -static void ro_gui_hotlist_addurl_bounce(wimp_message *message) -{ - if (hotlist_url != NULL) { - nsurl *nsurl; - - if (nsurl_create(hotlist_url, &nsurl) != NSERROR_OK) - return; - - hotlist_add_url(nsurl); - nsurl_unref(nsurl); - } - - ro_gui_hotlist_add_cleanup(); - - /* There's no longer any need to listen for the next Null poll. */ - - riscos_schedule(-1, ro_gui_hotlist_scheduled_callback, NULL); -} - - -/** - * Callback to schedule for the next available Null poll, by which point - * a hotlist client will have claimed the Message_HotlistAddURL and any - * details in RMA can safely be discarded. - * - * \param *p Unused data pointer. - */ - -static void ro_gui_hotlist_scheduled_callback(void *p) -{ - ro_gui_hotlist_add_cleanup(); -} - - -/** - * Clean up RMA storage used by the Message_HotlistAddURL protocol. - */ - +/* exported interface documented in riscos/hotlist.h */ void ro_gui_hotlist_add_cleanup(void) { if (hotlist_url != NULL) { @@ -608,59 +734,15 @@ void ro_gui_hotlist_add_cleanup(void) } -/** - * Remove a URL from the hotlist. This will be passed on to the core hotlist, - * unless we're configured to use external hotlists in which case we ignore it. - * - * \param *url The URL to be removed. - */ - -void ro_gui_hotlist_remove_page(nsurl *url) -{ - if (url == NULL || nsoption_bool(external_hotlists) || - !hotlist_has_url(url)) - return; - - /* Clean up any existing delete attempts before continuing. */ - - if (hotlist_query != QUERY_INVALID) { - query_close(hotlist_query); - hotlist_query = QUERY_INVALID; - } - - if (hotlist_delete_url != NULL) { - nsurl_unref(hotlist_delete_url); - hotlist_delete_url = NULL; - } - - /* Check with the user before removing the URL, unless they don't - * want us to be careful in which case just do it. - */ - - if (nsoption_bool(confirm_hotlist_remove)) { - hotlist_query = query_user("RemoveHotlist", NULL, - &remove_funcs, NULL, - messages_get("Remove"), - messages_get("DontRemove")); - - hotlist_delete_url = nsurl_ref(url); - } else { - hotlist_remove_url(url); - ro_toolbar_update_all_hotlists(); - } -} - - /** * Callback confirming a URL delete query. * - * \param id The ID of the query calling us. - * \param res The user's response to the query. - * \param *p Callback data (always NULL). + * \param id The ID of the query calling us. + * \param res The user's response to the query. + * \param p Callback data (always NULL). */ - -static void ro_gui_hotlist_remove_confirmed(query_id id, - enum query_response res, void *p) +static void +ro_gui_hotlist_remove_confirmed(query_id id, enum query_response res, void *p) { hotlist_remove_url(hotlist_delete_url); ro_toolbar_update_all_hotlists(); @@ -674,13 +756,12 @@ static void ro_gui_hotlist_remove_confirmed(query_id id, /** * Callback cancelling a URL delete query. * - * \param id The ID of the query calling us. - * \param res The user's response to the query. - * \param *p Callback data (always NULL). + * \param id The ID of the query calling us. + * \param res The user's response to the query. + * \param p Callback data (always NULL). */ - -static void ro_gui_hotlist_remove_cancelled(query_id id, - enum query_response res, void *p) +static void +ro_gui_hotlist_remove_cancelled(query_id id, enum query_response res, void *p) { nsurl_unref(hotlist_delete_url); hotlist_delete_url = NULL; @@ -689,50 +770,58 @@ static void ro_gui_hotlist_remove_cancelled(query_id id, /** - * Report whether the hotlist contains a given URL. This will be passed on to - * the core hotlist, unless we're configured to use an external hotlist in which - * case we always report false. - * - * \param *url The URL to be tested. - * \return true if the hotlist contains the URL; else false. + * removal query dialog callbacks. */ +static const query_callback remove_funcs = { + ro_gui_hotlist_remove_confirmed, + ro_gui_hotlist_remove_cancelled +}; + +/* exported interface documented in riscos/hotlist.h */ +void ro_gui_hotlist_remove_page(nsurl *url) +{ + if ((url == NULL) || + nsoption_bool(external_hotlists) || + !hotlist_has_url(url)) { + return; + } + + /* Clean up any existing delete attempts before continuing. */ + if (hotlist_query != QUERY_INVALID) { + query_close(hotlist_query); + hotlist_query = QUERY_INVALID; + } + + if (hotlist_delete_url != NULL) { + nsurl_unref(hotlist_delete_url); + hotlist_delete_url = NULL; + } + + /* Check with the user before removing the URL, unless they don't + * want us to be careful in which case just do it. + */ + if (nsoption_bool(confirm_hotlist_remove)) { + hotlist_query = query_user("RemoveHotlist", NULL, + &remove_funcs, NULL, + messages_get("Remove"), + messages_get("DontRemove")); + + hotlist_delete_url = nsurl_ref(url); + } else { + hotlist_remove_url(url); + ro_toolbar_update_all_hotlists(); + } +} + + +/* exported interface documented in riscos/hotlist.h */ bool ro_gui_hotlist_has_page(nsurl *url) { - if (url == NULL || nsoption_bool(external_hotlists)) + if ((url == NULL) || + nsoption_bool(external_hotlists)) { return false; + } return hotlist_has_url(url); } - - -#if 0 -/** - * Handle URL dropped on hotlist - * - * \param message the wimp message we're acting on - * \param url the URL to add - */ -void ro_gui_hotlist_url_drop(wimp_message *message, const char *url) -{ - int x, y; - nsurl *nsurl; - - if (hotlist_window.window != message->data.data_xfer.w) - return; - - if (url == NULL) - return; - - if (nsurl_create(url, &nsurl) != NSERROR_OK) - return; - - ro_gui_tree_get_tree_coordinates(hotlist_window.tree, - message->data.data_xfer.pos.x, - message->data.data_xfer.pos.y, - &x, &y); - - hotlist_add_entry(nsurl, NULL, true, y); - nsurl_unref(nsurl); -} -#endif diff --git a/frontends/riscos/hotlist.h b/frontends/riscos/hotlist.h index 0b87a2e96..14a661e88 100644 --- a/frontends/riscos/hotlist.h +++ b/frontends/riscos/hotlist.h @@ -34,20 +34,65 @@ #define message_HOTLIST_CHANGED 0x4af82 #endif -#include "riscos/menus.h" - struct nsurl; -void ro_gui_hotlist_preinitialise(void); -void ro_gui_hotlist_postinitialise(void); -void ro_gui_hotlist_destroy(void); -void ro_gui_hotlist_open(void); -void ro_gui_hotlist_save(void); +/** + * initialise the hotlist window template ready for subsequent use. + */ +void ro_gui_hotlist_initialise(void); + +/** + * make the cookie window visible. + * + * \return NSERROR_OK on success else appropriate error code on faliure. + */ +nserror ro_gui_hotlist_present(void); + +/** + * Free any resources allocated for the cookie window. + * + * \return NSERROR_OK on success else appropriate error code on faliure. + */ +nserror ro_gui_hotlist_finalise(void); + bool ro_gui_hotlist_check_window(wimp_w window); bool ro_gui_hotlist_check_menu(wimp_menu *menu); + +/** + * Add a URL to the hotlist. + * + * This will be passed on to the core hotlist, then + * Message_HotlistAddURL will broadcast to any bookmark applications + * via the Hotlist Protocol. + * + * \param *url The URL to be added. + */ void ro_gui_hotlist_add_page(struct nsurl *url); + +/** + * Clean up RMA storage used by the Message_HotlistAddURL protocol. + */ void ro_gui_hotlist_add_cleanup(void); + +/** + * Remove a URL from the hotlist. + * + * This will be passed on to the core hotlist, unless we're configured + * to use external hotlists in which case we ignore it. + * + * \param *url The URL to be removed. + */ void ro_gui_hotlist_remove_page(struct nsurl *url); + +/** + * Report whether the hotlist contains a given URL. + * + * This will be passed on to the core hotlist, unless we're configured + * to use an external hotlist in which case we always report false. + * + * \param url The URL to be tested. + * \return true if the hotlist contains the URL; else false. + */ bool ro_gui_hotlist_has_page(struct nsurl *url); #endif diff --git a/frontends/riscos/iconbar.c b/frontends/riscos/iconbar.c index 146f23261..e0ce15d09 100644 --- a/frontends/riscos/iconbar.c +++ b/frontends/riscos/iconbar.c @@ -150,8 +150,9 @@ bool ro_gui_iconbar_click(wimp_pointer *pointer) case wimp_CLICK_ADJUST: xosbyte1(osbyte_SCAN_KEYBOARD, 0 ^ 0x80, 0, &key_down); - if (key_down == 0) - ro_gui_hotlist_open(); + if (key_down == 0) { + ro_gui_hotlist_present(); + } break; } @@ -224,7 +225,7 @@ bool ro_gui_iconbar_menu_select(wimp_w w, wimp_i i, wimp_menu *menu, ro_gui_dialog_open_persistent(NULL, dialog_openurl, true); return true; case HOTLIST_SHOW: - ro_gui_hotlist_open(); + ro_gui_hotlist_present(); return true; case HISTORY_SHOW_GLOBAL: ro_gui_global_history_open(); diff --git a/frontends/riscos/window.c b/frontends/riscos/window.c index 488c3f591..569860ea6 100644 --- a/frontends/riscos/window.c +++ b/frontends/riscos/window.c @@ -1944,7 +1944,7 @@ bool ro_gui_window_handle_local_keypress(struct gui_window *g, wimp_key *key, return true; case IS_WIMP_KEY + wimp_KEY_F6: /* Hotlist */ - ro_gui_hotlist_open(); + ro_gui_hotlist_present(); return true; case IS_WIMP_KEY + wimp_KEY_F7: /* Show local history */ @@ -2704,7 +2704,7 @@ bool ro_gui_window_menu_select(wimp_w w, wimp_i i, wimp_menu *menu, ro_gui_window_action_add_bookmark(g); break; case HOTLIST_SHOW: - ro_gui_hotlist_open(); + ro_gui_hotlist_present(); break; /* cookies actions */ @@ -3623,7 +3623,7 @@ void ro_gui_window_toolbar_click(void *data, break; case TOOLBAR_BUTTON_BOOKMARK_OPEN: - ro_gui_hotlist_open(); + ro_gui_hotlist_present(); break; case TOOLBAR_BUTTON_BOOKMARK_ADD: