From 2affb76944a4cd83a2ff6722c3150abbb972f37d Mon Sep 17 00:00:00 2001 From: Richard Wilson Date: Thu, 3 Feb 2005 13:18:22 +0000 Subject: [project @ 2005-02-03 13:18:22 by rjw] Implementation of URL suggestion svn path=/import/netsurf/; revision=1488 --- riscos/dialog.c | 7 +- riscos/gui.c | 29 ++- riscos/gui.h | 3 +- riscos/hotlist.c | 5 - riscos/sprite.h | 2 + riscos/url_complete.c | 558 ++++++++++++++++++++++++++++++++++++++++++++++++++ riscos/url_complete.h | 26 +++ riscos/window.c | 30 ++- 8 files changed, 644 insertions(+), 16 deletions(-) create mode 100644 riscos/url_complete.c create mode 100644 riscos/url_complete.h (limited to 'riscos') diff --git a/riscos/dialog.c b/riscos/dialog.c index c6cb54fc7..223c268d0 100644 --- a/riscos/dialog.c +++ b/riscos/dialog.c @@ -43,7 +43,7 @@ wimp_w dialog_info, dialog_saveas, dialog_config, dialog_config_br, dialog_zoom, dialog_pageinfo, dialog_objinfo, dialog_tooltip, dialog_warning, dialog_config_th_pane, dialog_debug, dialog_folder, dialog_entry, dialog_search, dialog_print, - dialog_config_font, dialog_config_image; + dialog_config_font, dialog_config_image, dialog_url_complete; static int ro_gui_choices_font_size; static int ro_gui_choices_font_min_size; @@ -140,6 +140,7 @@ void ro_gui_dialog_init(void) dialog_config_font = ro_gui_dialog_create("config_font"); dialog_config_image = ro_gui_dialog_create("config_img"); dialog_theme_install = ro_gui_dialog_create("theme_inst"); + dialog_url_complete = ro_gui_dialog_create("url_suggest"); } @@ -811,12 +812,8 @@ void ro_gui_save_options(void) /* NCOS doesnt have the fancy Universal Boot vars; so select * the path to the choices file based on the build options */ #ifndef NCOS - xosfile_create_dir(".WWW", 0); - xosfile_create_dir(".WWW.NetSurf", 0); options_write(".WWW.NetSurf.Choices"); #else - xosfile_create_dir(".Choices.NetSurf", 0); - xosfile_create_dir(".Choices.NetSurf.Choices", 0); options_write(".Choices.NetSurf.Choices"); #endif } diff --git a/riscos/gui.c b/riscos/gui.c index 131320347..5750119d6 100644 --- a/riscos/gui.c +++ b/riscos/gui.c @@ -32,6 +32,7 @@ #include "oslib/wimp.h" #include "oslib/wimpspriteop.h" #include "oslib/uri.h" +#include "netsurf/content/url_store.h" #include "netsurf/utils/config.h" #include "netsurf/desktop/gui.h" #include "netsurf/desktop/netsurf.h" @@ -57,6 +58,7 @@ #ifdef WITH_URL #include "netsurf/riscos/url_protocol.h" #endif +#include "netsurf/riscos/url_complete.h" #include "netsurf/riscos/wimp.h" #include "netsurf/utils/log.h" #include "netsurf/utils/messages.h" @@ -184,6 +186,17 @@ void gui_init(int argc, char** argv) xhourglass_start(1); + /* create our choices directories */ +#ifndef NCOS + xosfile_create_dir(".WWW", 0); + xosfile_create_dir(".WWW.NetSurf", 0); + xosfile_create_dir(".WWW.NetSurf.Themes", 0); +#else + xosfile_create_dir(".Choices.NetSurf", 0); + xosfile_create_dir(".Choices.NetSurf.Choices", 0); + xosfile_create_dir(".Choices.NetSurf.Choices.Themes", 0); +#endif + #ifdef WITH_SAVE_COMPLETE save_complete_init(); #endif @@ -195,6 +208,8 @@ void gui_init(int argc, char** argv) options_read(".Choices.NetSurf.Choices"); #endif ro_gui_choose_language(); + + url_store_load("Choices:WWW.NetSurf.URL"); NETSURF_DIR = getenv("NetSurf$Dir"); if ((length = snprintf(path, sizeof(path), @@ -527,6 +542,7 @@ void gui_init2(int argc, char** argv) void gui_quit(void) { + url_store_save(".WWW.NetSurf.URL"); ro_gui_window_quit(); ro_gui_hotlist_save(); ro_gui_history_quit(); @@ -751,6 +767,8 @@ void ro_gui_null_reason_code(void) if (gui_track_wimp_w == history_window) ro_gui_history_mouse_at(&pointer); + if (gui_track_wimp_w == dialog_url_complete) + ro_gui_url_complete_mouse_at(&pointer); else if (gui_track_gui_window) ro_gui_window_mouse_at(gui_track_gui_window, &pointer); } @@ -766,6 +784,8 @@ void ro_gui_redraw_window_request(wimp_draw *redraw) if (redraw->w == history_window) ro_gui_history_redraw(redraw); + else if (redraw->w == dialog_url_complete) + ro_gui_url_complete_redraw(redraw); else if ((hotlist_tree) && (redraw->w == (wimp_w)hotlist_tree->handle)) ro_gui_tree_redraw(redraw, hotlist_tree); else if ((hotlist_toolbar) && (hotlist_toolbar->toolbar_handle == redraw->w)) @@ -827,8 +847,10 @@ void ro_gui_close_window_request(wimp_close *close) if (close->w == dialog_debug) ro_gui_debugwin_close(); - else if ((g = ro_gui_window_lookup(close->w)) != NULL) + else if ((g = ro_gui_window_lookup(close->w)) != NULL) { + ro_gui_url_complete_close(NULL, 0); browser_window_destroy(g->bw); + } else if ((dw = ro_gui_download_window_lookup(close->w)) != NULL) ro_gui_download_window_destroy(dw); else @@ -866,7 +888,8 @@ void ro_gui_pointer_entering_window(wimp_entering *entering) { gui_track_wimp_w = entering->w; gui_track_gui_window = ro_gui_window_lookup(entering->w); - gui_track = gui_track_gui_window || gui_track_wimp_w == history_window; + gui_track = gui_track_gui_window || gui_track_wimp_w == history_window || + gui_track_wimp_w == dialog_url_complete; } @@ -883,6 +906,8 @@ void ro_gui_mouse_click(wimp_pointer *pointer) ro_gui_icon_bar_click(pointer); else if (pointer->w == history_window) ro_gui_history_click(pointer); + else if (pointer->w == dialog_url_complete) + ro_gui_url_complete_mouse_at(pointer); else if ((hotlist_tree) && (pointer->w == (wimp_w)hotlist_tree->handle)) ro_gui_hotlist_click(pointer); else if (pointer->w == dialog_saveas) diff --git a/riscos/gui.h b/riscos/gui.h index 8d78b411f..7a3264c5e 100644 --- a/riscos/gui.h +++ b/riscos/gui.h @@ -30,7 +30,8 @@ extern wimp_w dialog_info, dialog_saveas, dialog_config, dialog_config_br, dialog_config_prox, dialog_config_th, dialog_zoom, dialog_pageinfo, dialog_objinfo, dialog_tooltip, dialog_warning, dialog_config_th_pane, dialog_debug, dialog_folder, dialog_entry, - dialog_search, dialog_print, dialog_config_font, dialog_theme_install; + dialog_search, dialog_print, dialog_config_font, dialog_theme_install, + dialog_url_complete; extern wimp_w history_window; extern wimp_menu *iconbar_menu, *browser_menu, *combo_menu, *hotlist_menu, *proxyauth_menu, *languages_menu, *toolbar_menu, diff --git a/riscos/hotlist.c b/riscos/hotlist.c index e1303c51e..3edec0ad0 100644 --- a/riscos/hotlist.c +++ b/riscos/hotlist.c @@ -152,11 +152,6 @@ void ro_gui_hotlist_save(void) { if (!hotlist_tree) return; - /* Ensure we have a directory to save to later. - */ - xosfile_create_dir(".WWW", 0); - xosfile_create_dir(".WWW.NetSurf", 0); - /* Save to our file */ options_save_hotlist(hotlist_tree, ".WWW.NetSurf.Hotlist"); diff --git a/riscos/sprite.h b/riscos/sprite.h index 605027635..3824ace43 100644 --- a/riscos/sprite.h +++ b/riscos/sprite.h @@ -12,6 +12,8 @@ #ifndef _NETSURF_RISCOS_SPRITE_H_ #define _NETSURF_RISCOS_SPRITE_H_ +#include + struct content; struct content_sprite_data { diff --git a/riscos/url_complete.c b/riscos/url_complete.c new file mode 100644 index 000000000..2aecfbdb9 --- /dev/null +++ b/riscos/url_complete.c @@ -0,0 +1,558 @@ +/* + * This file is part of NetSurf, http://netsurf.sourceforge.net/ + * Licensed under the GNU General Public License, + * http://www.opensource.org/licenses/gpl-license + * Copyright 2005 Richard Wilson + */ + +/** \file + * GUI URL auto-completion (implementation). + */ + +#include +#include +#include +#include +#include +#include "oslib/wimp.h" +#include "netsurf/content/url_store.h" +#include "netsurf/utils/log.h" +#include "netsurf/riscos/gui.h" +#include "netsurf/riscos/theme.h" +#include "netsurf/riscos/url_complete.h" +#include "netsurf/riscos/wimp.h" +#include "netsurf/utils/utils.h" + +#define MAXIMUM_VISIBLE_LINES 7 + +static char **url_complete_matches = NULL; +static int url_complete_matches_allocated = 0; +static int url_complete_matches_available = 0; +static char *url_complete_matched_string = NULL; +static int url_complete_matches_selection = -1; +static int url_complete_keypress_selection = -1; +static wimp_w url_complete_parent = 0; +static bool url_complete_matches_reset = false; +static char *url_complete_original_url = NULL; + +static char *url_complete_redraw[MAXIMUM_VISIBLE_LINES]; +static char url_complete_icon_null[] = "\0"; +static wimp_icon url_complete_icon; +static int mouse_x; +static int mouse_y; + + +/** + * Handles a keypress for URL completion + * + * \param g the gui_window to update + * \param key the key pressed + */ +bool ro_gui_url_complete_keypress(struct gui_window *g, int key) { + wimp_window_state state; + char **array_extend; + struct url_data *reference = NULL; + char *match_url; + char *url; + char *output; + int i, lines; + int old_selection; + bool ignore_changes = false; + int height; + os_error *error; + bool currently_open; + + /* we must have a toolbar/url bar */ + if ((!g->toolbar) || (!g->toolbar->display_url)) { + ro_gui_url_complete_close(NULL, 0); + return false; + } + + /* if we are currently active elsewhere, remove the previous window */ + currently_open = g->window == url_complete_parent; + if (g->window != url_complete_parent) { + ro_gui_url_complete_close(NULL, 0); + url_complete_parent = g->window; + } + + /* get the text to match */ + url = ro_gui_get_icon_string(g->toolbar->toolbar_handle, ICON_TOOLBAR_URL); + match_url = url_store_match_string(url); + if (!match_url) { + ro_gui_url_complete_close(NULL, 0); + return false; + } + + /* check if we should ignore text changes */ + if (url_complete_keypress_selection >= 0) + ignore_changes = !strcmp(url, + url_complete_matches[url_complete_keypress_selection]); + + /* if the text to match has changed then update it */ + if (!ignore_changes && ((!url_complete_matched_string) || + (strcmp(match_url, url_complete_matched_string)))) { + + /* memorize the current matches */ + lines = MAXIMUM_VISIBLE_LINES; + if (lines > url_complete_matches_available) + lines = url_complete_matches_available; + for (i = 0; i < MAXIMUM_VISIBLE_LINES; i++) + url_complete_redraw[i] = url_complete_matches[i]; + + /* our selection gets wiped */ + error = xwimp_force_redraw(dialog_url_complete, + 0, -(url_complete_matches_selection + 1) * 44, + 65536, -url_complete_matches_selection * 44); + if (error) { + LOG(("xwimp_force_redraw: 0x%x: %s", + error->errnum, error->errmess)); + warn_user("WimpError", error->errmess); + } + + /* clear our state */ + free(url_complete_original_url); + free(url_complete_matched_string); + url_complete_matched_string = match_url; + url_complete_original_url = NULL; + url_complete_matches_available = 0; + url_complete_matches_selection = -1; + url_complete_keypress_selection = -1; + + /* get some initial memory */ + if (!url_complete_matches) { + url_complete_matches = malloc(64 * sizeof(char *)); + if (!url_complete_matches) { + ro_gui_url_complete_close(NULL, 0); + return false; + } + url_complete_matches_allocated = 64; + } + + /* get all our matches */ + while ((output = url_store_match(match_url, &reference))) { + url_complete_matches_available++; + if (url_complete_matches_available > + url_complete_matches_allocated) { + + array_extend = realloc(url_complete_matches, + (url_complete_matches_allocated + 64) * + sizeof(char *)); + if (!array_extend) { + ro_gui_url_complete_close(NULL, 0); + return false; + } + url_complete_matches = array_extend; + url_complete_matches_allocated += 64; + } + url_complete_matches[url_complete_matches_available - 1] = + output; + + } + + /* update the window */ + state.w = g->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); + return false; + } + url_complete_matches_reset = true; + ro_gui_url_complete_resize(g, (wimp_open *)&state); + url_complete_matches_reset = false; + + /* redraw the relevant bits of the window */ + lines = MAXIMUM_VISIBLE_LINES; + if (lines > url_complete_matches_available) + lines = url_complete_matches_available; + for (i = 0; i < MAXIMUM_VISIBLE_LINES; i++) { + if (url_complete_redraw[i] != url_complete_matches[i]) { + error = xwimp_force_redraw(dialog_url_complete, + 0, -(i + 1) * 44, 65536, -i * 44); + if (error) { + LOG(("xwimp_force_redraw: 0x%x: %s", + error->errnum, error->errmess)); + warn_user("WimpError", error->errmess); + } + } + } + + } else { + free(match_url); + } + + /* handle keypresses */ + if (!currently_open) + return false; + old_selection = url_complete_matches_selection; + switch (key) { + case wimp_KEY_UP: + url_complete_matches_selection--; + break; + case wimp_KEY_DOWN: + url_complete_matches_selection++; + break; + case wimp_KEY_PAGE_UP: + url_complete_matches_selection -= MAXIMUM_VISIBLE_LINES; + break; + case wimp_KEY_PAGE_DOWN: + url_complete_matches_selection += MAXIMUM_VISIBLE_LINES; + break; + case wimp_KEY_CONTROL | wimp_KEY_UP: + url_complete_matches_selection = 0; + break; + case wimp_KEY_CONTROL | wimp_KEY_DOWN: + url_complete_matches_selection = 65536; + break; + } + if (url_complete_matches_selection > url_complete_matches_available - 1) + url_complete_matches_selection = url_complete_matches_available - 1; + else if (url_complete_matches_selection < -1) + url_complete_matches_selection = -1; + + if (old_selection == url_complete_matches_selection) + return false; + + error = xwimp_force_redraw(dialog_url_complete, + 0, -(old_selection + 1) * 44, 65536, -old_selection * 44); + if (error) { + LOG(("xwimp_force_redraw: 0x%x: %s", + error->errnum, error->errmess)); + warn_user("WimpError", error->errmess); + } + error = xwimp_force_redraw(dialog_url_complete, + 0, -(url_complete_matches_selection + 1) * 44, + 65536, -url_complete_matches_selection * 44); + if (error) { + LOG(("xwimp_force_redraw: 0x%x: %s", + error->errnum, error->errmess)); + warn_user("WimpError", error->errmess); + } + if (old_selection == -1) { + free(url_complete_original_url); + url_complete_original_url = malloc(strlen(url) + 1); + if (!url_complete_original_url) + return false; + strcpy(url_complete_original_url, url); + } + if (url_complete_matches_selection == -1) { + ro_gui_set_icon_string(g->toolbar->toolbar_handle, + ICON_TOOLBAR_URL, + url_complete_original_url); + } else { + ro_gui_set_icon_string(g->toolbar->toolbar_handle, + ICON_TOOLBAR_URL, + url_complete_matches[url_complete_matches_selection]); + } + url_complete_keypress_selection = url_complete_matches_selection; + + /* auto-scroll */ + state.w = dialog_url_complete; + 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); + return true; + } + if (state.yscroll < -(url_complete_matches_selection * 44)) + state.yscroll = -(url_complete_matches_selection * 44); + height = state.visible.y1 - state.visible.y0; + if (state.yscroll - height > -((url_complete_matches_selection + 1) * 44)) + state.yscroll = -((url_complete_matches_selection + 1) * 44) + height; + error = xwimp_open_window((wimp_open *)(&state)); + if (error) { + LOG(("xwimp_open_window: 0x%x: %s", + error->errnum, error->errmess)); + warn_user("WimpError", error->errmess); + return true; + } + + return true; +} + + +/** + * Move and resize the url completion window to match the toolbar. + * + * \param g the gui_window to update + * \param open the wimp_open request (updated on exit) + */ +void ro_gui_url_complete_resize(struct gui_window *g, wimp_open *open) { + os_box extent = { 0, 0, 0, 0 }; + wimp_icon_state url_state; + wimp_window_state toolbar_state; + wimp_window_state state; + os_error *error; + int lines; + int scroll_v = 0; + + /* if we the URL completion isn't for our window, or there is no toolbar, + * or there is no URL bar shown, or there are no URL matches, close it */ + if ((open->w != url_complete_parent) || (!g->toolbar) || + (!g->toolbar->display_url) || + (url_complete_matches_available == 0)) { + ro_gui_url_complete_close(NULL, 0); + return; + } + + /* get our current auto-complete window state for the scroll values */ + state.w = dialog_url_complete; + 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); + return; + } + if (url_complete_matches_reset) + state.yscroll = 0; + + /* move the window to the correct position */ + toolbar_state.w = g->toolbar->toolbar_handle; + error = xwimp_get_window_state(&toolbar_state); + if (error) { + LOG(("xwimp_get_window_state: 0x%x: %s", + error->errnum, error->errmess)); + warn_user("WimpError", error->errmess); + return; + } + url_state.w = g->toolbar->toolbar_handle; + url_state.i = ICON_TOOLBAR_URL; + error = xwimp_get_icon_state(&url_state); + if (error) { + LOG(("xwimp_get_window_state: 0x%x: %s", + error->errnum, error->errmess)); + warn_user("WimpError", error->errmess); + return; + } + lines = url_complete_matches_available; + extent.y0 = -(lines * 44); + extent.x1 = 65536; + error = xwimp_set_extent(dialog_url_complete, &extent); + if (error) { + LOG(("xwimp_set_extent: 0x%x: %s", + error->errnum, error->errmess)); + warn_user("WimpError", error->errmess); + return; + } + state.next = open->next; + state.flags &= ~wimp_WINDOW_VSCROLL; + state.flags &= ~(4095 << 16); /* clear bits 16-27 */ + if (lines > MAXIMUM_VISIBLE_LINES) { + lines = MAXIMUM_VISIBLE_LINES; + scroll_v = ro_get_vscroll_width(NULL) - 2; + state.flags |= wimp_WINDOW_VSCROLL; + } + state.visible.x0 = open->visible.x0 + 2 + url_state.icon.extent.x0; + state.visible.x1 = open->visible.x0 - 2 + url_state.icon.extent.x1 - scroll_v; + state.visible.y1 = open->visible.y1 - url_state.icon.extent.y1 + 2; + state.visible.y0 = state.visible.y1 - (lines * 44); + if (state.visible.x1 > toolbar_state.visible.x1) + state.visible.x1 = toolbar_state.visible.x1; + if (state.visible.x1 - state.visible.x0 - scroll_v < 0) { + error = xwimp_close_window(dialog_url_complete); + if (error) { + LOG(("xwimp_close_window: 0x%x: %s", + error->errnum, error->errmess)); + warn_user("WimpError", error->errmess); + } + } else { + error = xwimp_open_window_nested_with_flags(&state, (wimp_w)-1, 0); + if (error) { + LOG(("xwimp_open_window: 0x%x: %s", + error->errnum, error->errmess)); + warn_user("WimpError", error->errmess); + return; + } + open->next = dialog_url_complete; + } +} + + +/** + * Try to close the current url completion window + * + * \param g the gui_window the user clicked on (or NULL to forcibly close) + * \param i the icon the user clicked on to prompt the close + * \return whether the window was closed + */ +bool ro_gui_url_complete_close(struct gui_window *g, wimp_i i) { + os_error *error; + + if ((g && (i == ICON_TOOLBAR_URL) && (g->window == url_complete_parent))) + return false; + + free(url_complete_matches); + free(url_complete_matched_string); + free(url_complete_original_url); + url_complete_matches = NULL; + url_complete_matched_string = NULL; + url_complete_original_url = NULL; + url_complete_matches_allocated = 0; + url_complete_matches_available = 0; + url_complete_keypress_selection = -1; + url_complete_matches_selection = -1; + url_complete_parent = 0; + + error = xwimp_close_window(dialog_url_complete); + if (error) { + LOG(("xwimp_close_window: 0x%x: %s", + error->errnum, error->errmess)); + warn_user("WimpError", error->errmess); + } + return true; +} + + +/** + * Redraws a section of the URL completion window + * + * \param redraw the area to redraw + * \param tree the tree to redraw + */ +void ro_gui_url_complete_redraw(wimp_draw *redraw) { + osbool more; + os_error *error; + int clip_y0, clip_y1, origin_y; + int first_line, last_line, line; + + /* initialise our icon */ + url_complete_icon.flags = wimp_ICON_INDIRECTED | wimp_ICON_VCENTRED | + wimp_ICON_TEXT | wimp_ICON_FILLED | + (wimp_COLOUR_BLACK << wimp_ICON_FG_COLOUR_SHIFT) | + (wimp_COLOUR_WHITE << wimp_ICON_BG_COLOUR_SHIFT); + url_complete_icon.extent.x0 = 0; + url_complete_icon.extent.x1 = 16384; + url_complete_icon.data.indirected_text.validation = url_complete_icon_null; + + /* redraw */ + more = wimp_redraw_window(redraw); + while (more) { + origin_y = redraw->box.y1 - redraw->yscroll; + clip_y0 = redraw->clip.y0 - origin_y; + clip_y1 = redraw->clip.y1 - origin_y; + + first_line = (-clip_y1) / 44; + last_line = (-clip_y0 + 43) / 44; + + for (line = first_line; line < last_line; line++) { + if (line == url_complete_matches_selection) + url_complete_icon.flags |= wimp_ICON_SELECTED; + else + url_complete_icon.flags &= ~wimp_ICON_SELECTED; + url_complete_icon.extent.y1 = -line * 44; + url_complete_icon.extent.y0 = -(line + 1) * 44; + url_complete_icon.data.indirected_text.text = + url_complete_matches[line]; + url_complete_icon.data.indirected_text.size = + strlen(url_complete_matches[line]); + error = xwimp_plot_icon(&url_complete_icon); + if (error) { + LOG(("xwimp_plot_icon: 0x%x: %s", + error->errnum, error->errmess)); + warn_user("WimpError", error->errmess); + } + } + more = wimp_get_rectangle(redraw); + } +} + + +/** + * Handle mouse movements/clicks over the URL completion window. + */ +void ro_gui_url_complete_mouse_at(wimp_pointer *pointer) { + wimp_window_state state; + os_error *error; + int selection, old_selection; + struct gui_window *g; + char *url; + + if ((mouse_x == pointer->pos.x) && (mouse_y == pointer->pos.y) && + (pointer->buttons == 0)) + return; + mouse_x = pointer->pos.x; + mouse_y = pointer->pos.y; + + state.w = dialog_url_complete; + 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); + return; + } + selection = (state.visible.y1 - pointer->pos.y - state.yscroll) / 44; + if (selection != url_complete_matches_selection) { + if (url_complete_matches_selection == -1) { + g = ro_gui_window_lookup(url_complete_parent); + if (!g) + return; + url = ro_gui_get_icon_string(g->toolbar->toolbar_handle, + ICON_TOOLBAR_URL); + free(url_complete_original_url); + url_complete_original_url = malloc(strlen(url) + 1); + if (!url_complete_original_url) + return; + strcpy(url_complete_original_url, url); + } + old_selection = url_complete_matches_selection; + url_complete_matches_selection = selection; + error = xwimp_force_redraw(dialog_url_complete, + 0, -(old_selection + 1) * 44, 65536, -old_selection * 44); + if (error) { + LOG(("xwimp_force_redraw: 0x%x: %s", + error->errnum, error->errmess)); + warn_user("WimpError", error->errmess); + } + error = xwimp_force_redraw(dialog_url_complete, + 0, -(url_complete_matches_selection + 1) * 44, + 65536, -url_complete_matches_selection * 44); + if (error) { + LOG(("xwimp_force_redraw: 0x%x: %s", + error->errnum, error->errmess)); + warn_user("WimpError", error->errmess); + } + } + + /* clicks */ + if ((pointer->buttons == wimp_CLICK_SELECT) || + (pointer->buttons == wimp_CLICK_ADJUST)) { + g = ro_gui_window_lookup(url_complete_parent); + if (!g) + return; + ro_gui_set_icon_string(g->toolbar->toolbar_handle, + ICON_TOOLBAR_URL, + url_complete_matches[url_complete_matches_selection]); + browser_window_go(g->bw, + url_complete_matches[url_complete_matches_selection], + 0); + ro_gui_url_complete_close(NULL, 0); + } + +} + + +/** + * Dumps all matching URLs to stderr. + */ +void url_complete_dump_matches(const char *url) { + char *match_url; + struct url_data *reference = NULL; + char *output; + + match_url = url_store_match_string(url); + if (!match_url) + return; + + fprintf(stderr, "\nDumping matches for '%s' ('%s'):\n", url, match_url); + while ((output = url_store_match(match_url, &reference))) { + fprintf(stderr, " - "); + fprintf(stderr, output); + fprintf(stderr, "\n"); + } + fprintf(stderr, "\nEnd of matches.\n\n"); + free(match_url); +} diff --git a/riscos/url_complete.h b/riscos/url_complete.h new file mode 100644 index 000000000..fa70efc14 --- /dev/null +++ b/riscos/url_complete.h @@ -0,0 +1,26 @@ +/* + * This file is part of NetSurf, http://netsurf.sourceforge.net/ + * Licensed under the GNU General Public License, + * http://www.opensource.org/licenses/gpl-license + * Copyright 2005 Richard Wilson + */ + +/** \file + * Central repository for URL data (interface). + */ + +#ifndef _NETSURF_RISCOS_URLCOMPLETE_H_ +#define _NETSURF_RISCOS_URLCOMPLETE_H_ + +#include +#include "netsurf/riscos/gui.h" + +bool ro_gui_url_complete_keypress(struct gui_window *g, int key); +void ro_gui_url_complete_resize(struct gui_window *g, wimp_open *open); +bool ro_gui_url_complete_close(struct gui_window *g, wimp_i i); +void ro_gui_url_complete_redraw(wimp_draw *redraw); +void ro_gui_url_complete_mouse_at(wimp_pointer *pointer); + +void url_complete_dump_matches(const char *url); + +#endif diff --git a/riscos/window.c b/riscos/window.c index 87d63d86a..50c103739 100644 --- a/riscos/window.c +++ b/riscos/window.c @@ -25,6 +25,7 @@ #include "oslib/wimpspriteop.h" #include "netsurf/utils/config.h" #include "netsurf/content/content.h" +#include "netsurf/content/url_store.h" #include "netsurf/css/css.h" #include "netsurf/desktop/plotters.h" #include "netsurf/render/box.h" @@ -35,6 +36,7 @@ #include "netsurf/riscos/theme.h" #include "netsurf/riscos/thumbnail.h" #include "netsurf/riscos/treeview.h" +#include "netsurf/riscos/url_complete.h" #include "netsurf/riscos/wimp.h" #include "netsurf/utils/log.h" #include "netsurf/utils/url.h" @@ -929,6 +931,9 @@ void ro_gui_window_open(struct gui_window *g, wimp_open *open) } + /* first resize stops any flickering by making the URL window on top */ + ro_gui_url_complete_resize(g, open); + error = xwimp_open_window(open); if (error) { LOG(("xwimp_open_window: 0x%x: %s", @@ -957,8 +962,11 @@ void ro_gui_window_open(struct gui_window *g, wimp_open *open) g->old_height = height; } - if (g->toolbar) + if (g->toolbar) { ro_gui_theme_process_toolbar(g->toolbar, -1); + /* second resize updates to the new URL bar width */ + ro_gui_url_complete_resize(g, open); + } } @@ -1090,6 +1098,9 @@ void ro_gui_toolbar_click(struct gui_window *g, wimp_pointer *pointer) /* Store the toolbar */ current_toolbar = g->toolbar; + + /* try to close url-completion */ + ro_gui_url_complete_close(g, pointer->i); /* Handle Menu clicks */ @@ -1232,6 +1243,9 @@ void ro_gui_window_click(struct gui_window *g, wimp_pointer *pointer) assert(g); + /* try to close url-completion */ + ro_gui_url_complete_close(g, pointer->i); + xosbyte1(osbyte_SCAN_KEYBOARD, 0 ^ 0x80, 0, &shift); state.w = pointer->w; @@ -1486,6 +1500,10 @@ bool ro_gui_window_keypress(struct gui_window *g, int key, bool toolbar) ro_gui_view_source(content); return true; + case wimp_KEY_CONTROL + wimp_KEY_F8: /* Dump url_store. */ + url_store_dump(); + return true; + case wimp_KEY_F9: /* Dump content for debugging. */ switch (content->type) { case CONTENT_HTML: @@ -1513,6 +1531,7 @@ bool ro_gui_window_keypress(struct gui_window *g, int key, bool toolbar) case wimp_KEY_RETURN: if (!toolbar) break; + ro_gui_url_complete_close(NULL, 0); toolbar_url = ro_gui_get_icon_string(g->toolbar->toolbar_handle, ICON_TOOLBAR_URL); res = url_normalize(toolbar_url, &url); @@ -1524,6 +1543,8 @@ bool ro_gui_window_keypress(struct gui_window *g, int key, bool toolbar) return true; case wimp_KEY_ESCAPE: + if (ro_gui_url_complete_close(0, 0)) + return true; browser_window_stop(g->bw); return true; @@ -1569,9 +1590,12 @@ bool ro_gui_window_keypress(struct gui_window *g, int key, bool toolbar) case wimp_KEY_PAGE_DOWN: case wimp_KEY_CONTROL | wimp_KEY_UP: case wimp_KEY_CONTROL | wimp_KEY_DOWN: + if (toolbar) + return ro_gui_url_complete_keypress(g, key); break; - default: + if (toolbar) + return ro_gui_url_complete_keypress(g, key); return false; } @@ -1601,7 +1625,7 @@ bool ro_gui_window_keypress(struct gui_window *g, int key, bool toolbar) break; } - wimp_open_window((wimp_open *) &state); + wimp_open_window((wimp_open *) &state); return true; } -- cgit v1.2.3