From db41dc3dac1528afbc369de91a28d1ebd4cf028b Mon Sep 17 00:00:00 2001 From: Richard Wilson Date: Mon, 7 Feb 2005 14:28:43 +0000 Subject: [project @ 2005-02-07 14:28:43 by rjw] Initial work for global history (currently incomplete) svn path=/import/netsurf/; revision=1497 --- content/url_store.c | 41 +++---- content/url_store.h | 4 +- desktop/browser.c | 4 +- desktop/browser.h | 6 + desktop/options.c | 56 ++++----- desktop/options.h | 5 +- riscos/global_history.c | 315 ++++++++++++++++++++++++++++++++++++++++++++++++ riscos/global_history.h | 32 +++++ riscos/gui.c | 27 ++++- riscos/gui.h | 32 ++--- riscos/history.c | 15 ++- riscos/hotlist.c | 114 +----------------- riscos/menus.c | 275 +++++++++++++++++++++++++++++++++++++++--- riscos/options.h | 9 +- riscos/save.c | 17 ++- riscos/theme.c | 102 +++++++++++++--- riscos/theme.h | 4 +- riscos/treeview.c | 113 ++++++++++++++++- riscos/treeview.h | 3 + riscos/url_complete.c | 5 +- riscos/window.c | 57 +++++++-- 21 files changed, 992 insertions(+), 244 deletions(-) create mode 100644 riscos/global_history.c create mode 100644 riscos/global_history.h diff --git a/content/url_store.c b/content/url_store.c index 5d83c3751..e7a941b6f 100644 --- a/content/url_store.c +++ b/content/url_store.c @@ -151,8 +151,8 @@ struct url_content *url_store_find(const char *url) { /* try to find a matching url fairly quickly */ for (search = hostname_data->url; search; search = search->next) { if ((fast_exit_counter <= 0) || - (search->url_length == url_length)) { - compare = strcmp(url, search->url); + (search->data.url_length == url_length)) { + compare = strcmp(url, search->data.url); if (compare == 0) return &search->data; else if (compare < 0) @@ -167,13 +167,13 @@ struct url_content *url_store_find(const char *url) { result = calloc(sizeof(struct url_data), 1); if (!result) return NULL; - result->url = malloc(url_length + 1); - if (!result->url) { + result->data.url = malloc(url_length + 1); + if (!result->data.url) { free(result); return NULL; } - strcpy(result->url, url); - result->url_length = url_length; + strcpy(result->data.url, url); + result->data.url_length = url_length; result->data.requests = 0; result->data.visits = 0; result->parent = hostname_data; @@ -197,7 +197,7 @@ struct url_content *url_store_find(const char *url) { * to link to (we either had an early exit from the searching so we * know we're in the block following where we need to link, or we're * at the very end of the list as we were in the last block.) */ - while ((search) && (strcmp(url, search->url) < 0)) + while ((search) && (strcmp(url, search->data.url) < 0)) search = search->previous; /* simple case: our new hostname is the first in the list */ @@ -335,22 +335,22 @@ char *url_store_match(const char *url, struct url_data **reference) { return NULL; } else if ((search->data.visits > 0) && (search->data.requests > 0)){ /* straight match */ - if ((search->url_length >= url_length) && - (!strncmp(search->url, url, url_length))) { + if ((search->data.url_length >= url_length) && + (!strncmp(search->data.url, url, url_length))) { free(scheme); *reference = search; - return search->url; + return search->data.url; } /* try with 'www.' inserted after the scheme */ - if (www_test && ((search->url_length - 4) >= url_length) && - (!strncmp(search->url, scheme, scheme_length)) && - (!strncmp(search->url + scheme_length + 3, "www.", 4)) && - (!strncmp(search->url + scheme_length + 7, + if (www_test && ((search->data.url_length - 4) >= url_length) && + (!strncmp(search->data.url, scheme, scheme_length)) && + (!strncmp(search->data.url + scheme_length + 3, "www.", 4)) && + (!strncmp(search->data.url + scheme_length + 7, url + scheme_length + 3, url_length - scheme_length - 3))) { free(scheme); *reference = search; - return search->url; + return search->data.url; } } } @@ -442,12 +442,11 @@ void url_store_save(const char *file) { /* file format version number */ fprintf(fp, "100\n"); for (search = url_store_hostnames; search; search = search->next) { - for (url = search->url; url; url = url->next) { - if (strlen(url->url) < 1024) { - fprintf(fp, "%s\n%i\n%i\n", url->url, + for (url = search->url; url; url = url->next) + if ((url->data.requests > 0) && + (strlen(url->data.url) < MAXIMUM_URL_LENGTH)) + fprintf(fp, "%s\n%i\n%i\n", url->data.url, url->data.visits, url->data.requests); - } - } } fclose(fp); } @@ -467,7 +466,7 @@ void url_store_dump(void) { fprintf(stderr, ":\n"); for (url = search->url; url; url = url->next) { fprintf(stderr, " - "); - fprintf(stderr, url->url); + fprintf(stderr, url->data.url); fprintf(stderr, "\n"); } } diff --git a/content/url_store.h b/content/url_store.h index b152508af..6a101cfe8 100644 --- a/content/url_store.h +++ b/content/url_store.h @@ -13,14 +13,14 @@ #define _NETSURF_CONTENT_URLSTORE_H_ struct url_content { + char *url; /** URL (including hostname) */ + int url_length; /** Length of URL (including hostname) */ int visits; /** Number of times visited */ int requests; /** Number of times requested */ }; struct url_data { struct url_content data; /** Stored URL content data */ - char *url; /** URL (including hostname) */ - int url_length; /** Length of URL (including hostname) */ struct url_data *previous; /** Previous URL */ struct url_data *next; /** Next URL */ struct hostname_data *parent; /** Parent hostname data */ diff --git a/desktop/browser.c b/desktop/browser.c index 9e17657e1..d5fc888cc 100644 --- a/desktop/browser.c +++ b/desktop/browser.c @@ -282,8 +282,10 @@ void browser_window_callback(content_msg msg, struct content *c, browser_window_update(bw, true); content_open(c, bw, 0, 0, 0); browser_window_set_status(bw, c->status_message); - if (bw->history_add) + if (bw->history_add) { history_add(bw->history, c, bw->frag_id); + global_history_add(bw->window); + } break; case CONTENT_MSG_DONE: diff --git a/desktop/browser.h b/desktop/browser.h index b10579197..3562236fe 100644 --- a/desktop/browser.h +++ b/desktop/browser.h @@ -118,6 +118,12 @@ void history_forward(struct browser_window *bw, struct history *history); bool history_back_available(struct history *history); bool history_forward_available(struct history *history); +/* In platform specific global_history.c. */ +void global_history_add(struct gui_window *g); +void global_history_add_recent(const char *url); +char **global_history_get_recent(int *count); + + /* In platform specific schedule.c. */ void schedule(int t, void (*callback)(void *p), void *p); void schedule_remove(void (*callback)(void *p), void *p); diff --git a/desktop/options.c b/desktop/options.c index 3ad212a14..cdafe3279 100644 --- a/desktop/options.c +++ b/desktop/options.c @@ -96,12 +96,12 @@ struct { #define option_table_entries (sizeof option_table / sizeof option_table[0]) -static void options_load_hotlist_directory(xmlNode *ul, struct node *directory); -static void options_load_hotlist_entry(xmlNode *li, struct node *directory); -xmlNode *options_find_hotlist_element(xmlNode *node, const char *name); -bool options_save_hotlist_directory(struct node *directory, xmlNode *node); -bool options_save_hotlist_entry(struct node *entry, xmlNode *node); -bool options_save_hotlist_entry_comment(xmlNode *node, const char *name, int value); +static void options_load_tree_directory(xmlNode *ul, struct node *directory); +static void options_load_tree_entry(xmlNode *li, struct node *directory); +xmlNode *options_find_tree_element(xmlNode *node, const char *name); +bool options_save_tree_directory(struct node *directory, xmlNode *node); +bool options_save_tree_entry(struct node *entry, xmlNode *node); +bool options_save_tree_entry_comment(xmlNode *node, const char *name, int value); /** @@ -227,7 +227,7 @@ void options_write(const char *path) * \param filename name of file to read * \return the hotlist file represented as a tree, or NULL on failure */ -struct tree *options_load_hotlist(const char *filename) { +struct tree *options_load_tree(const char *filename) { xmlDoc *doc; xmlNode *html, *body, *ul; struct tree *tree; @@ -238,9 +238,9 @@ struct tree *options_load_hotlist(const char *filename) { return NULL; } - html = options_find_hotlist_element((xmlNode *) doc, "html"); - body = options_find_hotlist_element(html, "body"); - ul = options_find_hotlist_element(body, "ul"); + html = options_find_tree_element((xmlNode *) doc, "html"); + body = options_find_tree_element(html, "body"); + ul = options_find_tree_element(body, "ul"); if (!ul) { xmlFreeDoc(doc); warn_user("HotlistLoadError", @@ -257,7 +257,7 @@ struct tree *options_load_hotlist(const char *filename) { tree->root = tree_create_folder_node(NULL, "Root"); if (!tree->root) return NULL; - options_load_hotlist_directory(ul, tree->root); + options_load_tree_directory(ul, tree->root); tree->root->expanded = true; tree_initialise(tree); @@ -272,7 +272,7 @@ struct tree *options_load_hotlist(const char *filename) { * \param ul xmlNode for parsed ul * \param directory directory to add this directory to */ -void options_load_hotlist_directory(xmlNode *ul, struct node *directory) { +void options_load_tree_directory(xmlNode *ul, struct node *directory) { char *title; struct node *dir; xmlNode *n; @@ -290,7 +290,7 @@ void options_load_hotlist_directory(xmlNode *ul, struct node *directory) { if (strcmp(n->name, "li") == 0) { /* entry */ - options_load_hotlist_entry(n, directory); + options_load_tree_entry(n, directory); } else if (strcmp(n->name, "h4") == 0) { /* directory */ @@ -316,7 +316,7 @@ void options_load_hotlist_directory(xmlNode *ul, struct node *directory) { dir = tree_create_folder_node(directory, title); if (!dir) return; - options_load_hotlist_directory(n, dir); + options_load_tree_directory(n, dir); } } } @@ -328,7 +328,7 @@ void options_load_hotlist_directory(xmlNode *ul, struct node *directory) { * \param li xmlNode for parsed li * \param directory directory to add this entry to */ -void options_load_hotlist_entry(xmlNode *li, struct node *directory) { +void options_load_tree_entry(xmlNode *li, struct node *directory) { char *url = 0; char *title = 0; int filetype = 0xfaf; @@ -382,7 +382,7 @@ void options_load_hotlist_entry(xmlNode *li, struct node *directory) { * \return first child of node which is an element and matches name, or * 0 if not found or parameter node is 0 */ -xmlNode *options_find_hotlist_element(xmlNode *node, const char *name) { +xmlNode *options_find_tree_element(xmlNode *node, const char *name) { xmlNode *n; if (!node) return 0; @@ -400,7 +400,7 @@ xmlNode *options_find_hotlist_element(xmlNode *node, const char *name) { * * /param filename the file to save to */ -bool options_save_hotlist(struct tree *tree, const char *filename) { +bool options_save_tree(struct tree *tree, const char *filename, const char *page_title) { int res; xmlDoc *doc; xmlNode *html, *head, *title, *body; @@ -429,7 +429,7 @@ bool options_save_hotlist(struct tree *tree, const char *filename) { return false; } - title = xmlNewTextChild(head, NULL, "title", "NetSurf Hotlist"); + title = xmlNewTextChild(head, NULL, "title", page_title); if (!title) { warn_user("NoMemory", 0); xmlFreeDoc(doc); @@ -443,7 +443,7 @@ bool options_save_hotlist(struct tree *tree, const char *filename) { return false; } - if (!options_save_hotlist_directory(tree->root, body)) { + if (!options_save_tree_directory(tree->root, body)) { warn_user("NoMemory", 0); xmlFreeDoc(doc); return false; @@ -469,7 +469,7 @@ bool options_save_hotlist(struct tree *tree, const char *filename) { * \param node node to add ul to * \return true on success, false on memory exhaustion */ -bool options_save_hotlist_directory(struct node *directory, xmlNode *node) { +bool options_save_tree_directory(struct node *directory, xmlNode *node) { struct node *child; xmlNode *ul, *h4; @@ -480,7 +480,7 @@ bool options_save_hotlist_directory(struct node *directory, xmlNode *node) { for (child = directory->child; child; child = child->next) { if (!child->folder) { /* entry */ - if (!options_save_hotlist_entry(child, ul)) + if (!options_save_tree_entry(child, ul)) return false; } else { /* directory */ @@ -489,7 +489,7 @@ bool options_save_hotlist_directory(struct node *directory, xmlNode *node) { if (!h4) return false; - if (!options_save_hotlist_directory(child, ul)) + if (!options_save_tree_directory(child, ul)) return false; } } @@ -506,7 +506,7 @@ bool options_save_hotlist_directory(struct node *directory, xmlNode *node) { * \param node node to add li to * \return true on success, false on memory exhaustion */ -bool options_save_hotlist_entry(struct node *entry, xmlNode *node) { +bool options_save_tree_entry(struct node *entry, xmlNode *node) { xmlNode *li, *a; xmlAttr *href; struct node_element *element; @@ -527,25 +527,25 @@ bool options_save_hotlist_entry(struct node *entry, xmlNode *node) { return false; if (element->user_data != 0xfaf) - if (!options_save_hotlist_entry_comment(li, + if (!options_save_tree_entry_comment(li, "Type", element->user_data)) return false; element = tree_find_element(entry, TREE_ELEMENT_ADDED); if ((element) && (element->user_data != -1)) - if (!options_save_hotlist_entry_comment(li, + if (!options_save_tree_entry_comment(li, "Added", element->user_data)) return false; element = tree_find_element(entry, TREE_ELEMENT_LAST_VISIT); if ((element) && (element->user_data != -1)) - if (!options_save_hotlist_entry_comment(li, + if (!options_save_tree_entry_comment(li, "LastVisit", element->user_data)) return false; element = tree_find_element(entry, TREE_ELEMENT_VISITS); if ((element) && (element->user_data != 0)) - if (!options_save_hotlist_entry_comment(li, + if (!options_save_tree_entry_comment(li, "Visits", element->user_data)) return false; return true; @@ -560,7 +560,7 @@ bool options_save_hotlist_entry(struct node *entry, xmlNode *node) { * \param value value of special comment * \return true on success, false on memory exhaustion */ -bool options_save_hotlist_entry_comment(xmlNode *node, const char *name, int value) { +bool options_save_tree_entry_comment(xmlNode *node, const char *name, int value) { char s[40]; xmlNode *comment; diff --git a/desktop/options.h b/desktop/options.h index d811ffb7e..8e427620d 100644 --- a/desktop/options.h +++ b/desktop/options.h @@ -48,7 +48,8 @@ extern bool option_animate_images; void options_read(const char *path); void options_write(const char *path); -struct tree *options_load_hotlist(const char *filename); -bool options_save_hotlist(struct tree *tree, const char *filename); +struct tree *options_load_tree(const char *filename); +bool options_save_tree(struct tree *tree, const char *filename, + const char *page_title); #endif diff --git a/riscos/global_history.c b/riscos/global_history.c new file mode 100644 index 000000000..f0940b3b5 --- /dev/null +++ b/riscos/global_history.c @@ -0,0 +1,315 @@ +/* + * This file is part of NetSurf, http://netsurf.sourceforge.net/ + * Licensed under the GNU General Public License, + * http://www.opensource.org/licenses/gpl-license + * Copyright 2005 Richard Wilson + */ + +/** \file + * Global history (implementation). + */ + +#include +#include +#include +#include +#include +#include "oslib/wimp.h" +#include "oslib/wimpspriteop.h" +#include "netsurf/content/url_store.h" +#include "netsurf/desktop/tree.h" +#include "netsurf/riscos/global_history.h" +#include "netsurf/riscos/gui.h" +#include "netsurf/riscos/theme.h" +#include "netsurf/riscos/treeview.h" +#include "netsurf/utils/messages.h" +#include "netsurf/utils/log.h" +#include "netsurf/utils/url.h" +#include "netsurf/utils/utils.h" + +#define MAXIMUM_URL_LENGTH 1024 + +#define GLOBAL_HISTORY_RECENT_READ "Choices:WWW.NetSurf.Recent" +#define GLOBAL_HISTORY_RECENT_WRITE ".WWW.NetSurf.Recent" +#define GLOBAL_HISTORY_READ "Choices:WWW.NetSurf.History" +#define GLOBAL_HISTORY_WRITE ".WWW.NetSurf.History" + + +static char *global_history_recent_url[GLOBAL_HISTORY_RECENT_URLS]; +static int global_history_recent_count = 0; + +static void ro_gui_global_history_add(char *title, char *url, int visit_date); + +/* A basic window for the history +*/ +static wimp_window history_window_definition = { + {0, 0, 600, 800}, + 0, + 0, + wimp_TOP, + wimp_WINDOW_NEW_FORMAT | wimp_WINDOW_MOVEABLE | wimp_WINDOW_BACK_ICON | + wimp_WINDOW_CLOSE_ICON | wimp_WINDOW_TITLE_ICON | + wimp_WINDOW_TOGGLE_ICON | wimp_WINDOW_SIZE_ICON | + wimp_WINDOW_VSCROLL | wimp_WINDOW_IGNORE_XEXTENT | + wimp_WINDOW_IGNORE_YEXTENT, + wimp_COLOUR_BLACK, + wimp_COLOUR_LIGHT_GREY, + wimp_COLOUR_LIGHT_GREY, + wimp_COLOUR_WHITE, + wimp_COLOUR_DARK_GREY, + wimp_COLOUR_MID_LIGHT_GREY, + wimp_COLOUR_CREAM, + 0, + {0, -16384, 16384, 0}, + wimp_ICON_TEXT | wimp_ICON_INDIRECTED | wimp_ICON_HCENTRED | + wimp_ICON_VCENTRED, + wimp_BUTTON_DOUBLE_CLICK_DRAG << wimp_ICON_BUTTON_TYPE_SHIFT, + wimpspriteop_AREA, + 1, + 100, + {""}, + 0, + {} +}; + + +/* The history window, toolbar and plot origins +*/ +static wimp_w global_history_window; +struct toolbar *global_history_toolbar; +struct tree *global_history_tree; + +void ro_gui_global_history_initialise(void) { + char s[MAXIMUM_URL_LENGTH]; + FILE *fp; + const char *title; + os_error *error; + + /* Create our window + */ + title = messages_get("GlobalHistory"); + history_window_definition.title_data.indirected_text.text = strdup(title); + history_window_definition.title_data.indirected_text.validation = + (char *) -1; + history_window_definition.title_data.indirected_text.size = strlen(title); + error = xwimp_create_window(&history_window_definition, &global_history_window); + if (error) { + LOG(("xwimp_create_window: 0x%x: %s", + error->errnum, error->errmess)); + die(error->errmess); + } + + /* Create an empty tree + */ + global_history_tree = calloc(sizeof(struct tree), 1); + if (!global_history_tree) { + warn_user("NoMemory", 0); + return; + } + global_history_tree->root = tree_create_folder_node(NULL, "Root"); + if (!global_history_tree->root) { + warn_user("NoMemory", 0); + free(global_history_tree); + global_history_tree = NULL; + } + global_history_tree->root->expanded = true; + tree_initialise(global_history_tree); + + + if (!global_history_tree) return; + global_history_tree->handle = (int)global_history_window; + + /* Create our toolbar + */ + global_history_toolbar = ro_gui_theme_create_toolbar(NULL, + THEME_HISTORY_TOOLBAR); + if (global_history_toolbar) { + ro_gui_theme_attach_toolbar(global_history_toolbar, + global_history_window); + global_history_tree->offset_y = global_history_toolbar->height; + } + + /* load recent URLs */ + fp = fopen(GLOBAL_HISTORY_RECENT_READ, "r"); + if (!fp) + LOG(("Failed to open file '%s' for reading", + GLOBAL_HISTORY_RECENT_READ)); + else { + while (fgets(s, MAXIMUM_URL_LENGTH, fp)) { + if (s[strlen(s) - 1] == '\n') + s[strlen(s) - 1] = '\0'; + global_history_add_recent(s); + } + fclose(fp); + } +} + + +/** + * Saves the global history and recent URL data. + */ +void ro_gui_global_history_save(void) { + FILE *fp; + int i; + + /* save recent URLs */ + fp = fopen(GLOBAL_HISTORY_RECENT_WRITE, "w"); + if (!fp) + LOG(("Failed to open file '%s' for writing", + GLOBAL_HISTORY_RECENT_WRITE)); + else { + for (i = global_history_recent_count - 1; i >= 0; i--) + if (strlen(global_history_recent_url[i]) < MAXIMUM_URL_LENGTH) + fprintf(fp, "%s\n", global_history_recent_url[i]); + fclose(fp); + } + + /* save global history tree */ + +} + + +/** + * Shows the history window. + */ +void ro_gui_global_history_show(void) { + ro_gui_tree_show(global_history_tree, global_history_toolbar); + ro_gui_menu_prepare_global_history(); +} + + +/** + * Respond to a mouse click + * + * \param pointer the pointer state + */ +void ro_gui_global_history_click(wimp_pointer *pointer) { + ro_gui_tree_click(pointer, global_history_tree); + if (pointer->buttons == wimp_CLICK_MENU) + ro_gui_create_menu(global_history_menu, pointer->pos.x, + pointer->pos.y, NULL); + else + ro_gui_menu_prepare_global_history(); +} + + +/** + * Respond to a keypress + * + * \param key the key pressed + */ +bool ro_gui_global_history_keypress(int key) { + bool result = ro_gui_tree_keypress(key, global_history_tree); + ro_gui_menu_prepare_global_history(); + return result; +} + + +/** + * Handles a menu closed event + */ +void ro_gui_global_history_menu_closed(void) { + ro_gui_tree_menu_closed(global_history_tree); + current_menu = NULL; + ro_gui_menu_prepare_global_history(); +} + + +/** + * Attempts to process an interactive help message request + * + * \param x the x co-ordinate to give help for + * \param y the x co-ordinate to give help for + * \return the message code index + */ +int ro_gui_global_history_help(int x, int y) { + return -1; +} + + +/** + * Adds to the global history + * + * \param g the gui_window to add to the global history + */ +void global_history_add(struct gui_window *g) { + assert(g); + + if ((!g->bw->current_content) || (!global_history_tree)) + return; + + ro_gui_global_history_add(g->title, g->bw->current_content->url, time(NULL)); +} + + +/** + * Adds to the global history + * + * \param title the page title + * \param url the page URL + * \param visit_date the visit date + */ +void ro_gui_global_history_add(char *title, char *url, int visit_date) { + LOG(("Added '%s' ('%s') dated %i.", title, url, visit_date)); + +} + + +/** + * Adds a URL to the recently used list + * + * \param url the URL to add + */ +void global_history_add_recent(const char *url) { + struct url_content *data; + int i; + int j = -1; + char *current; + + /* by using the url_store, we get a central char* of the string that isn't + * going anywhere unless we tell it to */ + data = url_store_find(url); + if (!data) + return; + + /* try to find a string already there */ + for (i = 0; i < global_history_recent_count; i++) + if (global_history_recent_url[i] == data->url) + j = i; + + /* already at head of list */ + if (j == 0) + return; + + /* add to head of list */ + if (j < 0) { + memmove(&global_history_recent_url[1], + &global_history_recent_url[0], + (GLOBAL_HISTORY_RECENT_URLS - 1) * sizeof(char *)); + global_history_recent_url[0] = data->url; + global_history_recent_count++; + if (global_history_recent_count > GLOBAL_HISTORY_RECENT_URLS) + global_history_recent_count = GLOBAL_HISTORY_RECENT_URLS; + if (global_history_recent_count == 1) + ro_gui_window_prepare_navigate_all(); + } else { + /* move to head of list */ + current = global_history_recent_url[j]; + for (i = j; i > 0; i--) + global_history_recent_url[i] = + global_history_recent_url[i - 1]; + global_history_recent_url[0] = current; + } +} + + +/** + * Gets details of the currently used URL list. + * + * \param count set to the current number of entries in the URL array on exit + * \return the current URL array + */ +char **global_history_get_recent(int *count) { + *count = global_history_recent_count; + return global_history_recent_url; +} diff --git a/riscos/global_history.h b/riscos/global_history.h new file mode 100644 index 000000000..a1824679a --- /dev/null +++ b/riscos/global_history.h @@ -0,0 +1,32 @@ +/* + * This file is part of NetSurf, http://netsurf.sourceforge.net/ + * Licensed under the GNU General Public License, + * http://www.opensource.org/licenses/gpl-license + * Copyright 2005 Richard Wilson + */ + +/** \file + * Global history (interface). + */ + +#ifndef _NETSURF_RISCOS_GLOBALHISTORY_H_ +#define _NETSURF_RISCOS_GLOBALHISTORY_H_ + +#include +#include "oslib/wimp.h" +#include "netsurf/content/url_store.h" +#include "netsurf/desktop/browser.h" + +#define GLOBAL_HISTORY_RECENT_URLS 16 + +void ro_gui_global_history_initialise(void); +void ro_gui_global_history_save(void); +void ro_gui_global_history_show(void); +void ro_gui_global_history_click(wimp_pointer *pointer); +bool ro_gui_global_history_keypress(int key); +void ro_gui_global_history_dialog_click(wimp_pointer *pointer); +void ro_gui_global_history_menu_closed(void); +int ro_gui_global_history_help(int x, int y); + + +#endif diff --git a/riscos/gui.c b/riscos/gui.c index df2c70fd3..3f423e5cc 100644 --- a/riscos/gui.c +++ b/riscos/gui.c @@ -40,6 +40,7 @@ #include "netsurf/desktop/tree.h" #include "netsurf/render/font.h" #include "netsurf/render/html.h" +#include "netsurf/riscos/global_history.h" #include "netsurf/riscos/gui.h" #include "netsurf/riscos/help.h" #include "netsurf/riscos/options.h" @@ -273,6 +274,7 @@ void gui_init(int argc, char** argv) ro_gui_sprites_init(); ro_gui_tree_initialise(); /* must be done after sprite loading */ ro_gui_hotlist_initialise(); + ro_gui_global_history_initialise(); /* Load our chosen theme */ @@ -545,6 +547,7 @@ void gui_quit(void) { url_store_save(".WWW.NetSurf.URL"); ro_gui_window_quit(); + ro_gui_global_history_save(); ro_gui_hotlist_save(); ro_gui_history_quit(); free(gui_sprites); @@ -791,6 +794,11 @@ void ro_gui_redraw_window_request(wimp_draw *redraw) ro_gui_tree_redraw(redraw, hotlist_tree); else if ((hotlist_toolbar) && (hotlist_toolbar->toolbar_handle == redraw->w)) ro_gui_theme_redraw(hotlist_toolbar, redraw); + else if ((global_history_tree) && (redraw->w == (wimp_w)global_history_tree->handle)) + ro_gui_tree_redraw(redraw, global_history_tree); + else if ((global_history_toolbar) && + (global_history_toolbar->toolbar_handle == redraw->w)) + ro_gui_theme_redraw(global_history_toolbar, redraw); else if (redraw->w == dialog_debug) ro_gui_debugwin_redraw(redraw); else if ((g = ro_gui_window_lookup(redraw->w)) != NULL) @@ -817,6 +825,8 @@ void ro_gui_open_window_request(wimp_open *open) ro_gui_window_open(g, open); } else if ((hotlist_tree) && (open->w == (wimp_w)hotlist_tree->handle)){ ro_gui_tree_open(open, hotlist_tree); + } else if ((global_history_tree) && (open->w == (wimp_w)global_history_tree->handle)){ + ro_gui_tree_open(open, global_history_tree); } else { error = xwimp_open_window(open); if (error) { @@ -911,11 +921,17 @@ void ro_gui_mouse_click(wimp_pointer *pointer) ro_gui_url_complete_mouse_at(pointer); else if ((hotlist_tree) && (pointer->w == (wimp_w)hotlist_tree->handle)) ro_gui_hotlist_click(pointer); + else if ((global_history_tree) && (pointer->w == (wimp_w)global_history_tree->handle)) + ro_gui_global_history_click(pointer); else if (pointer->w == dialog_saveas) ro_gui_save_click(pointer); else if (hotlist_toolbar && hotlist_toolbar->toolbar_handle == pointer->w) - ro_gui_hotlist_toolbar_click(pointer); + ro_gui_tree_toolbar_click(pointer, hotlist_tree, hotlist_toolbar); + else if (global_history_toolbar && + global_history_toolbar->toolbar_handle == pointer->w) + ro_gui_tree_toolbar_click(pointer, global_history_tree, + global_history_toolbar); else if ((g = ro_gui_window_lookup(pointer->w)) != NULL) ro_gui_window_click(g, pointer); else if ((g = ro_gui_toolbar_lookup(pointer->w)) != NULL) @@ -1006,9 +1022,11 @@ void ro_gui_keypress(wimp_key *key) struct gui_window *g; os_error *error; - if ((hotlist_tree) && (key->w == (wimp_w)hotlist_tree->handle)) { + if ((hotlist_tree) && (key->w == (wimp_w)hotlist_tree->handle)) handled = ro_gui_hotlist_keypress(key->c); - } else if ((g = ro_gui_window_lookup(key->w)) != NULL) + else if ((global_history_tree) && (key->w == (wimp_w)global_history_tree->handle)) + handled = ro_gui_global_history_keypress(key->c); + else if ((g = ro_gui_window_lookup(key->w)) != NULL) handled = ro_gui_window_keypress(g, key->c, false); else if ((g = ro_gui_toolbar_lookup(key->w)) != NULL) handled = ro_gui_window_keypress(g, key->c, true); @@ -1071,6 +1089,9 @@ void ro_gui_user_message(wimp_event_no event, wimp_message *message) case message_MENUS_DELETED: if ((current_menu == hotlist_menu) && (hotlist_tree)) ro_gui_hotlist_menu_closed(); + else if ((current_menu == global_history_menu) && + (global_history_tree)) + ro_gui_global_history_menu_closed(); current_menu = NULL; current_gui = NULL; break; diff --git a/riscos/gui.h b/riscos/gui.h index 5a3bbe5e5..43a7b9e85 100644 --- a/riscos/gui.h +++ b/riscos/gui.h @@ -35,17 +35,17 @@ extern wimp_w dialog_info, dialog_saveas, dialog_config, dialog_config_br, extern wimp_w history_window; extern wimp_menu *iconbar_menu, *browser_menu, *combo_menu, *hotlist_menu, *proxyauth_menu, *languages_menu, *toolbar_menu, - *image_quality_menu; + *image_quality_menu, *global_history_menu, *url_suggest_menu; extern int iconbar_menu_height; extern struct form_control *current_gadget; extern bool gui_reformat_pending; extern bool gui_redraw_debug; extern wimp_menu *current_menu; extern osspriteop_area *gui_sprites; -extern struct toolbar *hotlist_toolbar; +extern struct toolbar *hotlist_toolbar, *global_history_toolbar; extern bool dialog_folder_add, dialog_entry_add, hotlist_insert; extern bool print_active, print_text_black; -extern struct tree *hotlist_tree; +extern struct tree *hotlist_tree, *global_history_tree; typedef enum { GUI_SAVE_SOURCE, @@ -58,6 +58,7 @@ typedef enum { GUI_SAVE_LINK_URL, GUI_SAVE_LINK_TEXT, GUI_SAVE_HOTLIST_EXPORT_HTML, + GUI_SAVE_HISTORY_EXPORT_HTML, } gui_save_type; typedef enum { GUI_DRAG_SELECTION, GUI_DRAG_DOWNLOAD_SAVE, @@ -113,6 +114,7 @@ void ro_gui_drag_box_start(wimp_pointer *pointer); /* in menus.c */ void ro_gui_menus_init(void); +bool ro_gui_menu_prepare_url_suggest(void); void ro_gui_create_menu(wimp_menu* menu, int x, int y, struct gui_window *g); void ro_gui_popup_menu(wimp_menu *menu, wimp_w w, wimp_i i); void ro_gui_menu_selection(wimp_selection* selection); @@ -121,6 +123,8 @@ void ro_gui_prepare_navigate(struct gui_window *gui); void ro_gui_menu_prepare_image_quality(unsigned int tinct_options); void ro_gui_menu_prepare_scale(void); void ro_gui_menu_prepare_pageinfo(void); +void ro_gui_menu_prepare_hotlist(void); +void ro_gui_menu_prepare_global_history(void); void ro_gui_display_font_menu(const char *tick, wimp_w w, wimp_i i); /* in dialog.c */ @@ -134,7 +138,6 @@ void ro_gui_dialog_click(wimp_pointer *pointer); void ro_gui_save_options(void); bool ro_gui_dialog_keypress(wimp_key *key); void ro_gui_dialog_close(wimp_w close); -void ro_gui_menu_prepare_hotlist(void); void ro_gui_dialog_open_config(void); void ro_gui_dialog_proxyauth_menu_selection(int item); void ro_gui_dialog_image_menu_selection(int item); @@ -192,13 +195,13 @@ bool ro_gui_window_dataload(struct gui_window *g, wimp_message *message); void ro_gui_window_process_reformats(void); void ro_gui_window_default_options(struct browser_window *bw); void ro_gui_window_redraw_all(void); +void ro_gui_window_prepare_navigate_all(void); /* in history.c */ void ro_gui_history_init(void); void ro_gui_history_quit(void); void ro_gui_history_mode_change(void); -void ro_gui_history_open(struct browser_window *bw, - struct history *history, int wx, int wy); +void ro_gui_history_open(struct browser_window *bw, struct history *history, bool pointer); void ro_gui_history_redraw(wimp_draw *redraw); void ro_gui_history_click(wimp_pointer *pointer); void ro_gui_history_mouse_at(wimp_pointer *pointer); @@ -255,10 +258,6 @@ void ro_plot_set_scale(float scale); /* in theme_install.c */ void ro_gui_theme_install_click(wimp_pointer *pointer); -/* toolbar types */ -#define TOOLBAR_BROWSER 0 -#define TOOLBAR_HOTLIST 1 - /* icon numbers for browser toolbars */ #define ICON_TOOLBAR_BACK 0 #define ICON_TOOLBAR_FORWARD 1 @@ -275,12 +274,13 @@ void ro_gui_theme_install_click(wimp_pointer *pointer); #define ICON_TOOLBAR_THROBBER 12 #define ICON_TOOLBAR_SUGGEST 13 -/* icon numbers for hotlist toolbars */ -#define ICON_TOOLBAR_CREATE 0 -#define ICON_TOOLBAR_DELETE 1 -#define ICON_TOOLBAR_EXPAND 2 -#define ICON_TOOLBAR_OPEN 3 -#define ICON_TOOLBAR_LAUNCH 4 +/* icon numbers for hotlist/history toolbars */ +#define ICON_TOOLBAR_DELETE 0 +#define ICON_TOOLBAR_EXPAND 1 +#define ICON_TOOLBAR_OPEN 2 +#define ICON_TOOLBAR_LAUNCH 3 +#define ICON_TOOLBAR_HISTORY_LAST 4 +#define ICON_TOOLBAR_CREATE 4 // must be after last history icon #define ICON_TOOLBAR_HOTLIST_LAST 5 /* icon numbers for toolbar status window */ diff --git a/riscos/history.c b/riscos/history.c index ebd4e7def..31595470b 100644 --- a/riscos/history.c +++ b/riscos/history.c @@ -283,10 +283,12 @@ void ro_gui_history_mode_change(void) /** * Open history window. + * + * \param pointer whether to open the window at the pointer */ void ro_gui_history_open(struct browser_window *bw, - struct history *history, int wx, int wy) + struct history *history, bool pointer) { bool done = false; unsigned int i, j, max_y = 0; @@ -353,12 +355,13 @@ void ro_gui_history_open(struct browser_window *bw, wimp_set_extent(history_window, &box); state.w = history_window; wimp_get_window_state(&state); - state.visible.x0 = wx - width / 2; - state.visible.y0 = wy - height / 2; - state.visible.x1 = wx + width / 2; - state.visible.y1 = wy + height / 2; - state.next = wimp_TOP; + state.visible.x0 = 0; + state.visible.y0 = 0; + state.visible.x1 = width; + state.visible.y1 = height; + state.next = wimp_HIDDEN; wimp_open_window((wimp_open *) &state); + ro_gui_dialog_open_persistant(bw->window->window, history_window, pointer); } diff --git a/riscos/hotlist.c b/riscos/hotlist.c index 3edec0ad0..fa3ed7c77 100644 --- a/riscos/hotlist.c +++ b/riscos/hotlist.c @@ -38,7 +38,7 @@ static void ro_gui_hotlist_visited(struct content *content, struct tree *tree, struct node *node); -/* A basic window for the toolbar and status +/* A basic window for the hotlist */ static wimp_window hotlist_window_definition = { {0, 0, 600, 800}, @@ -129,7 +129,7 @@ void ro_gui_hotlist_initialise(void) { tree_initialise(hotlist_tree); } else { fclose(fp); - hotlist_tree = options_load_hotlist("Choices:WWW.NetSurf.Hotlist"); + hotlist_tree = options_load_tree("Choices:WWW.NetSurf.Hotlist"); } if (!hotlist_tree) return; hotlist_tree->handle = (int)hotlist_window; @@ -154,7 +154,8 @@ void ro_gui_hotlist_save(void) { /* Save to our file */ - options_save_hotlist(hotlist_tree, ".WWW.NetSurf.Hotlist"); + options_save_tree(hotlist_tree, ".WWW.NetSurf.Hotlist", + "NetSurf hotlist"); error = xosfile_set_type(".WWW.NetSurf.Hotlist", 0xfaf); if (error) LOG(("xosfile_set_type: 0x%x: %s", @@ -166,67 +167,8 @@ void ro_gui_hotlist_save(void) { * Shows the hotlist window. */ void ro_gui_hotlist_show(void) { - os_error *error; - int screen_width, screen_height; - wimp_window_state state; - int dimension; - int scroll_width; - - /* We may have failed to initialise - */ - if (!hotlist_tree) return; - - /* Get the window state - */ - state.w = hotlist_window; - error = xwimp_get_window_state(&state); - if (error) { - warn_user("WimpError", error->errmess); - return; - } - - /* If we're open we jump to the top of the stack, if not then we - open in the centre of the screen. - */ - if (!(state.flags & wimp_WINDOW_OPEN)) { - - /* Cancel any editing - */ - ro_gui_tree_stop_edit(hotlist_tree); - - /* Set the default state - */ - if (hotlist_tree->root->child) - tree_handle_node_changed(hotlist_tree, hotlist_tree->root, - false, true); - - /* Get the current screen size - */ - ro_gui_screen_size(&screen_width, &screen_height); - - /* Move to the centre - */ - dimension = 600; /*state.visible.x1 - state.visible.x0;*/ - scroll_width = ro_get_vscroll_width(hotlist_window); - state.visible.x0 = (screen_width - (dimension + scroll_width)) / 2; - state.visible.x1 = state.visible.x0 + dimension; - dimension = 800; /*state.visible.y1 - state.visible.y0;*/ - state.visible.y0 = (screen_height - dimension) / 2; - state.visible.y1 = state.visible.y0 + dimension; - state.xscroll = 0; - state.yscroll = 0; - if (hotlist_toolbar) state.yscroll = hotlist_toolbar->height; - } - - /* Open the window at the top of the stack - */ + ro_gui_tree_show(hotlist_tree, hotlist_toolbar); ro_gui_menu_prepare_hotlist(); - state.next = wimp_TOP; - ro_gui_tree_open((wimp_open*)&state, hotlist_tree); - - /* Set the caret position - */ - xwimp_set_caret_position(state.w, -1, -100, -100, 32, -1); } @@ -251,13 +193,8 @@ void ro_gui_hotlist_click(wimp_pointer *pointer) { * \param key the key pressed */ bool ro_gui_hotlist_keypress(int key) { - // struct node_element *edit = hotlist_tree->editing; bool result = ro_gui_tree_keypress(key, hotlist_tree); ro_gui_menu_prepare_hotlist(); - -/* if ((edit) && (!hotlist_tree->editing)) - ro_gui_hotlist_save(); -*/ return result; } @@ -272,47 +209,6 @@ void ro_gui_hotlist_menu_closed(void) { } -/** - * Respond to a mouse click - * - * \param pointer the pointer state - */ -void ro_gui_hotlist_toolbar_click(wimp_pointer* pointer) { - struct node *node; - - current_toolbar = hotlist_toolbar; - ro_gui_tree_stop_edit(hotlist_tree); - - switch (pointer->i) { - case ICON_TOOLBAR_CREATE: - node = tree_create_folder_node(hotlist_tree->root, - messages_get("TreeNewFolder")); - tree_redraw_area(hotlist_tree, node->box.x - NODE_INSTEP, - 0, NODE_INSTEP, 16384); - tree_handle_node_changed(hotlist_tree, node, false, true); - ro_gui_tree_start_edit(hotlist_tree, &node->data, NULL); - break; - case ICON_TOOLBAR_OPEN: - tree_handle_expansion(hotlist_tree, hotlist_tree->root, - (pointer->buttons == wimp_CLICK_SELECT), - true, false); - break; - case ICON_TOOLBAR_EXPAND: - tree_handle_expansion(hotlist_tree, hotlist_tree->root, - (pointer->buttons == wimp_CLICK_SELECT), - false, true); - break; - case ICON_TOOLBAR_DELETE: - tree_delete_selected_nodes(hotlist_tree, - hotlist_tree->root); - break; - case ICON_TOOLBAR_LAUNCH: - ro_gui_tree_launch_selected(hotlist_tree); - break; - } -} - - /** * Informs the hotlist that some content has been visited * diff --git a/riscos/menus.c b/riscos/menus.c index 7d9325dba..bc7e31315 100644 --- a/riscos/menus.c +++ b/riscos/menus.c @@ -5,7 +5,7 @@ * Copyright 2003 Phil Mellor * Copyright 2004 James Bursa * Copyright 2003 John M Bell - * Copyright 2004 Richard Wilson + * Copyright 2005 Richard Wilson */ /** \file @@ -19,10 +19,12 @@ #include "oslib/osgbpb.h" #include "oslib/wimp.h" #include "oslib/wimpspriteop.h" +#include "netsurf/content/url_store.h" #include "netsurf/desktop/gui.h" #include "netsurf/render/box.h" #include "netsurf/render/form.h" #include "netsurf/riscos/gui.h" +#include "netsurf/riscos/global_history.h" #include "netsurf/riscos/help.h" #include "netsurf/riscos/options.h" #include "netsurf/riscos/tinct.h" @@ -59,6 +61,7 @@ static void ro_gui_menu_objectinfo(wimp_message_menu_warning *warning); static void ro_gui_menu_object_reload(void); static void ro_gui_menu_browser_warning(wimp_message_menu_warning *warning); static void ro_gui_menu_hotlist_warning(wimp_message_menu_warning *warning); +static void ro_gui_menu_global_history_warning(wimp_message_menu_warning *warning); static void ro_gui_font_menu_selection(wimp_selection *selection); struct gui_window *current_gui; @@ -257,17 +260,27 @@ static wimp_MENU(2) hotlist_util_menu = { }; +/* Hotlist submenu +*/ +static wimp_MENU(2) history_util_menu = { + { "History" }, 7,2,7,0, 300, 44, 0, + { + { 0, wimp_NO_SUB_MENU, DEFAULT_FLAGS, { "HistLocal" } }, + { wimp_MENU_LAST, wimp_NO_SUB_MENU, DEFAULT_FLAGS, { "HistGlobal" } } + } +}; + + /* Utilities submenu */ -static wimp_MENU(3) utilities_menu = { +static wimp_MENU(4) utilities_menu = { { "Utilities" }, 7,2,7,0, 300, 44, 0, { - { 0, (wimp_menu *)&hotlist_util_menu, DEFAULT_FLAGS, { "Hotlist" } }, - { wimp_MENU_GIVE_WARNING, (wimp_menu *)&window_menu, DEFAULT_FLAGS, { "Window" } }, - { wimp_MENU_GIVE_WARNING | wimp_MENU_LAST, (wimp_menu*)1, DEFAULT_FLAGS, { "FindText" } }, -/* { 0, wimp_NO_SUB_MENU, DEFAULT_FLAGS, { "HistLocal" } }, - { wimp_MENU_LAST, wimp_NO_SUB_MENU, DEFAULT_FLAGS, { "HistGlobal" } } -*/ } + { 0, (wimp_menu *)&hotlist_util_menu, DEFAULT_FLAGS, { "Hotlist" } }, + { 0, (wimp_menu *)&history_util_menu, DEFAULT_FLAGS, { "History" } }, + { wimp_MENU_GIVE_WARNING, (wimp_menu *)1, DEFAULT_FLAGS, { "FindText" } }, + { wimp_MENU_GIVE_WARNING | wimp_MENU_LAST, (wimp_menu *)&window_menu, DEFAULT_FLAGS, { "Window" } }, + } }; @@ -348,6 +361,17 @@ static wimp_MENU(4) hotlist_file = { } }; +/* History file submenu +*/ +static wimp_MENU(4) history_file = { + { "History" }, 7,2,7,0, 300, 44, 0, + { + { wimp_MENU_GIVE_WARNING | wimp_MENU_SEPARATE, (wimp_menu *)1, DEFAULT_FLAGS, { "Export" } }, + { 0, (wimp_menu *)&hotlist_expand, DEFAULT_FLAGS, { "Expand" } }, + { wimp_MENU_LAST, (wimp_menu *)&hotlist_collapse, DEFAULT_FLAGS, { "Collapse" } } + } +}; + /* Hotlist file submenu */ static wimp_MENU(4) hotlist_select = { @@ -360,6 +384,16 @@ static wimp_MENU(4) hotlist_select = { } }; +/* History file submenu +*/ +static wimp_MENU(4) history_select = { + { "Selection" }, 7,2,7,0, 300, 44, 0, + { + { 0, wimp_NO_SUB_MENU, DEFAULT_FLAGS, { "Launch" } }, + { wimp_MENU_LAST, wimp_NO_SUB_MENU, DEFAULT_FLAGS, { "Delete" } }, + } +}; + /* Hotlist menu */ static wimp_MENU(4) hotlist_root = { @@ -373,6 +407,19 @@ static wimp_MENU(4) hotlist_root = { }; wimp_menu *hotlist_menu = (wimp_menu *)&hotlist_root; +/* History menu +*/ +static wimp_MENU(4) history_root = { + { "History" }, 7,2,7,0, 200, 44, 0, + { + { 0, (wimp_menu *)&history_file, DEFAULT_FLAGS, { "History" } }, + { wimp_MENU_GIVE_WARNING, (wimp_menu *)&history_select, DEFAULT_FLAGS, { "Selection" } }, + { 0, wimp_NO_SUB_MENU, DEFAULT_FLAGS, { "SelectAll" } }, + { wimp_MENU_LAST, wimp_NO_SUB_MENU, DEFAULT_FLAGS, { "Clear" } } + } +}; +wimp_menu *global_history_menu = (wimp_menu *)&history_root; + /* Proxy auth popup menu (used in proxy Choices dialog) */ @@ -467,6 +514,11 @@ wimp_menu *toolbar_icon_menu = NULL; static wimp_menu *font_menu = NULL; static byte *font_menu_data = NULL; +/* URL suggestion menu +*/ +static wimp_MENU(GLOBAL_HISTORY_RECENT_URLS) url_suggest; +wimp_menu *url_suggest_menu = (wimp_menu *)&url_suggest; + static wimp_menu *browser_page_menu = (wimp_menu *)&page_menu; static wimp_menu *browser_export_menu = (wimp_menu *)&export_menu; static wimp_menu *browser_object_menu = (wimp_menu *)&object_menu; @@ -481,6 +533,7 @@ static wimp_menu *browser_render_menu = (wimp_menu *)&render_menu; static wimp_menu *browser_window_menu = (wimp_menu *)&window_menu; static wimp_menu *browser_utilities_menu = (wimp_menu *)&utilities_menu; static wimp_menu *browser_hotlist_menu = (wimp_menu *)&hotlist_util_menu; +static wimp_menu *browser_history_menu = (wimp_menu *)&history_util_menu; static wimp_menu *browser_help_menu = (wimp_menu *)&help_menu; static wimp_menu *hotlist_new_menu = (wimp_menu *)&hotlist_new; @@ -489,6 +542,9 @@ static wimp_menu *hotlist_collapse_menu = (wimp_menu *)&hotlist_collapse; static wimp_menu *hotlist_file_menu = (wimp_menu *)&hotlist_file; static wimp_menu *hotlist_select_menu = (wimp_menu *)&hotlist_select; +static wimp_menu *history_file_menu = (wimp_menu *)&history_file; +static wimp_menu *history_select_menu = (wimp_menu *)&history_select; + /** * Create menu structures. @@ -513,6 +569,7 @@ void ro_gui_menus_init(void) translate_menu(browser_window_menu); translate_menu(browser_utilities_menu); translate_menu(browser_hotlist_menu); + translate_menu(browser_history_menu); translate_menu(browser_help_menu); translate_menu(hotlist_menu); @@ -522,6 +579,11 @@ void ro_gui_menus_init(void) translate_menu(hotlist_file_menu); translate_menu(hotlist_select_menu); + translate_menu(global_history_menu); + translate_menu(history_file_menu); + translate_menu(history_select_menu); + + translate_menu(toolbar_menu); translate_menu(toolbar_browser_menu); translate_menu(toolbar_hotlist_menu); @@ -639,10 +701,46 @@ void build_languages_menu(void) languages_menu->entries[entries-1].menu_flags |= wimp_MENU_LAST; } + /** - * Display a menu. + * Builds the URL suggestion menu */ +bool ro_gui_menu_prepare_url_suggest(void) { + char **suggest_text; + int suggestions; + int i; + + suggest_text = global_history_get_recent(&suggestions); + if (suggestions < 1) + return false; + + url_suggest_menu->title_data.indirected_text.text = messages_get("URLSuggest"); + url_suggest_menu->title_fg = wimp_COLOUR_BLACK; + url_suggest_menu->title_bg = wimp_COLOUR_LIGHT_GREY; + url_suggest_menu->work_fg = wimp_COLOUR_BLACK; + url_suggest_menu->work_bg = wimp_COLOUR_WHITE; + url_suggest_menu->width = 300; + url_suggest_menu->height = 44; + url_suggest_menu->gap = 0; + + for (i = 0; i < suggestions; i++) { + url_suggest_menu->entries[i].menu_flags = 0; + url_suggest_menu->entries[i].sub_menu = wimp_NO_SUB_MENU; + url_suggest_menu->entries[i].icon_flags = DEFAULT_FLAGS | wimp_ICON_INDIRECTED; + url_suggest_menu->entries[i].data.indirected_text.text = suggest_text[i]; + url_suggest_menu->entries[i].data.indirected_text.validation = (char *)-1; + url_suggest_menu->entries[i].data.indirected_text.size = strlen(suggest_text[i]) + 1; + } + url_suggest_menu->entries[0].menu_flags |= wimp_MENU_TITLE_INDIRECTED; + url_suggest_menu->entries[suggestions - 1].menu_flags |= wimp_MENU_LAST; + return true; +} + + +/** + * Display a menu. + */ void ro_gui_create_menu(wimp_menu *menu, int x, int y, struct gui_window *g) { int doc_x, doc_y; @@ -702,6 +800,11 @@ void ro_gui_create_menu(wimp_menu *menu, int x, int y, struct gui_window *g) ro_gui_menu_prepare_theme(); } else if (menu == hotlist_menu) { ro_gui_menu_prepare_hotlist(); + } else if (menu == global_history_menu) { + ro_gui_menu_prepare_global_history(); + } else if (menu == url_suggest_menu) { + if (!ro_gui_menu_prepare_url_suggest()) + return; } error = xwimp_create_menu(menu, x - 64, y); @@ -732,7 +835,7 @@ void ro_gui_popup_menu(wimp_menu *menu, wimp_w w, wimp_i i) wimp_get_icon_state(&icon_state); ro_gui_create_menu(menu, state.visible.x0 + icon_state.icon.extent.x1 + 64, - state.visible.y1 + icon_state.icon.extent.y1, 0); + state.visible.y1 + icon_state.icon.extent.y1 - state.yscroll, current_gui); } @@ -775,6 +878,14 @@ void ro_gui_menu_selection(wimp_selection *selection) break; } + } else if (current_menu == url_suggest_menu) { + if (!current_gui) + LOG(("No current GUI")); + else if (selection->items[0] >= 0) { + browser_window_go(current_gui->bw, + url_suggest_menu->entries[selection->items[0]].data.indirected_text.text, 0); + global_history_add_recent(url_suggest_menu->entries[selection->items[0]].data.indirected_text.text); + } } else if (current_menu == toolbar_menu) { switch (selection->items[0]) { case 0: /* Icons-> */ @@ -980,6 +1091,8 @@ void ro_gui_menu_selection(wimp_selection *selection) case MENU_VIEW: switch (selection->items[1]) { case 0: /* Scale view */ + ro_gui_menu_prepare_scale(); + ro_gui_dialog_open_persistant(current_gui->window, dialog_zoom, false); break; case 1: /* Images -> */ switch (selection->items[2]) { @@ -1059,17 +1172,35 @@ void ro_gui_menu_selection(wimp_selection *selection) tree_handle_node_changed(hotlist_tree, node, false, true); ro_gui_tree_scroll_visible(hotlist_tree, &node->data); break; + case -1: case 1: /* Show hotlist */ ro_gui_hotlist_show(); break; } break; - case 1: /* Window -> */ + case 1: /* History -> */ + switch (selection->items[2]) { + case -1: + case 0: /* Local history */ + ro_gui_history_open(current_gui->bw, + current_gui->bw->history, false); + break; + case 1: /* Global history */ + ro_gui_global_history_show(); + break; + } + break; + case 2: /* Find Text -> */ +#ifdef WITH_SEARCH + ro_gui_search_open(current_gui, 0, 0, false, true); +#endif + break; + case 3: /* Window -> */ switch (selection->items[2]) { case 0: ro_gui_screen_size(&option_window_screen_width, &option_window_screen_height); - state.w = current_gui->bw->window->window; + state.w = current_gui->window; error = xwimp_get_window_state(&state); if (error) { LOG(("xwimp_get_window_state: 0x%x: %s", @@ -1092,11 +1223,10 @@ void ro_gui_menu_selection(wimp_selection *selection) option_window_screen_height = 0; break; } - ro_gui_save_options(); + if (selection->items[2] >= 0) + ro_gui_save_options(); ro_gui_menu_prepare_window(); break; - case 2: /* Find Text -> */ - break; } break; case MENU_HELP: @@ -1143,6 +1273,8 @@ void ro_gui_menu_selection(wimp_selection *selection) } else { if (current_menu == hotlist_menu) ro_gui_hotlist_menu_closed(); + else if (current_menu == global_history_menu) + ro_gui_global_history_menu_closed(); current_menu = NULL; current_gui = NULL; } @@ -1159,6 +1291,8 @@ void ro_gui_menu_warning(wimp_message_menu_warning *warning) ro_gui_menu_browser_warning(warning); else if (current_menu == hotlist_menu) ro_gui_menu_hotlist_warning(warning); + else if (current_menu == global_history_menu) + ro_gui_menu_global_history_warning(warning); } @@ -1342,11 +1476,7 @@ void ro_gui_menu_browser_warning(wimp_message_menu_warning *warning) case MENU_UTILITIES: switch (warning->selection.items[1]) { case 0: /* Hotlist -> */ - break; - case 1: /* Window -> */ - ro_gui_menu_prepare_window(); - error = xwimp_create_sub_menu(browser_window_menu, - warning->pos.x, warning->pos.y); + case 1: /* History -> */ break; case 2: /* Find text -> */ #ifdef WITH_SEARCH @@ -1355,7 +1485,12 @@ void ro_gui_menu_browser_warning(wimp_message_menu_warning *warning) warning->pos.y, true, false); + break; #endif + case 3: /* Window -> */ + ro_gui_menu_prepare_window(); + error = xwimp_create_sub_menu(browser_window_menu, + warning->pos.x, warning->pos.y); break; } break; @@ -1442,6 +1577,41 @@ void ro_gui_menu_hotlist_warning(wimp_message_menu_warning *warning) } +/** + * Handle Message_MenuWarning for the global history menu. + */ + +void ro_gui_menu_global_history_warning(wimp_message_menu_warning *warning) +{ + os_error *error = NULL; + + switch (warning->selection.items[0]) { + case 0: /* History-> */ + switch (warning->selection.items[1]) { + case 0: /* Export-> */ + ro_gui_save_open(GUI_SAVE_HISTORY_EXPORT_HTML, 0, true, + warning->pos.x, warning->pos.y, 0, false); + break; + } + break; + case 1: /* Selection-> */ + switch (warning->selection.items[1]) { + case -1: /* Root */ + ro_gui_menu_prepare_global_history(); + error = xwimp_create_sub_menu(hotlist_select_menu, + warning->pos.x, warning->pos.y); + break; + } + break; + } + + if (error) { + LOG(("xwimp_create_sub_menu: 0x%x: %s", + error->errnum, error->errmess)); + warn_user("MenuError", error->errmess); + } +} + /** * Update navigate menu status and toolbar icons. * @@ -1455,6 +1625,7 @@ void ro_gui_prepare_navigate(struct gui_window *gui) { bool update_menu = ((current_menu == browser_menu) && (current_gui == gui)); int menu_changed = 0; unsigned int i; + int suggestions; wimp_selection selection; if (!gui) { @@ -1509,6 +1680,8 @@ void ro_gui_prepare_navigate(struct gui_window *gui) { ro_gui_set_icon_shaded_state(t->toolbar_handle, ICON_TOOLBAR_HISTORY, true); } ro_gui_set_icon_shaded_state(t->toolbar_handle, ICON_TOOLBAR_BOOKMARK, !hotlist_tree); + global_history_get_recent(&suggestions); + ro_gui_set_icon_shaded_state(t->toolbar_handle, ICON_TOOLBAR_SUGGEST, (suggestions <= 0)); } /* Update the stop/refresh icons/buttons @@ -1786,7 +1959,18 @@ void ro_gui_menu_prepare_hotlist(void) { if (hotlist_tree->root->child) { single = tree_get_selected_node(hotlist_tree->root->child); selection = tree_has_selection(hotlist_tree->root->child); + hotlist_menu->entries[2].icon_flags &= ~wimp_ICON_SHADED; + hotlist_file_menu->entries[2].icon_flags &= ~wimp_ICON_SHADED; + hotlist_file_menu->entries[3].icon_flags &= ~wimp_ICON_SHADED; + } else { + hotlist_menu->entries[2].icon_flags |= wimp_ICON_SHADED; + hotlist_file_menu->entries[2].icon_flags |= wimp_ICON_SHADED; + hotlist_file_menu->entries[3].icon_flags &= wimp_ICON_SHADED; } + ro_gui_set_icon_shaded_state(hotlist_toolbar->toolbar_handle, + ICON_TOOLBAR_OPEN, !hotlist_tree->root->child); + ro_gui_set_icon_shaded_state(hotlist_toolbar->toolbar_handle, + ICON_TOOLBAR_EXPAND, !hotlist_tree->root->child); if (hotlist_toolbar) { ro_gui_set_icon_shaded_state(hotlist_toolbar->toolbar_handle, @@ -1824,6 +2008,57 @@ void ro_gui_menu_prepare_hotlist(void) { } +/** + * Update global history menu (all of) + */ +void ro_gui_menu_prepare_global_history(void) { + os_error *error; + bool reopen = false; + bool selection = false; + + if (global_history_tree->root->child) { + selection = tree_has_selection(global_history_tree->root->child); + global_history_menu->entries[2].icon_flags &= ~wimp_ICON_SHADED; + history_file_menu->entries[1].icon_flags &= ~wimp_ICON_SHADED; + history_file_menu->entries[2].icon_flags &= ~wimp_ICON_SHADED; + } else { + global_history_menu->entries[2].icon_flags |= wimp_ICON_SHADED; + history_file_menu->entries[1].icon_flags |= wimp_ICON_SHADED; + history_file_menu->entries[2].icon_flags |= wimp_ICON_SHADED; + } + ro_gui_set_icon_shaded_state(global_history_toolbar->toolbar_handle, + ICON_TOOLBAR_OPEN, !global_history_tree->root->child); + ro_gui_set_icon_shaded_state(global_history_toolbar->toolbar_handle, + ICON_TOOLBAR_EXPAND, !global_history_tree->root->child); + + if (hotlist_toolbar) { + ro_gui_set_icon_shaded_state(global_history_toolbar->toolbar_handle, + ICON_TOOLBAR_DELETE, !selection); + ro_gui_set_icon_shaded_state(global_history_toolbar->toolbar_handle, + ICON_TOOLBAR_LAUNCH, !selection); + } + + if (selection) { + reopen |= (global_history_menu->entries[1].icon_flags & wimp_ICON_SHADED); + global_history_menu->entries[1].icon_flags &= ~wimp_ICON_SHADED; + global_history_menu->entries[3].icon_flags &= ~wimp_ICON_SHADED; + } else { + reopen |= !(global_history_menu->entries[1].icon_flags & wimp_ICON_SHADED); + global_history_menu->entries[1].icon_flags |= wimp_ICON_SHADED; + global_history_menu->entries[3].icon_flags |= wimp_ICON_SHADED; + } + + if ((reopen) && (current_menu == global_history_menu)) { + error = xwimp_create_menu(global_history_menu, 0, 0); + if (error) { + LOG(("xwimp_create_menu: 0x%x: %s", + error->errnum, error->errmess)); + warn_user("MenuError", error->errmess); + } + } +} + + /** * Update the Interactive Help status * diff --git a/riscos/options.h b/riscos/options.h index 566d40161..db140b9dd 100644 --- a/riscos/options.h +++ b/riscos/options.h @@ -73,6 +73,7 @@ extern char *option_font_default_bold_italic; extern bool option_font_ufont; extern int option_screen_cache; extern bool option_block_popups; +extern bool option_url_suggestion; #define EXTRA_OPTION_DEFINE \ bool option_use_mouse_gestures = false;\ @@ -130,7 +131,8 @@ char *option_font_default_bold = 0; \ char *option_font_default_bold_italic = 0; \ bool option_font_ufont = false; \ int option_screen_cache = 0; \ -bool option_block_popups = 0; +bool option_block_popups = false; \ +bool option_url_suggestion = true; #define EXTRA_OPTION_TABLE \ { "use_mouse_gestures", OPTION_BOOL, &option_use_mouse_gestures },\ @@ -187,7 +189,8 @@ bool option_block_popups = 0; { "font_default_bold", OPTION_STRING, &option_font_default_bold }, \ { "font_default_bold_italic", OPTION_STRING, &option_font_default_bold_italic }, \ { "font_ufont", OPTION_BOOL, &option_font_ufont }, \ -{ "screen_cache", OPTION_INTEGER, &option_screen_cache }, \ -{ "block_popups", OPTION_BOOL, &option_block_popups } +{ "screen_cache", OPTION_INTEGER, &option_screen_cache }, \ +{ "block_popups", OPTION_BOOL, &option_block_popups }, \ +{ "url_suggestion", OPTION_BOOL, &option_url_suggestion } #endif diff --git a/riscos/save.c b/riscos/save.c index 08d1f9fa7..fd472384c 100644 --- a/riscos/save.c +++ b/riscos/save.c @@ -63,6 +63,7 @@ struct gui_save_table_entry gui_save_table[] = { /* GUI_SAVE_LINK_URL, */ { 0xb28, "SaveLink" }, /* GUI_SAVE_LINK_TEXT, */ { 0xfff, "SaveLink" }, /* GUI_SAVE_HOTLIST_EXPORT_HTML, */ { 0xfaf, "Hotlist" }, + /* GUI_SAVE_HISTORY_EXPORT_HTML, */ { 0xfaf, "History" }, }; @@ -88,7 +89,8 @@ void ro_gui_save_open(gui_save_type save_type, struct content *c, os_error *error; url_func_result res; - assert(save_type == GUI_SAVE_HOTLIST_EXPORT_HTML || c); + assert((save_type == GUI_SAVE_HOTLIST_EXPORT_HTML) || + (save_type == GUI_SAVE_HISTORY_EXPORT_HTML) || c); gui_save_current_type = save_type; gui_save_content = c; @@ -239,7 +241,8 @@ void ro_gui_save_datasave_ack(wimp_message *message) os_error *error; if (!gui_save_content && - gui_save_current_type != GUI_SAVE_HOTLIST_EXPORT_HTML) { + (gui_save_current_type != GUI_SAVE_HOTLIST_EXPORT_HTML) && + (gui_save_current_type != GUI_SAVE_HISTORY_EXPORT_HTML)) { LOG(("unexpected DataSaveAck: gui_save_content not set")); return; } @@ -309,7 +312,15 @@ void ro_gui_save_datasave_ack(wimp_message *message) return; break; case GUI_SAVE_HOTLIST_EXPORT_HTML: - if (!options_save_hotlist(hotlist_tree, path)) + if (!options_save_tree(hotlist_tree, path, "NetSurf hotlist")) + return; + error = xosfile_set_type(path, 0xfaf); + if (error) + LOG(("xosfile_set_type: 0x%x: %s", + error->errnum, error->errmess)); + break; + case GUI_SAVE_HISTORY_EXPORT_HTML: + if (!options_save_tree(global_history_tree, path, "NetSurf history")) return; error = xosfile_set_type(path, 0xfaf); if (error) diff --git a/riscos/theme.c b/riscos/theme.c index 545663564..a78c96790 100644 --- a/riscos/theme.c +++ b/riscos/theme.c @@ -20,6 +20,7 @@ #include "oslib/osfile.h" #include "oslib/osfind.h" #include "oslib/osspriteop.h" +#include "oslib/wimpspriteop.h" #include "oslib/squash.h" #include "oslib/wimp.h" #include "oslib/wimpextend.h" @@ -39,7 +40,8 @@ static struct theme_descriptor *theme_descriptors = NULL; static void ro_gui_theme_get_available_in_dir(const char *directory); static void ro_gui_theme_free(struct theme_descriptor *descriptor, bool list); -static void ro_gui_theme_add_toolbar_icon(struct toolbar *toolbar, const char *name, int icon_number); +static struct toolbar_icon *ro_gui_theme_add_toolbar_icon(struct toolbar *toolbar, const char *name, + int icon_number); static void ro_gui_theme_update_toolbar_icon(struct toolbar *toolbar, struct toolbar_icon *icon); static void ro_gui_theme_destroy_toolbar_icon(struct toolbar_icon *icon); @@ -51,7 +53,8 @@ static wimp_window theme_toolbar_window = { 0, 0, wimp_TOP, - wimp_WINDOW_NEW_FORMAT | wimp_WINDOW_MOVEABLE | wimp_WINDOW_FURNITURE_WINDOW, + wimp_WINDOW_NEW_FORMAT | wimp_WINDOW_MOVEABLE | wimp_WINDOW_FURNITURE_WINDOW | + wimp_WINDOW_IGNORE_XEXTENT | wimp_WINDOW_IGNORE_YEXTENT, wimp_COLOUR_BLACK, wimp_COLOUR_LIGHT_GREY, wimp_COLOUR_LIGHT_GREY, @@ -706,9 +709,12 @@ struct toolbar *ro_gui_theme_create_toolbar(struct theme_descriptor *descriptor, ro_gui_theme_add_toolbar_icon(toolbar, "hotlist", ICON_TOOLBAR_BOOKMARK); ro_gui_theme_add_toolbar_icon(toolbar, "save", ICON_TOOLBAR_SAVE); ro_gui_theme_add_toolbar_icon(toolbar, "print", ICON_TOOLBAR_PRINT); + toolbar->suggest = ro_gui_theme_add_toolbar_icon(NULL, "gright", + ICON_TOOLBAR_SUGGEST); break; case THEME_HOTLIST_TOOLBAR: ro_gui_theme_add_toolbar_icon(toolbar, "create", ICON_TOOLBAR_CREATE); + case THEME_HISTORY_TOOLBAR: ro_gui_theme_add_toolbar_icon(toolbar, "delete", ICON_TOOLBAR_DELETE); ro_gui_theme_add_toolbar_icon(toolbar, "launch", ICON_TOOLBAR_LAUNCH); ro_gui_theme_add_toolbar_icon(toolbar, NULL, -1); @@ -756,6 +762,7 @@ bool ro_gui_theme_update_toolbar(struct theme_descriptor *descriptor, struct too osspriteop_area *sprite_area; struct toolbar_icon *toolbar_icon; int width, max_icon; + wimp_icon_flags icon_flags; if (!toolbar) return false; /* Set the theme and window sprite area @@ -772,6 +779,8 @@ bool ro_gui_theme_update_toolbar(struct theme_descriptor *descriptor, struct too */ for (toolbar_icon = toolbar->icon; toolbar_icon; toolbar_icon = toolbar_icon->next) ro_gui_theme_update_toolbar_icon(toolbar, toolbar_icon); + if (toolbar->suggest) + ro_gui_theme_update_toolbar_icon(toolbar, toolbar->suggest); /* Recreate the toolbar window */ @@ -809,6 +818,8 @@ bool ro_gui_theme_update_toolbar(struct theme_descriptor *descriptor, struct too */ if (toolbar->type == THEME_HOTLIST_TOOLBAR) max_icon = ICON_TOOLBAR_HOTLIST_LAST; + else if (toolbar->type == THEME_HISTORY_TOOLBAR) + max_icon = ICON_TOOLBAR_HISTORY_LAST; else max_icon = ICON_TOOLBAR_URL; new_icon.w = toolbar->toolbar_handle; @@ -823,9 +834,11 @@ bool ro_gui_theme_update_toolbar(struct theme_descriptor *descriptor, struct too else new_icon.icon.flags |= (wimp_COLOUR_VERY_LIGHT_GREY << wimp_ICON_BG_COLOUR_SHIFT); + icon_flags = new_icon.icon.flags; for (int i = 0; i < max_icon; i++) { new_icon.icon.data.indirected_text.text = theme_null_text_string; + new_icon.icon.data.indirected_text.validation = theme_null_text_string; toolbar_icon = toolbar->icon; while (toolbar_icon) { if (toolbar_icon->icon_number == i) { @@ -877,6 +890,23 @@ bool ro_gui_theme_update_toolbar(struct theme_descriptor *descriptor, struct too warn_user("WimpError", error->errmess); return false; } + + /* Now the URL suggestion icon + */ + new_icon.icon.data.indirected_text.text = theme_null_text_string; + new_icon.icon.data.indirected_text.size = 1; + new_icon.icon.flags = icon_flags; + if (toolbar->suggest) + new_icon.icon.data.indirected_text.validation = toolbar->suggest->validation; + else + new_icon.icon.data.indirected_text.validation = theme_null_text_string; + error = xwimp_create_icon(&new_icon, 0); + if (error) { + LOG(("xwimp_create_icon: 0x%x: %s", + error->errnum, error->errmess)); + warn_user("WimpError", error->errmess); + return false; + } } if (toolbar->parent_handle) { ro_gui_theme_attach_toolbar(toolbar, toolbar->parent_handle); @@ -1138,7 +1168,10 @@ bool ro_gui_theme_process_toolbar(struct toolbar *toolbar, int width) { toolbar->height = toolbar->descriptor->theme->throbber_height + 8; } if ((toolbar->type == THEME_BROWSER_TOOLBAR) && (toolbar->display_url)) { - if (toolbar->height < 52 + 8) toolbar->height = 52 + 8; + if (toolbar->height < 52 + 8) + toolbar->height = 52 + 8; + if ((toolbar->suggest) && (toolbar->height < (toolbar->suggest->height + 8))) + toolbar->height = toolbar->suggest->height + 8; } /* Get the minimum height of the icons @@ -1165,8 +1198,13 @@ bool ro_gui_theme_process_toolbar(struct toolbar *toolbar, int width) { */ if (toolbar->type == THEME_BROWSER_TOOLBAR) { if (!toolbar->reformat_buttons) left_edge = bottom_edge; - if (toolbar->display_url) bottom_edge += 64; - if (bottom_edge > right_edge) right_edge = bottom_edge; + if (toolbar->display_url) { + bottom_edge += 64; + if (toolbar->suggest) + bottom_edge += toolbar->suggest->width + 8; + } + if (bottom_edge > right_edge) + right_edge = bottom_edge; if ((toolbar->descriptor) && (toolbar->descriptor->theme) && (toolbar->display_throbber) && (toolbar->descriptor->throbber_right)) { @@ -1188,6 +1226,8 @@ bool ro_gui_theme_process_toolbar(struct toolbar *toolbar, int width) { } xwimp_resize_icon(toolbar->toolbar_handle, ICON_TOOLBAR_URL, 0, -16384, 0, -16384); + xwimp_resize_icon(toolbar->toolbar_handle, ICON_TOOLBAR_SUGGEST, + 0, -16384, 0, -16384); } ro_gui_set_icon_shaded_state(toolbar->toolbar_handle, ICON_TOOLBAR_URL, !toolbar->display_url); @@ -1227,11 +1267,26 @@ bool ro_gui_theme_process_toolbar(struct toolbar *toolbar, int width) { /* Move the URL bar */ if (toolbar->display_url) { - xwimp_resize_icon(toolbar->toolbar_handle, ICON_TOOLBAR_URL, - left_edge, (toolbar->height / 2) - 26, - right_edge, (toolbar->height / 2) + 26); - xwimp_force_redraw(toolbar->toolbar_handle, - right_edge, 0, 16384, 16384); + if (toolbar->suggest) { + xwimp_resize_icon(toolbar->toolbar_handle, ICON_TOOLBAR_URL, + left_edge, (toolbar->height / 2) - 26, + right_edge - toolbar->suggest->width - 8, + (toolbar->height / 2) + 26); + xwimp_resize_icon(toolbar->toolbar_handle, ICON_TOOLBAR_SUGGEST, + right_edge - toolbar->suggest->width, + (toolbar->height - toolbar->suggest->height) / 2, + right_edge, + (toolbar->height + toolbar->suggest->height) / 2); + xwimp_force_redraw(toolbar->toolbar_handle, + right_edge - toolbar->suggest->width - 8, 0, + 16384, 16384); + } else { + xwimp_resize_icon(toolbar->toolbar_handle, ICON_TOOLBAR_URL, + left_edge, (toolbar->height / 2) - 26, + right_edge, (toolbar->height / 2) + 26); + xwimp_force_redraw(toolbar->toolbar_handle, + right_edge, 0, 16384, 16384); + } if (!xwimp_get_caret_position(&caret)) { if ((caret.w == toolbar->toolbar_handle) && (caret.i == ICON_TOOLBAR_URL)) { @@ -1389,6 +1444,7 @@ void ro_gui_theme_destroy_toolbar(struct toolbar *toolbar) { next_icon = icon->next; ro_gui_theme_destroy_toolbar_icon(icon); } + ro_gui_theme_destroy_toolbar_icon(toolbar->suggest); free(toolbar); } @@ -1400,8 +1456,8 @@ void ro_gui_theme_destroy_toolbar(struct toolbar *toolbar) { * \param name the icon name, or NULL for a separator * \param icon_number the RISC OS Wimp icon number for the icon (not used for separators) */ -void ro_gui_theme_add_toolbar_icon(struct toolbar *toolbar, const char *name, int icon_number) { - if (!toolbar) return; +struct toolbar_icon *ro_gui_theme_add_toolbar_icon(struct toolbar *toolbar, const char *name, + int icon_number) { struct toolbar_icon *toolbar_icon; struct toolbar_icon *link_icon; @@ -1418,7 +1474,7 @@ void ro_gui_theme_add_toolbar_icon(struct toolbar *toolbar, const char *name, in if (!toolbar_icon) { LOG(("No memory for malloc()")); warn_user("NoMemory", 0); - return; + return NULL; } /* Set up and link in the icon @@ -1427,13 +1483,16 @@ void ro_gui_theme_add_toolbar_icon(struct toolbar *toolbar, const char *name, in sprintf(toolbar_icon->validation, "R5;S%s,p%s", name, name); toolbar_icon->icon_number = icon_number; toolbar_icon->display = true; - if (!toolbar->icon) { - toolbar->icon = toolbar_icon; - } else { - link_icon = toolbar->icon; - while (link_icon->next) link_icon = link_icon->next; - link_icon->next = toolbar_icon; + if (toolbar) { + if (!toolbar->icon) { + toolbar->icon = toolbar_icon; + } else { + link_icon = toolbar->icon; + while (link_icon->next) link_icon = link_icon->next; + link_icon->next = toolbar_icon; + } } + return toolbar_icon; } @@ -1467,6 +1526,11 @@ void ro_gui_theme_update_toolbar_icon(struct toolbar *toolbar, struct toolbar_ic error = xosspriteop_read_sprite_info(osspriteop_USER_AREA, toolbar->descriptor->theme->sprite_area, (osspriteop_id)icon->name, &dimensions.x, &dimensions.y, 0, &mode); + + /* fallback to user area just for 'gright' */ + if ((error) && (!strcmp(icon->name, "gright"))) + error = xwimpspriteop_read_sprite_info(icon->name, + &dimensions.x, &dimensions.y, 0, &mode); if (error) { icon->width = default_width; icon->height = 0; diff --git a/riscos/theme.h b/riscos/theme.h index aa8061a78..0c6f369db 100644 --- a/riscos/theme.h +++ b/riscos/theme.h @@ -16,7 +16,8 @@ typedef enum { THEME_BROWSER_TOOLBAR, - THEME_HOTLIST_TOOLBAR + THEME_HOTLIST_TOOLBAR, + THEME_HISTORY_TOOLBAR } toolbar_type; struct theme_file_header { @@ -73,6 +74,7 @@ struct toolbar { char *throbber_buffer; /**< buffer for status text (read only) */ char *status_buffer; /**< buffer for status text (read only) */ struct toolbar_icon *icon; /**< first toolbar icon (read only) */ + struct toolbar_icon *suggest; /**< suggestion toolbar icon (read only) */ struct theme_descriptor *descriptor; /**< theme descriptor (read only) */ toolbar_type type; /**< toolbar type (read only) */ bool locked; /**< toolbar is locked from editing */ diff --git a/riscos/treeview.c b/riscos/treeview.c index bac64fa2f..ef5618aae 100644 --- a/riscos/treeview.c +++ b/riscos/treeview.c @@ -22,6 +22,7 @@ #include "oslib/wimp.h" #include "netsurf/desktop/tree.h" #include "netsurf/riscos/gui.h" +#include "netsurf/riscos/theme.h" #include "netsurf/riscos/tinct.h" #include "netsurf/riscos/treeview.h" #include "netsurf/riscos/wimp.h" @@ -784,6 +785,48 @@ void ro_gui_tree_menu_closed(struct tree *tree) { } +/** + * Respond to a mouse click for a tree (hotlist or history) toolbar + * + * \param pointer the pointer state + */ +void ro_gui_tree_toolbar_click(wimp_pointer* pointer, struct tree *tree, + struct toolbar *toolbar) { + struct node *node; + + current_toolbar = toolbar; + ro_gui_tree_stop_edit(tree); + + switch (pointer->i) { + case ICON_TOOLBAR_CREATE: + node = tree_create_folder_node(tree->root, + messages_get("TreeNewFolder")); + tree_redraw_area(tree, node->box.x - NODE_INSTEP, + 0, NODE_INSTEP, 16384); + tree_handle_node_changed(tree, node, false, true); + ro_gui_tree_start_edit(tree, &node->data, NULL); + break; + case ICON_TOOLBAR_OPEN: + tree_handle_expansion(tree, tree->root, + (pointer->buttons == wimp_CLICK_SELECT), + true, false); + break; + case ICON_TOOLBAR_EXPAND: + tree_handle_expansion(tree, tree->root, + (pointer->buttons == wimp_CLICK_SELECT), + false, true); + break; + case ICON_TOOLBAR_DELETE: + tree_delete_selected_nodes(tree, + tree->root); + break; + case ICON_TOOLBAR_LAUNCH: + ro_gui_tree_launch_selected(tree); + break; + } +} + + /** * Starts an editing session * @@ -920,6 +963,74 @@ void ro_gui_tree_scroll_visible(struct tree *tree, struct node_element *element) } +/** + * Shows the a tree window. + */ +void ro_gui_tree_show(struct tree *tree, struct toolbar *toolbar) { + os_error *error; + int screen_width, screen_height; + wimp_window_state state; + int dimension; + int scroll_width; + + /* We may have failed to initialise + */ + if (!tree) return; + + /* Get the window state + */ + state.w = (wimp_w)tree->handle; + error = xwimp_get_window_state(&state); + if (error) { + warn_user("WimpError", error->errmess); + return; + } + + /* If we're open we jump to the top of the stack, if not then we + open in the centre of the screen. + */ + if (!(state.flags & wimp_WINDOW_OPEN)) { + + /* Cancel any editing + */ + ro_gui_tree_stop_edit(tree); + + /* Set the default state + */ + if (tree->root->child) + tree_handle_node_changed(tree, tree->root, + false, true); + + /* Get the current screen size + */ + ro_gui_screen_size(&screen_width, &screen_height); + + /* Move to the centre + */ + dimension = 600; /*state.visible.x1 - state.visible.x0;*/ + scroll_width = ro_get_vscroll_width((wimp_w)tree->handle); + state.visible.x0 = (screen_width - (dimension + scroll_width)) / 2; + state.visible.x1 = state.visible.x0 + dimension; + dimension = 800; /*state.visible.y1 - state.visible.y0;*/ + state.visible.y0 = (screen_height - dimension) / 2; + state.visible.y1 = state.visible.y0 + dimension; + state.xscroll = 0; + state.yscroll = 0; + if (toolbar) + state.yscroll = toolbar->height; + } + + /* Open the window at the top of the stack + */ + state.next = wimp_TOP; + ro_gui_tree_open((wimp_open*)&state, tree); + + /* Set the caret position + */ + xwimp_set_caret_position(state.w, -1, -100, -100, 32, -1); +} + + /** * Handles a window open request * @@ -982,7 +1093,7 @@ bool ro_gui_tree_keypress(int key, struct tree *tree) { return true; case 24: /* CTRL+X */ ro_gui_tree_stop_edit(tree); - tree_delete_selected_nodes(hotlist_tree, hotlist_tree->root); + tree_delete_selected_nodes(tree, tree->root); return true; case 26: /* CTRL+Z */ tree->temp_selection = NULL; diff --git a/riscos/treeview.h b/riscos/treeview.h index 1757d2fd8..a3631de04 100644 --- a/riscos/treeview.h +++ b/riscos/treeview.h @@ -30,8 +30,11 @@ bool ro_gui_tree_initialise(void); void ro_gui_tree_redraw(wimp_draw *redraw, struct tree *tree); bool ro_gui_tree_click(wimp_pointer *pointer, struct tree *tree); void ro_gui_tree_menu_closed(struct tree *tree); +void ro_gui_tree_toolbar_click(wimp_pointer* pointer, struct tree *tree, + struct toolbar *toolbar); void ro_gui_tree_stop_edit(struct tree *tree); void ro_gui_tree_open(wimp_open *open, struct tree *tree); +void ro_gui_tree_show(struct tree *tree, struct toolbar *toolbar); bool ro_gui_tree_keypress(int key, struct tree *tree); void ro_gui_tree_selection_drag_end(wimp_dragged *drag); void ro_gui_tree_move_drag_end(wimp_dragged *drag); diff --git a/riscos/url_complete.c b/riscos/url_complete.c index 268f08597..6fc319527 100644 --- a/riscos/url_complete.c +++ b/riscos/url_complete.c @@ -17,7 +17,9 @@ #include "oslib/wimp.h" #include "netsurf/content/url_store.h" #include "netsurf/utils/log.h" +#include "netsurf/riscos/global_history.h" #include "netsurf/riscos/gui.h" +#include "netsurf/riscos/options.h" #include "netsurf/riscos/theme.h" #include "netsurf/riscos/url_complete.h" #include "netsurf/riscos/wimp.h" @@ -82,7 +84,7 @@ bool ro_gui_url_complete_keypress(struct gui_window *g, int key) { bool currently_open; /* we must have a toolbar/url bar */ - if ((!g->toolbar) || (!g->toolbar->display_url)) { + if ((!g->toolbar) || (!g->toolbar->display_url) || (!option_url_suggestion)) { ro_gui_url_complete_close(NULL, 0); return false; } @@ -563,6 +565,7 @@ void ro_gui_url_complete_mouse_at(wimp_pointer *pointer) { browser_window_go(g->bw, url_complete_matches[url_complete_matches_selection], 0); + global_history_add_recent(url_complete_matches[url_complete_matches_selection]); ro_gui_url_complete_close(NULL, 0); } diff --git a/riscos/window.c b/riscos/window.c index cf84daa4c..0e3c5bea8 100644 --- a/riscos/window.c +++ b/riscos/window.c @@ -31,6 +31,7 @@ #include "netsurf/render/box.h" #include "netsurf/render/form.h" #include "netsurf/riscos/buffer.h" +#include "netsurf/riscos/global_history.h" #include "netsurf/riscos/gui.h" #include "netsurf/riscos/options.h" #include "netsurf/riscos/theme.h" @@ -833,6 +834,19 @@ void ro_gui_window_update_theme(void) { 0, -16384, 16384, 16384); } } + if (global_history_toolbar) { + if (!ro_gui_theme_update_toolbar(NULL, global_history_toolbar)) { + ro_gui_theme_destroy_toolbar(global_history_toolbar); + global_history_toolbar = NULL; + } + if (global_history_tree) { + ro_gui_theme_attach_toolbar(global_history_toolbar, + (wimp_w)global_history_tree->handle); + global_history_tree->offset_y = global_history_toolbar->height; + xwimp_force_redraw((wimp_w)global_history_tree->handle, + 0, -16384, 16384, 16384); + } + } } @@ -1134,9 +1148,11 @@ void ro_gui_toolbar_click(struct gui_window *g, wimp_pointer *pointer) break; case ICON_TOOLBAR_HISTORY: - ro_gui_history_open(g->bw, - g->bw->history, - pointer->pos.x, pointer->pos.y); + if (pointer->buttons == wimp_CLICK_SELECT) { + ro_gui_history_open(g->bw, g->bw->history, true); + } else if (global_history_tree) { + ro_gui_global_history_show(); + } break; case ICON_TOOLBAR_HOME: if (option_homepage_url && option_homepage_url[0]) { @@ -1171,7 +1187,7 @@ void ro_gui_toolbar_click(struct gui_window *g, wimp_pointer *pointer) case ICON_TOOLBAR_BOOKMARK: if ((pointer->buttons == wimp_CLICK_ADJUST) && (hotlist_tree)) { node = tree_create_URL_node(hotlist_tree->root, - messages_get(g->title), + g->title, g->bw->current_content->url, ro_content_filetype(g->bw->current_content), time(NULL), -1, 0); @@ -1197,6 +1213,13 @@ void ro_gui_toolbar_click(struct gui_window *g, wimp_pointer *pointer) break; case ICON_TOOLBAR_URL: ro_gui_url_complete_start(g); + break; + case ICON_TOOLBAR_SUGGEST: + current_gui = g; + ro_gui_popup_menu(url_suggest_menu, + current_toolbar->toolbar_handle, + ICON_TOOLBAR_SUGGEST); + break; } } @@ -1496,12 +1519,15 @@ bool ro_gui_window_keypress(struct gui_window *g, int key, bool toolbar) ro_gui_hotlist_show(); return true; - case wimp_KEY_F7: /* Toggle fullscreen browsing. */ - - - + case wimp_KEY_F7: /* Show history. */ + current_gui = g; + ro_gui_history_open(current_gui->bw, + current_gui->bw->history, false); return true; + case wimp_KEY_CONTROL + wimp_KEY_F7: /* Show global history. */ + ro_gui_global_history_show(); + return true; case wimp_KEY_F8: /* View source. */ ro_gui_view_source(content); @@ -1545,6 +1571,7 @@ bool ro_gui_window_keypress(struct gui_window *g, int key, bool toolbar) if (res == URL_FUNC_OK) { gui_window_set_url(g, url); browser_window_go(g->bw, url, 0); + global_history_add_recent(url); free(url); } return true; @@ -1989,3 +2016,17 @@ void gui_window_new_content(struct gui_window *g) ro_gui_prepare_navigate(g); ro_gui_dialog_close_persistant(g->window); } + + +/** + * Updates the navigation controls for all toolbars; + * + * \param g the gui_window to launch the URL into + * \param url the URL to launch, or NULL to simply update the suggestion icon + */ +void ro_gui_window_prepare_navigate_all(void) { + struct gui_window *g; + + for (g = window_list; g; g = g->next) + ro_gui_prepare_navigate(g); +} -- cgit v1.2.3