Merge branch 'tlsa/selection-search-refactor'

This commit is contained in:
Michael Drake 2013-05-07 15:06:33 +01:00
commit a0fde060e8
22 changed files with 446 additions and 506 deletions

View File

@ -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;
}

View File

@ -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,
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);
}

View File

@ -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];

View File

@ -832,6 +832,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);

View File

@ -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);

View File

@ -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);

View File

@ -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.

View File

@ -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;

View File

@ -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)
/**
* 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 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)
{
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 == NULL || bw->current_content == NULL)
return;
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->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)
void browser_window_search_clear(struct browser_window *bw)
{
if (bw == NULL)
return false;
if (bw->cur_search == NULL)
return browser_window_search_create_context(bw,
gui_callbacks, gui_p);
if (bw == NULL || bw->current_content == NULL)
return;
return true;
content_search_clear(bw->current_content);
}
void browser_window_search_step(struct browser_window *bw,
search_flags_t flags, const char *string)
{
assert(bw != NULL);
if (bw->cur_search != NULL)
search_step(bw->cur_search, flags, string);
}
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);
}

View File

@ -22,10 +22,14 @@
#include <ctype.h>
#include <string.h>
struct browser_window;
typedef enum {
SEARCH_FLAG_NONE = 0,
SEARCH_FLAG_CASE_SENSITIVE = (1 << 0),
SEARCH_FLAG_FORWARDS = (1 << 1),
SEARCH_FLAG_SHOWALL = (1 << 2)
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

View File

@ -83,7 +83,7 @@ static bool traverse_tree(struct box *box, unsigned start_idx, unsigned end_idx,
seln_traverse_handler handler,
void *handle, save_text_whitespace *before, bool *first,
bool do_marker);
static unsigned selection_label_subtree(struct box *box, unsigned idx);
/**
* Get the browser window containing the content a selection object belongs to.
@ -210,19 +210,6 @@ void selection_init(struct selection *s, struct box *root)
}
/**
* Indicate whether the selected text is read only, ie. cannot be modified.
*
* \param s selection object
* \return true iff the selection is read only
*/
bool selection_read_only(struct selection *s)
{
return true;
}
/**
* Label each text box in the given box subtree with its position
* in a textual representation of the content.
@ -990,29 +977,3 @@ bool selection_highlighted(const struct selection *s,
return true;
}
/**
* Adjust the selection to reflect a change in the selected text,
* eg. editing in a text area/input field.
*
* \param s selection object
* \param byte_offset byte offset of insertion/removal point
* \param change byte size of change, +ve = insertion, -ve = removal
* \param redraw true iff the screen should be updated
*/
void selection_update(struct selection *s, size_t byte_offset,
int change, bool redraw)
{
if (selection_defined(s) &&
byte_offset >= s->start_idx &&
byte_offset < s->end_idx)
{
if (change > 0)
s->end_idx += change;
else
s->end_idx +=
max(change, (int)(byte_offset - s->end_idx));
}
}

View File

@ -75,8 +75,6 @@ void selection_reinit(struct selection *s, struct box *root);
/* bool selection_dragging_start(struct selection *s); */
#define selection_dragging_start(s) ((s)->drag_state == DRAG_START)
bool selection_read_only(struct selection *s);
void selection_clear(struct selection *s, bool redraw);
void selection_select_all(struct selection *s);
@ -99,11 +97,4 @@ bool selection_highlighted(const struct selection *s,
unsigned start, unsigned end,
unsigned *start_idx, unsigned *end_idx);
bool selection_save_text(struct selection *s, const char *path);
void selection_update(struct selection *s, size_t byte_offset, int change,
bool redraw);
unsigned selection_label_subtree(struct box *box, unsigned idx);
#endif

View File

@ -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);

View File

@ -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;
}

View File

@ -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,

View File

