From d21447d096a320a08b3efb2b8768fad0dcdcfd64 Mon Sep 17 00:00:00 2001 From: Vincent Sanders Date: Thu, 5 May 2016 22:28:51 +0100 Subject: move frontends into sub directory --- frontends/amiga/ctxmenu.c | 607 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 607 insertions(+) create mode 100644 frontends/amiga/ctxmenu.c (limited to 'frontends/amiga/ctxmenu.c') diff --git a/frontends/amiga/ctxmenu.c b/frontends/amiga/ctxmenu.c new file mode 100644 index 000000000..cc612da24 --- /dev/null +++ b/frontends/amiga/ctxmenu.c @@ -0,0 +1,607 @@ +/* + * Copyright 2015 Chris Young + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** \file + * Intuition-based context menu operations + */ + +#ifdef __amigaos4__ +#include + +#include +#include +#include + +#include +#include +#include +#include + +#include +#include + +#include "utils/utils.h" +#include "utils/log.h" +#include "utils/messages.h" +#include "utils/nsoption.h" +#include "utils/nsurl.h" +#include "content/hlcache.h" +#include "desktop/browser.h" +#include "desktop/browser_history.h" +#include "desktop/mouse.h" +#include "desktop/searchweb.h" +#include "desktop/textinput.h" + +#include "amiga/bitmap.h" +#include "amiga/clipboard.h" +#include "amiga/ctxmenu.h" +#include "amiga/filetype.h" +#include "amiga/gui.h" +#include "amiga/libs.h" +#include "amiga/plugin_hack.h" +#include "amiga/theme.h" +#include "amiga/utf8.h" + + +enum { + AMI_CTX_ID_NONE = 0, + + /* Text selection */ + AMI_CTX_ID_SELCOPY, + AMI_CTX_ID_WEBSEARCH, + + /* Links */ + AMI_CTX_ID_URLOPENTAB, + AMI_CTX_ID_URLOPENWIN, + AMI_CTX_ID_URLDOWNLOAD, + AMI_CTX_ID_URLCOPY, + + /* Objects */ + AMI_CTX_ID_OBJSHOW, + AMI_CTX_ID_OBJCOPY, + AMI_CTX_ID_OBJCMD, + + /* Frames */ + AMI_CTX_ID_FRAMESHOW, + + /* History */ + AMI_CTX_ID_HISTORY, + AMI_CTX_ID_HISTORY0, + AMI_CTX_ID_HISTORY9F = AMI_CTX_ID_HISTORY0 + 19, + + /* Tabs */ + AMI_CTX_ID_TABNEW, + AMI_CTX_ID_TABCLOSE_OTHER, + + AMI_CTX_ID_MAX +}; + +static Object *ctxmenu_obj = NULL; + +static struct Hook ctxmenu_item_hook[AMI_CTX_ID_MAX]; +static char *ctxmenu_item_label[AMI_CTX_ID_MAX]; +static char *ctxmenu_item_shortcut[AMI_CTX_ID_MAX]; +static Object *ctxmenu_item_image[AMI_CTX_ID_MAX]; + +/**************************** + * Menu item hook functions * + ****************************/ + +/** Menu functions - called automatically by RA_HandleInput **/ +HOOKF(void, ami_ctxmenu_item_selcopy, APTR, window, struct IntuiMessage *) +{ + struct gui_window_2 *gwin = (struct gui_window_2 *)hook->h_Data; + + browser_window_key_press(gwin->gw->bw, NS_KEY_COPY_SELECTION); + browser_window_key_press(gwin->gw->bw, NS_KEY_CLEAR_SELECTION); +} + +HOOKF(void, ami_ctxmenu_item_websearch, APTR, window, struct IntuiMessage *) +{ + nserror ret = NSERROR_OK; + nsurl *url; + + struct gui_window_2 *gwin = (struct gui_window_2 *)hook->h_Data; + char *sel = browser_window_get_selection(gwin->gw->bw); + + ret = search_web_omni(sel, SEARCH_WEB_OMNI_SEARCHONLY, &url); + if (ret == NSERROR_OK) { + browser_window_navigate(gwin->gw->bw, + url, + NULL, + BW_NAVIGATE_HISTORY, + NULL, + NULL, + NULL); + nsurl_unref(url); + } + if (ret != NSERROR_OK) { + amiga_warn_user(messages_get_errorcode(ret), 0); + } + + free(sel); +} + +HOOKF(void, ami_ctxmenu_item_urlopentab, APTR, window, struct IntuiMessage *) +{ + struct browser_window *bw; + nsurl *url = (nsurl *)hook->h_Data; + struct gui_window_2 *gwin; + + GetAttr(WINDOW_UserData, (Object *)window, (ULONG *)&gwin); + nserror error = browser_window_create(BW_CREATE_CLONE | BW_CREATE_HISTORY | BW_CREATE_TAB, + url, + browser_window_get_url(gwin->gw->bw), + gwin->gw->bw, + &bw); + + if (error != NSERROR_OK) + amiga_warn_user(messages_get_errorcode(error), 0); +} + +HOOKF(void, ami_ctxmenu_item_urlopenwin, APTR, window, struct IntuiMessage *) +{ + struct browser_window *bw; + nsurl *url = (nsurl *)hook->h_Data; + struct gui_window_2 *gwin; + + GetAttr(WINDOW_UserData, (Object *)window, (ULONG *)&gwin); + nserror error = browser_window_create(BW_CREATE_CLONE | BW_CREATE_HISTORY, + url, + browser_window_get_url(gwin->gw->bw), + gwin->gw->bw, + &bw); + + if (error != NSERROR_OK) + amiga_warn_user(messages_get_errorcode(error), 0); +} + +HOOKF(void, ami_ctxmenu_item_urldownload, APTR, window, struct IntuiMessage *) +{ + nsurl *url = (nsurl *)hook->h_Data; + struct gui_window_2 *gwin; + + GetAttr(WINDOW_UserData, (Object *)window, (ULONG *)&gwin); + + browser_window_navigate(gwin->gw->bw, + url, + browser_window_get_url(gwin->gw->bw), + BW_NAVIGATE_DOWNLOAD, + NULL, + NULL, + NULL); +} + +HOOKF(void, ami_ctxmenu_item_urlcopy, APTR, window, struct IntuiMessage *) +{ + nsurl *url = (nsurl *)hook->h_Data; + ami_easy_clipboard(nsurl_access(url)); +} + +HOOKF(void, ami_ctxmenu_item_objshow, APTR, window, struct IntuiMessage *) +{ + struct gui_window_2 *gwin; + GetAttr(WINDOW_UserData, (Object *)window, (ULONG *)&gwin); + + browser_window_navigate(gwin->gw->bw, + hlcache_handle_get_url(hook->h_Data), + browser_window_get_url(gwin->gw->bw), + BW_NAVIGATE_HISTORY, + NULL, + NULL, + NULL); +} + +HOOKF(void, ami_ctxmenu_item_objcopy, APTR, window, struct IntuiMessage *) +{ + struct bitmap *bm; + struct gui_window_2 *gwin; + GetAttr(WINDOW_UserData, (Object *)window, (ULONG *)&gwin); + + struct hlcache_handle *object = (struct hlcache_handle *)hook->h_Data; + if((bm = content_get_bitmap(object))) + { + ami_bitmap_set_url(bm, hlcache_handle_get_url(object)); + ami_bitmap_set_title(bm, content_get_title(object)); + ami_easy_clipboard_bitmap(bm); + } +#ifdef WITH_NS_SVG + else if(ami_mime_compare(object, "svg") == true) + { + ami_easy_clipboard_svg(object); + } +#endif +} + +HOOKF(void, ami_ctxmenu_item_objcmd, APTR, window, struct IntuiMessage *) +{ + amiga_plugin_hack_execute((struct hlcache_handle *)hook->h_Data); +} + +HOOKF(void, ami_ctxmenu_item_frameshow, APTR, window, struct IntuiMessage *) +{ + struct gui_window_2 *gwin; + GetAttr(WINDOW_UserData, (Object *)window, (ULONG *)&gwin); + + browser_window_navigate(gwin->gw->bw, + hlcache_handle_get_url(hook->h_Data), + browser_window_get_url(gwin->gw->bw), + BW_NAVIGATE_HISTORY, + NULL, + NULL, + NULL); +} + +/** Hooks for clicktab context menu entries **/ +HOOKF(void, ami_ctxmenu_item_tabnew, APTR, window, struct IntuiMessage *) +{ + struct gui_window_2 *gwin; + + GetAttr(WINDOW_UserData, (Object *)window, (ULONG *)&gwin); + ami_gui_new_blank_tab(gwin); +} + +HOOKF(void, ami_ctxmenu_item_tabclose_other, APTR, window, struct IntuiMessage *) +{ + struct gui_window_2 *gwin; + + GetAttr(WINDOW_UserData, (Object *)window, (ULONG *)&gwin); + ami_gui_close_inactive_tabs(gwin); +} + +/** Hook for history context menu entries **/ +HOOKF(void, ami_ctxmenu_item_history, APTR, window, struct IntuiMessage *) +{ + struct gui_window_2 *gwin; + + GetAttr(WINDOW_UserData, (Object *)window, (ULONG *)&gwin); + + browser_window_history_go(gwin->gw->bw, (struct history_entry *)hook->h_Data, false); +} + + +/************************* + * Browser context menus * + *************************/ + +/** Add an initialised item to a context menu **/ +static void ami_ctxmenu_add_item(Object *root_menu, int id, APTR data) +{ + ctxmenu_item_hook[id].h_Data = data; + + IDoMethod(root_menu, OM_ADDMEMBER, MStrip, + MA_Type, T_ITEM, + MA_ID, id, + MA_Label, ctxmenu_item_label[id], + MA_Key, ctxmenu_item_shortcut[id], + MA_Image, ctxmenu_item_image[id], + MA_UserData, &ctxmenu_item_hook[id], + MEnd); +} + +/** Hook function called by Intuition, creates context menu structure **/ +static uint32 ami_ctxmenu_hook_func(struct Hook *hook, struct Window *window, struct ContextMenuMsg *msg) +{ + Object *root_menu; + bool ctxmenu_has_content = false; + struct gui_window_2 *gwin = hook->h_Data; + struct hlcache_handle *cc = browser_window_get_content(gwin->gw->bw); + struct browser_window_features ccdata; + int mx = window->MouseX; + int my = window->MouseY; + int x, y; + char *sel; + + if(msg->State != CM_QUERY) return 0; + if(nsoption_bool(kiosk_mode) == true) return 0; +// check window is active + + if(ctxmenu_obj != NULL) DisposeObject(ctxmenu_obj); + + ctxmenu_obj = MStrip, + MA_Type, T_ROOT, + MA_AddChild, root_menu = MStrip, + MA_Type, T_MENU, + MA_Label, NULL, //"NetSurf", + MA_EmbeddedKey, FALSE, + MA_FreeImage, FALSE, + MEnd, + MEnd; + + if(ami_mouse_to_ns_coords(gwin, &x, &y, mx, my) == false) { + /* Outside browser render area */ + return 0; + } + + browser_window_get_features(gwin->gw->bw, x, y, &ccdata); + + if((browser_window_can_select(gwin->gw->bw)) && + ((browser_window_get_editor_flags(gwin->gw->bw) & BW_EDITOR_CAN_COPY)) && + (sel = browser_window_get_selection(gwin->gw->bw))) { + + ami_ctxmenu_add_item(root_menu, AMI_CTX_ID_SELCOPY, gwin); + ami_ctxmenu_add_item(root_menu, AMI_CTX_ID_WEBSEARCH, gwin); + + ctxmenu_has_content = true; + free(sel); + } + + if(ccdata.link) { + if(ctxmenu_has_content == true) + ami_ctxmenu_add_item(root_menu, AMI_CTX_ID_NONE, NULL); + + ami_ctxmenu_add_item(root_menu, AMI_CTX_ID_URLOPENTAB, ccdata.link); + ami_ctxmenu_add_item(root_menu, AMI_CTX_ID_URLOPENWIN, ccdata.link); + ami_ctxmenu_add_item(root_menu, AMI_CTX_ID_URLDOWNLOAD, ccdata.link); + ami_ctxmenu_add_item(root_menu, AMI_CTX_ID_URLCOPY, ccdata.link); + ctxmenu_has_content = true; + } + + if(ccdata.object) { + if(ctxmenu_has_content == true) + ami_ctxmenu_add_item(root_menu, AMI_CTX_ID_NONE, NULL); + + ami_ctxmenu_add_item(root_menu, AMI_CTX_ID_OBJSHOW, ccdata.object); + + if(content_get_type(ccdata.object) == CONTENT_IMAGE) + ami_ctxmenu_add_item(root_menu, AMI_CTX_ID_OBJCOPY, ccdata.object); + + if(ami_mime_content_to_cmd(ccdata.object)) + ami_ctxmenu_add_item(root_menu, AMI_CTX_ID_OBJCMD, ccdata.object); + + ctxmenu_has_content = true; + } + + if(ccdata.main && (ccdata.main != cc)) { + if(ctxmenu_has_content == true) + ami_ctxmenu_add_item(root_menu, AMI_CTX_ID_NONE, NULL); + + ami_ctxmenu_add_item(root_menu, AMI_CTX_ID_FRAMESHOW, ccdata.main); + + ctxmenu_has_content = true; + } + + if(ctxmenu_has_content == true) { + msg->Menu = ctxmenu_obj; + ami_set_pointer(gwin, GUI_POINTER_DEFAULT, false); + } + + return 0; +} + +/** Initial menu item creation **/ +static void ami_ctxmenu_alloc_item(int id, const char *label, const char *key, const char *image, void *func) +{ + if(label == ML_SEPARATOR) { + ctxmenu_item_label[id] = ML_SEPARATOR; + } else { + ctxmenu_item_label[id] = ami_utf8_easy(messages_get(label)); + } + + if(key != NULL) { + ctxmenu_item_shortcut[id] = strdup(key); + } else { + ctxmenu_item_shortcut[id] = NULL; + } + + if(image != NULL) { + ctxmenu_item_image[id] = BitMapObj, + BITMAP_Screen, scrn, + BITMAP_SourceFile, image, + BITMAP_Masking, TRUE, + BitMapEnd; + + SetAttrs(ctxmenu_item_image[id], + BITMAP_Width, 16, + BITMAP_Height, 16, + TAG_DONE); + } + + ctxmenu_item_hook[id].h_Entry = func; + ctxmenu_item_hook[id].h_Data = 0; +} + +/** Exported interface documented in ctxmenu.h **/ +struct Hook *ami_ctxmenu_get_hook(APTR data) +{ + return AllocSysObjectTags(ASOT_HOOK, + ASOHOOK_Entry, (HOOKFUNC)ami_ctxmenu_hook_func, + ASOHOOK_Data, data, + TAG_DONE); +} + +/** Exported interface documented in ctxmenu.h **/ +void ami_ctxmenu_release_hook(struct Hook *hook) +{ + FreeSysObject(ASOT_HOOK, hook); +} + +/** Exported interface documented in ctxmenu.h **/ +void ami_ctxmenu_free(void) +{ + for(int i = 1; i < AMI_CTX_ID_MAX; i++) { + if((ctxmenu_item_label[i] != NULL) && (ctxmenu_item_label[i] != ML_SEPARATOR)) { + ami_utf8_free(ctxmenu_item_label[i]); + } + ctxmenu_item_label[i] = NULL; + + if(ctxmenu_item_shortcut[i] != NULL) { + free(ctxmenu_item_shortcut[i]); + ctxmenu_item_shortcut[i] = NULL; + } + + if(ctxmenu_item_image[i] != NULL) { + DisposeObject(ctxmenu_item_image[i]); + ctxmenu_item_image[i] = NULL; + } + } + + if(ctxmenu_obj != NULL) DisposeObject(ctxmenu_obj); + ctxmenu_obj = NULL; +} + +/** Exported interface documented in ctxmenu.h **/ +void ami_ctxmenu_init(void) +{ + ami_ctxmenu_alloc_item(AMI_CTX_ID_NONE, ML_SEPARATOR, NULL, NULL, NULL); + + ami_ctxmenu_alloc_item(AMI_CTX_ID_SELCOPY, "CopyNS", "C", "TBImages:list_copy", + ami_ctxmenu_item_selcopy); + ami_ctxmenu_alloc_item(AMI_CTX_ID_WEBSEARCH, "SearchWeb", NULL, "TBImages:list_search", + ami_ctxmenu_item_websearch); + + ami_ctxmenu_alloc_item(AMI_CTX_ID_URLOPENTAB, "LinkNewTab", NULL, "TBImages:list_tab", + ami_ctxmenu_item_urlopentab); + ami_ctxmenu_alloc_item(AMI_CTX_ID_URLOPENWIN, "LinkNewWin", NULL, "TBImages:list_app", + ami_ctxmenu_item_urlopenwin); + ami_ctxmenu_alloc_item(AMI_CTX_ID_URLDOWNLOAD, "LinkDload", NULL, "TBImages:list_save", + ami_ctxmenu_item_urldownload); + ami_ctxmenu_alloc_item(AMI_CTX_ID_URLCOPY, "CopyURL", NULL, "TBImages:list_copy", + ami_ctxmenu_item_urlcopy); + + ami_ctxmenu_alloc_item(AMI_CTX_ID_OBJSHOW, "ObjShow", NULL, "TBImages:list_preview", + ami_ctxmenu_item_objshow); + ami_ctxmenu_alloc_item(AMI_CTX_ID_OBJCOPY, "CopyClip", NULL, "TBImages:list_copy", + ami_ctxmenu_item_objcopy); + ami_ctxmenu_alloc_item(AMI_CTX_ID_OBJCMD, "ExternalApp", NULL, "TBImages:list_tool", + ami_ctxmenu_item_objcmd); + + ami_ctxmenu_alloc_item(AMI_CTX_ID_FRAMESHOW, "FrameOnly", NULL, "TBImages:list_preview", + ami_ctxmenu_item_frameshow); + + ami_ctxmenu_alloc_item(AMI_CTX_ID_TABNEW, "NewTab", "T", "TBImages:list_tab", + ami_ctxmenu_item_tabnew); + ami_ctxmenu_alloc_item(AMI_CTX_ID_TABCLOSE_OTHER, "CloseInactive", "K", "TBImages:list_cancel", + ami_ctxmenu_item_tabclose_other); +} + +/******************************** + * History button context menus * + ********************************/ + +/** Create menu entries from browser history **/ +static bool ami_ctxmenu_history(int direction, struct gui_window_2 *gwin, const struct history_entry *entry) +{ + Object *history_root; + int id = AMI_CTX_ID_HISTORY0 + gwin->temp; + if(direction == AMI_CTXMENU_HISTORY_FORWARD) id += 10; + + if(gwin->temp >= 10) return false; + + ctxmenu_item_hook[id].h_Entry = (HOOKFUNC)ami_ctxmenu_item_history; + ctxmenu_item_hook[id].h_Data = (APTR)entry; + + history_root = (Object *)IDoMethod(gwin->history_ctxmenu[direction], MM_FINDID, 0, AMI_CTX_ID_HISTORY); + + IDoMethod(history_root, OM_ADDMEMBER, MStrip, + MA_Type, T_ITEM, + MA_Label, browser_window_history_entry_get_title(entry), + MA_ID, id, + MA_Image, NULL, + MA_UserData, &ctxmenu_item_hook[id], + MEnd); + + gwin->temp++; + + return true; +} + +/** Callback for browser_window_history_enumerate **/ +static bool ami_ctxmenu_history_back(const struct browser_window *bw, + int x0, int y0, int x1, int y1, + const struct history_entry *entry, void *user_data) +{ + return ami_ctxmenu_history(AMI_CTXMENU_HISTORY_BACK, (struct gui_window_2 *)user_data, entry); +} + +/** Callback for browser_window_history_enumerate **/ +static bool ami_ctxmenu_history_forward(const struct browser_window *bw, + int x0, int y0, int x1, int y1, + const struct history_entry *entry, void *user_data) +{ + return ami_ctxmenu_history(AMI_CTXMENU_HISTORY_FORWARD, (struct gui_window_2 *)user_data, entry); +} + +/** Exported interface documented in ctxmenu.h **/ +struct Menu *ami_ctxmenu_history_create(int direction, struct gui_window_2 *gwin) +{ + Object *obj; + + if(gwin->history_ctxmenu[direction] == NULL) { + if(ctxmenu_item_label[AMI_CTX_ID_HISTORY] == NULL) + ctxmenu_item_label[AMI_CTX_ID_HISTORY] = ami_utf8_easy(messages_get("History")); + + gwin->history_ctxmenu[direction] = MStrip, + MA_Type, T_ROOT, + MA_AddChild, MStrip, + MA_Type, T_MENU, + MA_ID, AMI_CTX_ID_HISTORY, + MA_Label, ctxmenu_item_label[AMI_CTX_ID_HISTORY], + MA_EmbeddedKey, FALSE, + //MA_FreeImage, FALSE, + MEnd, + MEnd; + } else { + for (int i = 0; i < 20; i++) { + obj = (Object *)IDoMethod(gwin->history_ctxmenu[direction], + MM_FINDID, 0, AMI_CTX_ID_HISTORY0 + i); + if(obj != NULL) IDoMethod(gwin->history_ctxmenu[direction], OM_REMMEMBER, obj); + } + + gwin->temp = 0; + + if(direction == AMI_CTXMENU_HISTORY_BACK) { + browser_window_history_enumerate_back(gwin->gw->bw, ami_ctxmenu_history_back, gwin); + } else { + browser_window_history_enumerate_forward(gwin->gw->bw, ami_ctxmenu_history_forward, gwin); + } + } + + return (struct Menu *)gwin->history_ctxmenu[direction]; +} + + +/************************** + * ClickTab context menus * + **************************/ + +/** Exported interface documented in ctxmenu.h **/ +struct Menu *ami_ctxmenu_clicktab_create(struct gui_window_2 *gwin) +{ + Object *root_menu; + + if(gwin->clicktab_ctxmenu != NULL) return (struct Menu *)gwin->clicktab_ctxmenu; + + gwin->clicktab_ctxmenu = MStrip, + MA_Type, T_ROOT, + MA_AddChild, root_menu = MStrip, + MA_Type, T_MENU, + MA_Label, NULL, + MA_EmbeddedKey, FALSE, + MEnd, + MEnd; + + ami_ctxmenu_add_item(root_menu, AMI_CTX_ID_TABNEW, gwin); + ami_ctxmenu_add_item(root_menu, AMI_CTX_ID_TABCLOSE_OTHER, gwin); + + return (struct Menu *)gwin->clicktab_ctxmenu; +} + + +#endif + -- cgit v1.2.3