Complete (but quite minimal at the moment) context menu implementation for AmigaOS:

Links, objects and upload file boxes have their own menu item or submenu.

Context menus can be enable/disabled and be made "sticky" with the following options:
context_menu
sticky_context_menu

Seperated clipboard related code out to clipboard.c to make it easier to maintain and
add the ability to copy URLs to the clipboard.  Copying images to the clipboard will
come later.


svn path=/trunk/netsurf/; revision=5629
This commit is contained in:
Chris Young 2008-10-25 16:37:08 +00:00
parent 5624bf590d
commit 2f4beda48c
14 changed files with 188 additions and 199 deletions

View File

@ -253,6 +253,15 @@ Settings:Settings
SnapshotWindow:Snapshot window
SettingsSave:Save settings
# Context menu
#
Link:Link
LinkNewTab:Open in new tab
LinkNewWin:Open in new window
CopyURL:Copy URL to clipboard
ObjShow:Show object
SelectFile:Select file...
# Treeview interface tokens
# =========================
#

View File

@ -253,6 +253,15 @@ Settings:Settings
SnapshotWindow:Snapshot window
SettingsSave:Save settings
# Context menu
#
Link:Link
LinkNewTab:Open in new tab
LinkNewWin:Open in new window
CopyURL:Copy URL to clipboard
ObjShow:Show object
SelectFile:Select file...
# Treeview interface tokens
# =========================
#

View File

@ -253,6 +253,15 @@ Settings:Settings
SnapshotWindow:Snapshot window
SettingsSave:Save settings
# Context menu
#
Link:Link
LinkNewTab:Open in new tab
LinkNewWin:Open in new window
CopyURL:Copy URL to clipboard
ObjShow:Show object
SelectFile:Select file...
# Treeview interface tokens
# =========================
#

View File

@ -254,6 +254,15 @@ Settings:Impostazioni
SnapshotWindow:Fissa finestra
SettingsSave:Salva impostazioni
# Context menu
#
Link:Link
LinkNewTab:Open in new tab
LinkNewWin:Open in new window
CopyURL:Copy URL to clipboard
ObjShow:Show object
SelectFile:Select file...
# Treeview interface tokens
# =========================
#

View File

@ -253,6 +253,15 @@ Settings:Settings
SnapshotWindow:Snapshot window
SettingsSave:Save settings
# Context menu
#
Link:Link
LinkNewTab:Open in new tab
LinkNewWin:Open in new window
CopyURL:Copy URL to clipboard
ObjShow:Show object
SelectFile:Select file...
# Treeview interface tokens
# =========================
#

View File

@ -90,7 +90,7 @@ S_DEBUG := $(addprefix debug/,$(S_DEBUG))
S_AMIGA := compat.c gui.c tree.c history.c hotlist.c schedule.c \
thumbnail.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
cookies.c context_menu.c clipboard.c
S_AMIGA := $(addprefix amiga/,$(S_AMIGA))
# S_FRAMEBUFFER are sources purely for the framebuffer build

View File

