summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Young <chris@unsatisfactorysoftware.co.uk>2015-09-05 16:38:48 +0100
committerChris Young <chris@unsatisfactorysoftware.co.uk>2015-09-05 16:38:48 +0100
commit1a8cf5b7a7e9982c859364638e6ae4b6ed1cfd93 (patch)
tree25a05797dd3cbcb1ea60966dee4ec301b38db666
parent2e4bfc5dc3ae3d6c13fbc6f956b611354ed37257 (diff)
parent5b880e586c9358db0ae86bb95edb2559f16d5da4 (diff)
downloadnetsurf-1a8cf5b7a7e9982c859364638e6ae4b6ed1cfd93.tar.gz
netsurf-1a8cf5b7a7e9982c859364638e6ae4b6ed1cfd93.tar.bz2
Merge branch 'chris/menuclass'
This replaces the old popupmenu.class-based context menus with Intuition-based ones. This provides the following advantages: - No more RMBTrap, so menu shortcuts work without having to be manually handled - Standard menus now display when not over a contextual zone, so the not-really-contextual menu items have been removed - No buggy system crash problems, so they are always enabled now - Menus can be attached directly to gadgets, so the history menu is now attached directly to the back/forward buttons (however they now need to be periodically refreshed as they can't be created on demand) Additionally, the menu items now have images. popupmenu.class is now only used (optionally) for form select menus. This code has been bug-fixed and is now toggleable from the prefs GUI. However, due to the inability to display more items than fit on the screen, it still isn't recommended to use it.
-rw-r--r--amiga/Makefile.target5
-rwxr-xr-xamiga/bitmap.h1
-rw-r--r--amiga/clipboard.c2
-rwxr-xr-xamiga/clipboard.h2
-rw-r--r--amiga/context_menu.c1340
-rw-r--r--amiga/ctxmenu.c557
-rw-r--r--amiga/ctxmenu.h89
-rw-r--r--amiga/gui.c184
-rw-r--r--[-rwxr-xr-x]amiga/gui.h15
-rwxr-xr-xamiga/gui_options.c31
-rw-r--r--amiga/menu.c2
-rw-r--r--amiga/options.h1
-rw-r--r--amiga/os3support.h2
-rw-r--r--amiga/selectmenu.c150
-rwxr-xr-xamiga/selectmenu.h (renamed from amiga/context_menu.h)18
-rw-r--r--desktop/gui_window.h1
-rw-r--r--render/form.h1
-rw-r--r--resources/FatMessages5
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