summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--!NetSurf/Resources/en/Templates,fecbin7168 -> 7689 bytes
-rw-r--r--!NetSurf/Resources/fr/Templates,fecbin7302 -> 7823 bytes
-rw-r--r--makefile2
-rw-r--r--riscos/dialog.c30
-rw-r--r--riscos/gui.h15
-rw-r--r--riscos/search.c296
-rw-r--r--riscos/window.c7
-rw-r--r--utils/config.h2
8 files changed, 348 insertions, 4 deletions
diff --git a/!NetSurf/Resources/en/Templates,fec b/!NetSurf/Resources/en/Templates,fec
index f3aabcfbe..e0c87cb9e 100644
--- a/!NetSurf/Resources/en/Templates,fec
+++ b/!NetSurf/Resources/en/Templates,fec
Binary files differ
diff --git a/!NetSurf/Resources/fr/Templates,fec b/!NetSurf/Resources/fr/Templates,fec
index bf7d117e0..d6c84b404 100644
--- a/!NetSurf/Resources/fr/Templates,fec
+++ b/!NetSurf/Resources/fr/Templates,fec
Binary files differ
diff --git a/makefile b/makefile
index 52c8e1e19..21947d379 100644
--- a/makefile
+++ b/makefile
@@ -30,7 +30,7 @@ OBJECTS_RISCOS += 401login.o debugwin.o \
gifread.o gui.o help.o history.o hotlist.o htmlinstance.o \
htmlredraw.o jpeg.o menus.o mng.o mouseactions.o plugin.o \
save.o save_complete.o save_draw.o save_text.o \
- schedule.o sprite.o textselection.o theme.o thumbnail.o \
+ schedule.o search.o sprite.o textselection.o theme.o thumbnail.o \
toolbar.o ufont.o uri.o url_protocol.o wimp.o window.o # riscos/
# OBJECTS_RISCOS += memdebug.o
diff --git a/riscos/dialog.c b/riscos/dialog.c
index 3bd0fffa4..d98cf1127 100644
--- a/riscos/dialog.c
+++ b/riscos/dialog.c
@@ -38,7 +38,7 @@ wimp_w dialog_info, dialog_saveas, dialog_config, dialog_config_br,
#endif
dialog_zoom, dialog_pageinfo, dialog_objinfo, dialog_tooltip,
dialog_warning, dialog_config_th_pane, dialog_debug,
- dialog_folder, dialog_entry;
+ dialog_folder, dialog_entry, dialog_search;
static int ro_gui_choices_font_size;
static int ro_gui_choices_font_min_size;
@@ -102,6 +102,7 @@ void ro_gui_dialog_init(void)
dialog_debug = ro_gui_dialog_create("debug");
dialog_folder = ro_gui_dialog_create("new_folder");
dialog_entry = ro_gui_dialog_create("new_entry");
+ dialog_search = ro_gui_dialog_create("search");
}
@@ -345,6 +346,8 @@ void ro_gui_dialog_close_persistant(wimp_w parent) {
bool ro_gui_dialog_keypress(wimp_key *key)
{
wimp_pointer pointer;
+ int i;
+
if (key->c == wimp_KEY_ESCAPE) {
ro_gui_dialog_close(key->w);
return true;
@@ -358,6 +361,20 @@ bool ro_gui_dialog_keypress(wimp_key *key)
ro_gui_hotlist_dialog_click(&pointer);
return true;
}
+ else if (key->w == dialog_search) {
+ pointer.w = key->w;
+ pointer.i = ICON_SEARCH_FIND;
+ pointer.buttons = wimp_CLICK_SELECT;
+ for (i = 0; i < MAX_PERSISTANT; i++) {
+ if (persistant_dialog[i].dialog ==
+ dialog_search) {
+ ro_gui_search_click(&pointer,
+ persistant_dialog[i].parent);
+ break;
+ }
+ }
+ return true;
+ }
}
#ifdef WITH_AUTH
if (key->w == dialog_401li)
@@ -373,6 +390,8 @@ bool ro_gui_dialog_keypress(wimp_key *key)
void ro_gui_dialog_click(wimp_pointer *pointer)
{
+ int i;
+
if (pointer->buttons == wimp_CLICK_MENU)
return;
@@ -396,6 +415,15 @@ void ro_gui_dialog_click(wimp_pointer *pointer)
ro_gui_dialog_click_warning(pointer);
else if ((pointer->w == dialog_folder) || (pointer->w == dialog_entry))
ro_gui_hotlist_dialog_click(pointer);
+ else if (pointer->w == dialog_search) {
+ for (i = 0; i < MAX_PERSISTANT; i++) {
+ if (persistant_dialog[i].dialog == dialog_search) {
+ ro_gui_search_click(pointer,
+ persistant_dialog[i].parent);
+ break;
+ }
+ }
+ }
}
diff --git a/riscos/gui.h b/riscos/gui.h
index 005b3a036..d16cfed86 100644
--- a/riscos/gui.h
+++ b/riscos/gui.h
@@ -26,7 +26,7 @@ struct toolbar;
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_debug, dialog_folder, dialog_entry, dialog_search;
extern wimp_w history_window;
extern wimp_w hotlist_window;
extern wimp_menu *iconbar_menu, *browser_menu, *combo_menu, *hotlist_menu,
@@ -238,6 +238,10 @@ void ro_gui_debugwin_open(void);
void ro_gui_debugwin_close(void);
void ro_gui_debugwin_redraw(wimp_draw *redraw);
+/* in search.c */
+void ro_gui_search_click(wimp_pointer *pointer, wimp_w parent);
+void ro_gui_search_prepare(void);
+
/* toolbar types */
#define TOOLBAR_BROWSER 0
#define TOOLBAR_HOTLIST 1
@@ -345,4 +349,13 @@ void ro_gui_debugwin_redraw(wimp_draw *redraw);
#define ICON_WARNING_CONTINUE 1
#define ICON_WARNING_HELP 2
+#define ICON_SEARCH_TEXT 0
+#define ICON_SEARCH_START 1
+#define ICON_SEARCH_CASE_SENSITIVE 2
+#define ICON_SEARCH_FORWARDS 3
+#define ICON_SEARCH_BACKWARDS 4
+#define ICON_SEARCH_CANCEL 5
+#define ICON_SEARCH_FIND 6
+
+
#endif
diff --git a/riscos/search.c b/riscos/search.c
new file mode 100644
index 000000000..9dc46299a
--- /dev/null
+++ b/riscos/search.c
@@ -0,0 +1,296 @@
+/*
+ * 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 2004 John M Bell <jmb202@ecs.soton.ac.uk>
+ */
+
+#include <string.h>
+
+#include "oslib/wimp.h"
+
+#include "netsurf/utils/config.h"
+#include "netsurf/content/content_type.h"
+#include "netsurf/desktop/browser.h"
+#include "netsurf/desktop/gui.h"
+#include "netsurf/render/box.h"
+#include "netsurf/render/html.h"
+#include "netsurf/riscos/gui.h"
+#include "netsurf/riscos/wimp.h"
+#include "netsurf/utils/log.h"
+#include "netsurf/utils/utils.h"
+
+
+#ifdef WITH_SEARCH
+
+struct list_entry {
+ struct box *box;
+ struct list_entry *prev;
+ struct list_entry *next;
+};
+
+static char *search_string = 0;
+static struct list_entry head = { 0, 0, 0 };
+static struct list_entry *found = &head;
+static struct list_entry *current = 0;
+static struct gui_window *w = 0;
+static bool prev_from_top = false;
+static bool prev_case_sens = false;
+
+static void do_search(struct gui_window *g, char *string, bool from_top, bool case_sens, bool forwards);
+static bool find_occurrences(char *string, struct box *cur, bool case_sens);
+static char * strcasestr(char *s1, char *s2);
+
+
+/**
+ * Handle clicks in the search dialog
+ *
+ * \param pointer wimp_pointer block
+ * \param parent The parent window of this persistent dialog
+ */
+void ro_gui_search_click(wimp_pointer *pointer, wimp_w parent)
+{
+ struct gui_window *g;
+ char *string;
+
+ if (pointer->buttons == wimp_CLICK_MENU)
+ return;
+
+ switch(pointer->i) {
+ case ICON_SEARCH_FORWARDS:
+ case ICON_SEARCH_BACKWARDS:
+ /* prevent deselection on adjust clicking */
+ if (pointer->buttons == wimp_CLICK_ADJUST)
+ ro_gui_set_icon_selected_state(dialog_search,
+ pointer->i, true);
+ break;
+ case ICON_SEARCH_FIND:
+ g = ro_gui_window_lookup(parent);
+ string = ro_gui_get_icon_string(pointer->w,
+ ICON_SEARCH_TEXT);
+ if (!g || strlen(string) == 0)
+ return;
+ do_search(g, string,
+ ro_gui_get_icon_selected_state(pointer->w,
+ ICON_SEARCH_START),
+ ro_gui_get_icon_selected_state(pointer->w,
+ ICON_SEARCH_CASE_SENSITIVE),
+ ro_gui_get_icon_selected_state(pointer->w,
+ ICON_SEARCH_FORWARDS));
+ break;
+ case ICON_SEARCH_CANCEL:
+ ro_gui_dialog_close(dialog_search);
+ break;
+ }
+}
+
+/**
+ * Prepare the search dialog for display
+ */
+void ro_gui_search_prepare(void)
+{
+ ro_gui_set_icon_string(dialog_search, ICON_SEARCH_TEXT, "");
+ ro_gui_set_icon_selected_state(dialog_search, ICON_SEARCH_FORWARDS,
+ true);
+ ro_gui_set_icon_selected_state(dialog_search, ICON_SEARCH_BACKWARDS,
+ false);
+ ro_gui_set_icon_selected_state(dialog_search, ICON_SEARCH_START,
+ false);
+ ro_gui_set_icon_selected_state(dialog_search,
+ ICON_SEARCH_CASE_SENSITIVE, false);
+}
+
+/**
+ * Search for a string in the box tree
+ *
+ * \param g gui_window which contains content to search
+ * \param string the string to search for
+ * \param from_top whether to display results from the top of the page, or
+ * the current scroll position
+ * \param case_sens whether to perform a case sensitive search
+ * \param forwards direction to search in
+ */
+void do_search(struct gui_window *g, char *string, bool from_top, bool case_sens, bool forwards)
+{
+ struct content *c;
+ struct box *box;
+ struct list_entry *a, *b;
+ int x,y;
+ bool new = false;
+
+ if (!g)
+ return;
+
+ c = g->bw->current_content;
+
+ /* only handle html contents */
+ if (c->type != CONTENT_HTML)
+ return;
+
+ box = c->data.html.layout->children;
+
+ if (!box)
+ return;
+
+// LOG(("'%s' - '%s' (%p, %p) %p (%d, %d) (%d, %d) %d", search_string, string, w, g, found->next, prev_from_top, from_top, prev_case_sens, case_sens, forwards));
+
+ /* check if we need to start a new search or continue an old one */
+ if (!search_string || !w || g != w || !found->next ||
+ prev_from_top != from_top || prev_case_sens != case_sens ||
+ (case_sens && strcmp(string, search_string) != 0) ||
+ (!case_sens && strcasecmp(string, search_string) != 0)) {
+ if (search_string)
+ free(search_string);
+ search_string = strdup(string);
+ current = 0;
+ for (a = found->next; a; a = b) {
+ b = a->next;
+ free(a);
+ }
+ found->prev = 0;
+ found->next = 0;
+ if (!find_occurrences(string, box, case_sens)) {
+ for (a = found->next; a; a = b) {
+ b = a->next;
+ free(a);
+ }
+ found->prev = 0;
+ found->next = 0;
+ return;
+ }
+ new = true;
+ w = g;
+ prev_from_top = from_top;
+ prev_case_sens = case_sens;
+ }
+
+// LOG(("%d %p %p (%p, %p)", new, found->next, current, current->prev, current->next));
+
+ if (!found->next)
+ return;
+
+ if (new && from_top) {
+ /* new search, beginning at the top of the page */
+ current = found->next;
+ }
+ else if (new) {
+ /* new search, beginning from user's current scroll
+ * position */
+ wimp_window_state state;
+ os_error *error;
+
+ 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;
+ }
+
+ for (a = found->next; a; a = a->next) {
+ box_coords(a->box, &x, &y);
+ LOG(("%d, %d", y, state.yscroll / 2));
+ if (forwards && -y <= state.yscroll / 2)
+ break;
+ if (!forwards && -y >= state.yscroll / 2)
+ break;
+ }
+
+ if (a)
+ current = a;
+ else
+ return;
+ }
+ else {
+ /* continued search in the direction specified */
+ if (forwards && current && current->next) {
+ current = current->next;
+ }
+ else if (!forwards && current && current->prev) {
+ current = current->prev;
+ }
+ }
+
+ if (!current)
+ return;
+
+ /* get box position and jump to it */
+ box_coords(current->box, &x, &y);
+// LOG(("%p (%d, %d)", current, x, y));
+ gui_window_set_scroll(g, x, y);
+
+}
+
+/**
+ * Finds all occurrences of a given string in the box tree
+ *
+ * \param string the string to search for
+ * \param cur pointer to the current box
+ * \param case_sens whether to perform a case sensitive search
+ * \return true on success, false on memory allocation failure
+ */
+bool find_occurrences(char *string, struct box *cur, bool case_sens)
+{
+ struct box *a;
+ char *pos, *buf;
+ struct list_entry *entry;
+
+ /* ignore this box, if there's no visible text */
+ if (!cur->object && cur->text) {
+ buf = strndup(cur->text, cur->length);
+ if (case_sens)
+ pos = strstr(buf, string);
+ else
+ pos = strcasestr(buf, string);
+ free(buf);
+ if (pos) {
+ /* found string in box => add to list */
+ entry = calloc(1, sizeof(*entry));
+ if (!entry) {
+ warn_user("NoMemory", 0);
+ return false;
+ }
+ entry->box = cur;
+ entry->next = 0;
+ entry->prev = found->prev;
+ if (!found->prev)
+ found->next = entry;
+ else
+ found->prev->next = entry;
+ found->prev = entry;
+ }
+ }
+
+ /* and recurse */
+ for (a = cur->children; a; a = a->next) {
+ if (a->type != BOX_FLOAT_LEFT && a->type != BOX_FLOAT_RIGHT)
+ if (!find_occurrences(string, a, case_sens))
+ return false;
+ }
+
+ for (a = cur->float_children; a; a = a->next_float) {
+ if (a->type != BOX_FLOAT_LEFT && a->type != BOX_FLOAT_RIGHT)
+ if (!find_occurrences(string, a, case_sens))
+ return false;
+ }
+
+ return true;
+}
+
+/* case insensitive strstr */
+char * strcasestr(char *s1, char *s2)
+{
+ int l1 = strlen(s1), l2 = strlen(s2);
+ char *e1 = s1 + l1 - l2;
+
+ while (s1 <= e1) {
+ if (!strncasecmp(s1, s2, l2))
+ return s1;
+ s1++;
+ }
+
+ return 0;
+}
+
+#endif
diff --git a/riscos/window.c b/riscos/window.c
index 1a914f707..39d21f8d5 100644
--- a/riscos/window.c
+++ b/riscos/window.c
@@ -521,7 +521,7 @@ void gui_window_update_box(struct gui_window *g,
clear_background = true;
while (more) {
-
+
if (use_buffer) ro_gui_buffer_open(&update);
if (data->redraw.full_redraw) {
if (clear_background) {
@@ -1265,6 +1265,11 @@ bool ro_gui_window_keypress(struct gui_window *g, int key, bool toolbar)
ro_gui_open_help_page("docs");
return true;
+ case wimp_KEY_F4: /* Search */
+ ro_gui_search_prepare();
+ ro_gui_dialog_open_persistant(g->window, dialog_search, false);
+ return true;
+
case wimp_KEY_F5: /* Refresh. */
browser_window_reload(g->bw, false);
return true;
diff --git a/utils/config.h b/utils/config.h
index 5bc039a3d..8c58e27e0 100644
--- a/utils/config.h
+++ b/utils/config.h
@@ -44,6 +44,8 @@
#define WITH_URL
/* Keyboard navigation support */
#define WITH_KEYBOARD_NAVIGATION
+ /* Free text search */
+ #define WITH_SEARCH
#endif
#ifdef ncos
/* Kiosk style browsing support */