From 0f8e3e06e4bf946a932e77c0c27dd044cb1d9f4e Mon Sep 17 00:00:00 2001 From: John Mark Bell Date: Wed, 5 May 2004 00:02:13 +0000 Subject: [project @ 2004-05-05 00:02:13 by jmb] Implement saving of Links as URI, URL and Text Implement saving of page objects in their original format Implement export of page images as Sprite Fix NULL pointer causing ofla when extracting page charset from libxml svn path=/import/netsurf/; revision=826 --- !NetSurf/Resources/en/Messages | 7 +- !NetSurf/Resources/en/Templates,fec | Bin 5820 -> 6234 bytes !NetSurf/Resources/fr/Messages | 5 + !NetSurf/Resources/fr/Templates,fec | Bin 5906 -> 6320 bytes riscos/dialog.c | 3 +- riscos/gui.h | 12 +- riscos/menus.c | 224 ++++++++++++++++++++++++++++++++++-- riscos/save.c | 140 ++++++++++++++++++---- 8 files changed, 352 insertions(+), 39 deletions(-) diff --git a/!NetSurf/Resources/en/Messages b/!NetSurf/Resources/en/Messages index 9a412a3da..fd5303eae 100644 --- a/!NetSurf/Resources/en/Messages +++ b/!NetSurf/Resources/en/Messages @@ -22,6 +22,9 @@ Object:Object ObjInfo:Info ObjSave:Save ObjReload:Reload +URI:Acorn URI +URL:ANT URL +LinkText:Text Selection:Selection Copy:Copy to clipboard ^C SelectAll:Select all ^A @@ -112,4 +115,6 @@ SelectMenu:Select SaveSource:Source SaveDraw:Webpage -SaveText:PageWeb +SaveText:Webpage +SaveObject:Object +SaveLink:Link diff --git a/!NetSurf/Resources/en/Templates,fec b/!NetSurf/Resources/en/Templates,fec index 3658dffae..44544f305 100644 Binary files a/!NetSurf/Resources/en/Templates,fec and b/!NetSurf/Resources/en/Templates,fec differ diff --git a/!NetSurf/Resources/fr/Messages b/!NetSurf/Resources/fr/Messages index b954682db..c3c98e079 100644 --- a/!NetSurf/Resources/fr/Messages +++ b/!NetSurf/Resources/fr/Messages @@ -22,6 +22,9 @@ Object:Object ObjInfo:Info ObjSave:Save ObjReload:Reload +URI:Acorn URI +URL:ANT URL +LinkText:Text Selection:Sélection Copy:Copier vers le presse papier SelectAll:Tout sélectionner @@ -111,3 +114,5 @@ SelectMenu:S SaveSource:Source SaveDraw:PageWeb SaveText:PageWeb +SaveObject:Object +SaveLink:Link diff --git a/!NetSurf/Resources/fr/Templates,fec b/!NetSurf/Resources/fr/Templates,fec index 8b2424749..13952254d 100644 Binary files a/!NetSurf/Resources/fr/Templates,fec and b/!NetSurf/Resources/fr/Templates,fec differ diff --git a/riscos/dialog.c b/riscos/dialog.c index 645f66772..ca7dd2763 100644 --- a/riscos/dialog.c +++ b/riscos/dialog.c @@ -31,7 +31,7 @@ wimp_w dialog_info, dialog_saveas, dialog_config, dialog_config_br, #ifdef WITH_AUTH dialog_401li, #endif - dialog_zoom, dialog_pageinfo, dialog_tooltip; + dialog_zoom, dialog_pageinfo, dialog_objinfo, dialog_tooltip; wimp_menu* theme_menu = NULL; static int font_size; @@ -75,6 +75,7 @@ void ro_gui_dialog_init(void) dialog_config_th = ro_gui_dialog_create("config_th"); dialog_zoom = ro_gui_dialog_create("zoom"); dialog_pageinfo = ro_gui_dialog_create("pageinfo"); + dialog_objinfo = ro_gui_dialog_create("objectinfo"); dialog_tooltip = ro_gui_dialog_create("tooltip"); set_browser_choices(); diff --git a/riscos/gui.h b/riscos/gui.h index 7f6c7cd01..61e6bf664 100644 --- a/riscos/gui.h +++ b/riscos/gui.h @@ -22,7 +22,7 @@ extern wimp_w dialog_info, dialog_saveas, dialog_config, dialog_config_br, dialog_config_prox, dialog_config_th, dialog_zoom, dialog_pageinfo, - dialog_tooltip; + dialog_objinfo, dialog_tooltip; extern wimp_w history_window; extern wimp_menu *iconbar_menu, *browser_menu, *combo_menu, *theme_menu; extern int iconbar_menu_height; @@ -34,7 +34,10 @@ extern gui_window *current_gui; typedef enum { GUI_BROWSER_WINDOW, GUI_DOWNLOAD_WINDOW } gui_window_type; typedef enum { GUI_SAVE_SOURCE, GUI_SAVE_DRAW, GUI_SAVE_TEXT, - GUI_SAVE_COMPLETE } gui_save_type; + GUI_SAVE_COMPLETE, + GUI_SAVE_OBJECT_ORIG, GUI_SAVE_OBJECT_NATIVE, + GUI_SAVE_LINK_URI, GUI_SAVE_LINK_URL, + GUI_SAVE_LINK_TEXT } gui_save_type; extern gui_save_type gui_current_save_type; typedef enum { GUI_DRAG_SELECTION, GUI_DRAG_DOWNLOAD_SAVE, GUI_DRAG_SAVE, GUI_DRAG_STATUS_RESIZE } gui_drag_type; @@ -276,4 +279,9 @@ void schedule_run(void); #define ICON_PAGEINFO_TYPE 3 #define ICON_PAGEINFO_ICON 4 +#define ICON_OBJINFO_URL 0 +#define ICON_OBJINFO_TARGET 1 +#define ICON_OBJINFO_TYPE 2 +#define ICON_OBJINFO_ICON 3 + #endif diff --git a/riscos/menus.c b/riscos/menus.c index a287dadba..9fcc3dc4e 100644 --- a/riscos/menus.c +++ b/riscos/menus.c @@ -30,23 +30,25 @@ be quickly commented out. Use -ve numbers below -1 to hide an entry. */ #define MENU_PAGE 0 -#define MENU_OBJECT -2 +#define MENU_OBJECT 1 #define MENU_SELECTION -2 -#define MENU_NAVIGATE 1 -#define MENU_VIEW 2 +#define MENU_NAVIGATE 2 +#define MENU_VIEW 3 #define MENU_UTILITIES -2 -#define MENU_HELP 3 +#define MENU_HELP 4 static void translate_menu(wimp_menu *menu); static void ro_gui_menu_prepare_images(void); static void ro_gui_menu_prepare_toolbars(void); static void ro_gui_menu_pageinfo(wimp_message_menu_warning *warning); - +static void ro_gui_menu_objectinfo(wimp_message_menu_warning *warning); +static struct box *find_object_box(void); static wimp_menu *current_menu; static int current_menu_x, current_menu_y; gui_window *current_gui; - +struct content *save_content; +char *save_link; /* Default menu item flags */ @@ -79,6 +81,15 @@ static wimp_MENU(2) export_menu = { } }; +static wimp_MENU(3) link_menu = { + { "SaveLink" }, 7,2,7,0, 200, 44, 0, + { + { wimp_MENU_GIVE_WARNING, (wimp_menu*)1, DEFAULT_FLAGS, { "URI" } }, + { wimp_MENU_GIVE_WARNING, (wimp_menu*)1, DEFAULT_FLAGS, { "URL" } }, + { wimp_MENU_LAST | wimp_MENU_GIVE_WARNING, (wimp_menu*)1, DEFAULT_FLAGS, { "LinkText" } } + } +}; + /* Page submenu */ @@ -89,7 +100,7 @@ static wimp_MENU(7) page_menu = { { wimp_MENU_GIVE_WARNING, (wimp_menu *)1, DEFAULT_FLAGS, { "Save" } }, { wimp_MENU_GIVE_WARNING, (wimp_menu *)1, DEFAULT_FLAGS, { "SaveComp" } }, { 0, (wimp_menu *)&export_menu, DEFAULT_FLAGS, { "Export" } }, - { wimp_MENU_GIVE_WARNING, (wimp_menu *)1, DEFAULT_FLAGS, { "SaveURL" } }, + { 0, (wimp_menu *)&link_menu, DEFAULT_FLAGS, { "SaveURL" } }, { wimp_MENU_SEPARATE, wimp_NO_SUB_MENU, DEFAULT_FLAGS | wimp_ICON_SHADED, { "Print" } }, { wimp_MENU_LAST, wimp_NO_SUB_MENU, DEFAULT_FLAGS, { "ViewSrc" } } } @@ -114,7 +125,7 @@ static wimp_MENU(5) object_menu = { { wimp_MENU_GIVE_WARNING, (wimp_menu *)1, DEFAULT_FLAGS, { "ObjInfo" } }, { wimp_MENU_GIVE_WARNING, (wimp_menu *)1, DEFAULT_FLAGS, { "ObjSave" } }, { 0, (wimp_menu *)&object_export_menu, DEFAULT_FLAGS, { "Export" } }, - { wimp_MENU_GIVE_WARNING | wimp_MENU_SEPARATE, (wimp_menu *)1, DEFAULT_FLAGS, { "SaveURL" } }, + { wimp_MENU_SEPARATE, (wimp_menu *)&link_menu, DEFAULT_FLAGS, { "SaveURL" } }, { wimp_MENU_LAST, wimp_NO_SUB_MENU, DEFAULT_FLAGS, { "ObjReload" } } } }; @@ -228,7 +239,7 @@ static wimp_MENU(5) menu = { { "NetSurf" }, 7,2,7,0, 200, 44, 0, { { 0, (wimp_menu *)&page_menu, DEFAULT_FLAGS, { "Page" } }, -// { 0, (wimp_menu *)&object_menu, DEFAULT_FLAGS, { "Object" } }, + { 0, (wimp_menu *)&object_menu, DEFAULT_FLAGS, { "Object" } }, // { 0, (wimp_menu *)&selection_menu, DEFAULT_FLAGS, { "Selection" } }, { 0, (wimp_menu *)&navigate_menu, DEFAULT_FLAGS, { "Navigate" } }, { 0, (wimp_menu *)&view_menu, DEFAULT_FLAGS, { "View" } }, @@ -242,6 +253,7 @@ wimp_menu *browser_menu = (wimp_menu *) &menu; 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; +static wimp_menu *browser_link_menu = (wimp_menu *)&link_menu; static wimp_menu *browser_object_export_menu = (wimp_menu *)&object_export_menu; static wimp_menu *browser_selection_menu = (wimp_menu *)&selection_menu; static wimp_menu *browser_navigate_menu = (wimp_menu *)&navigate_menu; @@ -264,6 +276,7 @@ void ro_gui_menus_init(void) translate_menu(browser_page_menu); translate_menu(browser_export_menu); translate_menu(browser_object_menu); + translate_menu(browser_link_menu); translate_menu(browser_object_export_menu); translate_menu(browser_selection_menu); translate_menu(browser_navigate_menu); @@ -276,6 +289,7 @@ void ro_gui_menus_init(void) iconbar_menu->entries[0].sub_menu = (wimp_menu *) dialog_info; browser_page_menu->entries[0].sub_menu = (wimp_menu*) dialog_pageinfo; + browser_object_menu->entries[0].sub_menu = (wimp_menu*) dialog_objinfo; // browser_page_menu->entries[1].sub_menu = (wimp_menu *) dialog_saveas; // browser_page_menu->entries[2].sub_menu = (wimp_menu *) dialog_saveas; // browser_export_menu->entries[0].sub_menu = (wimp_menu *) dialog_saveas; @@ -399,6 +413,14 @@ void ro_gui_menu_selection(wimp_selection *selection) case 3: /* Export */ break; case 4: /* Save location */ + switch (selection->items[2]) { + case 0: /* URI */ + break; + case 1: /* URL */ + break; + case 2: /* Text */ + break; + } break; case 5: /* Print */ break; @@ -407,6 +429,26 @@ void ro_gui_menu_selection(wimp_selection *selection) break; } break; + case MENU_OBJECT: + switch (selection->items[1]) { + case 0: /* Info */ + break; + case 1: /* Save */ + break; + case 2: /* Export */ + break; + case 3: /* Save Link */ + switch (selection->items[2]) { + case 0: /* URI */ + break; + case 1: /* URL */ + break; + case 2: /* Text */ + break; + } + break; + } + break; case MENU_SELECTION: switch (selection->items[1]) { case 0: /* Copy to clipboard */ @@ -526,6 +568,21 @@ void ro_gui_menu_warning(wimp_message_menu_warning *warning) switch (warning->selection.items[0]) { case MENU_PAGE: /* Page -> */ switch (warning->selection.items[1]) { + case 4: /* Save Link */ + switch (warning->selection.items[2]) { + case 0: /* URI */ + gui_current_save_type = GUI_SAVE_LINK_URI; + break; + + case 1: /* URL */ + gui_current_save_type = GUI_SAVE_LINK_URL; + break; + + case 2: /* Text */ + gui_current_save_type = GUI_SAVE_LINK_TEXT; + break; + } + break; case 3: /* Export as -> */ switch (warning->selection.items[2]) { case 0: /* Draw */ @@ -552,10 +609,54 @@ void ro_gui_menu_warning(wimp_message_menu_warning *warning) gui_current_save_type = GUI_SAVE_SOURCE; break; } + save_link = xstrdup(c->url); ro_gui_menu_prepare_save(c); error = xwimp_create_sub_menu((wimp_menu *) dialog_saveas, warning->pos.x, warning->pos.y); + if (error) xfree(save_link); break; + case MENU_OBJECT: /* Object -> */ + switch (warning->selection.items[1]) { + case 0: /* Object info */ + ro_gui_menu_objectinfo(warning); + return; + + case 1: /* Save */ + gui_current_save_type = GUI_SAVE_OBJECT_ORIG; + break; + + case 2: /* Export */ + switch (warning->selection.items[2]) { + case 0: /* Sprite */ + gui_current_save_type = GUI_SAVE_OBJECT_NATIVE; + break; + } + break; + case 3: /* Save Link */ + switch (warning->selection.items[2]) { + case 0: /* URI */ + gui_current_save_type = GUI_SAVE_LINK_URI; + break; + + case 1: /* URL */ + gui_current_save_type = GUI_SAVE_LINK_URL; + break; + + case 2: /* Text */ + gui_current_save_type = GUI_SAVE_LINK_TEXT; + break; + } + break; + } + struct box *box = find_object_box(); + if (box) { + ro_gui_menu_prepare_save(box->object); + error = xwimp_create_sub_menu((wimp_menu *) dialog_saveas, + warning->pos.x, warning->pos.y); + if (!error && box->href) + save_link = url_join(box->href, c->url); + } + break; case MENU_VIEW: /* View -> */ switch (warning->selection.items[1]) { case 0: /* Scale view -> */ @@ -620,11 +721,35 @@ void ro_gui_menu_prepare_save(struct content *c) icon = "file_faf"; name = messages_get("SaveComplete"); break; + case GUI_SAVE_OBJECT_ORIG: + if (c) + sprintf(icon_buf, "file_%x", + ro_content_filetype(c)); + name = messages_get("SaveObject"); + break; + case GUI_SAVE_OBJECT_NATIVE: + icon = "file_ff9"; + name = messages_get("SaveObject"); + break; + case GUI_SAVE_LINK_URI: + icon = "file_f91"; + name = messages_get("SaveLink"); + break; + case GUI_SAVE_LINK_URL: + icon = "file_b28"; + name = messages_get("SaveLink"); + break; + case GUI_SAVE_LINK_TEXT: + icon = "file_fff"; + name = messages_get("SaveLink"); + break; } - if (c) + if (c) { + save_content = c; if ((nice = url_nice(c->url))) name = nice; + } ro_gui_set_icon_string(dialog_saveas, ICON_SAVE_ICON, icon); ro_gui_set_icon_string(dialog_saveas, ICON_SAVE_PATH, name); @@ -707,7 +832,7 @@ void ro_gui_menu_pageinfo(wimp_message_menu_warning *warning) sprintf(icon_buf, "file_%x", ro_content_filetype(c)); - if (c->type == CONTENT_HTML) { + if (c->type == CONTENT_HTML && c->data.html.encoding != 0) { enc = xmlGetCharEncodingName(c->data.html.encoding); } @@ -724,3 +849,80 @@ void ro_gui_menu_pageinfo(wimp_message_menu_warning *warning) warn_user(error->errmess); } } + +void ro_gui_menu_objectinfo(wimp_message_menu_warning *warning) +{ + struct content *c = current_gui->data.browser.bw->current_content; + struct box *box; + os_error *error; + char icon_buf[20] = "file_xxx"; + const char *icon = icon_buf; + const char *url = "-"; + const char *target = "-"; + const char *mime = "-"; + + box = find_object_box(); + if (box) { + sprintf(icon_buf, "file_%x", ro_content_filetype(box->object)); + if (box->object->url) url = box->object->url; + if (box->href) target = box->href; + if (box->object->mime_type) mime = box->object->mime_type; + } + else if (c->type == CONTENT_JPEG || c->type == CONTENT_PNG || + c->type == CONTENT_GIF || c->type == CONTENT_SPRITE || + c->type == CONTENT_DRAW) { + sprintf(icon_buf, "file_%x", ro_content_filetype(c)); + if (c->url) url = c->url; + if (c->mime_type) mime = c->mime_type; + } + + ro_gui_set_icon_string(dialog_objinfo, ICON_OBJINFO_ICON, icon); + ro_gui_set_icon_string(dialog_objinfo, ICON_OBJINFO_URL, url); + ro_gui_set_icon_string(dialog_objinfo, ICON_OBJINFO_TARGET, target); + ro_gui_set_icon_string(dialog_objinfo, ICON_OBJINFO_TYPE, mime); + + error = xwimp_create_sub_menu((wimp_menu *) dialog_objinfo, + warning->pos.x, warning->pos.y); + if (error) { + LOG(("0x%x: %s\n", error->errnum, error->errmess)); + warn_user(error->errmess); + } +} + +struct box *find_object_box(void) +{ + struct content *c = current_gui->data.browser.bw->current_content; + struct box_selection *boxes = NULL; + struct box *box = NULL; + int found = 0, plot_index = 0, i, x, y; + wimp_window_state state; + + state.w = current_gui->window; + wimp_get_window_state(&state); + + /* The menu is initially created 64 units to the left + * of the mouse position. Therefore, we negate the offset here + */ + x = window_x_units(current_menu_x+64, &state) / 2 / current_gui->scale; + y = -window_y_units(current_menu_y, &state) / 2 / current_gui->scale; + + if (c->type == CONTENT_HTML) { + + box_under_area(c, c->data.html.layout->children, + x, y, 0, 0, &boxes, &found, &plot_index); + + if (found > 0) { + for (i=found-1;i>=0;i--) { + if (boxes[i].box->object != 0) { + box = boxes[i].box; + break; + } + } + } + + free(boxes); + } + + return box; +} + diff --git a/riscos/save.c b/riscos/save.c index e36d85b85..79c79adfb 100644 --- a/riscos/save.c +++ b/riscos/save.c @@ -29,7 +29,12 @@ gui_save_type gui_current_save_type; -void ro_gui_save_complete(struct content *c, char *path); +extern struct content *save_content; +extern char *save_link; + +static void ro_gui_save_complete(struct content *c, char *path); +static void ro_gui_save_object_native(struct content *c, char *path); +static void ro_gui_save_link(int format, char *path); /** @@ -133,7 +138,7 @@ void ro_gui_save_drag_end(wimp_dragged *drag) void ro_gui_save_datasave_ack(wimp_message *message) { char *path = message->data.data_xfer.file_name; - struct content *c = current_gui->data.browser.bw->current_content; + struct content *c = save_content; os_error *error; ro_gui_set_icon_string(dialog_saveas, ICON_SAVE_PATH, path); @@ -171,8 +176,48 @@ void ro_gui_save_datasave_ack(wimp_message *message) save_as_text(c, path); xosfile_set_type(path, 0xfff); break; + + case GUI_SAVE_OBJECT_ORIG: + if (!c) + return; + error = xosfile_save_stamped(path, + ro_content_filetype(c), + c->source_data, + c->source_data + c->source_size); + if (error) { + LOG(("xosfile_save_stamped: 0x%x: %s", + error->errnum, error->errmess)); + warn_user(error->errmess); + } + break; + + case GUI_SAVE_OBJECT_NATIVE: + if (!c) + return; + ro_gui_save_object_native(c, path); + break; + + case GUI_SAVE_LINK_URI: + if (!save_link) + return; + ro_gui_save_link(1, path); + break; + + case GUI_SAVE_LINK_URL: + if (!save_link) + return; + ro_gui_save_link(2, path); + break; + + case GUI_SAVE_LINK_TEXT: + if (!save_link) + return; + ro_gui_save_link(3, path); + break; } + if (save_link) xfree(save_link); + save_content = NULL; wimp_create_menu(wimp_CLOSE_MENU, 0, 0); } @@ -230,29 +275,9 @@ void ro_gui_save_complete(struct content *c, char *path) warn_user("Failed to acquire dirname"); return; } -/* snprintf(spritename, sizeof spritename, "%s", appname+1); - area = malloc(SPRITE_SIZE); - if (!area) { - LOG(("malloc failed")); - warn_user("No memory for sprite"); - return; - } - area->size = SPRITE_SIZE; - area->sprite_count = 0; - area->first = 16; - area->used = 16; - error = xosspriteop_create_sprite(osspriteop_NAME, area, - spritename, false, - WIDTH / 2, HEIGHT / 2, os_MODE8BPP90X90); - if (error) { - LOG(("Failed to create sprite")); - warn_user("Failed to create iconsprite"); - free(area); - return; - } -*/ + area = thumbnail_initialise(34, 34, os_MODE8BPP90X90); - if (!area) { + if (!area) { LOG(("Iconsprite initialisation failed.")); return; } @@ -297,3 +322,70 @@ void ro_gui_save_complete(struct content *c, char *path) save_complete(c, path); } + +void ro_gui_save_object_native(struct content *c, char *path) +{ + os_error *error; + osspriteop_area *temp; + + switch (c->type) { + case CONTENT_JPEG: + error = xosspriteop_save_sprite_file(osspriteop_USER_AREA, c->data.jpeg.sprite_area, path); + break; + case CONTENT_PNG: + error = xosspriteop_save_sprite_file(osspriteop_USER_AREA, c->data.png.sprite_area, path); + break; + case CONTENT_GIF: + /* create sprite area */ + temp = calloc(c->data.gif.gif->frame_image->size+16, + sizeof(char)); + temp->size = c->data.gif.gif->frame_image->size+16; + temp->sprite_count = 1; + temp->first = 16; + temp->used = c->data.gif.gif->frame_image->size+16; + memcpy((char*)temp+16, + (char*)c->data.gif.gif->frame_image, + c->data.gif.gif->frame_image->size); + /* ensure extra words for name are null */ + memset((char*)temp+24, 0, 8); + error = xosspriteop_save_sprite_file(osspriteop_USER_AREA, temp, path); + free(temp); + break; + default: + break; + } +} + +void ro_gui_save_link(int format, char *path) +{ + FILE *fp = fopen(path, "w"); + + if (!fp) return; + + switch (format) { + case 1: /* URI */ + fprintf(fp, "%s\t%s\n", "URI", "100"); + fprintf(fp, "\t# NetSurf %s\n\n", netsurf_version); + fprintf(fp, "\t%s\n", save_link); + fprintf(fp, "\t*\n"); + break; + case 2: /* URL */ + case 3: /* Text */ + fprintf(fp, "%s\n", save_link); + break; + } + + fclose(fp); + + switch (format) { + case 1: /* URI */ + xosfile_set_type(path, 0xf91); + break; + case 2: /* URL */ + xosfile_set_type(path, 0xb28); + break; + case 3: /* Text */ + xosfile_set_type(path, 0xfff); + break; + } +} -- cgit v1.2.3