diff options
-rw-r--r-- | amiga/Makefile.target | 5 | ||||
-rwxr-xr-x | amiga/bitmap.h | 1 | ||||
-rw-r--r-- | amiga/clipboard.c | 2 | ||||
-rwxr-xr-x | amiga/clipboard.h | 2 | ||||
-rw-r--r-- | amiga/context_menu.c | 1340 | ||||
-rw-r--r-- | amiga/ctxmenu.c | 557 | ||||
-rw-r--r-- | amiga/ctxmenu.h | 89 | ||||
-rw-r--r-- | amiga/gui.c | 184 | ||||
-rw-r--r--[-rwxr-xr-x] | amiga/gui.h | 15 | ||||
-rwxr-xr-x | amiga/gui_options.c | 31 | ||||
-rw-r--r-- | amiga/menu.c | 2 | ||||
-rw-r--r-- | amiga/options.h | 1 | ||||
-rw-r--r-- | amiga/os3support.h | 2 | ||||
-rw-r--r-- | amiga/selectmenu.c | 150 | ||||
-rwxr-xr-x | amiga/selectmenu.h (renamed from amiga/context_menu.h) | 18 | ||||
-rw-r--r-- | desktop/gui_window.h | 1 | ||||
-rw-r--r-- | render/form.h | 1 | ||||
-rw-r--r-- | resources/FatMessages | 5 |
18 files changed, 887 insertions, 1519 deletions
diff --git a/amiga/Makefile.target b/amiga/Makefile.target index e704eb5f4..29b3905d3 100644 --- a/amiga/Makefile.target +++ b/amiga/Makefile.target @@ -70,12 +70,13 @@ MESSAGES_FILTER=ami S_AMIGA := gui.c tree.c history.c hotlist.c schedule.c file.c \ misc.c bitmap.c font.c filetype.c utf8.c login.c \ plotters.c object.c menu.c save_pdf.c arexx.c version.c \ - cookies.c context_menu.c clipboard.c help.c font_scan.c \ + cookies.c ctxmenu.c clipboard.c help.c font_scan.c \ launch.c search.c history_local.c download.c iff_dr2d.c \ sslcert.c gui_options.c print.c theme.c drag.c icon.c libs.c \ datatypes.c dt_picture.c dt_anim.c dt_sound.c plugin_hack.c \ stringview/stringview.c stringview/urlhistory.c rtg.c \ - agclass/amigaguide_class.c os3support.c font_bitmap.c + agclass/amigaguide_class.c os3support.c font_bitmap.c \ + selectmenu.c S_AMIGA := $(addprefix amiga/,$(S_AMIGA)) # This is the final source build list diff --git a/amiga/bitmap.h b/amiga/bitmap.h index f27087171..ff1b01c6e 100755 --- a/amiga/bitmap.h +++ b/amiga/bitmap.h @@ -19,6 +19,7 @@ #ifndef AMIGA_BITMAP_H #define AMIGA_BITMAP_H +#include <stdbool.h> #include <exec/types.h> #include <proto/graphics.h> #include <intuition/classusr.h> diff --git a/amiga/clipboard.c b/amiga/clipboard.c index 7495398b6..10f0faf8f 100644 --- a/amiga/clipboard.c +++ b/amiga/clipboard.c @@ -327,7 +327,7 @@ void ami_drag_selection(struct gui_window *g) } } -bool ami_easy_clipboard(char *text) +bool ami_easy_clipboard(const char *text) { gui_set_clipboard(text, strlen(text), NULL, 0); return true; diff --git a/amiga/clipboard.h b/amiga/clipboard.h index db6fc35cc..bc5b779ef 100755 --- a/amiga/clipboard.h +++ b/amiga/clipboard.h @@ -34,7 +34,7 @@ void gui_start_selection(struct gui_window *g); void ami_clipboard_init(void); void ami_clipboard_free(void); void ami_drag_selection(struct gui_window *g); -bool ami_easy_clipboard(char *text); +bool ami_easy_clipboard(const char *text); bool ami_easy_clipboard_bitmap(struct bitmap *bitmap); #ifdef WITH_NS_SVG bool ami_easy_clipboard_svg(struct hlcache_handle *c); diff --git a/amiga/context_menu.c b/amiga/context_menu.c deleted file mode 100644 index 9a10a2529..000000000 --- a/amiga/context_menu.c +++ /dev/null @@ -1,1340 +0,0 @@ -/* - * Copyright 2008 - 2011 Chris Young <chris@unsatisfactorysoftware.co.uk> - * - * 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 <http://www.gnu.org/licenses/>. - */ - -#ifdef __amigaos4__ - -#include <proto/popupmenu.h> -#include <proto/intuition.h> -#include <proto/asl.h> -#include <proto/dos.h> -#include <proto/exec.h> -#include <reaction/reaction_macros.h> -#include <string.h> - -#include "utils/nsoption.h" -#include "utils/utf8.h" -#include "utils/messages.h" -#include "utils/utils.h" -#include "render/form.h" -#include "desktop/browser_history.h" -#include "desktop/browser.h" -#include "desktop/hotlist.h" -#include "desktop/searchweb.h" -#include "desktop/textinput.h" -#include "desktop/gui_window.h" - -#include "amiga/clipboard.h" -#include "amiga/bitmap.h" -#include "amiga/file.h" -#include "amiga/filetype.h" -#include "amiga/gui.h" -#include "amiga/history_local.h" -#include "amiga/iff_dr2d.h" -#include "amiga/plugin_hack.h" -#include "amiga/theme.h" -#include "amiga/tree.h" -#include "amiga/utf8.h" -#include "amiga/context_menu.h" - - -HOOKF(uint32, ami_context_menu_hook, Object *, item, APTR); -HOOKF(uint32, ami_popup_hook, Object *, item, APTR); - -static bool ami_context_menu_history(const struct browser_window *bw, int x0, int y0, - int x1, int y1, const struct history_entry *entry, void *user_data); - -enum { - CMID_SELECTFILE, - CMID_COPYURL, - CMID_URLOPEN, - CMID_URLOPENWIN, - CMID_URLOPENTAB, - CMID_URLHOTLIST, - CMID_SAVEURL, - CMID_SHOWOBJ, - CMID_COPYOBJ, - CMID_CLIPOBJ, - CMID_SAVEOBJ, - CMID_SAVEIFFOBJ, - CMID_RELOADOBJ, - CMID_SELALL, - CMID_SELCLEAR, - CMID_SELCUT, - CMID_SELCOPY, - CMID_SELPASTE, - CMID_SELSEARCH, - CMID_SELSAVE, - CMID_FRAMEWIN, - CMID_FRAMETAB, - CMID_FRAMESHOW, - CMID_FRAMERELOAD, - CMID_FRAMECOPYURL, - CMID_FRAMESAVE, - CMID_FRAMESAVECOMPLETE, - CMID_PLUGINCMD, - CMID_NAVHOME, - CMID_NAVBACK, - CMID_NAVFORWARD, - CMID_NAVRELOAD, - CMID_NAVSTOP, - CMID_PAGEOPEN, - CMID_PAGESAVE, - CMID_PAGESAVECOMPLETE, - CMID_PAGEHOTLIST, - CMID_PAGECLOSE, - - CMID_TREE_EXPAND, - CMID_TREE_COLLAPSE, - CMID_TREE_LAUNCH, - CMID_TREE_NEWFOLDER, - CMID_TREE_NEWITEM, - CMID_TREE_SETDEFAULT, - CMID_TREE_CLEARDEFAULT, - CMID_TREE_DELETE, - CMID_TREE_EDITTITLE, - CMID_TREE_EDITLINK, - CMID_TREE_EDITFOLDER, - CMID_TREE_ADDHOTLIST, - - CMSUB_OBJECT, - CMSUB_URL, - CMSUB_SEL, - CMSUB_PAGE, - CMSUB_FRAME, - CMSUB_NAVIGATE, - CMID_HISTORY, - CMID_LAST -}; - -struct ami_file_input_menu_data { - int x; - int y; - struct browser_window *bw; -}; - -struct Library *PopupMenuBase = NULL; -struct PopupMenuIFace *IPopupMenu = NULL; -static char *ctxmenulab[CMID_LAST]; -static Object *ctxmenuobj = NULL; -static struct Hook ctxmenuhook; - -void ami_context_menu_init(void) -{ - if((PopupMenuBase = OpenLibrary("popupmenu.class",0))) { - IPopupMenu = (struct PopupMenuIFace *)GetInterface(PopupMenuBase,"main",1,NULL); - } - - ctxmenulab[CMID_SELECTFILE] = ami_utf8_easy((char *)messages_get("SelectFile")); - - ctxmenulab[CMID_SHOWOBJ] = ami_utf8_easy((char *)messages_get("ObjShow")); - ctxmenulab[CMID_RELOADOBJ] = ami_utf8_easy((char *)messages_get("ObjReload")); - ctxmenulab[CMID_COPYOBJ] = ami_utf8_easy((char *)messages_get("CopyURL")); - ctxmenulab[CMID_CLIPOBJ] = ami_utf8_easy((char *)messages_get("CopyClip")); - ctxmenulab[CMID_SAVEOBJ] = ami_utf8_easy((char *)messages_get("SaveAs")); - ctxmenulab[CMID_SAVEIFFOBJ] = ami_utf8_easy((char *)messages_get("SaveIFF")); - - ctxmenulab[CMID_PAGEOPEN] = ami_utf8_easy((char *)messages_get("OpenFile")); - ctxmenulab[CMID_PAGESAVE] = ami_utf8_easy((char *)messages_get("SaveAs")); - ctxmenulab[CMID_PAGESAVECOMPLETE] = ami_utf8_easy((char *)messages_get("SaveComplete")); - ctxmenulab[CMID_PAGEHOTLIST] = ami_utf8_easy((char *)messages_get("HotlistAdd")); - ctxmenulab[CMID_PAGECLOSE] = ami_utf8_easy((char *)messages_get("Close")); - - ctxmenulab[CMID_FRAMEWIN] = ami_utf8_easy((char *)messages_get("FrameNewWin")); - ctxmenulab[CMID_FRAMETAB] = ami_utf8_easy((char *)messages_get("FrameNewTab")); - ctxmenulab[CMID_FRAMESHOW] = ami_utf8_easy((char *)messages_get("FrameOnly")); - ctxmenulab[CMID_FRAMESAVE] = ami_utf8_easy((char *)messages_get("SaveAs")); - ctxmenulab[CMID_FRAMESAVECOMPLETE] = ami_utf8_easy((char *)messages_get("SaveComplete")); - ctxmenulab[CMID_FRAMECOPYURL] = ami_utf8_easy((char *)messages_get("CopyURL")); - ctxmenulab[CMID_FRAMERELOAD] = ami_utf8_easy((char *)messages_get("ObjReload")); - - ctxmenulab[CMID_SAVEURL] = ami_utf8_easy((char *)messages_get("LinkDload")); - ctxmenulab[CMID_URLOPEN] = ami_utf8_easy((char *)messages_get("Open")); - ctxmenulab[CMID_URLOPENWIN] = ami_utf8_easy((char *)messages_get("LinkNewWin")); - ctxmenulab[CMID_URLOPENTAB] = ami_utf8_easy((char *)messages_get("LinkNewTab")); - ctxmenulab[CMID_URLHOTLIST] = ami_utf8_easy((char *)messages_get("HotlistAdd")); - ctxmenulab[CMID_COPYURL] = ami_utf8_easy((char *)messages_get("CopyURL")); - - ctxmenulab[CMID_NAVHOME] = ami_utf8_easy((char *)messages_get("Home")); - ctxmenulab[CMID_NAVBACK] = ami_utf8_easy((char *)messages_get("Back")); - ctxmenulab[CMID_NAVFORWARD] = ami_utf8_easy((char *)messages_get("Forward")); - ctxmenulab[CMID_NAVRELOAD] = ami_utf8_easy((char *)messages_get("ObjReload")); - ctxmenulab[CMID_NAVSTOP] = ami_utf8_easy((char *)messages_get("Stop")); - - ctxmenulab[CMID_SELCUT] = ami_utf8_easy((char *)messages_get("CutNS")); - ctxmenulab[CMID_SELCOPY] = ami_utf8_easy((char *)messages_get("CopyNS")); - ctxmenulab[CMID_SELPASTE] = ami_utf8_easy((char *)messages_get("PasteNS")); - ctxmenulab[CMID_SELALL] = ami_utf8_easy((char *)messages_get("SelectAllNS")); - ctxmenulab[CMID_SELCLEAR] = ami_utf8_easy((char *)messages_get("ClearNS")); - ctxmenulab[CMID_SELSEARCH] = ami_utf8_easy((char *)messages_get("SearchWeb")); - ctxmenulab[CMID_SELSAVE] = ami_utf8_easy((char *)messages_get("SaveAs")); - - ctxmenulab[CMID_PLUGINCMD] = ami_utf8_easy((char *)messages_get("ExternalApp")); - - ctxmenulab[CMSUB_PAGE] = ami_utf8_easy((char *)messages_get("Page")); - ctxmenulab[CMSUB_FRAME] = ami_utf8_easy((char *)messages_get("Frame")); - ctxmenulab[CMSUB_OBJECT] = ami_utf8_easy((char *)messages_get("Object")); - ctxmenulab[CMSUB_NAVIGATE] = ami_utf8_easy((char *)messages_get("Navigate")); - ctxmenulab[CMSUB_URL] = ami_utf8_easy((char *)messages_get("Link")); - ctxmenulab[CMSUB_SEL] = ami_utf8_easy((char *)messages_get("Selection")); - - /* Back button */ - ctxmenulab[CMID_HISTORY] = ami_utf8_easy((char *)messages_get("HistLocalNS")); - - /* treeviews */ - ctxmenulab[CMID_TREE_EXPAND] = ami_utf8_easy((char *)messages_get("Expand")); - ctxmenulab[CMID_TREE_COLLAPSE] = ami_utf8_easy((char *)messages_get("Collapse")); - ctxmenulab[CMID_TREE_LAUNCH] = ami_utf8_easy((char *)messages_get("TreeLaunch")); - ctxmenulab[CMID_TREE_NEWFOLDER] = ami_utf8_easy((char *)messages_get("TreeNewFolder")); - ctxmenulab[CMID_TREE_NEWITEM] = ami_utf8_easy((char *)messages_get("TreeNewLink")); - ctxmenulab[CMID_TREE_SETDEFAULT] = ami_utf8_easy((char *)messages_get("TreeDefault")); - ctxmenulab[CMID_TREE_CLEARDEFAULT] = ami_utf8_easy((char *)messages_get("TreeClear")); - ctxmenulab[CMID_TREE_DELETE] = ami_utf8_easy((char *)messages_get("TreeDelete")); - ctxmenulab[CMID_TREE_EDITTITLE] = ami_utf8_easy((char *)messages_get("EditTitle")); - ctxmenulab[CMID_TREE_EDITLINK] = ami_utf8_easy((char *)messages_get("EditLink")); - ctxmenulab[CMID_TREE_EDITFOLDER] = ami_utf8_easy((char *)messages_get("EditFolder")); - ctxmenulab[CMID_TREE_ADDHOTLIST] = ami_utf8_easy((char *)messages_get("HotlistAdd")); - -} - -static void ami_context_menu_add_submenu(Object *ctxmenuobj, ULONG cmsub, void *userdata) -{ - /* - * CMSUB_PAGE - userdata = hlcache_object * - * CMSUB_FRAME - userdata = hlcache_object * - * CMSUB_URL - userdata = char * - * CMSUB_OBJECT - userdata = hlcache_object * - * CMSUB_SEL - userdata = gui_window * (only for menu construction) - * CMSUB_NAVIGATE - userdata = browser_window * - * CMID_SELECTFILE - userdata = ami_file_input_menu_data * - */ - - struct gui_window *gw = NULL; - - switch(cmsub) - { - case CMSUB_PAGE: - IDoMethod(ctxmenuobj, PM_INSERT, - NewObject(POPUPMENU_GetItemClass(), NULL, - PMIA_Title, (ULONG)ctxmenulab[CMSUB_PAGE], - PMSIMPLESUB, - PMA_AddItem, NewObject(POPUPMENU_GetItemClass(), NULL, - PMIA_Title, (ULONG)ctxmenulab[CMID_PAGEOPEN], - PMIA_ID, CMID_PAGEOPEN, - PMIA_UserData, userdata, - PMIA_CommKey, "O", - TAG_DONE), - PMA_AddItem, NewObject(POPUPMENU_GetItemClass(), NULL, - PMIA_Title, (ULONG)ctxmenulab[CMID_PAGESAVE], - PMIA_ID, CMID_PAGESAVE, - PMIA_UserData, userdata, - PMIA_CommKey, "S", - TAG_DONE), - PMA_AddItem, NewObject(POPUPMENU_GetItemClass(), NULL, - PMIA_Title, (ULONG)ctxmenulab[CMID_PAGESAVECOMPLETE], - PMIA_ID, CMID_PAGESAVECOMPLETE, - PMIA_UserData, userdata, - PMIA_Disabled, (content_get_type(userdata) != CONTENT_HTML), - TAG_DONE), - PMA_AddItem,NewObject(POPUPMENU_GetItemClass(), NULL, - PMIA_Title, ~0, - TAG_DONE), - PMA_AddItem, NewObject(POPUPMENU_GetItemClass(), NULL, - PMIA_Title, (ULONG)ctxmenulab[CMID_PAGECLOSE], - PMIA_ID, CMID_PAGECLOSE, - PMIA_UserData, userdata, - PMIA_CommKey, "K", - TAG_DONE), - PMA_AddItem,NewObject(POPUPMENU_GetItemClass(), NULL, - PMIA_Title, ~0, - TAG_DONE), - PMA_AddItem,NewObject(POPUPMENU_GetItemClass(), NULL, - PMIA_Title, (ULONG)ctxmenulab[CMID_PAGEHOTLIST], - PMIA_ID, CMID_PAGEHOTLIST, - PMIA_UserData, nsurl_access(hlcache_handle_get_url(userdata)), - PMIA_CommKey, "B", - TAG_DONE), - PMEND, - TAG_DONE), - ~0); - break; - - case CMSUB_FRAME: - IDoMethod(ctxmenuobj,PM_INSERT, - NewObject(POPUPMENU_GetItemClass(), NULL, - PMIA_Title, (ULONG)ctxmenulab[CMSUB_FRAME], - PMSIMPLESUB, - PMA_AddItem, NewObject(POPUPMENU_GetItemClass(), NULL, - PMIA_Title, (ULONG)ctxmenulab[CMID_FRAMEWIN], - PMIA_ID, CMID_FRAMEWIN, - PMIA_UserData, nsurl_access(hlcache_handle_get_url(userdata)), - TAG_DONE), - PMA_AddItem, NewObject(POPUPMENU_GetItemClass(), NULL, - PMIA_Title, (ULONG)ctxmenulab[CMID_FRAMETAB], - PMIA_ID, CMID_FRAMETAB, - PMIA_UserData, nsurl_access(hlcache_handle_get_url(userdata)), - TAG_DONE), - PMA_AddItem, NewObject(POPUPMENU_GetItemClass(), NULL, - PMIA_Title, (ULONG)ctxmenulab[CMID_FRAMESHOW], - PMIA_ID, CMID_FRAMESHOW, - PMIA_UserData, userdata, - TAG_DONE), - PMA_AddItem,NewObject(POPUPMENU_GetItemClass(), NULL, - PMIA_Title, ~0, - TAG_DONE), - PMA_AddItem, NewObject(POPUPMENU_GetItemClass(), NULL, - PMIA_Title, (ULONG)ctxmenulab[CMID_FRAMERELOAD], - PMIA_ID, CMID_FRAMERELOAD, - PMIA_UserData, userdata, - TAG_DONE), - PMA_AddItem,NewObject(POPUPMENU_GetItemClass(), NULL, - PMIA_Title, ~0, - TAG_DONE), - PMA_AddItem, NewObject(POPUPMENU_GetItemClass(), NULL, - PMIA_Title, (ULONG)ctxmenulab[CMID_FRAMECOPYURL], - PMIA_ID, CMID_FRAMECOPYURL, - PMIA_UserData, nsurl_access(hlcache_handle_get_url(userdata)), - TAG_DONE), - PMA_AddItem,NewObject(POPUPMENU_GetItemClass(), NULL, - PMIA_Title, ~0, - TAG_DONE), - PMA_AddItem, NewObject(POPUPMENU_GetItemClass(), NULL, - PMIA_Title, (ULONG)ctxmenulab[CMID_FRAMESAVE], - PMIA_ID, CMID_FRAMESAVE, - PMIA_UserData, userdata, - TAG_DONE), - PMA_AddItem, NewObject(POPUPMENU_GetItemClass(), NULL, - PMIA_Title, (ULONG)ctxmenulab[CMID_FRAMESAVECOMPLETE], - PMIA_ID, CMID_FRAMESAVECOMPLETE, - PMIA_UserData, userdata, - PMIA_Disabled, (content_get_type(userdata) != CONTENT_HTML), - TAG_DONE), - PMEND, - TAG_DONE), - ~0); - break; - - case CMSUB_NAVIGATE: - IDoMethod(ctxmenuobj, PM_INSERT, - NewObject(POPUPMENU_GetItemClass(), NULL, - PMIA_Title, (ULONG)ctxmenulab[CMSUB_NAVIGATE], - PMSIMPLESUB, - PMA_AddItem, NewObject(POPUPMENU_GetItemClass(), NULL, - PMIA_Title, (ULONG)ctxmenulab[CMID_NAVHOME], - PMIA_ID, CMID_NAVHOME, - PMIA_UserData, userdata, - TAG_DONE), - PMA_AddItem, NewObject(POPUPMENU_GetItemClass(), NULL, - PMIA_Title, (ULONG)ctxmenulab[CMID_NAVBACK], - PMIA_ID, CMID_NAVBACK, - PMIA_UserData, userdata, - PMIA_Disabled, !browser_window_back_available(userdata), - TAG_DONE), - PMA_AddItem, NewObject(POPUPMENU_GetItemClass(), NULL, - PMIA_Title, (ULONG)ctxmenulab[CMID_NAVFORWARD], - PMIA_ID, CMID_NAVFORWARD, - PMIA_UserData, userdata, - PMIA_Disabled, !browser_window_forward_available(userdata), - TAG_DONE), - PMA_AddItem, NewObject(POPUPMENU_GetItemClass(), NULL, - PMIA_Title, (ULONG)ctxmenulab[CMID_NAVRELOAD], - PMIA_ID, CMID_NAVRELOAD, - PMIA_UserData, userdata, - PMIA_CommKey, "R", - PMIA_Disabled, !browser_window_reload_available(userdata), - TAG_DONE), - PMA_AddItem, NewObject(POPUPMENU_GetItemClass(), NULL, - PMIA_Title, (ULONG)ctxmenulab[CMID_NAVSTOP], - PMIA_ID, CMID_NAVSTOP, - PMIA_UserData, userdata, - PMIA_Disabled, !browser_window_stop_available(userdata), - TAG_DONE), - PMEND, - TAG_DONE), - ~0); - break; - - case CMSUB_URL: - IDoMethod(ctxmenuobj,PM_INSERT, - NewObject(POPUPMENU_GetItemClass(), NULL, - PMIA_Title, (ULONG)ctxmenulab[CMSUB_URL], - PMSIMPLESUB, - PMA_AddItem, NewObject(POPUPMENU_GetItemClass(), NULL, - PMIA_Title, (ULONG)ctxmenulab[CMID_URLOPEN], - PMIA_ID, CMID_URLOPEN, - PMIA_UserData, userdata, - TAG_DONE), - PMA_AddItem, NewObject(POPUPMENU_GetItemClass(), NULL, - PMIA_Title, (ULONG)ctxmenulab[CMID_URLOPENWIN], - PMIA_ID, CMID_URLOPENWIN, - PMIA_UserData, userdata, - TAG_DONE), - PMA_AddItem, NewObject(POPUPMENU_GetItemClass(), NULL, - PMIA_Title, (ULONG)ctxmenulab[CMID_URLOPENTAB], - PMIA_ID, CMID_URLOPENTAB, - PMIA_UserData, userdata, - TAG_DONE), - PMA_AddItem,NewObject(POPUPMENU_GetItemClass(), NULL, - PMIA_Title, ~0, - TAG_DONE), - PMA_AddItem, NewObject(POPUPMENU_GetItemClass(), NULL, - PMIA_Title, (ULONG)ctxmenulab[CMID_COPYURL], - PMIA_ID, CMID_COPYURL, - PMIA_UserData, userdata, - TAG_DONE), - PMA_AddItem,NewObject(POPUPMENU_GetItemClass(), NULL, - PMIA_Title, (ULONG)ctxmenulab[CMID_URLHOTLIST], - PMIA_ID, CMID_URLHOTLIST, - PMIA_UserData, userdata, - TAG_DONE), - PMA_AddItem,NewObject(POPUPMENU_GetItemClass(), NULL, - PMIA_Title, ~0, - TAG_DONE), - PMA_AddItem, NewObject(POPUPMENU_GetItemClass(), NULL, - PMIA_Title, (ULONG)ctxmenulab[CMID_SAVEURL], - PMIA_ID, CMID_SAVEURL, - PMIA_UserData, userdata, - TAG_DONE), - PMEND, - TAG_DONE), - ~0); - break; - - case CMSUB_OBJECT: - IDoMethod(ctxmenuobj, PM_INSERT, - NewObject(POPUPMENU_GetItemClass(), NULL, - PMIA_Title, (ULONG)ctxmenulab[CMSUB_OBJECT], - PMSIMPLESUB, - PMA_AddItem, NewObject(POPUPMENU_GetItemClass(), NULL, - PMIA_Title, (ULONG)ctxmenulab[CMID_SHOWOBJ], - PMIA_ID, CMID_SHOWOBJ, - PMIA_UserData, userdata, - TAG_DONE), - PMA_AddItem, NewObject(POPUPMENU_GetItemClass(), NULL, - PMIA_Title, (ULONG)ctxmenulab[CMID_RELOADOBJ], - PMIA_ID, CMID_RELOADOBJ, - PMIA_UserData, userdata, - TAG_DONE), - PMA_AddItem,NewObject(POPUPMENU_GetItemClass(), NULL, - PMIA_Title, ~0, - TAG_DONE), - PMA_AddItem,NewObject(POPUPMENU_GetItemClass(), NULL, - PMIA_Title, (ULONG)ctxmenulab[CMID_COPYOBJ], - PMIA_ID, CMID_COPYOBJ, - PMIA_UserData, nsurl_access(hlcache_handle_get_url(userdata)), - TAG_DONE), - PMA_AddItem, NewObject(POPUPMENU_GetItemClass(), NULL, - PMIA_Title, (ULONG)ctxmenulab[CMID_CLIPOBJ], - PMIA_ID, CMID_CLIPOBJ, - PMIA_UserData, userdata, - PMIA_Disabled, (content_get_type(userdata) != CONTENT_IMAGE), - TAG_DONE), - PMA_AddItem,NewObject(POPUPMENU_GetItemClass(), NULL, - PMIA_Title, ~0, - TAG_DONE), - PMA_AddItem, NewObject(POPUPMENU_GetItemClass(), NULL, - PMIA_Title, (ULONG)ctxmenulab[CMID_SAVEOBJ], - PMIA_ID, CMID_SAVEOBJ, - PMIA_UserData, userdata, - TAG_DONE), - PMA_AddItem, NewObject(POPUPMENU_GetItemClass(), NULL, - PMIA_Title, (ULONG)ctxmenulab[CMID_SAVEIFFOBJ], - PMIA_ID, CMID_SAVEIFFOBJ, - PMIA_UserData, userdata, - PMIA_Disabled, (content_get_type(userdata) != CONTENT_IMAGE), - TAG_DONE), - PMA_AddItem,NewObject(POPUPMENU_GetItemClass(), NULL, - PMIA_Title, ~0, - TAG_DONE), - PMA_AddItem, NewObject(POPUPMENU_GetItemClass(), NULL, - PMIA_Title, (ULONG)ctxmenulab[CMID_PLUGINCMD], - PMIA_ID, CMID_PLUGINCMD, - PMIA_UserData, userdata, - PMIA_Disabled, !ami_mime_content_to_cmd(userdata), - TAG_DONE), - PMEND, - TAG_DONE), - ~0); - break; - - case CMSUB_SEL: - gw = userdata; - BOOL disabled_noselection = !(browser_window_get_editor_flags(gw->bw) & BW_EDITOR_CAN_COPY); - - IDoMethod(ctxmenuobj,PM_INSERT, - NewObject(POPUPMENU_GetItemClass(), NULL, - PMIA_Title, (ULONG)ctxmenulab[CMSUB_SEL], - PMIA_SubMenu, NewObject(POPUPMENU_GetClass(), NULL, - PMA_AddItem,NewObject(POPUPMENU_GetItemClass(), NULL, - PMIA_Title, (ULONG)ctxmenulab[CMID_SELCUT], - PMIA_ID,CMID_SELCUT, - PMIA_Disabled, !(browser_window_get_editor_flags(gw->bw) & BW_EDITOR_CAN_CUT), - PMIA_CommKey, "X", - TAG_DONE), - PMA_AddItem,NewObject(POPUPMENU_GetItemClass(), NULL, - PMIA_Title, (ULONG)ctxmenulab[CMID_SELCOPY], - PMIA_ID,CMID_SELCOPY, - PMIA_Disabled, disabled_noselection, - PMIA_CommKey, "C", - TAG_DONE), - PMA_AddItem,NewObject(POPUPMENU_GetItemClass(), NULL, - PMIA_Title, (ULONG)ctxmenulab[CMID_SELPASTE], - PMIA_ID,CMID_SELPASTE, - PMIA_Disabled, (gw->c_h == 0), - PMIA_CommKey, "V", - TAG_DONE), - PMA_AddItem,NewObject(POPUPMENU_GetItemClass(), NULL, - PMIA_Title, (ULONG)ctxmenulab[CMID_SELALL], - PMIA_ID,CMID_SELALL, - PMIA_CommKey, "A", - TAG_DONE), - PMA_AddItem,NewObject(POPUPMENU_GetItemClass(), NULL, - PMIA_Title, (ULONG)ctxmenulab[CMID_SELCLEAR], - PMIA_ID,CMID_SELCLEAR, - PMIA_Disabled, disabled_noselection, - TAG_DONE), - PMA_AddItem,NewObject(POPUPMENU_GetItemClass(), NULL, - PMIA_Title, ~0, - TAG_DONE), - PMA_AddItem,NewObject(POPUPMENU_GetItemClass(), NULL, - PMIA_Title, (ULONG)ctxmenulab[CMID_SELSEARCH], - PMIA_ID,CMID_SELSEARCH, - PMIA_Disabled, disabled_noselection, - TAG_DONE), - PMA_AddItem,NewObject(POPUPMENU_GetItemClass(), NULL, - PMIA_Title, (ULONG)ctxmenulab[CMID_SELSAVE], - PMIA_ID,CMID_SELSAVE, - PMIA_Disabled, disabled_noselection, - TAG_DONE), - TAG_DONE), - TAG_DONE), - ~0); - break; - - case CMID_SELECTFILE: - IDoMethod(ctxmenuobj,PM_INSERT, - NewObject(POPUPMENU_GetItemClass(), NULL, - PMIA_Title, (ULONG)ctxmenulab[CMID_SELECTFILE], - PMIA_ID, CMID_SELECTFILE, - PMIA_UserData, userdata, - TAG_DONE), - ~0); - break; - } -} - -void ami_context_menu_free(void) -{ - int i; - - if(ctxmenuobj) DisposeObject(ctxmenuobj); - - for(i=0;i<CMID_LAST;i++) - { - ami_utf8_free(ctxmenulab[i]); - } - - if(IPopupMenu) DropInterface((struct Interface *)IPopupMenu); - if(PopupMenuBase) CloseLibrary(PopupMenuBase); -} - -BOOL ami_context_menu_mouse_trap(struct gui_window_2 *gwin, BOOL trap) -{ - if(nsoption_bool(context_menu) == false) return FALSE; - - if((nsoption_bool(kiosk_mode) == false) && (trap == FALSE)) - { - if(browser_window_back_available(gwin->gw->bw) && - ami_gadget_hit(gwin->objects[GID_BACK], - gwin->win->MouseX, gwin->win->MouseY)) - trap = TRUE; - - if(browser_window_forward_available(gwin->gw->bw) && - ami_gadget_hit(gwin->objects[GID_FORWARD], - gwin->win->MouseX, gwin->win->MouseY)) - trap = TRUE; - } - - if(gwin->rmbtrapped == trap) return trap; - - SetWindowAttr(gwin->win, WA_RMBTrap, (APTR)(ULONG)trap, sizeof(BOOL)); - gwin->rmbtrapped = trap; - - return trap; -} - -void ami_context_menu_show(struct gui_window_2 *gwin,int x,int y) -{ - struct hlcache_handle *cc = browser_window_get_content(gwin->gw->bw); - bool no_more_menus = false; - bool menuhascontent = false; - struct browser_window_features ccdata; - - if(!cc) return; - if(ctxmenuobj) DisposeObject(ctxmenuobj); - - ctxmenuhook.h_Entry = ami_context_menu_hook; - ctxmenuhook.h_SubEntry = NULL; - ctxmenuhook.h_Data = gwin; - - ctxmenuobj = NewObject( POPUPMENU_GetClass(), NULL, - PMA_MenuHandler, &ctxmenuhook, - TAG_DONE); - - if(gwin->gw->bw && ami_gadget_hit(gwin->objects[GID_BACK], - gwin->win->MouseX, gwin->win->MouseY)) - { - gwin->temp = 0; - browser_window_history_enumerate_back(gwin->gw->bw, ami_context_menu_history, gwin); - - IDoMethod(ctxmenuobj, PM_INSERT, - NewObject(POPUPMENU_GetItemClass(), NULL, - PMIA_Title, ~0, - TAG_DONE), - ~0); - - IDoMethod(ctxmenuobj, PM_INSERT, - NewObject(POPUPMENU_GetItemClass(), NULL, - PMIA_Title, (ULONG)ctxmenulab[CMID_HISTORY], - PMIA_ID, CMID_HISTORY, - PMIA_UserData, NULL, - TAG_DONE), - ~0); - - menuhascontent = true; - } - else if(gwin->gw->bw && ami_gadget_hit(gwin->objects[GID_FORWARD], - gwin->win->MouseX, gwin->win->MouseY)) - { - gwin->temp = 0; - browser_window_history_enumerate_forward(gwin->gw->bw, ami_context_menu_history, gwin); - - IDoMethod(ctxmenuobj, PM_INSERT, - NewObject(POPUPMENU_GetItemClass(), NULL, - PMIA_Title, ~0, - TAG_DONE), - ~0); - - IDoMethod(ctxmenuobj, PM_INSERT, - NewObject(POPUPMENU_GetItemClass(), NULL, - PMIA_Title, (ULONG)ctxmenulab[CMID_HISTORY], - PMIA_ID, CMID_HISTORY, - PMIA_UserData, NULL, - TAG_DONE), - ~0); - - menuhascontent = true; - } - else - { - if(no_more_menus == false) - { - browser_window_get_features(gwin->gw->bw, x, y, &ccdata); - - ami_context_menu_add_submenu(ctxmenuobj, CMSUB_PAGE, cc); - menuhascontent = true; - - if(ccdata.main && (ccdata.main != cc)) - { - ami_context_menu_add_submenu(ctxmenuobj, CMSUB_FRAME, ccdata.main); - menuhascontent = true; - } - - if(ccdata.link) - { - ami_context_menu_add_submenu(ctxmenuobj, CMSUB_URL, (char *)nsurl_access(ccdata.link)); - menuhascontent = true; - } - - if(ccdata.object) - { - ami_context_menu_add_submenu(ctxmenuobj, CMSUB_OBJECT, ccdata.object); - menuhascontent = true; - } - - if(ccdata.form_features == CTX_FORM_FILE) - { - struct ami_file_input_menu_data file_input = { - .x = x, - .y = y, - .bw = gwin->gw->bw - }; - ami_context_menu_add_submenu(ctxmenuobj, CMID_SELECTFILE, &file_input); - menuhascontent = true; - } - - ami_context_menu_add_submenu(ctxmenuobj, CMSUB_NAVIGATE, gwin->gw->bw); - menuhascontent = true; - - if(browser_window_can_select(gwin->gw->bw)) - { - ami_context_menu_add_submenu(ctxmenuobj, CMSUB_SEL, gwin->gw); - menuhascontent = true; - } - } - } - - if(!menuhascontent) return; - - gui_window_set_pointer(gwin->gw, GUI_POINTER_DEFAULT); - - IDoMethod(ctxmenuobj, PM_OPEN, gwin->win); -} - -HOOKF(uint32, ami_context_menu_hook, Object *, item, APTR) -{ - int32 itemid = 0; - struct gui_window_2 *gwin = hook->h_Data; - APTR userdata = NULL; - struct browser_window *bw; - struct hlcache_handle *object; - struct bitmap *bm; - nsurl *url; - nserror error; - - if(GetAttrs(item, PMIA_ID, &itemid, - PMIA_UserData, &userdata, - TAG_DONE)) { - switch(itemid) - { - case CMID_SELECTFILE: - if(AslRequestTags(filereq, - ASLFR_Window, gwin->win, - ASLFR_SleepWindow, TRUE, - ASLFR_TitleText,messages_get("NetSurf"), - ASLFR_Screen,scrn, - ASLFR_DoSaveMode,FALSE, - TAG_DONE)) - { - struct ami_file_input_menu_data - *file_input = userdata; - char fname[1024]; - - strlcpy(fname,filereq->fr_Drawer,1024); - AddPart(fname,filereq->fr_File,1024); - - browser_window_drop_file_at_point( - file_input->bw, - file_input->x, - file_input->y, - fname); - } - break; - - case CMID_PAGEOPEN: - ami_file_open(gwin); - break; - - case CMID_PAGECLOSE: - browser_window_destroy(gwin->gw->bw); - break; - - case CMID_URLHOTLIST: - case CMID_PAGEHOTLIST: - { - if (nsurl_create(userdata, &url) != NSERROR_OK) - break; - - hotlist_add_url(url); - nsurl_unref(url); - ami_gui_update_hotlist_button(gwin); - } - break; - - case CMID_FRAMECOPYURL: - case CMID_COPYURL: - case CMID_COPYOBJ: - ami_easy_clipboard((char *)userdata); - break; - - case CMID_FRAMEWIN: - case CMID_URLOPENWIN: - error = nsurl_create(userdata, &url); - if (error == NSERROR_OK) { - error = browser_window_create(BW_CREATE_CLONE | BW_CREATE_HISTORY, - url, - browser_window_get_url(gwin->gw->bw), - gwin->gw->bw, - &bw); - nsurl_unref(url); - } - if (error != NSERROR_OK) { - warn_user(messages_get_errorcode(error), 0); - } - - - break; - - case CMID_FRAMETAB: - case CMID_URLOPENTAB: - error = nsurl_create(userdata, &url); - if (error == NSERROR_OK) { - 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); - nsurl_unref(url); - } - if (error != NSERROR_OK) { - warn_user(messages_get_errorcode(error), 0); - } - - break; - - case CMID_FRAMESAVE: - case CMID_SAVEURL: - { - nsurl *url; - if (nsurl_create(userdata, &url) != NSERROR_OK) { - warn_user("NoMemory", 0); - } else { - browser_window_navigate(gwin->gw->bw, - url, - browser_window_get_url(gwin->gw->bw), - BW_NAVIGATE_DOWNLOAD, - NULL, - NULL, - NULL); - nsurl_unref(url); - } - } - break; - - case CMID_FRAMESHOW: - case CMID_SHOWOBJ: - browser_window_navigate(gwin->gw->bw, - hlcache_handle_get_url(userdata), - browser_window_get_url(gwin->gw->bw), - BW_NAVIGATE_HISTORY, - NULL, - NULL, - NULL); - - break; - - case CMID_URLOPEN: - { - nsurl *url; - if (nsurl_create(userdata, &url) != NSERROR_OK) { - warn_user("NoMemory", 0); - } else { - browser_window_navigate(gwin->gw->bw, - url, - browser_window_get_url(gwin->gw->bw), - BW_NAVIGATE_HISTORY, - NULL, - NULL, - NULL); - nsurl_unref(url); - } - } - break; - - case CMID_FRAMERELOAD: - case CMID_RELOADOBJ: - object = (struct hlcache_handle *)userdata; - content_invalidate_reuse_data(object); - browser_window_reload(gwin->gw->bw, false); - break; - - case CMID_CLIPOBJ: - object = (struct hlcache_handle *)userdata; - if((bm = content_get_bitmap(object))) - { - bm->url = (char *)nsurl_access(hlcache_handle_get_url(object)); - bm->title = (char *)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 - break; - - case CMID_SAVEOBJ: - case CMID_PAGESAVE: - ami_file_save_req(AMINS_SAVE_SOURCE, gwin, - (struct hlcache_handle *)userdata); - break; - - case CMID_PAGESAVECOMPLETE: - case CMID_FRAMESAVECOMPLETE: - ami_file_save_req(AMINS_SAVE_COMPLETE, gwin, - (struct hlcache_handle *)userdata); - break; - - case CMID_SAVEIFFOBJ: - ami_file_save_req(AMINS_SAVE_IFF, gwin, - (struct hlcache_handle *)userdata); - break; - - case CMID_PLUGINCMD: - amiga_plugin_hack_execute((struct hlcache_handle *)userdata); - break; - - case CMID_HISTORY: - if(userdata == NULL) - { - ami_history_open(gwin->gw); - } - else - { - browser_window_history_go(gwin->gw->bw, - (struct history_entry *)userdata, false); - } - break; - - case CMID_NAVHOME: - { - nsurl *url; - - if (nsurl_create(nsoption_charp(homepage_url), &url) != NSERROR_OK) { - warn_user("NoMemory", 0); - } else { - browser_window_navigate(gwin->gw->bw, - url, - NULL, - BW_NAVIGATE_HISTORY, - NULL, - NULL, - NULL); - nsurl_unref(url); - } - - } - break; - - case CMID_NAVBACK: - ami_gui_history(gwin, true); - break; - - case CMID_NAVFORWARD: - ami_gui_history(gwin, false); - break; - - case CMID_NAVSTOP: - if(browser_window_stop_available(gwin->gw->bw)) - browser_window_stop(gwin->gw->bw); - break; - - case CMID_NAVRELOAD: - if(browser_window_reload_available(gwin->gw->bw)) - browser_window_reload(gwin->gw->bw, true); - break; - - case CMID_SELCUT: - browser_window_key_press(gwin->gw->bw, NS_KEY_CUT_SELECTION); - break; - - case CMID_SELCOPY: - browser_window_key_press(gwin->gw->bw, NS_KEY_COPY_SELECTION); - browser_window_key_press(gwin->gw->bw, NS_KEY_CLEAR_SELECTION); - break; - - case CMID_SELPASTE: - browser_window_key_press(gwin->gw->bw, NS_KEY_PASTE); - break; - - case CMID_SELALL: - browser_window_key_press(gwin->gw->bw, NS_KEY_SELECT_ALL); - gui_start_selection(gwin->gw); - break; - - case CMID_SELCLEAR: - browser_window_key_press(gwin->gw->bw, NS_KEY_CLEAR_SELECTION); - break; - - case CMID_SELSAVE: - ami_file_save_req(AMINS_SAVE_SELECTION, gwin, NULL); - break; - - case CMID_SELSEARCH: - { - char *sel; - - if((sel = browser_window_get_selection(gwin->gw->bw))) - { - nserror ret; - nsurl *url; - - ret = search_web_omni(sel, SEARCH_WEB_OMNI_SEARCHONLY, &url); - free(sel); - if (ret == NSERROR_OK) { - ret = browser_window_navigate(gwin->gw->bw, - url, - NULL, - BW_NAVIGATE_HISTORY, - NULL, - NULL, - NULL); - nsurl_unref(url); - } - if (ret != NSERROR_OK) { - warn_user(messages_get_errorcode(ret), 0); - } - } - } - break; - } - } - - return itemid; -} - -#if 0 -/* \todo This is the context menu for the treeviews which needs fixing */ -static uint32 ami_context_menu_hook_tree(struct Hook *hook, Object *item, APTR reserved) -{ - int32 itemid = 0; - struct tree *tree = hook->h_Data; - APTR userdata = NULL; - - if(GetAttrs(item,PMIA_ID, &itemid, - PMIA_UserData, &userdata, - TAG_DONE)) - { - switch(itemid) - { - case CMID_TREE_LAUNCH: - tree_keypress(tree, NS_KEY_CR); - break; - - case CMID_TREE_EDITFOLDER: - hotlist_edit_selection(); - break; - - case CMID_TREE_EDITTITLE: - warn_user("TODO.", 0); - break; - - case CMID_TREE_EDITLINK: - warn_user("TODO.", 0); - break; - - case CMID_TREE_NEWFOLDER: - hotlist_add_folder(NULL, false, 0); - break; - - case CMID_TREE_NEWITEM: - hotlist_add_entry(NULL, NULL, false, 0); - break; - - case CMID_TREE_SETDEFAULT: - warn_user("TODO.", 0); - break; - - case CMID_TREE_CLEARDEFAULT: - warn_user("TODO.", 0); - break; - - case CMID_TREE_ADDHOTLIST: - warn_user("TODO.", 0); - break; - - case CMID_TREE_DELETE: - tree_keypress(tree, NS_KEY_DELETE_RIGHT); - break; - } - } - return itemid; -} - -void ami_context_menu_show_tree(struct tree *tree, struct Window *win, int type) -{ - struct node *root = tree_get_root(tree); - struct node *sel_node = tree_get_selected_node(root); - bool has_selection = tree_node_has_selection(root); - bool menu_content = false; - - if(ctxmenuobj) DisposeObject(ctxmenuobj); - - ctxmenuhook.h_Entry = ami_context_menu_hook_tree; - ctxmenuhook.h_SubEntry = NULL; - ctxmenuhook.h_Data = tree; - - ctxmenuobj = NewObject( POPUPMENU_GetClass(), NULL, - PMA_MenuHandler, &ctxmenuhook, - TAG_DONE); - - if(has_selection && (type != AMI_TREE_COOKIES) && - ((sel_node == NULL) || - (tree_node_is_folder(sel_node) == false))) { - IDoMethod(ctxmenuobj, PM_INSERT, - NewObject(POPUPMENU_GetItemClass(), NULL, - PMIA_Title, (ULONG)ctxmenulab[CMID_TREE_LAUNCH], - PMIA_ID, CMID_TREE_LAUNCH, - PMIA_UserData, NULL, - TAG_DONE), - ~0); - - menu_content = true; - } - - if(type == AMI_TREE_HOTLIST) { - if(menu_content == true) { - IDoMethod(ctxmenuobj, PM_INSERT, - NewObject(POPUPMENU_GetItemClass(), NULL, - PMIA_Title, ~0, - TAG_DONE), - ~0); - - menu_content = false; - } - - if(has_selection && (sel_node != NULL)) { - if(tree_node_is_folder(sel_node) == true) { - IDoMethod(ctxmenuobj, PM_INSERT, - NewObject(POPUPMENU_GetItemClass(), NULL, - PMIA_Title, (ULONG)ctxmenulab[CMID_TREE_EDITFOLDER], - PMIA_ID, CMID_TREE_EDITFOLDER, - PMIA_UserData, NULL, - TAG_DONE), - ~0); - } - else - { - IDoMethod(ctxmenuobj, PM_INSERT, - NewObject(POPUPMENU_GetItemClass(), NULL, - PMIA_Title, (ULONG)ctxmenulab[CMID_TREE_EDITTITLE], - PMIA_ID, CMID_TREE_EDITTITLE, - PMIA_UserData, sel_node, - TAG_DONE), - ~0); - - IDoMethod(ctxmenuobj, PM_INSERT, - NewObject(POPUPMENU_GetItemClass(), NULL, - PMIA_Title, (ULONG)ctxmenulab[CMID_TREE_EDITLINK], - PMIA_ID, CMID_TREE_EDITLINK, - PMIA_UserData, sel_node, - TAG_DONE), - ~0); - } - menu_content = true; - } - - if(menu_content == true) { - IDoMethod(ctxmenuobj, PM_INSERT, - NewObject(POPUPMENU_GetItemClass(), NULL, - PMIA_Title, ~0, - TAG_DONE), - ~0); - - menu_content = false; - } - - IDoMethod(ctxmenuobj, PM_INSERT, - NewObject(POPUPMENU_GetItemClass(), NULL, - PMIA_Title, (ULONG)ctxmenulab[CMID_TREE_NEWFOLDER], - PMIA_ID, CMID_TREE_NEWFOLDER, - PMIA_UserData, NULL, - TAG_DONE), - ~0); - - IDoMethod(ctxmenuobj, PM_INSERT, - NewObject(POPUPMENU_GetItemClass(), NULL, - PMIA_Title, (ULONG)ctxmenulab[CMID_TREE_NEWITEM], - PMIA_ID, CMID_TREE_NEWITEM, - PMIA_UserData, NULL, - TAG_DONE), - ~0); - - if(has_selection && (sel_node != NULL) && - (tree_node_is_folder(sel_node) == true)) { - - IDoMethod(ctxmenuobj, PM_INSERT, - NewObject(POPUPMENU_GetItemClass(), NULL, - PMIA_Title, ~0, - TAG_DONE), - ~0); - - if(tree_node_is_default(sel_node) == true) - { - IDoMethod(ctxmenuobj, PM_INSERT, - NewObject(POPUPMENU_GetItemClass(), NULL, - PMIA_Title, (ULONG)ctxmenulab[CMID_TREE_CLEARDEFAULT], - PMIA_ID, CMID_TREE_CLEARDEFAULT, - PMIA_UserData, NULL, - TAG_DONE), - ~0); - } - else - { - IDoMethod(ctxmenuobj, PM_INSERT, - NewObject(POPUPMENU_GetItemClass(), NULL, - PMIA_Title, (ULONG)ctxmenulab[CMID_TREE_SETDEFAULT], - PMIA_ID, CMID_TREE_SETDEFAULT, - PMIA_UserData, NULL, - TAG_DONE), - ~0); - } - } - - menu_content = true; - } - - if((type == AMI_TREE_HISTORY) && has_selection && - (sel_node != NULL) && (tree_node_is_folder(sel_node) == false)) { - if(menu_content == true) { - IDoMethod(ctxmenuobj, PM_INSERT, - NewObject(POPUPMENU_GetItemClass(), NULL, - PMIA_Title, ~0, - TAG_DONE), - ~0); - } - - IDoMethod(ctxmenuobj, PM_INSERT, - NewObject(POPUPMENU_GetItemClass(), NULL, - PMIA_Title, (ULONG)ctxmenulab[CMID_TREE_ADDHOTLIST], - PMIA_ID, CMID_TREE_ADDHOTLIST, - PMIA_UserData, sel_node, - TAG_DONE), - ~0); - - menu_content = true; - } - - if(has_selection) { - if(menu_content == true) { - IDoMethod(ctxmenuobj, PM_INSERT, - NewObject(POPUPMENU_GetItemClass(), NULL, - PMIA_Title, ~0, - TAG_DONE), - ~0); - } - - IDoMethod(ctxmenuobj, PM_INSERT, - NewObject(POPUPMENU_GetItemClass(), NULL, - PMIA_Title, (ULONG)ctxmenulab[CMID_TREE_DELETE], - PMIA_ID, CMID_TREE_DELETE, - PMIA_UserData, root, - TAG_DONE), - ~0); - - menu_content = true; - } - - if(menu_content == true) - IDoMethod(ctxmenuobj, PM_OPEN, win); -} -#endif - -static bool ami_context_menu_history(const struct browser_window *bw, - int x0, int y0, int x1, int y1, - const struct history_entry *entry, void *user_data) -{ - struct gui_window_2 *gwin = (struct gui_window_2 *)user_data; - - gwin->temp++; - if(gwin->temp > 10) return false; - - IDoMethod(ctxmenuobj, PM_INSERT, - NewObject(POPUPMENU_GetItemClass(), NULL, - PMIA_Title, (ULONG)browser_window_history_entry_get_title(entry), - PMIA_ID, CMID_HISTORY, - PMIA_UserData, entry, - TAG_DONE), - ~0); - - return true; -} - -HOOKF(uint32, ami_popup_hook, Object *, item, APTR) -{ - uint32 itemid = 0; - struct gui_window *gwin = hook->h_Data; - - if(GetAttr(PMIA_ID, item, &itemid)) - { - form_select_process_selection(gwin->shared->control,itemid); - } - - return itemid; -} - -void gui_create_form_select_menu(struct gui_window *g, - struct form_control *control) -{ - /* TODO: PMIA_Title memory leaks as we don't free the strings. - * We use the core menu anyway, but in future when popupmenu.class - * improves we will probably start using this again. - */ - - struct gui_window *gwin = g; - struct form_option *opt = form_select_get_option(control, 0); - ULONG i = 0; - - if(ctxmenuobj) DisposeObject(ctxmenuobj); - - ctxmenuhook.h_Entry = ami_popup_hook; - ctxmenuhook.h_SubEntry = NULL; - ctxmenuhook.h_Data = gwin; - - gwin->shared->control = control; - - ctxmenuobj = PMMENU(ami_utf8_easy(form_control_get_name(control))), - PMA_MenuHandler, &ctxmenuhook, End; - - while(opt) - { - IDoMethod(ctxmenuobj, PM_INSERT, - NewObject( POPUPMENU_GetItemClass(), NULL, - PMIA_Title, (ULONG)ami_utf8_easy(opt->text), - PMIA_ID, i, - PMIA_CheckIt, TRUE, - PMIA_Checked, opt->selected, - TAG_DONE), - ~0); - - opt = opt->next; - i++; - } - - gui_window_set_pointer(gwin, GUI_POINTER_DEFAULT); // Clear the menu-style pointer - - IDoMethod(ctxmenuobj, PM_OPEN, gwin->shared->win); -} - -#else - -#include <proto/dos.h> -#include "amiga/context_menu.h" - -void ami_context_menu_init(void) -{ -} - -void ami_context_menu_free(void) -{ -} - -BOOL ami_context_menu_mouse_trap(struct gui_window_2 *gwin, BOOL trap) -{ - return FALSE; -} - -void ami_context_menu_show(struct gui_window_2 *gwin, int x, int y) -{ -} - -void gui_create_form_select_menu(struct gui_window *g, struct form_control *control) -{ -} -#endif - diff --git a/amiga/ctxmenu.c b/amiga/ctxmenu.c new file mode 100644 index 000000000..42d0da38b --- /dev/null +++ b/amiga/ctxmenu.c @@ -0,0 +1,557 @@ +/* + * Copyright 2015 Chris Young <chris@unsatisfactorysoftware.co.uk> + * + * 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 <http://www.gnu.org/licenses/>. + */ + +/** \file + * Intuition-based context menu operations + */ + +#ifdef __amigaos4__ +#include <string.h> + +#include <proto/exec.h> +#include <proto/intuition.h> + +#include <proto/bitmap.h> +#include <images/bitmap.h> +#include <proto/window.h> +#include <classes/window.h> + +#include <intuition/menuclass.h> +#include <reaction/reaction_macros.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" + +#include "desktop/browser.h" +#include "desktop/browser_history.h" +#include "desktop/mouse.h" +#include "desktop/textinput.h" + +#include "utils/log.h" +#include "utils/messages.h" +#include "utils/nsoption.h" + +enum { + AMI_CTX_ID_NONE = 0, + + /* Text selection */ + AMI_CTX_ID_SELCOPY, + + /* 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_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_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) + 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) + 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))) + { + bm->url = (char *)nsurl_access(hlcache_handle_get_url(object)); + bm->title = (char *)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); +} + +/** 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; + + 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))) { + + ami_ctxmenu_add_item(root_menu, AMI_CTX_ID_SELCOPY, gwin); + + ctxmenu_has_content = true; + } + + 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_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_add", + ami_ctxmenu_item_tabnew); +} + +/******************************** + * 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); + + return (struct Menu *)gwin->clicktab_ctxmenu; +} + + +#endif + diff --git a/amiga/ctxmenu.h b/amiga/ctxmenu.h new file mode 100644 index 000000000..79c0dc793 --- /dev/null +++ b/amiga/ctxmenu.h @@ -0,0 +1,89 @@ +/* + * Copyright 2015 Chris Young <chris@unsatisfactorysoftware.co.uk> + * + * 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 <http://www.gnu.org/licenses/>. + */ + +/** \file + * Interface to Intuition-based context menu operations + */ + +#ifndef AMIGA_CTXMENU_H +#define AMIGA_CTXMENU_H 1 + +struct Hook; +struct Menu; +struct gui_window_2; + +enum { + AMI_CTXMENU_HISTORY_BACK = 0, + AMI_CTXMENU_HISTORY_FORWARD = 1 +}; + +/** + * Initialise context menus code (allocate label text, etc) + * Must be called *after* NetSurf's screen pointer is obtained. + */ +void ami_ctxmenu_init(void); + +/** + * Cleanup context menus code + */ +void ami_ctxmenu_free(void); + +/** + * Get a Hook for WA_ContextMenuHook + * + * \param data ptr for the hook to use (struct gui_window_2 *) + * \returns pointer to a struct Hook + */ +struct Hook *ami_ctxmenu_get_hook(APTR data); + +/** + * Release a Hook for WA_ContextMenuHook + * + * \param hook ptr to hook + */ +void ami_ctxmenu_release_hook(struct Hook *hook); + +/** + * Create history context menu + * The first time this is run it will create an empty menu, + * Subsequent runs will (re-)populate with the history. + * This is to allow the pointer to be obtained before the browser_window is opened. + * + * \param direction AMI_CTXMENU_HISTORY_(BACK|FORWARD) + * \param gwin struct gui_window_2 * + * \returns pointer to menu (for convenience, is also stored in gwin structure) + * The returned pointer MUST be disposed of with DisposeObject before program exit. + */ +struct Menu *ami_ctxmenu_history_create(int direction, struct gui_window_2 *gwin); + +/** + * Create ClickTab context menu + * + * \param gwin struct gui_window_2 * + * \returns pointer to menu (for convenience, is also stored in gwin structure) + * The returned pointer MUST be disposed of with DisposeObject before program exit. + */ +struct Menu *ami_ctxmenu_clicktab_create(struct gui_window_2 *gwin); + +#else +inline void ami_ctxmenu_init(void) {} +inline void ami_ctxmenu_free(void) {} +inline struct Hook *ami_ctxmenu_get_hook(APTR data) {return NULL;} +inline void ami_ctxmenu_release_hook(struct Hook *hook) {} +inline struct Menu *ami_ctxmenu_history_create(int direction, struct gui_window_2 *gwin) {return NULL;} +#endif diff --git a/amiga/gui.c b/amiga/gui.c index aa84b52a5..47bd2c715 100644 --- a/amiga/gui.c +++ b/amiga/gui.c @@ -1,5 +1,5 @@ /* - * Copyright 2008-2014 Chris Young <chris@unsatisfactorysoftware.co.uk> + * Copyright 2008-2015 Chris Young <chris@unsatisfactorysoftware.co.uk> * * This file is part of NetSurf, http://www.netsurf-browser.org/ * @@ -34,9 +34,6 @@ #include <proto/intuition.h> #include <proto/keymap.h> #include <proto/locale.h> -#ifdef __amigaos4__ -#include <proto/popupmenu.h> -#endif #include <proto/utility.h> #include <proto/wb.h> @@ -119,8 +116,8 @@ #include "amiga/arexx.h" #include "amiga/bitmap.h" #include "amiga/clipboard.h" -#include "amiga/context_menu.h" #include "amiga/cookies.h" +#include "amiga/ctxmenu.h" #include "amiga/datatypes.h" #include "amiga/download.h" #include "amiga/drag.h" @@ -144,6 +141,7 @@ #include "amiga/print.h" #include "amiga/schedule.h" #include "amiga/search.h" +#include "amiga/selectmenu.h" #include "amiga/theme.h" #include "amiga/tree.h" #include "amiga/utf8.h" @@ -541,9 +539,8 @@ static nserror ami_set_options(struct nsoption_s *defaults) STRPTR tempacceptlangs; char temp[1024]; - /* The following line disables the popupmenu.class select menu - ** This will become a user option when/if popupmenu.class is - ** updated to show more items than can fit in one column vertically + /* The following line disables the popupmenu.class select menu. + ** It's not recommended to use it! */ nsoption_set_bool(core_select_menu, true); @@ -626,9 +623,6 @@ static nserror ami_set_options(struct nsoption_s *defaults) } } - if(popupmenu_lib_ok == FALSE) - nsoption_set_bool(context_menu, false); - #ifndef __amigaos4__ nsoption_set_bool(download_notify, false); nsoption_set_bool(font_antialiasing, false); @@ -1102,6 +1096,10 @@ static void ami_update_buttons(struct gui_window_2 *gwin) SetGadgetAttrs((struct Gadget *)gwin->objects[GID_CLOSETAB], gwin->win, NULL, GA_Disabled, tabclose, TAG_DONE); } + + /* Update the back/forward buttons history context menu */ + ami_ctxmenu_history_create(AMI_CTXMENU_HISTORY_BACK, gwin); + ami_ctxmenu_history_create(AMI_CTXMENU_HISTORY_FORWARD, gwin); } void ami_gui_history(struct gui_window_2 *gwin, bool back) @@ -1317,7 +1315,7 @@ static bool ami_spacebox_to_ns_coords(struct gui_window_2 *gwin, int *x, int *y, return true; } -static bool ami_mouse_to_ns_coords(struct gui_window_2 *gwin, int *x, int *y, +bool ami_mouse_to_ns_coords(struct gui_window_2 *gwin, int *x, int *y, int mouse_x, int mouse_y) { int ns_x, ns_y; @@ -1918,7 +1916,6 @@ static void ami_handle_msg(void) if((x>=xs) && (y>=ys) && (x<width+xs) && (y<height+ys)) { ami_update_quals(gwin); - ami_context_menu_mouse_trap(gwin, TRUE); if(gwin->mouse_state & BROWSER_MOUSE_PRESS_1) { @@ -1934,11 +1931,7 @@ static void ami_handle_msg(void) { browser_window_mouse_track(gwin->gw->bw,gwin->mouse_state | gwin->key_state,x,y); } - } - else - { - ami_context_menu_mouse_trap(gwin, FALSE); - + } else { if(!gwin->mouse_state) ami_set_pointer(gwin, GUI_POINTER_DEFAULT, true); } break; @@ -1988,10 +1981,6 @@ static void ami_handle_msg(void) switch(code) { - case MENUDOWN: - ami_context_menu_show(gwin,x,y); - break; - case SELECTUP: if(gwin->mouse_state & BROWSER_MOUSE_PRESS_1) { @@ -2265,104 +2254,10 @@ static void ami_handle_msg(void) if((ie->ie_Qualifier & IEQUALIFIER_RCOMMAND) && ((31 < nskey) && (nskey < 127))) { - /* We are duplicating the menu shortcuts here, as if RMBTRAP is - * active (ie. when context menus are enabled and the mouse is over - * the browser rendering area), Intuition also does not catch the - * menu shortcut key presses. Context menus possibly need to be - * changed to use MENUVERIFY not RMBTRAP. - * NB: Some keypresses are converted to generic keypresses above - * rather than being "menu-emulated" here. - */ + /* NB: Some keypresses are converted to generic keypresses above + * rather than being "menu-emulated" here. */ switch(nskey) { - case 'n': - if ((nsoption_bool(kiosk_mode) == false)) { - nsurl *urlns; - nserror error; - - error = nsurl_create(nsoption_charp(homepage_url), &urlns); - if (error == NSERROR_OK) { - error = browser_window_create(BW_CREATE_CLONE | BW_CREATE_HISTORY, - urlns, - NULL, - gwin->gw->bw, - NULL); - nsurl_unref(urlns); - } - if (error != NSERROR_OK) { - warn_user(messages_get_errorcode(error), 0); - } - - } - break; - - case 't': - if((nsoption_bool(kiosk_mode) == false)) { - nsurl *urlns; - nserror error; - - error = nsurl_create(nsoption_charp(homepage_url), &urlns); - if (error == NSERROR_OK) { - error = browser_window_create(BW_CREATE_CLONE | BW_CREATE_HISTORY | - BW_CREATE_TAB, - urlns, - NULL, - gwin->gw->bw, - NULL); - nsurl_unref(urlns); - } - if (error != NSERROR_OK) { - warn_user(messages_get_errorcode(error), 0); - } - - } - break; - - case 'k': - if((nsoption_bool(kiosk_mode) == false)) - browser_window_destroy(gwin->gw->bw); - break; - - case 'o': - ami_file_open(gwin); - break; - - case 's': - ami_file_save_req(AMINS_SAVE_SOURCE, gwin, - browser_window_get_content(gwin->gw->bw)); - break; - - case 'p': - ami_print_ui(browser_window_get_content(gwin->gw->bw)); - break; - - case 'q': - if((nsoption_bool(kiosk_mode) == false)) - ami_quit_netsurf(); - break; - - case 'f': - ami_search_open(gwin->gw); - break; - - case 'h': - if((nsoption_bool(kiosk_mode) == false)) - ami_tree_open(hotlist_window, AMI_TREE_HOTLIST); - break; - - case '-': - if(gwin->gw->scale > 0.1) - ami_gui_set_scale(gwin->gw, gwin->gw->scale - 0.1); - break; - - case '=': - ami_gui_set_scale(gwin->gw, 1.0); - break; - - case '+': - ami_gui_set_scale(gwin->gw, gwin->gw->scale + 0.1); - break; - /* The following aren't available from the menu at the moment */ case 'r': // reload @@ -3037,7 +2932,7 @@ static void gui_quit(void) if(nsscreentitle) FreeVec(nsscreentitle); LOG("Freeing menu items"); - ami_context_menu_free(); + ami_ctxmenu_free(); ami_menu_free_glyphs(); LOG("Freeing mouse pointers"); @@ -3314,6 +3209,7 @@ static void ami_toggletabbar(struct gui_window_2 *gwin, bool show) GA_ID, GID_TABS, GA_RelVerify, TRUE, GA_Underscore, 13, // disable kb shortcuts + GA_ContextMenu, ami_ctxmenu_clicktab_create(gwin), CLICKTAB_Labels, &gwin->tab_list, CLICKTAB_LabelTruncate, TRUE, CLICKTAB_CloseImage, gwin->objects[GID_CLOSETAB_BM], @@ -3849,7 +3745,7 @@ gui_window_create(struct browser_window *bw, } ami_NewMinList(&g->shared->shared_pens); - + g->shared->scrollerhook.h_Entry = (void *)ami_scroller_hook; g->shared->scrollerhook.h_Data = g->shared; @@ -3861,6 +3757,11 @@ gui_window_create(struct browser_window *bw, newprefs_hook.h_Entry = (void *)ami_gui_newprefs_hook; newprefs_hook.h_Data = 0; + + g->shared->ctxmenu_hook = ami_ctxmenu_get_hook(g->shared); + g->shared->history_ctxmenu[AMI_CTXMENU_HISTORY_BACK] = NULL; + g->shared->history_ctxmenu[AMI_CTXMENU_HISTORY_FORWARD] = NULL; + g->shared->clicktab_ctxmenu = NULL; if(nsoption_bool(window_simple_refresh) == true) { refresh_mode = WA_SimpleRefresh; @@ -4024,6 +3925,7 @@ gui_window_create(struct browser_window *bw, WA_ReportMouse,TRUE, refresh_mode, TRUE, WA_SizeBBottom, TRUE, + WA_ContextMenuHook, g->shared->ctxmenu_hook, WA_IDCMP, IDCMP_MENUPICK | IDCMP_MOUSEMOVE | IDCMP_MOUSEBUTTONS | IDCMP_NEWSIZE | IDCMP_RAWKEY | idcmp_sizeverify | @@ -4051,9 +3953,10 @@ gui_window_create(struct browser_window *bw, LAYOUT_AddChild, g->shared->objects[GID_TOOLBARLAYOUT] = LayoutHObj, LAYOUT_VertAlignment, LALIGN_CENTER, LAYOUT_AddChild, g->shared->objects[GID_BACK] = ButtonObj, - GA_ID,GID_BACK, - GA_RelVerify,TRUE, - GA_Disabled,TRUE, + GA_ID, GID_BACK, + GA_RelVerify, TRUE, + GA_Disabled, TRUE, + GA_ContextMenu, ami_ctxmenu_history_create(AMI_CTXMENU_HISTORY_BACK, g->shared), GA_HintInfo, g->shared->helphints[GID_BACK], BUTTON_RenderImage,BitMapObj, BITMAP_SourceFile,nav_west, @@ -4066,9 +3969,10 @@ gui_window_create(struct browser_window *bw, CHILD_WeightedWidth,0, CHILD_WeightedHeight,0, LAYOUT_AddChild, g->shared->objects[GID_FORWARD] = ButtonObj, - GA_ID,GID_FORWARD, - GA_RelVerify,TRUE, - GA_Disabled,TRUE, + GA_ID, GID_FORWARD, + GA_RelVerify, TRUE, + GA_Disabled, TRUE, + GA_ContextMenu, ami_ctxmenu_history_create(AMI_CTXMENU_HISTORY_FORWARD, g->shared), GA_HintInfo, g->shared->helphints[GID_FORWARD], BUTTON_RenderImage,BitMapObj, BITMAP_SourceFile,nav_east, @@ -4423,8 +4327,7 @@ static void gui_window_destroy(struct gui_window *g) cur_gw = NULL; - if(g->shared->tabs > 1) - { + if(g->shared->tabs > 1) { SetGadgetAttrs((struct Gadget *)g->shared->objects[GID_TABS],g->shared->win,NULL, CLICKTAB_Labels,~0, TAG_DONE); @@ -4467,7 +4370,6 @@ static void gui_window_destroy(struct gui_window *g) DisposeObject(g->shared->objects[OID_MAIN]); ami_gui_appicon_remove(g->shared); if(g->shared->appwin) RemoveAppWindow(g->shared->appwin); - ami_gui_hotlist_toolbar_free(g->shared, &g->shared->hotlist_toolbar_list); /* These aren't freed by the above. @@ -4481,6 +4383,11 @@ static void gui_window_destroy(struct gui_window *g) ami_gui_opts_websearch_free(g->shared->web_search_list); if(g->shared->search_bm) DisposeObject(g->shared->search_bm); + /* This appears to be disposed along with the ClickTab object + if(g->shared->clicktab_ctxmenu) DisposeObject((Object *)g->shared->clicktab_ctxmenu); */ + DisposeObject((Object *)g->shared->history_ctxmenu[AMI_CTXMENU_HISTORY_BACK]); + DisposeObject((Object *)g->shared->history_ctxmenu[AMI_CTXMENU_HISTORY_FORWARD]); + ami_ctxmenu_release_hook(g->shared->ctxmenu_hook); ami_free_menulabs(g->shared); #ifndef __amigaos4__ ami_menu_free_os3(g->shared); @@ -4493,8 +4400,7 @@ static void gui_window_destroy(struct gui_window *g) free(g->shared->helphints[gid]); DelObject(g->shared->node); - if(g->tab_node) - { + if(g->tab_node) { Remove(g->tab_node); FreeClickTabNode(g->tab_node); } @@ -5446,19 +5352,6 @@ int main(int argc, char** argv) /* Open splash window */ Object *splash_window = ami_gui_splash_open(); - /* Open popupmenu.library just to check the version. - * Versions older than 53.11 are dangerous, so we - * forcibly disable context menus if these are in use. - */ - popupmenu_lib_ok = FALSE; -#ifdef __amigaos4__ - if((PopupMenuBase = OpenLibrary("popupmenu.library", 53))) { - LOG("popupmenu.library v%d.%d", PopupMenuBase->lib_Version, PopupMenuBase->lib_Revision); - if(LIB_IS_AT_LEAST((struct Library *)PopupMenuBase, 53, 11)) - popupmenu_lib_ok = TRUE; - CloseLibrary(PopupMenuBase); - } -#endif if (ami_open_resources() == false) { /* alloc message ports */ ami_misc_fatal_error("Unable to allocate resources"); return RETURN_FAIL; @@ -5523,7 +5416,6 @@ int main(int argc, char** argv) ami_openurl_open(); ami_amiupdate(); /* set env-vars for AmiUpdate */ ami_init_fonts(); - ami_context_menu_init(); save_complete_init(); ami_theme_init(); ami_init_mouse_pointers(); @@ -5539,6 +5431,8 @@ int main(int argc, char** argv) gui_init2(argc, argv); + ami_ctxmenu_init(); /* Requires screen pointer */ + ami_gui_splash_close(splash_window); strlcpy(script, nsoption_charp(arexx_dir), 1024); diff --git a/amiga/gui.h b/amiga/gui.h index adad63d4f..6348884ce 100755..100644 --- a/amiga/gui.h +++ b/amiga/gui.h @@ -1,5 +1,5 @@ /* - * Copyright 2008-2014 Chris Young <chris@unsatisfactorysoftware.co.uk> + * Copyright 2008-2015 Chris Young <chris@unsatisfactorysoftware.co.uk> * * This file is part of NetSurf, http://www.netsurf-browser.org/ * @@ -18,15 +18,16 @@ #ifndef AMIGA_GUI_H #define AMIGA_GUI_H - +#include <stdbool.h> #include <graphics/rastport.h> -#include "amiga/object.h" #include <intuition/classusr.h> #include <dos/dos.h> #include <devices/inputevent.h> +#include "amiga/menu.h" +#include "amiga/object.h" #include "amiga/os3support.h" #include "amiga/plotters.h" -#include "amiga/menu.h" +#include "desktop/gui_window.h" #ifdef __amigaos4__ #define HOOKF(ret,func,type,ptr,msgtype) static ret func(struct Hook *hook, type ptr, msgtype msg) @@ -131,6 +132,9 @@ struct gui_window_2 { struct DiskObject *dobj; /* iconify appicon */ struct Hook favicon_hook; struct Hook throbber_hook; + struct Hook *ctxmenu_hook; + Object *history_ctxmenu[2]; + Object *clicktab_ctxmenu; gui_drag_type drag_op; struct IBox *ptr_lock; struct AppWindow *appwin; @@ -173,6 +177,8 @@ void ami_schedule_redraw(struct gui_window_2 *gwin, bool full_redraw); STRPTR ami_locale_langs(void); int ami_key_to_nskey(ULONG keycode, struct InputEvent *ie); bool ami_text_box_at_point(struct gui_window_2 *gwin, ULONG *x, ULONG *y); +bool ami_mouse_to_ns_coords(struct gui_window_2 *gwin, int *x, int *y, + int mouse_x, int mouse_y); BOOL ami_gadget_hit(Object *obj, int x, int y); void ami_gui_history(struct gui_window_2 *gwin, bool back); void ami_gui_hotlist_update_all(void); @@ -220,6 +226,5 @@ struct MsgPort *sport; struct gui_window *cur_gw; struct gui_globals browserglob; BOOL ami_autoscroll; -BOOL popupmenu_lib_ok; #endif diff --git a/amiga/gui_options.c b/amiga/gui_options.c index 42ee09a5b..cfa78e8ca 100755 --- a/amiga/gui_options.c +++ b/amiga/gui_options.c @@ -71,6 +71,7 @@ #include "amiga/libs.h" #include "amiga/misc.h" #include "amiga/object.h" +#include "amiga/selectmenu.h" #include "amiga/theme.h" #include "amiga/utf8.h" @@ -132,7 +133,7 @@ enum GID_OPTS_TAB_CLOSE, GID_OPTS_SEARCH_PROV, GID_OPTS_CLIPBOARD, - GID_OPTS_CONTEXTMENU, + GID_OPTS_SELECTMENU, GID_OPTS_STARTUP_NO_WIN, GID_OPTS_CLOSE_NO_QUIT, GID_OPTS_DOCKY, @@ -328,7 +329,7 @@ static void ami_gui_opts_setup(struct ami_gui_opts_window *gow) gadlab[GID_OPTS_TAB_CLOSE] = (char *)ami_utf8_easy((char *)messages_get("TabClose")); gadlab[GID_OPTS_SEARCH_PROV] = (char *)ami_utf8_easy((char *)messages_get("SearchProvider")); gadlab[GID_OPTS_CLIPBOARD] = (char *)ami_utf8_easy((char *)messages_get("ClipboardUTF8")); - gadlab[GID_OPTS_CONTEXTMENU] = (char *)ami_utf8_easy((char *)messages_get("ContextMenu")); + gadlab[GID_OPTS_SELECTMENU] = (char *)ami_utf8_easy((char *)messages_get("PopupMenu")); gadlab[GID_OPTS_STARTUP_NO_WIN] = (char *)ami_utf8_easy((char *)messages_get("OptionNoWindow")); gadlab[GID_OPTS_CLOSE_NO_QUIT] = (char *)ami_utf8_easy((char *)messages_get("OptionNoQuit")); gadlab[GID_OPTS_DOCKY] = (char *)ami_utf8_easy((char *)messages_get("OptionDocky")); @@ -1360,22 +1361,22 @@ void ami_gui_opts_open(void) LAYOUT_BevelStyle, BVS_GROUP, LAYOUT_Label, gadlab[GRP_OPTS_MISC], LAYOUT_SpaceOuter, TRUE, -#ifdef __amigaos4__ - LAYOUT_AddChild, gow->objects[GID_OPTS_CONTEXTMENU] = CheckBoxObj, - GA_ID, GID_OPTS_CONTEXTMENU, - GA_RelVerify, TRUE, - GA_Text, gadlab[GID_OPTS_CONTEXTMENU], - GA_Selected, nsoption_bool(context_menu), - GA_Disabled, !popupmenu_lib_ok, - CheckBoxEnd, -#endif LAYOUT_AddChild, gow->objects[GID_OPTS_FASTSCROLL] = CheckBoxObj, GA_ID, GID_OPTS_FASTSCROLL, GA_RelVerify, TRUE, GA_Text, gadlab[GID_OPTS_FASTSCROLL], GA_Selected, nsoption_bool(faster_scroll), CheckBoxEnd, - LayoutEnd, // context menus +#ifdef __amigaos4__ + LAYOUT_AddChild, gow->objects[GID_OPTS_SELECTMENU] = CheckBoxObj, + GA_ID, GID_OPTS_SELECTMENU, + GA_RelVerify, TRUE, + GA_Text, gadlab[GID_OPTS_SELECTMENU], + GA_Selected, !nsoption_bool(core_select_menu), + GA_Disabled, !ami_selectmenu_is_safe(), + CheckBoxEnd, +#endif + LayoutEnd, // misc CHILD_WeightedHeight, 0, LayoutEnd, // page vgroup @@ -1855,11 +1856,11 @@ static void ami_gui_opts_use(bool save) nsoption_set_bool(clipboard_write_utf8, false); } - GetAttr(GA_Selected,gow->objects[GID_OPTS_CONTEXTMENU],(ULONG *)&data); + GetAttr(GA_Selected,gow->objects[GID_OPTS_SELECTMENU],(ULONG *)&data); if (data) { - nsoption_set_bool(context_menu, true); + nsoption_set_bool(core_select_menu, false); } else { - nsoption_set_bool(context_menu, false); + nsoption_set_bool(core_select_menu, true); } GetAttr(GA_Selected,gow->objects[GID_OPTS_STARTUP_NO_WIN],(ULONG *)&data); diff --git a/amiga/menu.c b/amiga/menu.c index 571f411fd..c4e0a51d7 100644 --- a/amiga/menu.c +++ b/amiga/menu.c @@ -561,7 +561,7 @@ static void ami_menu_alloc_item(struct gui_window_2 *gwin, int num, UBYTE type, gwin->menulab[num] = ami_utf8_easy(messages_get(label)); } } - + gwin->menuicon[num] = NULL; if(key) gwin->menukey[num] = key; if(func) gwin->menu_hook[num].h_Entry = (HOOKFUNC)func; diff --git a/amiga/options.h b/amiga/options.h index b28a4f0a2..317e5dfdc 100644 --- a/amiga/options.h +++ b/amiga/options.h @@ -34,7 +34,6 @@ NSOPTION_INTEGER(screen_ydpi, 85) NSOPTION_INTEGER(cache_bitmaps, 0) NSOPTION_STRING(theme, "PROGDIR:Resources/Themes/Default") NSOPTION_BOOL(clipboard_write_utf8, false) -NSOPTION_BOOL(context_menu, true) NSOPTION_BOOL(truecolour_mouse_pointers, false) NSOPTION_BOOL(os_mouse_pointers, true) NSOPTION_BOOL(use_openurl_lib, false) diff --git a/amiga/os3support.h b/amiga/os3support.h index ac7f31590..45a917a46 100644 --- a/amiga/os3support.h +++ b/amiga/os3support.h @@ -73,6 +73,7 @@ #define GETFONT_ScalableOnly TAG_IGNORE #define PDTA_PromoteMask TAG_IGNORE #define RPTAG_APenColor TAG_IGNORE +#define GA_ContextMenu TAG_IGNORE #define GA_HintInfo TAG_IGNORE #define GAUGEIA_Level TAG_IGNORE #define IA_InBorder TAG_IGNORE @@ -81,6 +82,7 @@ #define SBNA_Text TAG_IGNORE #define TNA_CloseGadget TAG_IGNORE #define TNA_HintInfo TAG_IGNORE +#define WA_ContextMenuHook TAG_IGNORE #define WA_ToolBox TAG_IGNORE #define WINDOW_BuiltInScroll TAG_IGNORE #define WINDOW_NewMenu TAG_IGNORE diff --git a/amiga/selectmenu.c b/amiga/selectmenu.c new file mode 100644 index 000000000..e6eae2a99 --- /dev/null +++ b/amiga/selectmenu.c @@ -0,0 +1,150 @@ +/* + * Copyright 2008 - 2011 Chris Young <chris@unsatisfactorysoftware.co.uk> + * + * 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 <http://www.gnu.org/licenses/>. + */ + +#ifdef __amigaos4__ + +#include <stdbool.h> +#include <proto/exec.h> +#include <proto/intuition.h> +#include <proto/popupmenu.h> +#include <proto/utility.h> +#include <reaction/reaction_macros.h> + +#include "utils/errors.h" +#include "utils/log.h" +#include "render/form.h" +#include "desktop/mouse.h" + +#include "amiga/gui.h" +#include "amiga/selectmenu.h" +#include "amiga/theme.h" +#include "amiga/utf8.h" + +/* Maximum number of items for a popupmenu.class select menu. + * 50 is about the limit for my screen, and popupmenu doesn't scroll. + */ +#define AMI_SELECTMENU_MAX 50 + +/** Exported interface documented in selectmenu.h **/ +BOOL ami_selectmenu_is_safe(void) +{ + struct Library *PopupMenuBase; + BOOL popupmenu_lib_ok = FALSE; + + if((PopupMenuBase = OpenLibrary("popupmenu.library", 53))) { + LOG("popupmenu.library v%d.%d", PopupMenuBase->lib_Version, PopupMenuBase->lib_Revision); + if(LIB_IS_AT_LEAST((struct Library *)PopupMenuBase, 53, 11)) + popupmenu_lib_ok = TRUE; + CloseLibrary(PopupMenuBase); + } + + return popupmenu_lib_ok; +} + +HOOKF(uint32, ami_popup_hook, Object *, item, APTR) +{ + uint32 itemid = 0; + struct gui_window *gwin = hook->h_Data; + + if(GetAttr(PMIA_ID, item, &itemid)) { + form_select_process_selection(gwin->shared->control, itemid); + } + + return itemid; +} + +void gui_create_form_select_menu(struct gui_window *g, + struct form_control *control) +{ + struct Library *PopupMenuBase = NULL; + struct PopupMenuIFace *IPopupMenu = NULL; + struct Hook selectmenuhook; + Object *selectmenuobj; + char *selectmenu_item[AMI_SELECTMENU_MAX]; + struct form_option *opt = form_select_get_option(control, 0); + ULONG i = 0; + + if(ami_selectmenu_is_safe() == FALSE) return; + + if((PopupMenuBase = OpenLibrary("popupmenu.class", 0))) { + IPopupMenu = (struct PopupMenuIFace *)GetInterface(PopupMenuBase, "main", 1, NULL); + } + + if(IPopupMenu == NULL) return; + + ClearMem(selectmenu_item, AMI_SELECTMENU_MAX * 4); + + selectmenuhook.h_Entry = ami_popup_hook; + selectmenuhook.h_SubEntry = NULL; + selectmenuhook.h_Data = g; + + g->shared->control = control; + + selectmenuobj = PMMENU(form_control_get_name(control)), + PMA_MenuHandler, &selectmenuhook, End; + + while(opt) { + selectmenu_item[i] = ami_utf8_easy(opt->text); + + IDoMethod(selectmenuobj, PM_INSERT, + NewObject(POPUPMENU_GetItemClass(), NULL, + PMIA_Title, (ULONG)selectmenu_item[i], + PMIA_ID, i, + PMIA_CheckIt, TRUE, + PMIA_Checked, opt->selected, + TAG_DONE), + ~0); + + opt = opt->next; + i++; + + if(i >= AMI_SELECTMENU_MAX) break; + } + + ami_set_pointer(g->shared, GUI_POINTER_DEFAULT, false); // Clear the menu-style pointer + + IDoMethod(selectmenuobj, PM_OPEN, g->shared->win); + + /* PM_OPEN is blocking, so dispose menu immediately... */ + if(selectmenuobj) DisposeObject(selectmenuobj); + + /* ...and get rid of popupmenu.class ASAP */ + if(IPopupMenu) DropInterface((struct Interface *)IPopupMenu); + if(PopupMenuBase) CloseLibrary(PopupMenuBase); + + /* Free the menu labels */ + for(i = 0; i < AMI_SELECTMENU_MAX; i++) { + if(selectmenu_item[i] != NULL) { + ami_utf8_free(selectmenu_item[i]); + selectmenu_item[i] = NULL; + } + } +} + +#else +#include "amiga/selectmenu.h" +void gui_create_form_select_menu(struct gui_window *g, struct form_control *control) +{ +} + +BOOL ami_selectmenu_is_safe() +{ + return FALSE; +} +#endif + diff --git a/amiga/context_menu.h b/amiga/selectmenu.h index 5697b5611..760f58997 100755 --- a/amiga/context_menu.h +++ b/amiga/selectmenu.h @@ -16,20 +16,22 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ -#ifndef AMIGA_CONTEXT_MENU_H -#define AMIGA_CONTEXT_MENU_H +#ifndef AMIGA_SELECTMENU_H +#define AMIGA_SELECTMENU_H -struct tree; struct gui_window; -struct gui_window_2; struct form_control; -void ami_context_menu_init(void); -void ami_context_menu_free(void); -BOOL ami_context_menu_mouse_trap(struct gui_window_2 *gwin, BOOL trap); -void ami_context_menu_show(struct gui_window_2 *gwin, int x, int y); +BOOL popupmenu_lib_ok; void gui_create_form_select_menu(struct gui_window *g, struct form_control *control); +/** + * Opens popupmenu.library to check the version. + * Versions older than 53.11 are dangerous! + * + * \returns TRUE if popupmenu is safe, FALSE otherwise. + */ +BOOL ami_selectmenu_is_safe(void); #endif diff --git a/desktop/gui_window.h b/desktop/gui_window.h index 7ecd3c21d..7f542ff7b 100644 --- a/desktop/gui_window.h +++ b/desktop/gui_window.h @@ -63,6 +63,7 @@ struct hlcache_handle; struct nsurl; enum gui_pointer_shape; +enum nserror; /** * Graphical user interface window function table. diff --git a/render/form.h b/render/form.h index 44f383960..744ac32e7 100644 --- a/render/form.h +++ b/render/form.h @@ -26,6 +26,7 @@ #define _NETSURF_RENDER_FORM_H_ struct form_control; +struct rect; /** Option in a select. */ struct form_option { diff --git a/resources/FatMessages b/resources/FatMessages index fa661255a..765f037c2 100644 --- a/resources/FatMessages +++ b/resources/FatMessages @@ -6159,6 +6159,11 @@ de.ami.OptionDocky:In AmiDock zeigen fr.ami.OptionDocky:Afficher dans AmiDock it.ami.OptionDocky:Mostra icona di NetSurf su AmiDock nl.ami.OptionDocky:Show in AmiDock +en.ami.PopupMenu:Use popupmenu for forms +de.ami.PopupMenu:Use popupmenu for forms +fr.ami.PopupMenu:Use popupmenu for forms +it.ami.PopupMenu:Use popupmenu for forms +nl.ami.PopupMenu:Use popupmenu for forms en.all.Clipboard:Clipboard de.all.Clipboard:Clipboard fr.all.Clipboard:Presse-papiers |