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