From 32db7e04d0c3bd255b2e8aa7dbd7c2b884b35614 Mon Sep 17 00:00:00 2001 From: Richard Wilson Date: Thu, 9 Dec 2004 10:30:44 +0000 Subject: [project @ 2004-12-09 10:30:43 by rjw] Re-implementation of hotlist via general tree code. Animations can be stopped once more. Purged a few xcalloc() calls. svn path=/import/netsurf/; revision=1394 --- riscos/401login.c | 13 +- riscos/gui.c | 123 ++- riscos/gui.h | 24 +- riscos/help.c | 2 +- riscos/hotlist.c | 2697 ++++++----------------------------------------------- riscos/menus.c | 307 +++--- riscos/options.h | 3 - riscos/save.c | 7 +- riscos/treeview.c | 1183 +++++++++++++++++++++++ riscos/treeview.h | 45 + riscos/wimp.c | 12 +- riscos/wimp.h | 1 + riscos/window.c | 44 +- 13 files changed, 1826 insertions(+), 2635 deletions(-) create mode 100644 riscos/treeview.c create mode 100644 riscos/treeview.h (limited to 'riscos') diff --git a/riscos/401login.c b/riscos/401login.c index b2f3cf4f0..c9fe9a895 100644 --- a/riscos/401login.c +++ b/riscos/401login.c @@ -27,9 +27,9 @@ static void get_unamepwd(void); static wimp_window *dialog_401_template; extern wimp_w dialog_401li; -static char *uname; +static char uname[256]; static char *url; -static char *pwd; +static char pwd[256]; static struct browser_window *bwin; @@ -66,8 +66,6 @@ void gui_401login_open(struct browser_window *bw, struct content *c, char *realm void ro_gui_401login_open(wimp_w parent, char *host, char* realm, char *fetchurl) { url = xstrdup(fetchurl); - uname = xcalloc(1, 256); - pwd = xcalloc(1, 256); uname[0] = pwd[0] = 0; /* fill in download window icons */ @@ -128,9 +126,12 @@ void ro_gui_401login_click(wimp_pointer *pointer) void get_unamepwd(void) { - char *lidets = xcalloc(strlen(uname)+strlen(pwd)+2, sizeof(char)); - if (lidets == NULL) + char *lidets = calloc(strlen(uname)+strlen(pwd)+2, sizeof(char)); + if (!lidets) { + LOG(("Insufficient memory for calloc")); + warn_user("NoMemory", 0); return; + } sprintf(lidets, "%s:%s", uname, pwd); diff --git a/riscos/gui.c b/riscos/gui.c index b8134589f..4b5856efb 100644 --- a/riscos/gui.c +++ b/riscos/gui.c @@ -1,7 +1,7 @@ /* * This file is part of NetSurf, http://netsurf.sourceforge.net/ * Licensed under the GNU General Public License, - * http://www.opensource.org/licenses/gpl-license + * http://www.opensource.org/licenses/gpl-license * Copyright 2003 Phil Mellor * Copyright 2004 James Bursa * Copyright 2003 John M Bell @@ -36,6 +36,7 @@ #include "netsurf/desktop/gui.h" #include "netsurf/desktop/netsurf.h" #include "netsurf/desktop/options.h" +#include "netsurf/desktop/tree.h" #include "netsurf/render/font.h" #include "netsurf/render/html.h" #include "netsurf/riscos/gui.h" @@ -49,6 +50,7 @@ #endif #include "netsurf/riscos/save_complete.h" #include "netsurf/riscos/theme.h" +#include "netsurf/riscos/treeview.h" #ifdef WITH_URI #include "netsurf/riscos/uri.h" #endif @@ -61,7 +63,7 @@ #include "netsurf/utils/utils.h" const char *__dynamic_da_name = "NetSurf"; /**< For UnixLib. */ -int __feature_imagefs_is_file = 1; /**< For UnixLib. */ +int __feature_imagefs_is_file = 1; /**< For UnixLib. */ /* default filename handling */ int __riscosify_control = __RISCOSIFY_NO_SUFFIX | __RISCOSIFY_NO_REVERSE_SUFFIX; @@ -84,11 +86,11 @@ bool gui_reformat_pending = false; gui_drag_type gui_current_drag_type; wimp_t task_handle; /**< RISC OS wimp task handle. */ static clock_t gui_last_poll; /**< Time of last wimp_poll. */ -osspriteop_area *gui_sprites; /**< Sprite area containing pointer and hotlist sprites */ +osspriteop_area *gui_sprites; /**< Sprite area containing pointer and hotlist sprites */ /** Accepted wimp user messages. */ static wimp_MESSAGE_LIST(34) task_messages = { { - message_HELP_REQUEST, + message_HELP_REQUEST, message_DATA_SAVE, message_DATA_SAVE_ACK, message_DATA_LOAD, @@ -184,7 +186,7 @@ void gui_init(int argc, char** argv) save_complete_init(); #endif - /* We don't have the universal boot sequence on NCOS */ + /* We don't have the universal boot sequence on NCOS */ #ifndef ncos options_read("Choices:WWW.NetSurf.Choices"); #else @@ -203,8 +205,8 @@ void gui_init(int argc, char** argv) default_stylesheet_url = strdup("file://Resources/CSS"); adblock_stylesheet_url = strdup("file://Resources/AdBlock"); - /* Totally pedantic, but base the taskname on the build options. - */ + /* Totally pedantic, but base the taskname on the build options. + */ #ifndef ncos error = xwimp_initialise(wimp_VERSION_RO38, "NetSurf", (const wimp_message_list *) &task_messages, 0, @@ -220,7 +222,7 @@ void gui_init(int argc, char** argv) die(error->errmess); } - /* We don't need to check the fonts on NCOS */ + /* We don't need to check the fonts on NCOS */ #ifndef ncos ro_gui_check_fonts(); #endif @@ -231,11 +233,11 @@ void gui_init(int argc, char** argv) xwimp_start_task("Desktop", 0); /* Load our chosen theme - */ - ro_gui_theme_initialise(); - descriptor = ro_gui_theme_find(option_theme); - if (!descriptor) descriptor = ro_gui_theme_find("NetSurf"); - ro_gui_theme_apply(descriptor); + */ + ro_gui_theme_initialise(); + descriptor = ro_gui_theme_find(option_theme); + if (!descriptor) descriptor = ro_gui_theme_find("NetSurf"); + ro_gui_theme_apply(descriptor); /* Open the templates */ @@ -258,9 +260,10 @@ void gui_init(int argc, char** argv) ro_gui_history_init(); wimp_close_template(); ro_gui_sprites_init(); - ro_gui_hotlist_init(); + ro_gui_tree_initialise(); /* must be done after sprite loading */ + ro_gui_hotlist_initialise(); - /* We don't create an Iconbar icon on NCOS */ + /* We don't create an Iconbar icon on NCOS */ #ifndef ncos ro_gui_icon_bar_create(); #endif @@ -519,7 +522,7 @@ void gui_init2(int argc, char** argv) void gui_quit(void) { ro_gui_window_quit(); - ro_gui_hotlist_save(); + ro_gui_hotlist_save(); ro_gui_history_quit(); free(gui_sprites); xwimp_close_down(task_handle); @@ -686,10 +689,21 @@ void gui_multitask(void) void ro_gui_poll_queue(wimp_event_no event, wimp_block *block) { struct ro_gui_poll_block *q = - xcalloc(1, sizeof(struct ro_gui_poll_block)); + calloc(1, sizeof(struct ro_gui_poll_block)); + if (!q) { + LOG(("Insufficient memory for calloc")); + warn_user("NoMemory", 0); + return; + } q->event = event; - q->block = xcalloc(1, sizeof(*block)); + q->block = calloc(1, sizeof(*block)); + if (!q->block) { + free(q); + LOG(("Insufficient memory for calloc")); + warn_user("NoMemory", 0); + return; + } memcpy(q->block, block, sizeof(*block)); q->next = NULL; @@ -746,8 +760,8 @@ void ro_gui_redraw_window_request(wimp_draw *redraw) if (redraw->w == history_window) ro_gui_history_redraw(redraw); - else if (redraw->w == hotlist_window) - ro_gui_hotlist_redraw(redraw); + else if ((hotlist_tree) && (redraw->w == (wimp_w)hotlist_tree->handle)) + ro_gui_tree_redraw(redraw, hotlist_tree); else if ((hotlist_toolbar) && (hotlist_toolbar->toolbar_handle == redraw->w)) ro_gui_theme_redraw(hotlist_toolbar, redraw); else if (redraw->w == dialog_debug) @@ -757,7 +771,7 @@ void ro_gui_redraw_window_request(wimp_draw *redraw) else if ((g = ro_gui_toolbar_lookup(redraw->w)) != NULL) ro_gui_theme_redraw(g->toolbar, redraw); else { - ro_gui_dialog_redraw(redraw); + ro_gui_dialog_redraw(redraw); } } @@ -774,6 +788,8 @@ void ro_gui_open_window_request(wimp_open *open) g = ro_gui_window_lookup(open->w); if (g) { 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 { error = xwimp_open_window(open); if (error) { @@ -861,7 +877,7 @@ void ro_gui_mouse_click(wimp_pointer *pointer) ro_gui_icon_bar_click(pointer); else if (pointer->w == history_window) ro_gui_history_click(pointer); - else if (pointer->w == hotlist_window) + else if ((hotlist_tree) && (pointer->w == (wimp_w)hotlist_tree->handle)) ro_gui_hotlist_click(pointer); else if (pointer->w == dialog_saveas) ro_gui_save_click(pointer); @@ -937,12 +953,12 @@ void ro_gui_drag_end(wimp_dragged *drag) case GUI_DRAG_STATUS_RESIZE: break; - case GUI_DRAG_HOTLIST_SELECT: - ro_gui_hotlist_selection_drag_end(drag); + case GUI_DRAG_TREE_SELECT: + ro_gui_tree_selection_drag_end(drag); break; - case GUI_DRAG_HOTLIST_MOVE: - ro_gui_hotlist_move_drag_end(drag); + case GUI_DRAG_TREE_MOVE: + ro_gui_tree_move_drag_end(drag); break; } } @@ -958,13 +974,13 @@ void ro_gui_keypress(wimp_key *key) struct gui_window *g; os_error *error; - if (key->w == hotlist_window) + 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 ((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); - else + else handled = ro_gui_dialog_keypress(key); if (!handled) { @@ -1021,9 +1037,10 @@ void ro_gui_user_message(wimp_event_no event, wimp_message *message) &message->data); break; case message_MENUS_DELETED: - if (current_menu == hotlist_menu) { + if ((current_menu == hotlist_menu) && (hotlist_tree)) ro_gui_hotlist_menu_closed(); - } + current_menu = NULL; + current_gui = NULL; break; case message_MODE_CHANGE: ro_gui_history_mode_change(); @@ -1127,10 +1144,13 @@ void ro_msg_dataload(wimp_message *message) int file_type = message->data.data_xfer.file_type; char *url = 0; struct gui_window *g; + struct node *node; + struct node *link; os_error *error; + int x, y; + bool before; g = ro_gui_window_lookup(message->data.data_xfer.w); - if (g && ro_gui_window_dataload(g, message)) return; @@ -1152,6 +1172,35 @@ void ro_msg_dataload(wimp_message *message) else return; + + if (!url) + /* error has already been reported by one of the three + * functions called above */ + return; + + if (g) { + browser_window_go(g->bw, url, 0); + } else { + if ((hotlist_tree) && ((wimp_w)hotlist_tree->handle == + message->data.data_xfer.w)) { + ro_gui_tree_get_tree_coordinates(hotlist_tree, + message->data.data_xfer.pos.x, + message->data.data_xfer.pos.y, + &x, &y); + link = tree_get_link_details(hotlist_tree, x, y, &before); + node = tree_create_URL_node(NULL, + messages_get("TreeImport"), url, file_type, + time(NULL), -1, 0); + tree_link_node(link, node, before); + tree_handle_node_changed(hotlist_tree, node, false, true); + tree_redraw_area(hotlist_tree, node->box.x - NODE_INSTEP, 0, + NODE_INSTEP, 16384); + ro_gui_tree_start_edit(hotlist_tree, &node->data, NULL); + } else { + browser_window_create(url, 0, 0); + } + } + /* send DataLoadAck */ message->action = message_DATA_LOAD_ACK; message->your_ref = message->my_ref; @@ -1163,16 +1212,6 @@ void ro_msg_dataload(wimp_message *message) return; } - if (!url) - /* error has already been reported by one of the three - * functions called above */ - return; - - if (g) - browser_window_go(g->bw, url, 0); - else - browser_window_create(url, 0, 0); - free(url); } diff --git a/riscos/gui.h b/riscos/gui.h index c4d55f29a..bf5db9b85 100644 --- a/riscos/gui.h +++ b/riscos/gui.h @@ -19,6 +19,7 @@ #include "netsurf/desktop/netsurf.h" #include "netsurf/desktop/gui.h" #include "netsurf/desktop/options.h" +#include "netsurf/desktop/tree.h" #define THEMES_DIR ".Themes" @@ -31,7 +32,6 @@ extern wimp_w dialog_info, dialog_saveas, dialog_config, dialog_config_br, dialog_config_th_pane, dialog_debug, dialog_folder, dialog_entry, dialog_search, dialog_print, dialog_config_font; extern wimp_w history_window; -extern wimp_w hotlist_window; extern wimp_menu *iconbar_menu, *browser_menu, *combo_menu, *hotlist_menu, *proxyauth_menu, *languages_menu, *toolbar_menu, *image_quality_menu; @@ -44,6 +44,7 @@ extern osspriteop_area *gui_sprites; extern struct toolbar *hotlist_toolbar; extern bool dialog_folder_add, dialog_entry_add, hotlist_insert; extern bool print_active, print_text_black; +extern struct tree *hotlist_tree; typedef enum { GUI_SAVE_SOURCE, @@ -60,7 +61,7 @@ typedef enum { typedef enum { GUI_DRAG_SELECTION, GUI_DRAG_DOWNLOAD_SAVE, GUI_DRAG_SAVE, GUI_DRAG_STATUS_RESIZE, - GUI_DRAG_HOTLIST_SELECT, GUI_DRAG_HOTLIST_MOVE } gui_drag_type; + GUI_DRAG_TREE_SELECT, GUI_DRAG_TREE_MOVE } gui_drag_type; extern gui_drag_type gui_current_drag_type; @@ -86,7 +87,6 @@ struct gui_window { /** Options. */ struct { float scale; /**< Scale, 1.0 = 100%. */ - bool animate_images; /**< Animations should run. */ bool background_images; /**< Display background images. */ bool background_blending; /**< Perform background blending on text. */ bool buffer_animations; /**< Use screen buffering for animations. */ @@ -203,26 +203,16 @@ void ro_gui_history_click(wimp_pointer *pointer); void ro_gui_history_mouse_at(wimp_pointer *pointer); /* in hotlist.c */ -void ro_gui_hotlist_init(void); +void ro_gui_hotlist_initialise(void); void ro_gui_hotlist_save(void); void ro_gui_hotlist_show(void); -void ro_gui_hotlist_add(char *title, struct content *content); -void ro_gui_hotlist_redraw(wimp_draw *redraw); void ro_gui_hotlist_click(wimp_pointer *pointer); -void ro_gui_hotlist_selection_drag_end(wimp_dragged *drag); -void ro_gui_hotlist_move_drag_end(wimp_dragged *drag); bool ro_gui_hotlist_keypress(int key); -void ro_gui_hotlist_menu_closed(void); void ro_gui_hotlist_toolbar_click(wimp_pointer* pointer); -int ro_gui_hotlist_get_selected(bool folders); -void ro_gui_hotlist_reset_statistics(void); -void ro_gui_hotlist_set_selected(bool selected); -void ro_gui_hotlist_set_expanded(bool expand, bool folders, bool links); -void ro_gui_hotlist_delete_selected(void); -void ro_gui_hotlist_save_as(const char *file); -void ro_gui_hotlist_prepare_folder_dialog(bool selected); -void ro_gui_hotlist_prepare_entry_dialog(bool selected); +void ro_gui_hotlist_prepare_folder_dialog(struct node *node); +void ro_gui_hotlist_prepare_entry_dialog(struct node *node); void ro_gui_hotlist_dialog_click(wimp_pointer *pointer); +void ro_gui_hotlist_menu_closed(void); int ro_gui_hotlist_help(int x, int y); /* in save.c */ diff --git a/riscos/help.c b/riscos/help.c index 22fc5b09b..b6d7c0bb3 100644 --- a/riscos/help.c +++ b/riscos/help.c @@ -119,7 +119,7 @@ void ro_gui_interactive_help_request(wimp_message *message) { sprintf(message_token, "HelpHotFolder%i", (int)icon); } else if (window == dialog_entry) { sprintf(message_token, "HelpHotEntry%i", (int)icon); - } else if (window == hotlist_window) { + } else if ((hotlist_tree) && (window == (wimp_w)hotlist_tree->handle)) { sprintf(message_token, "HelpHotlist%i", ro_gui_hotlist_help(message_data->pos.x, message_data->pos.y)); diff --git a/riscos/hotlist.c b/riscos/hotlist.c index 021c5c365..055b71190 100644 --- a/riscos/hotlist.c +++ b/riscos/hotlist.c @@ -11,6 +11,7 @@ #include #include +#include #include #include #include @@ -22,102 +23,20 @@ #include "oslib/wimp.h" #include "oslib/wimpspriteop.h" #include "netsurf/content/content.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" #include "netsurf/utils/log.h" #include "netsurf/utils/messages.h" #include "netsurf/utils/utils.h" #include "netsurf/utils/url.h" -#define HOTLIST_EXPAND 0 -#define HOTLIST_COLLAPSE 1 -#define HOTLIST_ENTRY 2 -#define HOTLIST_LINE 3 -#define HOTLIST_TLINE 4 -#define HOTLIST_BLINE 5 - -#define HOTLIST_TEXT_BUFFER 256 - -#define HOTLIST_LEAF_INSET 32 -#define HOTLIST_ICON_WIDTH 36 -#define HOTLIST_LINE_HEIGHT 44 -#define HOTLIST_TEXT_PADDING 16 - -struct hotlist_entry { - - /** The next hotlist entry at this level, or NULL for no more - */ - struct hotlist_entry *next_entry; - - /** The child hotlist entry (NULL for no children). - The children value must be set for this value to take effect. - */ - struct hotlist_entry *child_entry; - - /** The hotlist entry that has this entry as its next entry - */ - struct hotlist_entry *previous_entry; - - /** The hotlist entry that this is a child of - */ - struct hotlist_entry *parent_entry; - - /** The number of children (-1 for non-folders, >=0 for folders) - */ - int children; - - /** The title of the hotlist entry/folder, UTF-8. - */ - char *title; - - /** The URL of the hotlist entry (NULL for folders) - */ - char *url; - - /** Whether this entry is expanded - */ - bool expanded; - - /** Whether this entry is selected - */ - bool selected; - - /** The content filetype (not for folders) - */ - int filetype; - - /** The number of visits - */ - int visits; - - /** Add/last visit dates - */ - time_t add_date; - time_t last_date; - - /** Position on last reformat (relative to window origin) - */ - int x0; - int y0; - int width; - int height; - - /** Cached values - */ - int collapsed_width; - int expanded_width; - - /** The width of the various lines sub-text - */ - int widths[4]; - - /** Whether the item is awaiting processing - */ - bool process; -}; +static void ro_gui_hotlist_visited(struct content *content, struct tree *tree, + struct node *node); /* A basic window for the toolbar and status */ @@ -129,7 +48,8 @@ static wimp_window hotlist_window_definition = { 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_VSCROLL | wimp_WINDOW_IGNORE_XEXTENT | + wimp_WINDOW_IGNORE_YEXTENT, wimp_COLOUR_BLACK, wimp_COLOUR_LIGHT_GREY, wimp_COLOUR_LIGHT_GREY, @@ -138,158 +58,42 @@ static wimp_window hotlist_window_definition = { wimp_COLOUR_MID_LIGHT_GREY, wimp_COLOUR_CREAM, 0, - {0, -800, 16384, 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, - 256, + 100, {""}, - 0 + 0, + {} }; -/* An icon to plot text with -*/ -static wimp_icon text_icon; -static wimp_icon sprite_icon; - -/* Temporary workspace for plotting -*/ -static char drag_name[12]; -static char icon_name[12]; -static char extended_text[HOTLIST_TEXT_BUFFER]; - -/* Whether a reformat is pending -*/ -static bool reformat_pending = false; -static int max_width = 0; -static int max_height = 0; /* The hotlist window, toolbar and plot origins */ -wimp_w hotlist_window; -struct toolbar *hotlist_toolbar = NULL; -static int origin_x, origin_y; - -/* The current redraw rectangle -*/ -static int clip_x0, clip_y0, clip_x1, clip_y1; - -/* The root entry -*/ -static struct hotlist_entry root; - -/* The sprite header addresses for Tinct -*/ -static char *sprite[6]; - -/* The drag buttons -*/ -bool dragging; -wimp_mouse_state drag_buttons; - -/* Whether the current selection was from a menu click -*/ -bool menu_selection = false; -bool menu_open = false; +static wimp_w hotlist_window; +struct toolbar *hotlist_toolbar; +struct tree *hotlist_tree; /* Whether the editing facilities are for add so that we know how to reset the dialog boxes on a adjust-cancel and the action to perform on ok. */ -bool dialog_folder_add = false; -bool dialog_entry_add = false; -bool hotlist_insert = false; - - -static bool ro_gui_hotlist_initialise_sprite(const char *name, int number); -static bool ro_gui_hotlist_load(void); -static void ro_gui_hotlist_load_file(const char *filename); -static void ro_gui_hotlist_load_directory(xmlNode *ul, - struct hotlist_entry *directory); -static void ro_gui_hotlist_load_entry(xmlNode *li, - struct hotlist_entry *directory); -xmlNode *ro_gui_hotlist_find_element(xmlNode *node, const char *name); -bool ro_gui_hotlist_save_directory(struct hotlist_entry *directory, - xmlNode *node); -bool ro_gui_hotlist_save_entry(struct hotlist_entry *entry, - xmlNode *node); -bool ro_gui_hotlist_save_entry_comment(xmlNode *node, - const char *name, int value); -static void ro_gui_hotlist_link_entry(struct hotlist_entry *link, struct hotlist_entry *entry, bool before); -static void ro_gui_hotlist_delink_entry(struct hotlist_entry *entry); -static void ro_gui_hotlist_delete_entry(struct hotlist_entry *entry, bool siblings); -static void ro_gui_hotlist_visited_update(struct content *content, struct hotlist_entry *entry); -static int ro_gui_hotlist_redraw_tree(struct hotlist_entry *entry, int level, int x0, int y0); -static int ro_gui_hotlist_redraw_item(struct hotlist_entry *entry, int level, int x0, int y0); -static struct hotlist_entry *ro_gui_hotlist_create_entry(const char *title, const char *url, - int filetype, struct hotlist_entry *folder); -static void ro_gui_hotlist_update_entry_size(struct hotlist_entry *entry); -static struct hotlist_entry *ro_gui_hotlist_find_entry(int x, int y, struct hotlist_entry *entry); -static int ro_gui_hotlist_selection_state(struct hotlist_entry *entry, bool selected, bool redraw); -static void ro_gui_hotlist_selection_drag(struct hotlist_entry *entry, - int x0, int y0, int x1, int y1, - bool toggle, bool redraw); -static int ro_gui_hotlist_selection_count(struct hotlist_entry *entry, bool folders); -static void ro_gui_hotlist_update_expansion(struct hotlist_entry *entry, bool only_selected, - bool folders, bool links, bool expand, bool contract); -static void ro_gui_hotlist_launch_selection(struct hotlist_entry *entry); -static void ro_gui_hotlist_invalidate_statistics(struct hotlist_entry *entry); -static struct hotlist_entry *ro_gui_hotlist_first_selection(struct hotlist_entry *entry); -static void ro_gui_hotlist_selection_to_process(struct hotlist_entry *entry); -static bool ro_gui_hotlist_move_processing(struct hotlist_entry *entry, struct hotlist_entry *destination, bool before); - -#define hotlist_ensure_sprite(buffer, fallback) if (xwimpspriteop_read_sprite_info(buffer, 0, 0, 0, 0)) sprintf(buffer, fallback) -#define hotlist_redraw_entry(entry, full) xwimp_force_redraw(hotlist_window, full ? 0 : entry->x0, \ - full ? -16384 : entry->y0, full ? 16384 : entry->x0 + entry->expanded_width, entry->y0 + entry->height); -#define hotlist_redraw_entry_title(entry) xwimp_force_redraw(hotlist_window, entry->x0, \ - entry->y0 + entry->height - HOTLIST_LINE_HEIGHT, entry->x0 + entry->width, entry->y0 + entry->height); - +struct node *dialog_folder_node; +struct node *dialog_entry_node; - -void ro_gui_hotlist_init(void) { +void ro_gui_hotlist_initialise(void) { + FILE *fp; const char *title; - os_box extent = {0, 0, 0, 0}; os_error *error; - - /* Set the initial root options - */ - root.next_entry = NULL; - root.child_entry = NULL; - root.children = 0; - root.expanded = true; - - /* Load the hotlist - */ - if (!ro_gui_hotlist_load()) return; - - /* Get our sprite ids for faster plotting. - */ - if (ro_gui_hotlist_initialise_sprite("expand", HOTLIST_EXPAND) || - ro_gui_hotlist_initialise_sprite("collapse", HOTLIST_COLLAPSE) || - ro_gui_hotlist_initialise_sprite("entry", HOTLIST_ENTRY) || - ro_gui_hotlist_initialise_sprite("line", HOTLIST_LINE) || - ro_gui_hotlist_initialise_sprite("halflinet", HOTLIST_TLINE) || - ro_gui_hotlist_initialise_sprite("halflineb", HOTLIST_BLINE)) { - return; - } - - /* Update our text icon - */ - text_icon.data.indirected_text.validation = (char *) -1; - text_icon.data.indirected_text.size = 256; - sprite_icon.flags = wimp_ICON_SPRITE | wimp_ICON_INDIRECTED | - wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | - (wimp_COLOUR_BLACK << wimp_ICON_FG_COLOUR_SHIFT) | - (wimp_COLOUR_VERY_LIGHT_GREY << wimp_ICON_BG_COLOUR_SHIFT); - sprite_icon.data.indirected_sprite.area = wimpspriteop_AREA; - sprite_icon.data.indirected_text.size = 12; + struct node *node; /* Create our window */ title = messages_get("Hotlist"); - hotlist_window_definition.title_data.indirected_text.text = title; + hotlist_window_definition.title_data.indirected_text.text = strdup(title); hotlist_window_definition.title_data.indirected_text.validation = (char *) -1; hotlist_window_definition.title_data.indirected_text.size = strlen(title); @@ -299,47 +103,70 @@ void ro_gui_hotlist_init(void) { error->errnum, error->errmess)); die(error->errmess); } + + /* Either load or create a hotlist + */ + fp = fopen("Choices:WWW.NetSurf.Hotlist", "r"); + if (!fp) { + hotlist_tree = calloc(sizeof(struct tree), 1); + if (!hotlist_tree) { + warn_user("NoMemory", 0); + return; + } + hotlist_tree->root = tree_create_folder_node(NULL, "Root"); + if (!hotlist_tree->root) { + warn_user("NoMemory", 0); + free(hotlist_tree); + hotlist_tree = NULL; + } + hotlist_tree->root->expanded = true; + node = tree_create_folder_node(hotlist_tree->root, "NetSurf"); + if (!node) + node = hotlist_tree->root; + tree_create_URL_node(node, messages_get("HotlistHomepage"), + "http://netsurf.sourceforge.net/", 0xfaf, + time(NULL), -1, 0); + tree_create_URL_node(node, messages_get("HotlistTestBuild"), + "http://netsurf.strcprstskrzkrk.co.uk/", 0xfaf, + time(NULL), -1, 0); + tree_initialise(hotlist_tree); + } else { + fclose(fp); + hotlist_tree = options_load_hotlist("Choices:WWW.NetSurf.Hotlist"); + } + if (!hotlist_tree) return; + hotlist_tree->handle = (int)hotlist_window; /* Create our toolbar */ hotlist_toolbar = ro_gui_theme_create_toolbar(NULL, THEME_HOTLIST_TOOLBAR); - ro_gui_theme_attach_toolbar(hotlist_toolbar, hotlist_window); - - /* Update the extent - */ if (hotlist_toolbar) { - extent.x1 = 16384; - extent.y1 = hotlist_toolbar->height; - extent.y0 = -16384; - error = xwimp_set_extent(hotlist_window, &extent); - if (error) { - LOG(("xwimp_set_extent: 0x%x: %s", - error->errnum, error->errmess)); - die(error->errmess); - } - reformat_pending = true; - } + ro_gui_theme_attach_toolbar(hotlist_toolbar, hotlist_window); + hotlist_tree->offset_y = hotlist_toolbar->height; + } } + /** - * Initialise a hotlist sprite for use with Tinct - * - * \param name the name of the sprite - * \param number the sprite cache number - * \return whether an error occurred + * Perform a save to the default file */ -bool ro_gui_hotlist_initialise_sprite(const char *name, int number) { - os_error *error; - sprintf(icon_name, "tr_%s", name); - error = xosspriteop_select_sprite(osspriteop_USER_AREA, gui_sprites, - (osspriteop_id)icon_name, - (osspriteop_header **)&sprite[number]); - if (error) { - warn_user("MiscError", error->errmess); - LOG(("Failed to load hotlist sprite 'tr_%s'", name)); - return true; - } - return false; +void ro_gui_hotlist_save(void) { + os_error *error; + + if (!hotlist_tree) return; + + /* Ensure we have a directory to save to later. + */ + xosfile_create_dir(".WWW", 0); + xosfile_create_dir(".WWW.NetSurf", 0); + + /* Save to our file + */ + options_save_hotlist(hotlist_tree, ".WWW.NetSurf.Hotlist"); + error = xosfile_set_type(".WWW.NetSurf.Hotlist", 0xfaf); + if (error) + LOG(("xosfile_set_type: 0x%x: %s", + error->errnum, error->errmess)); } @@ -355,7 +182,7 @@ void ro_gui_hotlist_show(void) { /* We may have failed to initialise */ - if (!hotlist_window) return; + if (!hotlist_tree) return; /* Get the window state */ @@ -370,10 +197,16 @@ void ro_gui_hotlist_show(void) { open in the centre of the screen. */ if (!(state.flags & wimp_WINDOW_OPEN)) { - /* Clear the selection/expansion states - */ - ro_gui_hotlist_update_expansion(root.child_entry, false, true, true, false, true); - ro_gui_hotlist_selection_state(root.child_entry, false, false); + + /* 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 */ @@ -381,11 +214,11 @@ void ro_gui_hotlist_show(void) { /* Move to the centre */ - dimension = state.visible.x1 - state.visible.x0; + 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 = state.visible.y1 - state.visible.y0; + 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; @@ -397,2212 +230,302 @@ void ro_gui_hotlist_show(void) { */ ro_gui_menu_prepare_hotlist(); state.next = wimp_TOP; - error = xwimp_open_window((wimp_open*)&state); - if (error) { - warn_user("WimpError", error->errmess); - return; - } + ro_gui_tree_open((wimp_open*)&state, hotlist_tree); /* Set the caret position */ - xwimp_set_caret_position(state.w, -1, -100, - -100, 32, -1); + xwimp_set_caret_position(state.w, -1, -100, -100, 32, -1); } -bool ro_gui_hotlist_load(void) { - fileswitch_object_type obj_type = 0; - struct hotlist_entry *netsurf; - struct hotlist_entry *entry; - - /* Check if we have an initial hotlist. OS_File does funny things relating to errors, - so we use the object type to determine success - */ - xosfile_read_stamped_no_path("Choices:WWW.NetSurf.Hotlist", &obj_type, - (bits)0, (bits)0, (int *)0, (fileswitch_attr)0, (bits)0); - if (obj_type == fileswitch_IS_FILE) { - ro_gui_hotlist_load_file("Choices:WWW.NetSurf.Hotlist"); - return true; - - } else { - /* Create a folder - */ - netsurf = ro_gui_hotlist_create_entry("NetSurf", NULL, 0, &root); - if (!netsurf) - return false; - - /* Add some content - */ - entry = ro_gui_hotlist_create_entry("NetSurf homepage", - "http://netsurf.sourceforge.net/", - 0xfaf, netsurf); - if (!entry) - return false; - entry->add_date = (time_t) -1; - entry = ro_gui_hotlist_create_entry("NetSurf test builds", - "http://netsurf.strcprstskrzkrk.co.uk/", - 0xfaf, netsurf); - if (!entry) - return false; - entry->add_date = (time_t) -1; - - /* We succeeded - */ - return true; - } +/** + * Respond to a mouse click + * + * \param pointer the pointer state + */ +void ro_gui_hotlist_click(wimp_pointer *pointer) { + ro_gui_tree_click(pointer, hotlist_tree); + if (pointer->buttons == wimp_CLICK_MENU) + ro_gui_create_menu(hotlist_menu, pointer->pos.x, + pointer->pos.y, NULL); + else + ro_gui_menu_prepare_hotlist(); } /** - * Load the hotlist from file. + * Respond to a keypress * - * \param filename name of file to read + * \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(); -void ro_gui_hotlist_load_file(const char *filename) -{ - xmlDoc *doc; - xmlNode *html, *body, *ul; - - doc = htmlParseFile(filename, "iso-8859-1"); - if (!doc) { - warn_user("HotlistLoadError", messages_get("ParsingFail")); - return; - } - - html = ro_gui_hotlist_find_element((xmlNode *) doc, "html"); - body = ro_gui_hotlist_find_element(html, "body"); - ul = ro_gui_hotlist_find_element(body, "ul"); - if (!ul) { - xmlFreeDoc(doc); - warn_user("HotlistLoadError", - "(......