From 3afd9c97310d58c0c6588d18887244328590731e Mon Sep 17 00:00:00 2001 From: Michael Drake Date: Tue, 7 May 2013 14:41:40 +0100 Subject: Remove search context from browser window, simplify search interface for front ends. Added content interface for search. Removed bw->cur_search search context. Desktop layer now does nothing except pass search requests from front end onto the bw's current_content via the content interface. Search API reduced to a pair of functions at each level: {desktop|content|html|textplain}_search and {desktop|content|html|textplain}_search_clear Updated front ends to use simplified search API. Only tested GTK and RO builds. These confine the search stuff to render/. However search still uses struct selection. The handling for which is still spread over desktop/ and render/. Also the render/search code itself still fiddles inside html and textplain privates. --- amiga/search.c | 28 +++------ atari/search.c | 14 ++--- cocoa/SearchWindowController.m | 6 +- content/content.c | 22 +++++++ content/content.h | 5 ++ content/content_protected.h | 5 ++ desktop/browser.c | 5 -- desktop/browser_private.h | 3 - desktop/search.c | 103 +++++++++----------------------- desktop/search.h | 20 +++---- gtk/scaffolding.c | 10 ++-- gtk/search.c | 28 ++++----- render/html.c | 34 ++--------- render/html_interaction.c | 76 +++++++++++++++++++++++- render/html_internal.h | 8 ++- render/search.c | 111 +++++++++++++--------------------- render/search.h | 25 ++------ render/textplain.c | 113 +++++++++++++++++++++++++---------- render/textplain.h | 1 - riscos/search.c | 131 ++++++++++++++++------------------------- 20 files changed, 365 insertions(+), 383 deletions(-) diff --git a/amiga/search.c b/amiga/search.c index 12fe582cb..dd2aa2320 100755 --- a/amiga/search.c +++ b/amiga/search.c @@ -86,15 +86,11 @@ static struct gui_search_callbacks ami_search_callbacks = { */ void ami_search_open(struct gui_window *gwin) { - if (browser_window_search_create_context(gwin->shared->bw, - &ami_search_callbacks, NULL) == false) - return; - search_insert = true; if(fwin) { - browser_window_search_destroy_context(fwin->gwin->shared->bw); + browser_window_search_clear(fwin->gwin->shared->bw); ami_search_set_forward_state(true, NULL); ami_search_set_back_state(true, NULL); fwin->gwin->shared->searchwin = NULL; @@ -181,7 +177,7 @@ void ami_search_open(struct gui_window *gwin) void ami_search_close(void) { - browser_window_search_destroy_context(fwin->gwin->shared->bw); + browser_window_search_clear(fwin->gwin->shared->bw); ami_search_set_forward_state(true, NULL); ami_search_set_back_state(true, NULL); fwin->gwin->shared->searchwin = NULL; @@ -206,7 +202,7 @@ BOOL ami_search_event(void) switch(result & WMHI_GADGETMASK) { case GID_SEARCHSTRING: - browser_window_search_destroy_context( + browser_window_search_clear( fwin->gwin->shared->bw); ami_search_set_forward_state( true, NULL); @@ -229,13 +225,10 @@ BOOL ami_search_event(void) search_insert = true; flags = SEARCH_FLAG_FORWARDS | ami_search_flags(); - if (browser_window_search_verify_new( + browser_window_search( fwin->gwin->shared->bw, - &ami_search_callbacks, NULL)) - browser_window_search_step( - fwin->gwin->shared->bw, - flags, - ami_search_string()); + &ami_search_callbacks, NULL, + flags, ami_search_string()); ActivateWindow(fwin->gwin->shared->win); break; @@ -243,13 +236,10 @@ BOOL ami_search_event(void) search_insert = true; flags = ~SEARCH_FLAG_FORWARDS & ami_search_flags(); - if (browser_window_search_verify_new( + browser_window_search( fwin->gwin->shared->bw, - &ami_search_callbacks, NULL)) - browser_window_search_step( - fwin->gwin->shared->bw, - flags, - ami_search_string()); + &ami_search_callbacks, NULL, + flags, ami_search_string()); ActivateWindow(fwin->gwin->shared->win); break; } diff --git a/atari/search.c b/atari/search.c index 17241d1ae..6d8f53bec 100644 --- a/atari/search.c +++ b/atari/search.c @@ -224,7 +224,7 @@ void nsatari_search_session_destroy(struct s_search_form_session *s) { if (s != NULL) { LOG(("")); - browser_window_search_destroy_context(s->bw); + browser_window_search_clear(s->bw); free(s); } } @@ -270,7 +270,7 @@ void nsatari_search_perform(struct s_search_form_session *s, OBJECT *obj, if(search_session_compare(s, obj)){ - browser_window_search_destroy_context(s->bw); + browser_window_search_clear(s->bw); apply_form(obj, &s->state); } else { @@ -282,11 +282,9 @@ void nsatari_search_perform(struct s_search_form_session *s, OBJECT *obj, else s->state.flags &= (~SEARCH_FLAG_FORWARDS); - if( browser_window_search_verify_new(s->bw, &nsatari_search_callbacks, s) ){ - LOG(("searching for: %s\n", gemtk_obj_get_text(obj, TOOLBAR_TB_SRCH))); - browser_window_search_step(s->bw, s->state.flags, - gemtk_obj_get_text(obj, TOOLBAR_TB_SRCH)); - } + browser_window_search(s->bw, &nsatari_search_callbacks, s, + s->state.flags, + gemtk_obj_get_text(obj, TOOLBAR_TB_SRCH)); } @@ -305,7 +303,7 @@ struct s_search_form_session * nsatari_search_session_create(OBJECT * obj, apply_form(obj, &sfs->state); - browser_window_search_destroy_context(bw); + browser_window_search_clear(bw); return(sfs); } diff --git a/cocoa/SearchWindowController.m b/cocoa/SearchWindowController.m index 858ed0e0d..06147fa1a 100644 --- a/cocoa/SearchWindowController.m +++ b/cocoa/SearchWindowController.m @@ -76,15 +76,13 @@ static struct gui_search_callbacks cocoa_search_callbacks = { if (selectAll) flags |= SEARCH_FLAG_SHOWALL; struct browser_window *bw = [browser browser]; - if (bw != NULL && browser_window_search_verify_new( bw, &cocoa_search_callbacks, self )) { - browser_window_search_step( bw, flags, [searchString UTF8String] ); - } + browser_window_search( bw, &cocoa_search_callbacks, self, flags, [searchString UTF8String] ); } - (IBAction) searchStringDidChange: (id) sender; { struct browser_window *bw = [browser browser]; - browser_window_search_destroy_context( bw ); + browser_window_search_clear( bw ); [self setCanGoBack: YES]; [self setCanGoForward: YES]; diff --git a/content/content.c b/content/content.c index 3533d943c..74abdbfab 100644 --- a/content/content.c +++ b/content/content.c @@ -831,6 +831,28 @@ bool content_drop_file_at_point(struct hlcache_handle *h, } +void content_search(struct hlcache_handle *h, + struct gui_search_callbacks *gui_callbacks, void *gui_data, + search_flags_t flags, const char *string) +{ + struct content *c = hlcache_handle_get_content(h); + assert(c != 0); + + if (c->handler->search != NULL) + c->handler->search(c, gui_callbacks, gui_data, flags, string); +} + + +void content_search_clear(struct hlcache_handle *h) +{ + struct content *c = hlcache_handle_get_content(h); + assert(c != 0); + + if (c->handler->search_clear != NULL) + c->handler->search_clear(c); +} + + void content_debug_dump(struct hlcache_handle *h, FILE *f) { struct content *c = hlcache_handle_get_content(h); diff --git a/content/content.h b/content/content.h index 3f93d603b..3e5588815 100644 --- a/content/content.h +++ b/content/content.h @@ -38,6 +38,7 @@ #include "utils/types.h" #include "content/content_factory.h" #include "content/content_type.h" +#include "desktop/search.h" #include "desktop/mouse.h" #include "desktop/plot_style.h" @@ -254,6 +255,10 @@ bool content_scroll_at_point(struct hlcache_handle *h, int x, int y, int scrx, int scry); bool content_drop_file_at_point(struct hlcache_handle *h, int x, int y, char *file); +void content_search(struct hlcache_handle *h, + struct gui_search_callbacks *gui_callbacks, void *gui_data, + search_flags_t flags, const char *string); +void content_search_clear(struct hlcache_handle *h); void content_debug_dump(struct hlcache_handle *h, FILE *f); struct content_rfc5988_link *content_find_rfc5988_link(struct hlcache_handle *c, lwc_string *rel); diff --git a/content/content_protected.h b/content/content_protected.h index 8efe763aa..57ce35775 100644 --- a/content/content_protected.h +++ b/content/content_protected.h @@ -73,6 +73,11 @@ struct content_handler { int scrx, int scry); bool (*drop_file_at_point)(struct content *c, int x, int y, char *file); + void (*search)(struct content *c, + struct gui_search_callbacks *gui_callbacks, + void *gui_data, search_flags_t flags, + const char *string); + void (*search_clear)(struct content *c); void (*debug_dump)(struct content *c, FILE *f); nserror (*clone)(const struct content *old, struct content **newc); bool (*matches_quirks)(const struct content *c, bool quirks); diff --git a/desktop/browser.c b/desktop/browser.c index 9e12e8c0d..a02807eeb 100644 --- a/desktop/browser.c +++ b/desktop/browser.c @@ -764,7 +764,6 @@ void browser_window_initialise_common(struct browser_window *bw, bw->history = history_clone(clone->history); /* window characteristics */ - bw->cur_search = NULL; bw->refresh_interval = -1; bw->reformat_pending = false; @@ -2128,10 +2127,6 @@ void browser_window_destroy_internal(struct browser_window *bw) } } - /* Destroying a search context causes it to redraw any deselected, - * content areas, so do this first */ - browser_window_search_destroy_context(bw); - /* Destruction order is important: we must ensure that the frontend * destroys any window(s) associated with this browser window before * we attempt any destructive cleanup. diff --git a/desktop/browser_private.h b/desktop/browser_private.h index 4c14b1700..4412f4bf4 100644 --- a/desktop/browser_private.h +++ b/desktop/browser_private.h @@ -153,9 +153,6 @@ struct browser_window { } selection; bool can_edit; - /** Current context for free text search, or NULL if none */ - struct search_context *cur_search; - /** current javascript context */ struct jscontext *jsctx; diff --git a/desktop/search.c b/desktop/search.c index 29d28bdaa..014488e2d 100644 --- a/desktop/search.c +++ b/desktop/search.c @@ -44,93 +44,44 @@ #include "utils/utils.h" -/* callback informing us that a search context is nolonger valid */ -static void browser_window_search_invalidate(struct search_context *context, - void *p) -{ - struct browser_window *bw = p; - assert(bw != NULL); - - if (bw->cur_search != NULL && bw->cur_search == context) { - /* The browser's current search is the one being invalidated */ - bw->cur_search = NULL; - } -} -bool browser_window_search_create_context(struct browser_window *bw, - struct gui_search_callbacks *gui_callbacks, void *gui_p) +/** + * Starts or continues an existing search. + * + * \param bw the browser_window to search + * \param callbacks callbacks vtable to update frontend according to results + * \param gui_data a pointer returned to the callbacks + * \param flags search flags + * \param string string to search for + */ +void browser_window_search(struct browser_window *bw, + struct gui_search_callbacks *gui_callbacks, void *gui_data, + search_flags_t flags, const char *string) { - struct search_callbacks callbacks; - assert(bw != NULL); assert(gui_callbacks != NULL); - if (bw->cur_search != NULL) - search_destroy_context(bw->cur_search); - bw->cur_search = NULL; - - if (!bw->current_content) - return false; - - callbacks.gui = gui_callbacks; - callbacks.gui_p = gui_p; - callbacks.invalidate = browser_window_search_invalidate; - callbacks.p = bw; - bw->cur_search = search_create_context(bw->current_content, callbacks); - - if (bw->cur_search == NULL) - return false; - - return true; -} - - -void browser_window_search_destroy_context(struct browser_window *bw) -{ - assert(bw != NULL); + if (bw == NULL || bw->current_content == NULL) + return; - if (bw->cur_search != NULL) - search_destroy_context(bw->cur_search); - bw->cur_search = NULL; + content_search(bw->current_content, gui_callbacks, gui_data, + flags, string); } /** - * to simplify calls to search_step(); checks that the browser_window is - * non-NULL, creates a new search_context in case of a new search - * \param bw the browser_window the search refers to - * \param callbacks the callbacks to modify appearance according to results - * \param gui_p a pointer returned to the callbacks - * \return true for success + * Clear up a search. Frees any memory used by the search + * + * \param bw the browser_window to search + * \param callbacks callbacks vtable to update frontend according to results + * \param gui_data a pointer returned to the callbacks + * \param flags search flags + * \param string string to search for */ -bool browser_window_search_verify_new(struct browser_window *bw, - struct gui_search_callbacks *gui_callbacks, void *gui_p) -{ - if (bw == NULL) - return false; - if (bw->cur_search == NULL) - return browser_window_search_create_context(bw, - gui_callbacks, gui_p); - - return true; -} - - -void browser_window_search_step(struct browser_window *bw, - search_flags_t flags, const char *string) +void browser_window_search_clear(struct browser_window *bw) { - assert(bw != NULL); + if (bw == NULL || bw->current_content == NULL) + return; - if (bw->cur_search != NULL) - search_step(bw->cur_search, flags, string); + content_search_clear(bw->current_content); } - - -void browser_window_search_show_all(bool all, struct browser_window *bw) -{ - assert(bw != NULL); - - if (bw->cur_search != NULL) - search_show_all(all, bw->cur_search); -} - diff --git a/desktop/search.h b/desktop/search.h index e178138de..8440ce982 100644 --- a/desktop/search.h +++ b/desktop/search.h @@ -22,10 +22,14 @@ #include #include +struct browser_window; + typedef enum { - SEARCH_FLAG_CASE_SENSITIVE = (1 << 0), - SEARCH_FLAG_FORWARDS = (1 << 1), - SEARCH_FLAG_SHOWALL = (1 << 2) + SEARCH_FLAG_NONE = 0, + SEARCH_FLAG_CASE_SENSITIVE = (1 << 0), + SEARCH_FLAG_FORWARDS = (1 << 1), + SEARCH_FLAG_BACKWARDS = (1 << 2), + SEARCH_FLAG_SHOWALL = (1 << 3) } search_flags_t; /** @@ -74,13 +78,9 @@ struct gui_search_callbacks { }; -bool browser_window_search_create_context(struct browser_window *bw, - struct gui_search_callbacks *gui_callbacks, void *gui_p); -void browser_window_search_destroy_context(struct browser_window *bw); -bool browser_window_search_verify_new(struct browser_window *bw, - struct gui_search_callbacks *gui_callbacks, void *gui_p); -void browser_window_search_step(struct browser_window *bw, +void browser_window_search(struct browser_window *bw, + struct gui_search_callbacks *gui_callbacks, void *gui_data, search_flags_t flags, const char *string); -void browser_window_search_show_all(bool all, struct browser_window *bw); +void browser_window_search_clear(struct browser_window *bw); #endif diff --git a/gtk/scaffolding.c b/gtk/scaffolding.c index 4097837a9..8f1f4447e 100644 --- a/gtk/scaffolding.c +++ b/gtk/scaffolding.c @@ -1423,7 +1423,7 @@ MULTIHANDLER(reload) return TRUE; /* clear potential search effects */ - browser_window_search_destroy_context(bw); + browser_window_search_clear(bw); nsgtk_search_set_forward_state(true, bw); nsgtk_search_set_back_state(true, bw); @@ -1442,7 +1442,7 @@ MULTIHANDLER(back) return TRUE; /* clear potential search effects */ - browser_window_search_destroy_context(bw); + browser_window_search_clear(bw); nsgtk_search_set_forward_state(true, bw); nsgtk_search_set_back_state(true, bw); @@ -1462,7 +1462,7 @@ MULTIHANDLER(forward) return TRUE; /* clear potential search effects */ - browser_window_search_destroy_context(bw); + browser_window_search_clear(bw); nsgtk_search_set_forward_state(true, bw); nsgtk_search_set_back_state(true, bw); @@ -2431,7 +2431,7 @@ void nsgtk_scaffolding_toggle_search_bar_visibility(nsgtk_scaffolding *g) g_object_get(G_OBJECT(g->search->bar), "visible", &vis, NULL); if (vis) { if (bw != NULL) - browser_window_search_destroy_context(bw); + browser_window_search_clear(bw); nsgtk_search_set_forward_state(true, bw); nsgtk_search_set_back_state(true, bw); gtk_widget_hide(GTK_WIDGET(g->search->bar)); @@ -2468,7 +2468,7 @@ void nsgtk_scaffolding_set_top_level(struct gui_window *gw) nsgtk_window_update_back_forward(sc); /* clear effects of potential searches */ - browser_window_search_destroy_context(bw); + browser_window_search_clear(bw); nsgtk_search_set_forward_state(true, bw); nsgtk_search_set_back_state(true, bw); diff --git a/gtk/search.c b/gtk/search.c index 37b7397c4..3d6bba05d 100644 --- a/gtk/search.c +++ b/gtk/search.c @@ -70,10 +70,9 @@ gboolean nsgtk_search_forward_button_clicked(GtkWidget *widget, gpointer data) (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON( nsgtk_scaffolding_search(g)->checkAll)) ? SEARCH_FLAG_SHOWALL : 0); - if (browser_window_search_verify_new(bw, &nsgtk_search_callbacks, - (void *)bw)) - browser_window_search_step(bw, flags, gtk_entry_get_text( - nsgtk_scaffolding_search(g)->entry)); + + browser_window_search(bw, &nsgtk_search_callbacks, (void *)bw, flags, + gtk_entry_get_text(nsgtk_scaffolding_search(g)->entry)); return TRUE; } @@ -94,10 +93,9 @@ gboolean nsgtk_search_back_button_clicked(GtkWidget *widget, gpointer data) (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON( nsgtk_scaffolding_search(g)->checkAll)) ? SEARCH_FLAG_SHOWALL : 0); - if (browser_window_search_verify_new(bw, &nsgtk_search_callbacks, - (void *)bw)) - browser_window_search_step(bw, flags, gtk_entry_get_text( - nsgtk_scaffolding_search(g)->entry)); + + browser_window_search(bw, &nsgtk_search_callbacks, (void *)bw, flags, + gtk_entry_get_text(nsgtk_scaffolding_search(g)->entry)); return TRUE; } @@ -120,8 +118,6 @@ gboolean nsgtk_search_entry_changed(GtkWidget *widget, gpointer data) assert(bw != NULL); - browser_window_search_destroy_context(bw); - nsgtk_search_set_forward_state(true, (void *)bw); nsgtk_search_set_back_state(true, (void *)bw); @@ -133,10 +129,8 @@ gboolean nsgtk_search_entry_changed(GtkWidget *widget, gpointer data) nsgtk_scaffolding_search(g)->checkAll)) ? SEARCH_FLAG_SHOWALL : 0); - if (browser_window_search_verify_new(bw, &nsgtk_search_callbacks, - (void *)bw)) - browser_window_search_step(bw, flags, gtk_entry_get_text( - nsgtk_scaffolding_search(g)->entry)); + browser_window_search(bw, &nsgtk_search_callbacks, (void *)bw, flags, + gtk_entry_get_text(nsgtk_scaffolding_search(g)->entry)); return TRUE; } @@ -158,10 +152,8 @@ gboolean nsgtk_search_entry_activate(GtkWidget *widget, gpointer data) nsgtk_scaffolding_search(g)->checkAll)) ? SEARCH_FLAG_SHOWALL : 0); - if (browser_window_search_verify_new(bw, &nsgtk_search_callbacks, - (void *)bw)) - browser_window_search_step(bw, flags, gtk_entry_get_text( - nsgtk_scaffolding_search(g)->entry)); + browser_window_search(bw, &nsgtk_search_callbacks, (void *)bw, flags, + gtk_entry_get_text(nsgtk_scaffolding_search(g)->entry)); return FALSE; } diff --git a/render/html.c b/render/html.c index 1ff1c7cc7..364083bae 100644 --- a/render/html.c +++ b/render/html.c @@ -330,6 +330,8 @@ html_create_html_data(html_content *c, const http_parameter *params) c->selection_owner.none = true; c->focus_type = HTML_FOCUS_SELF; c->focus_owner.self = true; + c->search = NULL; + c->search_string = NULL; c->scripts_count = 0; c->scripts = NULL; c->jscontext = NULL; @@ -2006,36 +2008,6 @@ static void html_debug_dump(struct content *c, FILE *f) } -/** - * Set an HTML content's search context - * - * \param c content of type html - * \param s search context, or NULL if none - */ - -void html_set_search(struct content *c, struct search_context *s) -{ - html_content *html = (html_content *) c; - - html->search = s; -} - - -/** - * Return an HTML content's search context - * - * \param c content of type html - * \return content's search context, or NULL if none - */ - -struct search_context *html_get_search(struct content *c) -{ - html_content *html = (html_content *) c; - - return html->search; -} - - #if ALWAYS_DUMP_FRAMESET /** * Print a frameset tree to stderr. @@ -2276,6 +2248,8 @@ static const content_handler html_content_handler = { .get_contextual_content = html_get_contextual_content, .scroll_at_point = html_scroll_at_point, .drop_file_at_point = html_drop_file_at_point, + .search = html_search, + .search_clear = html_search_clear, .debug_dump = html_debug_dump, .clone = html_clone, .type = html_content_type, diff --git a/render/html_interaction.c b/render/html_interaction.c index 0dc36472d..7c3de2a01 100644 --- a/render/html_interaction.c +++ b/render/html_interaction.c @@ -43,6 +43,7 @@ #include "render/form.h" #include "render/html_internal.h" #include "render/imagemap.h" +#include "render/search.h" #include "javascript/js.h" #include "utils/messages.h" #include "utils/utils.h" @@ -952,7 +953,7 @@ void html_mouse_action(struct content *c, struct browser_window *bw, /** * Handle keypresses. * - * \param c content of type CONTENT_TEXTPLAIN + * \param c content of type HTML * \param key The UCS4 character codepoint * \return true if key handled, false otherwise */ @@ -1004,6 +1005,79 @@ bool html_keypress(struct content *c, uint32_t key) } +/** + * Handle search. + * + * \param c content of type HTML + * \param gui_callbacks vtable for updating front end + * \param gui_data front end private data + * \param flags search flags + * \param string search string + */ +void html_search(struct content *c, + struct gui_search_callbacks *gui_callbacks, void *gui_data, + search_flags_t flags, const char *string) +{ + html_content *html = (html_content *)c; + + assert(c != NULL); + + if (string != NULL && html->search_string != NULL && + strcmp(string, html->search_string) == 0 && + html->search != NULL) { + /* Continue prev. search */ + search_step(html->search, flags, string); + + } else if (string != NULL) { + /* New search */ + free(html->search_string); + html->search_string = strdup(string); + if (html->search_string == NULL) + return; + + if (html->search != NULL) { + search_destroy_context(html->search); + html->search = NULL; + } + + html->search = search_create_context(c, CONTENT_HTML, + gui_callbacks, gui_data); + + if (html->search == NULL) + return; + + search_step(html->search, flags, string); + + } else { + /* Clear search */ + html_search_clear(c); + + free(html->search_string); + html->search_string = NULL; + } +} + + +/** + * Terminate a search. + * + * \param c content of type HTML + */ +void html_search_clear(struct content *c) +{ + html_content *html = (html_content *)c; + + assert(c != NULL); + + free(html->search_string); + html->search_string = NULL; + + if (html->search != NULL) + search_destroy_context(html->search); + html->search = NULL; +} + + /** * Callback for in-page scrollbars. */ diff --git a/render/html_internal.h b/render/html_internal.h index a78dc8f8a..b491f197a 100644 --- a/render/html_internal.h +++ b/render/html_internal.h @@ -161,6 +161,8 @@ typedef struct html_content { /** Context for free text search, or NULL if none */ struct search_context *search; + /** Search string or NULL */ + char *search_string; } html_content; @@ -210,8 +212,6 @@ void html_set_focus(html_content *html, html_focus_type focus_type, struct browser_window *html_get_browser_window(struct content *c); -struct search_context *html_get_search(struct content *c); -void html_set_search(struct content *c, struct search_context *s); /** * Complete conversion of an HTML document @@ -247,6 +247,10 @@ void html_mouse_action(struct content *c, struct browser_window *bw, bool html_keypress(struct content *c, uint32_t key); void html_overflow_scroll_callback(void *client_data, struct scrollbar_msg_data *scrollbar_data); +void html_search(struct content *c, + struct gui_search_callbacks *gui_callbacks, void *gui_data, + search_flags_t flags, const char *string); +void html_search_clear(struct content *c); /* in render/html_script.c */ diff --git a/render/search.c b/render/search.c index 617d7ebcf..895cff0a1 100644 --- a/render/search.c +++ b/render/search.c @@ -63,7 +63,8 @@ struct list_entry { }; struct search_context { - struct search_callbacks callbacks; + struct gui_search_callbacks *gui; + void *gui_p; struct content *c; struct list_entry *found; struct list_entry *current; /* first for select all */ @@ -75,18 +76,14 @@ struct search_context { /* Exported function documented in search.h */ -struct search_context * search_create_context(hlcache_handle *h, - struct search_callbacks callbacks) +struct search_context * search_create_context(struct content *c, + content_type type, struct gui_search_callbacks *callbacks, + void *gui_data) { struct search_context *context; struct list_entry *search_head; - struct content *c = hlcache_handle_get_content(h); - if (h == NULL) - return NULL; - - if (content_get_type(h) != CONTENT_HTML && - content_get_type(h) != CONTENT_TEXTPLAIN) { + if (type != CONTENT_HTML && type != CONTENT_TEXTPLAIN) { return NULL; } @@ -117,14 +114,9 @@ struct search_context * search_create_context(hlcache_handle *h, context->prev_case_sens = false; context->newsearch = true; context->c = c; - context->is_html = (content_get_type(h) == CONTENT_HTML) ? true : false; - context->callbacks = callbacks; - - if (context->is_html) { - html_set_search(context->c, context); - } else { - textplain_set_search(context->c, context); - } + context->is_html = (type == CONTENT_HTML) ? true : false; + context->gui = callbacks; + context->gui_p = gui_data; return context; } @@ -477,10 +469,8 @@ static void search_text(const char *string, int string_len, context->string[string_len] = '\0'; } - if ((context->callbacks.gui != NULL) && - (context->callbacks.gui->hourglass != NULL)) - context->callbacks.gui->hourglass(true, - context->callbacks.gui_p); + if ((context->gui != NULL) && (context->gui->hourglass != NULL)) + context->gui->hourglass(true, context->gui_p); if (context->is_html == true) { res = find_occurrences_html(string, string_len, @@ -492,17 +482,14 @@ static void search_text(const char *string, int string_len, if (!res) { free_matches(context); - if ((context->callbacks.gui != NULL) && - (context->callbacks.gui->hourglass != - NULL)) - context->callbacks.gui->hourglass(false, - context->callbacks.gui_p); + if ((context->gui != NULL) && + (context->gui->hourglass != NULL)) + context->gui->hourglass(false, context->gui_p); return; } - if ((context->callbacks.gui != NULL) && - (context->callbacks.gui->hourglass != NULL)) - context->callbacks.gui->hourglass(false, - context->callbacks.gui_p); + if ((context->gui != NULL) && + (context->gui->hourglass != NULL)) + context->gui->hourglass(false, context->gui_p); context->prev_case_sens = case_sensitive; @@ -521,23 +508,22 @@ static void search_text(const char *string, int string_len, } } - if (context->callbacks.gui == NULL) + if (context->gui == NULL) return; - if (context->callbacks.gui->status != NULL) - context->callbacks.gui->status((context->current != NULL), - context->callbacks.gui_p); + if (context->gui->status != NULL) + context->gui->status((context->current != NULL), + context->gui_p); search_show_all(showall, context); - if (context->callbacks.gui->back_state != NULL) - context->callbacks.gui->back_state((context->current != NULL) && + if (context->gui->back_state != NULL) + context->gui->back_state((context->current != NULL) && (context->current->prev != NULL), - context->callbacks.gui_p); - if (context->callbacks.gui->forward_state != NULL) - context->callbacks.gui->forward_state( - (context->current != NULL) && - (context->current->next != NULL), - context->callbacks.gui_p); + context->gui_p); + if (context->gui->forward_state != NULL) + context->gui->forward_state((context->current != NULL) && + (context->current->next != NULL), + context->gui_p); if (context->current == NULL) return; @@ -572,14 +558,13 @@ void search_step(struct search_context *context, search_flags_t flags, int string_len; int i = 0; - if ((context == NULL) || (context->callbacks.gui == NULL)) { + if ((context == NULL) || (context->gui == NULL)) { warn_user("SearchError", 0); return; } - if (context->callbacks.gui->add_recent != NULL) - context->callbacks.gui->add_recent(string, - context->callbacks.gui_p); + if (context->gui->add_recent != NULL) + context->gui->add_recent(string, context->gui_p); string_len = strlen(string); for (i = 0; i < string_len; i++) @@ -588,15 +573,12 @@ void search_step(struct search_context *context, search_flags_t flags, if (i >= string_len) { union content_msg_data msg_data; free_matches(context); - if (context->callbacks.gui->status != NULL) - context->callbacks.gui->status(true, - context->callbacks.gui_p); - if (context->callbacks.gui->back_state != NULL) - context->callbacks.gui->back_state(false, - context->callbacks.gui_p); - if (context->callbacks.gui->forward_state != NULL) - context->callbacks.gui->forward_state(false, - context->callbacks.gui_p); + if (context->gui->status != NULL) + context->gui->status(true, context->gui_p); + if (context->gui->back_state != NULL) + context->gui->back_state(false, context->gui_p); + if (context->gui->forward_state != NULL) + context->gui->forward_state(false, context->gui_p); msg_data.scroll.area = false; msg_data.scroll.x0 = 0; @@ -672,22 +654,9 @@ void search_destroy_context(struct search_context *context) { assert(context != NULL); - if (context->callbacks.invalidate != NULL) { - context->callbacks.invalidate(context, context->callbacks.p); - } - - if (context->c != NULL) { - - if (context->is_html) { - html_set_search(context->c, NULL); - } else { - textplain_set_search(context->c, NULL); - } - } - if ((context->string != NULL) && (context->callbacks.gui != NULL) && - (context->callbacks.gui->add_recent != NULL)) { - context->callbacks.gui->add_recent(context->string, - context->callbacks.gui_p); + if ((context->string != NULL) && (context->gui != NULL) && + (context->gui->add_recent != NULL)) { + context->gui->add_recent(context->string, context->gui_p); free(context->string); } free_matches(context); diff --git a/render/search.h b/render/search.h index 70da31bca..43c93b3ab 100644 --- a/render/search.h +++ b/render/search.h @@ -26,31 +26,18 @@ struct search_context; -/** - * Called when a search context is destroyed - * \param context search context being invalidated - * \param p pointer for client data - */ -typedef void (*search_invalidate_callback)(struct search_context *context, - void *p); - -struct search_callbacks { - struct gui_search_callbacks *gui; - void *gui_p; /* private gui owned data */ - search_invalidate_callback invalidate; - void *p; /* private client data */ -}; - /** * create a search_context * - * \param h the hlcache_handle the search_context is connected to + * \param c the content the search_context is connected to + * \param type the content type of c * \param callbacks the callbacks to modify appearance according to results - * \param p the pointer to send to the callbacks + * \param p the pointer to send to the callbacks * \return true for success */ -struct search_context * search_create_context(struct hlcache_handle *h, - struct search_callbacks callbacks); +struct search_context * search_create_context(struct content *c, + content_type type, struct gui_search_callbacks *callbacks, + void *gui_data); /** * Ends the search process, invalidating all state diff --git a/render/textplain.c b/render/textplain.c index b9d0b81e5..89628f914 100644 --- a/render/textplain.c +++ b/render/textplain.c @@ -45,6 +45,7 @@ #include "render/search.h" #include "render/textplain.h" #include "render/html.h" +#include "render/search.h" #include "utils/http.h" #include "utils/log.h" #include "utils/messages.h" @@ -73,6 +74,8 @@ typedef struct textplain_content { /** Context for free text search, or NULL if none */ struct search_context *search; + /** Current search string, or NULL if none */ + char *search_string; } textplain_content; @@ -109,6 +112,10 @@ static void textplain_mouse_track(struct content *c, struct browser_window *bw, static void textplain_mouse_action(struct content *c, struct browser_window *bw, browser_mouse_state mouse, int x, int y); static bool textplain_keypress(struct content *c, uint32_t key); +static void textplain_search(struct content *c, + struct gui_search_callbacks *gui_callbacks, void *gui_data, + search_flags_t flags, const char *string); +static void textplain_search_clear(struct content *c); static void textplain_reformat(struct content *c, int width, int height); static void textplain_destroy(struct content *c); static bool textplain_redraw(struct content *c, struct content_redraw_data *data, @@ -117,7 +124,6 @@ static void textplain_open(struct content *c, struct browser_window *bw, struct content *page, struct object_params *params); void textplain_close(struct content *c); char *textplain_get_selection(struct content *c); -struct search_context *textplain_get_search(struct content *c); static nserror textplain_clone(const struct content *old, struct content **newc); static content_type textplain_content_type(void); @@ -142,6 +148,8 @@ static const content_handler textplain_content_handler = { .mouse_track = textplain_mouse_track, .mouse_action = textplain_mouse_action, .keypress = textplain_keypress, + .search = textplain_search, + .search_clear = textplain_search_clear, .redraw = textplain_redraw, .open = textplain_open, .close = textplain_close, @@ -758,6 +766,79 @@ bool textplain_keypress(struct content *c, uint32_t key) } +/** + * Handle search. + * + * \param c content of type text + * \param gui_callbacks vtable for updating front end + * \param gui_data front end private data + * \param flags search flags + * \param string search string + */ +void textplain_search(struct content *c, + struct gui_search_callbacks *gui_callbacks, void *gui_data, + search_flags_t flags, const char *string) +{ + textplain_content *text = (textplain_content *) c; + + assert(c != NULL); + + if (string != NULL && text->search_string != NULL && + strcmp(string, text->search_string) == 0 && + text->search != NULL) { + /* Continue prev. search */ + search_step(text->search, flags, string); + + } else if (string != NULL) { + /* New search */ + free(text->search_string); + text->search_string = strdup(string); + if (text->search_string == NULL) + return; + + if (text->search != NULL) { + search_destroy_context(text->search); + text->search = NULL; + } + + text->search = search_create_context(c, CONTENT_TEXTPLAIN, + gui_callbacks, gui_data); + + if (text->search == NULL) + return; + + search_step(text->search, flags, string); + + } else { + /* Clear search */ + textplain_search_clear(c); + + free(text->search_string); + text->search_string = NULL; + } +} + + +/** + * Terminate a search. + * + * \param c content of type text + */ +void textplain_search_clear(struct content *c) +{ + textplain_content *text = (textplain_content *) c; + + assert(c != NULL); + + free(text->search_string); + text->search_string = NULL; + + if (text->search != NULL) + search_destroy_context(text->search); + text->search = NULL; +} + + /** * Draw a CONTENT_TEXTPLAIN using the current set of plotters (plot). * @@ -943,36 +1024,6 @@ char *textplain_get_selection(struct content *c) return selection_get_copy(&text->sel); } - -/** - * Set an TEXTPLAIN content's search context - * - * \param c content of type text - * \param s search context, or NULL if none - */ - -void textplain_set_search(struct content *c, struct search_context *s) -{ - textplain_content *text = (textplain_content *) c; - - text->search = s; -} - - -/** - * Return an TEXTPLAIN content's search context - * - * \param c content of type text - * \return content's search context, or NULL if none - */ - -struct search_context *textplain_get_search(struct content *c) -{ - textplain_content *text = (textplain_content *) c; - - return text->search; -} - /** * Retrieve number of lines in content * diff --git a/render/textplain.h b/render/textplain.h index b7761a20d..c3f2a0f6a 100644 --- a/render/textplain.h +++ b/render/textplain.h @@ -47,6 +47,5 @@ int textplain_find_line(struct content *c, unsigned offset); char *textplain_get_raw_data(struct content *c, unsigned start, unsigned end, size_t *plen); struct browser_window *textplain_get_browser_window(struct content *c); -void textplain_set_search(struct content *c, struct search_context *s); #endif diff --git a/riscos/search.c b/riscos/search.c index db87cad8d..be6db2714 100644 --- a/riscos/search.c +++ b/riscos/search.c @@ -123,12 +123,10 @@ bool ro_gui_search_next(wimp_w w) search_data.search_insert = true; search_flags_t flags = SEARCH_FLAG_FORWARDS | ro_gui_search_update_flags(); - if (browser_window_search_verify_new(search_data.search_window, - &ro_gui_search_callbacks, NULL)) - browser_window_search_step( - search_data.search_window, flags, - ro_gui_get_icon_string(dialog_search, - ICON_SEARCH_TEXT)); + browser_window_search(search_data.search_window, + &ro_gui_search_callbacks, NULL, flags, + ro_gui_get_icon_string(dialog_search, + ICON_SEARCH_TEXT)); return false; } @@ -166,35 +164,30 @@ bool ro_gui_search_click(wimp_pointer *pointer) search_data.search_insert = true; flags = ~SEARCH_FLAG_FORWARDS & ro_gui_search_update_flags(); - if (browser_window_search_verify_new( - search_data.search_window, - &ro_gui_search_callbacks, NULL)) - browser_window_search_step( - search_data.search_window, - flags, - ro_gui_get_icon_string( - dialog_search, - ICON_SEARCH_TEXT)); + browser_window_search(search_data.search_window, + &ro_gui_search_callbacks, NULL, + flags, + ro_gui_get_icon_string(dialog_search, + ICON_SEARCH_TEXT)); return true; case ICON_SEARCH_CASE_SENSITIVE: flags = SEARCH_FLAG_FORWARDS | ro_gui_search_update_flags(); - if (browser_window_search_verify_new( - search_data.search_window, - &ro_gui_search_callbacks, NULL)) - browser_window_search_step( - search_data.search_window, - flags, - ro_gui_get_icon_string( - dialog_search, - ICON_SEARCH_TEXT)); + browser_window_search(search_data.search_window, + &ro_gui_search_callbacks, NULL, + flags, + ro_gui_get_icon_string(dialog_search, + ICON_SEARCH_TEXT)); return true; case ICON_SEARCH_SHOW_ALL: - /* TODO: call browser_window_search_verify_new() ? */ - browser_window_search_show_all( - ro_gui_get_icon_selected_state( - pointer->w, pointer->i), - search_data.search_window); + flags = ro_gui_get_icon_selected_state( + pointer->w, pointer->i) ? + SEARCH_FLAG_SHOWALL : SEARCH_FLAG_NONE; + browser_window_search(search_data.search_window, + &ro_gui_search_callbacks, NULL, + flags, + ro_gui_get_icon_string(dialog_search, + ICON_SEARCH_TEXT)); return true; } return false; @@ -292,9 +285,6 @@ void ro_gui_search_prepare(struct browser_window *bw) ro_gui_search_set_forward_state(true, bw); ro_gui_search_set_back_state(true, bw); - browser_window_search_create_context(bw, - &ro_gui_search_callbacks, NULL); - search_data.search_window = bw; ro_gui_set_icon_string(dialog_search, ICON_SEARCH_TEXT, "", true); @@ -321,14 +311,14 @@ bool ro_gui_search_keypress(wimp_key *key) search_flags_t flags; switch (key->c) { - case 1: { /* ctrl a */ - bool sel = !ro_gui_get_icon_selected_state(key->w, - ICON_SEARCH_SHOW_ALL); - ro_gui_set_icon_selected_state(key->w, - ICON_SEARCH_SHOW_ALL, sel); - /* TODO: call browser_window_search_verify_new() ? */ - browser_window_search_show_all(sel, - search_data.search_window); + case 1: { + flags = ro_gui_search_update_flags() + ^ SEARCH_FLAG_SHOWALL; + browser_window_search(search_data.search_window, + &ro_gui_search_callbacks, NULL, + flags, + ro_gui_get_icon_string(dialog_search, + ICON_SEARCH_TEXT)); } break; case 9: /* ctrl i */ @@ -338,50 +328,38 @@ bool ro_gui_search_keypress(wimp_key *key) ICON_SEARCH_CASE_SENSITIVE, !state); flags = SEARCH_FLAG_FORWARDS | ro_gui_search_update_flags(); - if (browser_window_search_verify_new( - search_data.search_window, - &ro_gui_search_callbacks, NULL)) - browser_window_search_step( - search_data.search_window, - flags, - ro_gui_get_icon_string( - dialog_search, - ICON_SEARCH_TEXT)); + browser_window_search(search_data.search_window, + &ro_gui_search_callbacks, NULL, + flags, + ro_gui_get_icon_string(dialog_search, + ICON_SEARCH_TEXT)); return true; case IS_WIMP_KEY | wimp_KEY_UP: search_data.search_insert = true; flags = ~SEARCH_FLAG_FORWARDS & ro_gui_search_update_flags(); - if (browser_window_search_verify_new( - search_data.search_window, - &ro_gui_search_callbacks, NULL)) - browser_window_search_step( - search_data.search_window, - flags, - ro_gui_get_icon_string( - dialog_search, - ICON_SEARCH_TEXT)); + browser_window_search(search_data.search_window, + &ro_gui_search_callbacks, NULL, + flags, + ro_gui_get_icon_string(dialog_search, + ICON_SEARCH_TEXT)); return true; case IS_WIMP_KEY | wimp_KEY_DOWN: search_data.search_insert = true; flags = SEARCH_FLAG_FORWARDS | ro_gui_search_update_flags(); - if (browser_window_search_verify_new( - search_data.search_window, - &ro_gui_search_callbacks, NULL)) - browser_window_search_step( - search_data.search_window, - flags, - ro_gui_get_icon_string( - dialog_search, - ICON_SEARCH_TEXT)); + browser_window_search(search_data.search_window, + &ro_gui_search_callbacks, NULL, + flags, + ro_gui_get_icon_string(dialog_search, + ICON_SEARCH_TEXT)); return true; default: if (key->c == 21) { /* ctrl+u means the user's starting * a new search */ - browser_window_search_destroy_context( + browser_window_search_clear( search_data.search_window); ro_gui_search_set_forward_state(true, search_data.search_window); @@ -394,21 +372,14 @@ bool ro_gui_search_keypress(wimp_key *key) (key->c >= 0x20 && key->c <= 0x7f)) { flags = SEARCH_FLAG_FORWARDS | ro_gui_search_update_flags(); - browser_window_search_destroy_context( - search_data.search_window); ro_gui_search_set_forward_state(true, search_data.search_window); ro_gui_search_set_back_state(true, search_data.search_window); - if (browser_window_search_verify_new( - search_data.search_window, - &ro_gui_search_callbacks, - NULL)) - browser_window_search_step( - search_data. - search_window, - flags, - ro_gui_get_icon_string( + browser_window_search(search_data.search_window, + &ro_gui_search_callbacks, NULL, + flags, + ro_gui_get_icon_string( dialog_search, ICON_SEARCH_TEXT)); return true; @@ -425,7 +396,7 @@ bool ro_gui_search_keypress(wimp_key *key) */ void ro_gui_search_end(wimp_w w) { - browser_window_search_destroy_context(search_data.search_window); + browser_window_search_clear(search_data.search_window); ro_gui_search_set_forward_state(true, search_data.search_window); ro_gui_search_set_back_state(true, search_data.search_window); } -- cgit v1.2.3