Files
Mozilla/mozilla/cmd/xfe/src/HTMLDrag.cpp
ltabb 8ed5afe62c Free the lizard
git-svn-id: svn://10.0.0.236/trunk@10 18797224-902f-48f8-a5cc-f745e15eee43
1998-03-28 02:44:41 +00:00

258 lines
7.4 KiB
C++

/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
/*
HTMLDrag.cpp -- class definition for the HTMLView drag class
Created: Alastair Gourlay <sgidev@netscape.com>, 1-Jan-96.
*/
#include <stdio.h>
#include <Xm/Xm.h>
#include <Xm/AtomMgr.h>
#include "HTMLDrag.h"
#include "layers.h"
#if defined(DEBUG_sgidev) || defined(DEBUG_tao)
#define XDEBUG(x) x
#else
#define XDEBUG(x)
#endif
//
// XFE_HTMLDrag class
//
static void HTMLDragDestroyCb(Widget,XtPointer,XtPointer);
// provide access to HTML Drag class from old XFE C code.
extern "C" void XFE_HTMLDragCreate(Widget widget,MWContext *context)
{
if (widget && context) {
XFE_HTMLDrag *htmlDrag=new XFE_HTMLDrag(widget,context);
XtAddCallback(widget,XmNdestroyCallback,HTMLDragDestroyCb,(XtPointer)htmlDrag);
}
}
// auto-cleanup of classes created with C API
static void HTMLDragDestroyCb(Widget widget,XtPointer cd, XtPointer)
{
XDEBUG(printf("HTMLDragDestroyCb(%x)\n",widget));
if (cd) {
XFE_HTMLDrag *htmlDrag=(XFE_HTMLDrag*)cd;
delete htmlDrag;
}
}
// constructor
XFE_HTMLDrag::XFE_HTMLDrag(Widget w,MWContext *context) : XFE_DragNetscape(w)
{
_context=context;
}
// destructor
XFE_HTMLDrag::~XFE_HTMLDrag()
{
}
// Called by xfe.c, in the Layer event handler when a link
// is armed by a Button1Down.
// (Motif DND needs a hook into the Layer event mgmt in order
// to process drags on links within layers.)
static CL_Layer *_dragLayer=NULL;
extern "C" void fe_HTMLDragSetLayer(CL_Layer *layer)
{
// record layer of Button1 press on a link in a layer
_dragLayer=layer;
}
// Extract URL from context, layer, x, y
// (caller must free the returned URL_Struct)
// Note: XFE_HTMLView has similar code, but FE_HTMLDrag doesn't
// have an XFE_HTMLView*, only an MWContext*.
URL_Struct *
XFE_HTMLDrag::urlAtPosition(int x, int y, CL_Layer *layer)
{
URL_Struct *urlStruct = NULL;
if (!_context)
return NULL;
// adjust for document origin
int docX = x + CONTEXT_DATA(_context)->document_x;
int docY = y + CONTEXT_DATA(_context)->document_y;
// adjust layer origin
if (layer) {
docX -= CL_GetLayerXOrigin(layer);
docY -= CL_GetLayerYOrigin(layer);
}
LO_Element *le=LO_XYToElement(_context,docX,docY,layer);
if (!le)
return NULL;
switch (le->type) {
case LO_TEXT:
if (le->lo_text.anchor_href && le->lo_text.anchor_href->anchor)
urlStruct = NET_CreateURLStruct ((char *)le->lo_text.anchor_href->anchor,
NET_DONT_RELOAD);
break;
case LO_IMAGE:
{
long ix = le->lo_image.x + le->lo_image.x_offset;
long iy = le->lo_image.y + le->lo_image.y_offset;
long mx = docX - ix - le->lo_image.border_width;
long my = docY - iy - le->lo_image.border_width;
// check for client-side image map
if (le->lo_image.image_attr->usemap_name != NULL) {
LO_AnchorData *anchorData=LO_MapXYToAreaAnchor(_context,
(LO_ImageStruct *)le,
mx, my);
if (anchorData && anchorData->anchor)
urlStruct=NET_CreateURLStruct ((char *)anchorData->anchor,
NET_DONT_RELOAD);
}
// check for regular image or server-side image map
else if (le->lo_image.anchor_href && le->lo_image.anchor_href->anchor) {
urlStruct=NET_CreateURLStruct ((char *)le->lo_image.anchor_href->anchor,
NET_DONT_RELOAD);
// if this is an image map (and not an about: link), add the
//coordinates to the URL
if (XP_STRNCASECMP(urlStruct->address, "about:",6)!=0 &&
le->lo_image.image_attr->attrmask & LO_ATTR_ISMAP) {
NET_AddCoordinatesToURLStruct (urlStruct,
((mx < 0) ? 0 : mx),
((my < 0) ? 0 : my));
}
}
}
break;
default:
urlStruct=NULL;
break;
}
return urlStruct;
}
//
// drag virtual methods - derived class can override
//
// decide if this drag is interesting
int XFE_HTMLDrag::dragStart(int x,int y)
{
XDEBUG(printf("XFE_HTMLDrag::dragStart(%d,%d)\n",x,y));
_dragURLStruct=urlAtPosition(x,y,_dragLayer);
// clean up drag layer for next click
_dragLayer=NULL;
if (!_dragURLStruct || !_dragURLStruct->address || strlen(_dragURLStruct->address)==0)
return FALSE;
// reject URL's which don't point to document:
// addbook:add URL's
// mailbox:displayattachments URL
// javascript code
// about: urls
// mailto: urls
if (XP_STRNCASECMP(_dragURLStruct->address,"addbook:add",11)==0 ||
XP_STRNCASECMP(_dragURLStruct->address,"about:",6)==0 ||
XP_STRNCASECMP(_dragURLStruct->address,"mailto:",7)==0 ||
XP_STRNCASECMP(_dragURLStruct->address,"mailbox:displayattachments",26)==0 ||
XP_STRNCASECMP(_dragURLStruct->address,"javascript:",11)==0)
return FALSE;
// disarm link and clear selection, since XmDragStart() will steal the Btn1Up
XtCallActionProc(_widget,"DisarmLink",(XEvent*)&_dragButtonEvent,NULL,0);
LO_ClearSelection(_context);
// files get dragged to desktop as a symbolic link
if (isFileURL(_dragURLStruct->address))
dragFilesAsLinks(TRUE);
// try to be sensitive to type of URL
#ifdef MOZ_MAIL_NEWS
setDragIconForType(guessUrlMimeType(_dragURLStruct->address));
#endif
return TRUE;
}
// specify types for this particular drag
void XFE_HTMLDrag::targets()
{
_numTargets=2;
_targets=new Atom[_numTargets];
_targets[0]=_XA_NETSCAPE_URL;
_targets[1]=XA_STRING;
setFileTarget(_XA_NETSCAPE_URL);
}
// specify operations for this particualr drag
void XFE_HTMLDrag::operations()
{
_operations=XmDROP_COPY;
}
// provide data for requested target from targets() list
char *XFE_HTMLDrag::getTargetData(Atom target)
{
// WARNING - data *must* be allocated with Xt malloc API, since Xt
// will free the data with XtFree()
if (target==_XA_NETSCAPE_URL) {
// translate drag data to NetscapeURL format
XFE_URLDesktopType urlData;
urlData.createItemList(1);
urlData.url(0,_dragURLStruct->address);
return (char*)XtNewString(urlData.getString());
}
if (target==XA_STRING) {
// return the URL
return (char*)XtNewString(_dragURLStruct->address);
}
return NULL;
}
// clean up after drag
void XFE_HTMLDrag::dragComplete()
{
if (_dragURLStruct) {
NET_FreeURLStruct(_dragURLStruct);
_dragURLStruct=NULL;
}
}