@ -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"
@ -847,9 +848,7 @@ void html_mouse_action(struct content *c, struct browser_window *bw,
if (selection_defined(&html->sel)) {
sel_owner.none = false;
html_set_selection(html, HTML_SELECTION_SELF,
sel_owner,
selection_read_only(
&html->sel));
sel_owner, true);
} else if (click && html->selection_type !=
HTML_SELECTION_NONE) {
sel_owner.none = true;
@ -954,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
*/
@ -1006,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.
*/

View File

@ -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 */

View File

@ -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 */
@ -74,25 +75,15 @@ struct search_context {
};
/**
* create a search_context
* \param h the hlcache_handle the search_context is connected to
* \param callbacks the callbacks to modify appearance according to results
* \param p the pointer to send to the callbacks
* \return true for success
*/
struct search_context * search_create_context(hlcache_handle *h,
struct search_callbacks callbacks)
/* Exported function documented in search.h */
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;
}
@ -123,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;
}
@ -149,8 +135,8 @@ static void free_matches(struct search_context *context)
a = context->found->next;
/* empty the list before clearing and deleting the
selections because the the clearing updates the
screen immediately, causing nested accesses to the list */
* selections because the the clearing updates the
* screen immediately, causing nested accesses to the list */
context->found->prev = NULL;
context->found->next = NULL;
@ -241,11 +227,11 @@ static const char *find_pattern(const char *string, int s_len,
}
matches = true;
}
else
} else {
matches = false;
}
else if (s < es) {
} else if (s < es) {
char ch = *p;
if (ch == '#')
matches = true;
@ -259,16 +245,17 @@ static const char *find_pattern(const char *string, int s_len,
ss = s; /* remember first non-'*' char */
first = false;
}
}
else
} else {
matches = false;
}
if (matches) {
p++; s++;
}
else {
/* doesn't match, resume with stacked context if we have one */
if (--top < 0) return NULL; /* no match, give up */
} else {
/* doesn't match,
* resume with stacked context if we have one */
if (--top < 0)
return NULL; /* no match, give up */
ss = context[top].ss;
s = context[top].s;
@ -309,10 +296,12 @@ static struct list_entry *add_entry(unsigned start_idx, unsigned end_idx,
entry->next = 0;
entry->prev = context->found->prev;
if (context->found->prev == NULL)
context->found->next = entry;
else
context->found->prev->next = entry;
context->found->prev = entry;
return entry;
@ -347,7 +336,8 @@ static bool find_occurrences_html(const char *pattern, int p_len,
const char *pos = find_pattern(text, length,
pattern, p_len, case_sens,
&match_length);
if (!pos) break;
if (!pos)
break;
/* found string in box => add to list */
match_offset = pos - cur->text;
@ -409,7 +399,8 @@ static bool find_occurrences_text(const char *pattern, int p_len,
const char *pos = find_pattern(text, length,
pattern, p_len, case_sens,
&match_length);
if (!pos) break;
if (!pos)
break;
/* found string in line => add to list */
start_idx = offset + (pos - text);
@ -461,9 +452,6 @@ static void search_text(const char *string, int string_len,
return;
}
/* LOG(("do_search '%s' - '%s' (%p, %p) %p (%d, %d) %d",
search_data.string, string, search_data.content, c, search_data.found->next,
search_data.prev_case_sens, case_sens, forwards)); */
/* check if we need to start a new search or continue an old one */
if (context->newsearch) {
@ -471,6 +459,7 @@ static void search_text(const char *string, int string_len,
if (context->string != NULL)
free(context->string);
context->current = NULL;
free_matches(context);
@ -480,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,
@ -495,53 +482,48 @@ 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;
/* LOG(("%d %p %p (%p, %p)", new, search_data.found->next, search_data.current,
search_data.current->prev, search_data.current->next)); */
/* new search, beginning at the top of the page */
context->current = context->found->next;
context->newsearch = false;
}
else if (context->current != NULL) {
} else if (context->current != NULL) {
/* continued search in the direction specified */
if (forwards) {
if (context->current->next)
context->current = context->current->next;
}
else {
} else {
if (context->current->prev)
context->current = context->current->prev;
}
}
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->gui_p);
if (context->gui->forward_state != NULL)
context->gui->forward_state((context->current != NULL) &&
(context->current->next != NULL),
context->callbacks.gui_p);
context->gui_p);
if (context->current == NULL)
return;
@ -569,45 +551,34 @@ static void search_text(const char *string, int string_len,
}
/**
* Begins/continues the search process
* Note that this may be called many times for a single search.
*
* \param bw the browser_window to search in
* \param flags the flags forward/back etc
* \param string the string to match
*/
/* Exported function documented in search.h */
void search_step(struct search_context *context, search_flags_t flags,
const char *string)
{
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++)
if (string[i] != '#' && string[i] != '*') break;
if (string[i] != '#' && string[i] != '*')
break;
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;
@ -619,18 +590,7 @@ void search_step(struct search_context *context, search_flags_t flags,
}
/**
* Determines whether any portion of the given text box should be
* selected because it matches the current search string.
*
* \param bw browser window
* \param start_offset byte offset within text of string to be checked
* \param end_offset byte offset within text
* \param start_idx byte offset within string of highlight start
* \param end_idx byte offset of highlight end
* \return true iff part of the box should be highlighted
*/
/* Exported function documented in search.h */
bool search_term_highlighted(struct content *c,
unsigned start_offset, unsigned end_offset,
unsigned *start_idx, unsigned *end_idx,
@ -650,11 +610,7 @@ bool search_term_highlighted(struct content *c,
}
/**
* Specifies whether all matches or just the current match should
* be highlighted in the search text.
*/
/* Exported function documented in search.h */
void search_show_all(bool all, struct search_context *context)
{
struct list_entry *a;
@ -693,29 +649,14 @@ void search_show_all(bool all, struct search_context *context)
}
/**
* Ends the search process, invalidating all state
* freeing the list of found boxes
*/
/* Exported function documented in search.h */
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);

View File

@ -27,29 +27,52 @@
struct search_context;
/**
* Called when a search context is destroyed
* \param context search context being invalidated
* \param p pointer for client data
* create a search_context
*
* \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
* \return true for success
*/
typedef void (*search_invalidate_callback)(struct search_context *context,
void *p);
struct search_context * search_create_context(struct content *c,
content_type type, struct gui_search_callbacks *callbacks,
void *gui_data);
struct search_callbacks {
struct gui_search_callbacks *gui;
void *gui_p; /* private gui owned data */
search_invalidate_callback invalidate;
void *p; /* private client data */
};
struct search_context * search_create_context(struct hlcache_handle *h,
struct search_callbacks callbacks);
/**
* Ends the search process, invalidating all state
* freeing the list of found boxes
*/
void search_destroy_context(struct search_context *context);
/**
* Begins/continues the search process
* Note that this may be called many times for a single search.
*
* \param bw the browser_window to search in
* \param flags the flags forward/back etc
* \param string the string to match
*/
void search_step(struct search_context *context, search_flags_t flags,
const char * string);
/**
* Specifies whether all matches or just the current match should
* be highlighted in the search text.
*/
void search_show_all(bool all, struct search_context *context);
/**
* Determines whether any portion of the given text box should be
* selected because it matches the current search string.
*
* \param bw browser window
* \param start_offset byte offset within text of string to be checked
* \param end_offset byte offset within text
* \param start_idx byte offset within string of highlight start
* \param end_idx byte offset of highlight end
* \return true iff part of the box should be highlighted
*/
bool search_term_highlighted(struct content *c,
unsigned start_offset, unsigned end_offset,
unsigned *start_idx, unsigned *end_idx,

View File

@ -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
*

View File

@ -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

View File

@ -123,10 +123,8 @@ 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,
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,
browser_window_search(search_data.search_window,
&ro_gui_search_callbacks, NULL,
flags,
ro_gui_get_icon_string(
dialog_search,
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,
browser_window_search(search_data.search_window,
&ro_gui_search_callbacks, NULL,
flags,
ro_gui_get_icon_string(
dialog_search,
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,42 +328,30 @@ 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,
browser_window_search(search_data.search_window,
&ro_gui_search_callbacks, NULL,
flags,
ro_gui_get_icon_string(
dialog_search,
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,
browser_window_search(search_data.search_window,
&ro_gui_search_callbacks, NULL,
flags,
ro_gui_get_icon_string(
dialog_search,
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,
browser_window_search(search_data.search_window,
&ro_gui_search_callbacks, NULL,
flags,
ro_gui_get_icon_string(
dialog_search,
ro_gui_get_icon_string(dialog_search,
ICON_SEARCH_TEXT));
return true;
@ -381,7 +359,7 @@ bool ro_gui_search_keypress(wimp_key *key)
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,19 +372,12 @@ 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,
browser_window_search(search_data.search_window,
&ro_gui_search_callbacks, NULL,
flags,
ro_gui_get_icon_string(
dialog_search,
@ -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);
}