@ -22,10 +22,51 @@
#include <proto/popupmenu.h>
#include <proto/intuition.h>
#include "amiga/utf8.h"
#include "utils/utf8.h"
#include "utils/messages.h"
#include "amiga/options.h"
#include "amiga/clipboard.h"
#include <proto/asl.h>
#include <proto/dos.h>
#include <string.h>
#include "utils/utils.h"
uint32 ami_context_menu_hook(struct Hook *hook,Object *item,APTR reserved);
char *ctxmenulab[CMID_LAST];
void ami_context_menu_init(void)
{
ctxmenulab[CMID_SELECTFILE] = ami_utf8_easy((char *)messages_get("SelectFile"));
ctxmenulab[CMID_COPYURL] = ami_utf8_easy((char *)messages_get("CopyURL"));
ctxmenulab[CMID_SHOWOBJ] = ami_utf8_easy((char *)messages_get("ObjShow"));
ctxmenulab[CMID_COPYOBJ] = ami_utf8_easy((char *)messages_get("CopyURL"));
if(!option_force_tabs)
{
ctxmenulab[CMID_URLOPENWIN] = ami_utf8_easy((char *)messages_get("LinkNewWin"));
ctxmenulab[CMID_URLOPENTAB] = ami_utf8_easy((char *)messages_get("LinkNewTab"));
}
else
{
ctxmenulab[CMID_URLOPENWIN] = ami_utf8_easy((char *)messages_get("LinkNewTab"));
ctxmenulab[CMID_URLOPENTAB] = ami_utf8_easy((char *)messages_get("LinkNewWin"));
}
ctxmenulab[CMSUB_OBJECT] = ami_utf8_easy((char *)messages_get("Object"));
ctxmenulab[CMSUB_URL] = ami_utf8_easy((char *)messages_get("Link"));
}
void ami_context_menu_free(void)
{
int i;
for(i=0;i<CMID_LAST;i++)
{
ami_utf8_free(ctxmenulab[i]);
}
}
void ami_context_menu_show(struct gui_window_2 *gwin,int x,int y)
{
struct box *curbox = gwin->bw->current_content->data.html.layout;
@ -52,18 +93,25 @@ void ami_context_menu_show(struct gui_window_2 *gwin,int x,int y)
{
IDoMethod(gwin->objects[OID_MENU],PM_INSERT,
NewObject(POPUPMENU_GetItemClass(), NULL,
PMIA_Title, (ULONG)ami_utf8_easy((char *)messages_get("CopyURL")),
PMIA_ID,CMID_COPYURL,
PMIA_UserData,curbox->href,
TAG_DONE),
~0);
IDoMethod(gwin->objects[OID_MENU],PM_INSERT,
NewObject(POPUPMENU_GetItemClass(), NULL,
PMIA_Title, (ULONG)ami_utf8_easy((char *)messages_get("SaveURL")),
PMIA_ID,CMID_SAVEURL,
PMIA_UserData,curbox->href,
PMIA_Title, (ULONG)ctxmenulab[CMSUB_URL],
PMSIMPLESUB,
PMA_AddItem,NewObject(POPUPMENU_GetItemClass(), NULL,
PMIA_Title, (ULONG)ctxmenulab[CMID_URLOPENWIN],
PMIA_ID,CMID_URLOPENWIN,
PMIA_UserData,curbox->href,
TAG_DONE),
PMA_AddItem,NewObject(POPUPMENU_GetItemClass(), NULL,
PMIA_Title, (ULONG)ctxmenulab[CMID_URLOPENTAB],
PMIA_ID,CMID_URLOPENTAB,
PMIA_UserData,curbox->href,
TAG_DONE),
PMA_AddItem,NewObject(POPUPMENU_GetItemClass(), NULL,
PMIA_Title, (ULONG)ctxmenulab[CMID_COPYURL],
PMIA_ID,CMID_COPYURL,
PMIA_UserData,curbox->href,
TAG_DONE),
TAG_DONE),
TAG_DONE),
~0);
}
@ -71,20 +119,21 @@ void ami_context_menu_show(struct gui_window_2 *gwin,int x,int y)
{
IDoMethod(gwin->objects[OID_MENU],PM_INSERT,
NewObject(POPUPMENU_GetItemClass(), NULL,
PMIA_Title, (ULONG)ami_utf8_easy((char *)messages_get("ObjShow")),
PMIA_ID,CMID_SHOWOBJ,
PMIA_UserData,curbox->object->url,
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,curbox->object->url,
TAG_DONE),
PMA_AddItem,NewObject(POPUPMENU_GetItemClass(), NULL,
PMIA_Title, (ULONG)ctxmenulab[CMID_COPYOBJ],
PMIA_ID,CMID_COPYOBJ,
PMIA_UserData,curbox->object->url,
TAG_DONE),
TAG_DONE),
TAG_DONE),
~0);
IDoMethod(gwin->objects[OID_MENU],PM_INSERT,
NewObject(POPUPMENU_GetItemClass(), NULL,
PMIA_Title, (ULONG)ami_utf8_easy((char *)messages_get("ObjSave")),
PMIA_ID,CMID_SAVEOBJ,
PMIA_UserData,curbox->object->url,
TAG_DONE),
~0);
}
if (curbox->gadget)
@ -94,9 +143,9 @@ void ami_context_menu_show(struct gui_window_2 *gwin,int x,int y)
case GADGET_FILE:
IDoMethod(gwin->objects[OID_MENU],PM_INSERT,
NewObject(POPUPMENU_GetItemClass(), NULL,
PMIA_Title, (ULONG)ami_utf8_easy((char *)messages_get("SelectFile")),
PMIA_Title, (ULONG)ctxmenulab[CMID_SELECTFILE],
PMIA_ID,CMID_SELECTFILE,
PMIA_UserData,curbox->gadget,
PMIA_UserData,curbox,
TAG_DONE),
~0);
break;
@ -113,6 +162,7 @@ uint32 ami_context_menu_hook(struct Hook *hook,Object *item,APTR reserved)
int32 itemid = 0;
struct gui_window_2 *gwin = hook->h_Data;
APTR userdata = NULL;
struct browser_window *bw;
if(GetAttrs(item,PMIA_ID,&itemid,
PMIA_UserData,&userdata,
@ -121,20 +171,51 @@ uint32 ami_context_menu_hook(struct Hook *hook,Object *item,APTR reserved)
switch(itemid)
{
case CMID_SELECTFILE:
printf("select file - gadget %lx\n",userdata);
if(AslRequestTags(filereq,
ASLFR_TitleText,messages_get("NetSurf"),
ASLFR_Screen,scrn,
ASLFR_DoSaveMode,FALSE,
TAG_DONE))
{
struct box *box = userdata;
char *utf8_fn;
char fname[1024];
int x,y;
strlcpy(&fname,filereq->fr_Drawer,1024);
AddPart(fname,filereq->fr_File,1024);
if(utf8_from_local_encoding(fname,0,&utf8_fn) != UTF8_CONVERT_OK)
{
warn_user("NoMemory","");
break;
}
free(box->gadget->value);
box->gadget->value = utf8_fn;
box_coords(box, (int *)&x, (int *)&y);
gui_window_redraw(gwin->bw->window,x,y,
x + box->width,
y + box->height);
}
break;
case CMID_COPYURL:
printf("add to clipboard: %s\n",userdata);
case CMID_COPYOBJ:
ami_easy_clipboard((char *)userdata);
break;
case CMID_URLOPENWIN:
bw = browser_window_create(userdata,gwin->bw, gwin->bw->current_content->url, true, false);
break;
case CMID_URLOPENTAB:
bw = browser_window_create(userdata,gwin->bw, gwin->bw->current_content->url, true, true);
break;
case CMID_SHOWOBJ:
browser_window_go(gwin->bw,userdata,NULL,true);
break;
case CMID_SAVEOBJ:
case CMID_SAVEURL:
printf("download: %s\n",userdata);
browser_window_go(gwin->bw,userdata,gwin->bw->current_content->url,true);
break;
}
}

View File

@ -23,10 +23,16 @@
enum {
CMID_SELECTFILE,
CMID_COPYURL,
CMID_SAVEURL,
CMID_URLOPENWIN,
CMID_URLOPENTAB,
CMID_SHOWOBJ,
CMID_SAVEOBJ
CMID_COPYOBJ,
CMSUB_OBJECT,
CMSUB_URL,
CMID_LAST
};
void ami_context_menu_init(void);
void ami_context_menu_free(void);
void ami_context_menu_show(struct gui_window_2 *gwin,int x,int y);
#endif

View File

@ -34,7 +34,8 @@ The options file is stored in Resources/Options by default. The following optio
@{b}theme@{ub} Path to theme (default is Resources/Themes/Default - an alternative included theme is Resources/Themes/AISS)
@{b}no_iframes@{ub} Disable IFrames
@{b}clipboard_write_utf8@{ub} Write UTF-8 strings to the clipboard along with a charset identifier (when this option is 0, NetSurf will convert copied strings to local charset)
@{b}throbber_frames@{ub} Not used (now in theme description file)
@{b}context_menu@{ub} Enable context menus
@{b}sticky_context_menu@{ub} When disabled, context menu requires mouse button to be held down to keep it visible
@{b}truecolour_mouse_pointers@{ub} Use 32-bit mouse pointers, when disabled NetSurf will use old-style 4 colour images (see Resources/Pointers)
@{b}os_mouse_pointers@{ub} Don't override default and busy mouse pointers
@{b}always_open_tabs@{ub} Force opening tabs instead of windows (actually swaps the functions so ctrl-click now opens windows and middle mouse button opens tabs)

View File

@ -4,7 +4,7 @@ Author: NetSurf contributors (OS4 port by Chris Young)
Type: comm/www
Version: 2.0 development (SVN 5591)
Architecture: ppc-amigaos >= 4.0.0
Requires: AISS
Requires: AISS, dev/c/pthreads.lha
This is a preview release of the OS4 native port of NetSurf.
It is beta software, which means it is unstable and missing

View File

@ -39,8 +39,6 @@
#include <libraries/gadtools.h>
#include <proto/layers.h>
#include <proto/asl.h>
#include <proto/iffparse.h>
#include <datatypes/textclass.h>
#include <datatypes/pictureclass.h>
#include "desktop/selection.h"
#include "utils/utf8.h"
@ -53,12 +51,10 @@
#include <intuition/pointerclass.h>
#include <math.h>
#include <workbench/workbench.h>
#include "amiga/iff_cset.h"
#include <proto/datatypes.h>
#include <proto/icon.h>
#include <workbench/icon.h>
#include "amiga/tree.h"
#include <parserutils/charset/mibenum.h>
#include "utils/utils.h"
#include "amiga/login.h"
#include "utils/url.h"
@ -68,6 +64,7 @@
#include "amiga/history.h"
#include "amiga/context_menu.h"
#include "amiga/cookies.h"
#include "amiga/clipboard.h"
#ifdef WITH_HUBBUB
#include <hubbub/hubbub.h>
@ -112,7 +109,6 @@ ULONG throbber_width,throbber_height,throbber_frames;
BOOL rmbtrapped;
static struct RastPort dummyrp;
struct IFFHandle *iffh = NULL;
#define AMI_LASTPOINTER GUI_POINTER_PROGRESS+1
Object *mouseptrobj[AMI_LASTPOINTER+1];
@ -193,13 +189,7 @@ void gui_init(int argc, char** argv)
ami_arexx_init();
if(iffh = AllocIFF())
{
if(iffh->iff_Stream = OpenClipboard(0))
{
InitIFFasClip(iffh);
}
}
ami_clipboard_init();
win_destroyed = false;
@ -323,6 +313,7 @@ void gui_init(int argc, char** argv)
/* end Amiupdate */
ami_init_menulabs();
if(option_context_menu) ami_context_menu_init();
schedule_list = NewObjList();
window_list = NewObjList();
@ -571,7 +562,11 @@ void ami_handle_msg(void)
break;
case MENUDOWN:
ami_context_menu_show(gwin,x,y);
if(!option_sticky_context_menu) ami_context_menu_show(gwin,x,y);
break;
case MENUUP:
if(option_sticky_context_menu) ami_context_menu_show(gwin,x,y);
break;
}
}
@ -1053,6 +1048,8 @@ void gui_quit(void)
if(!option_use_wb) CloseScreen(scrn);
p96FreeBitMap(dummyrp.BitMap);
FreeVec(nsscreentitle);
if(option_context_menu) ami_context_menu_free();
ami_free_menulabs();
for(i=0;i<=AMI_LASTPOINTER;i++)
@ -1065,8 +1062,7 @@ void gui_quit(void)
}
}
if(iffh->iff_Stream) CloseClipboard((struct ClipboardHandle *)iffh->iff_Stream);
if(iffh) FreeIFF(iffh);
ami_clipboard_free();
ami_arexx_cleanup();
FreeSysObject(ASOT_PORT,appport);
@ -2425,150 +2421,6 @@ void gui_drag_save_object(gui_save_type type, struct content *c,
{
}
void gui_drag_save_selection(struct selection *s, struct gui_window *g)
{
}
void gui_start_selection(struct gui_window *g)
{
}
void gui_paste_from_clipboard(struct gui_window *g, int x, int y)
{
/* This and the other clipboard code is heavily based on the RKRM examples */
struct ContextNode *cn;
ULONG rlen=0,error;
struct CSet cset;
char *clip;
STRPTR readbuf = AllocVec(1024,MEMF_CLEAR);
cset.CodeSet = 0;
if(OpenIFF(iffh,IFFF_READ)) return;
if(StopChunk(iffh,ID_FTXT,ID_CHRS)) return;
if(StopChunk(iffh,ID_FTXT,ID_CSET)) return;
while(1)
{
error = ParseIFF(iffh,IFFPARSE_SCAN);
if(error == IFFERR_EOC) continue;
else if(error) break;
cn = CurrentChunk(iffh);
if((cn)&&(cn->cn_Type == ID_FTXT)&&(cn->cn_ID == ID_CSET))
{
rlen = ReadChunkBytes(iffh,&cset,24);
}
if((cn)&&(cn->cn_Type == ID_FTXT)&&(cn->cn_ID == ID_CHRS))
{
while((rlen = ReadChunkBytes(iffh,readbuf,1024)) > 0)
{
if(cset.CodeSet == 0)
{
utf8_from_local_encoding(readbuf,rlen,&clip);
}
else
{
utf8_from_enc(readbuf,parserutils_charset_mibenum_to_name(cset.CodeSet),rlen,&clip);
}
browser_window_paste_text(g->shared->bw,clip,rlen,true);
}
if(rlen < 0) error = rlen;
}
}
CloseIFF(iffh);
}
bool gui_empty_clipboard(void)
{
}
bool gui_add_to_clipboard(const char *text, size_t length, bool space)
{
char *buffer;
if(option_utf8_clipboard)
{
WriteChunkBytes(iffh,text,length);
}
else
{
utf8_to_local_encoding(text,length,&buffer);
if(buffer) WriteChunkBytes(iffh,buffer,strlen(buffer));
ami_utf8_free(buffer);
}
return true;
}
bool gui_commit_clipboard(void)
{
if(iffh) CloseIFF(iffh);
return true;
}
bool ami_clipboard_copy(const char *text, size_t length, struct box *box,
void *handle, const char *whitespace_text,size_t whitespace_length)
{
if(!(PushChunk(iffh,0,ID_CHRS,IFFSIZE_UNKNOWN)))
{
if (whitespace_text)
{
if(!gui_add_to_clipboard(whitespace_text,whitespace_length, false)) return false;
}
if(text)
{
if (!gui_add_to_clipboard(text, length, box->space)) return false;
}
PopChunk(iffh);
}
else
{
PopChunk(iffh);
return false;
}
return true;
}
bool gui_copy_to_clipboard(struct selection *s)
{
struct CSet cset = {0};
if(!(OpenIFF(iffh,IFFF_WRITE)))
{
if(!(PushChunk(iffh,ID_FTXT,ID_FORM,IFFSIZE_UNKNOWN)))
{
if(option_utf8_clipboard)
{
if(!(PushChunk(iffh,0,ID_CSET,24)))
{
cset.CodeSet = 106; // UTF-8
WriteChunkBytes(iffh,&cset,24);
PopChunk(iffh);
}
}
if (s->defined && selection_traverse(s, ami_clipboard_copy, NULL))
{
gui_commit_clipboard();
return true;
}
}
else
{
PopChunk(iffh);
}
CloseIFF(iffh);
}
return false;
}
void gui_create_form_select_menu(struct browser_window *bw,
struct form_control *control)
{

View File

@ -18,6 +18,7 @@
#ifndef AMIGA_IFF_CSET_H
#define AMIGA_IFF_CSET_H
#include <exec/types.h>
/* This structure is for the IFF CSET chunk, registered by Martin Taillefer */

View File

@ -29,6 +29,7 @@ extern char *option_theme;
extern bool option_no_iframes;
extern bool option_utf8_clipboard;
extern bool option_context_menu;
extern bool option_sticky_context_menu;
extern bool option_truecolour_mouse_pointers;
extern bool option_use_os_pointers;
extern bool option_force_tabs;
@ -45,7 +46,8 @@ int option_modeid = 0; \
char *option_theme = 0; \
bool option_no_iframes = false; \
bool option_utf8_clipboard = false; \
bool option_context_menu = false; \
bool option_context_menu = true; \
bool option_sticky_context_menu = true; \
bool option_truecolour_mouse_pointers = true; \
bool option_use_os_pointers = false; \
bool option_force_tabs = false; \
@ -63,6 +65,7 @@ char *option_recent_file = 0; \
{ "no_iframes", OPTION_BOOL, &option_no_iframes}, \
{ "clipboard_write_utf8", OPTION_BOOL, &option_utf8_clipboard}, \
{ "context_menu", OPTION_BOOL, &option_context_menu}, \
{ "sticky_context_menu", OPTION_BOOL, &option_sticky_context_menu}, \
{ "truecolour_mouse_pointers", OPTION_BOOL, &option_truecolour_mouse_pointers}, \
{ "os_mouse_pointers", OPTION_BOOL, &option_use_os_pointers}, \
{ "always_open_tabs", OPTION_BOOL, &option_force_tabs}, \

View File

@ -307,7 +307,7 @@ bool ami_bitmap_tile(int x, int y, int width, int height,
ri.RGBFormat = RGBFB_R8G8B8A8;
max_width = (repeat_x ? scrn->Width : width);
max_height = (repeat_y ? scrn->Height: height);
max_height = (repeat_y ? scrn->Height : height);
for(xf=0;xf<max_width;xf+=bitmap->width)
{