home *** CD-ROM | disk | FTP | other *** search
/ Tools / WinSN5.0Ver.iso / NETSCAP.50 / WIN1998.ZIP / ns / cmd / xfe / src / HTMLDrag.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1998-04-08  |  7.7 KB  |  258 lines

  1. /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
  2.  *
  3.  * The contents of this file are subject to the Netscape Public License
  4.  * Version 1.0 (the "NPL"); you may not use this file except in
  5.  * compliance with the NPL.  You may obtain a copy of the NPL at
  6.  * http://www.mozilla.org/NPL/
  7.  *
  8.  * Software distributed under the NPL is distributed on an "AS IS" basis,
  9.  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
  10.  * for the specific language governing rights and limitations under the
  11.  * NPL.
  12.  *
  13.  * The Initial Developer of this code under the NPL is Netscape
  14.  * Communications Corporation.  Portions created by Netscape are
  15.  * Copyright (C) 1998 Netscape Communications Corporation.  All Rights
  16.  * Reserved.
  17.  */
  18. /* 
  19.    HTMLDrag.cpp -- class definition for the HTMLView drag class
  20.    Created: Alastair Gourlay <sgidev@netscape.com>, 1-Jan-96.
  21.  */
  22.  
  23.  
  24.  
  25. #include <stdio.h>
  26. #include <Xm/Xm.h>
  27. #include <Xm/AtomMgr.h>
  28. #include "HTMLDrag.h"
  29. #include "layers.h"
  30.  
  31. #if defined(DEBUG_sgidev) || defined(DEBUG_tao)
  32. #define XDEBUG(x) x
  33. #else
  34. #define XDEBUG(x)
  35. #endif
  36.  
  37. //
  38. // XFE_HTMLDrag class
  39. //
  40.  
  41. static void HTMLDragDestroyCb(Widget,XtPointer,XtPointer);
  42.  
  43. // provide access to HTML Drag class from old XFE C code.
  44.  
  45. extern "C" void XFE_HTMLDragCreate(Widget widget,MWContext *context)
  46. {
  47.     if (widget && context) {
  48.         XFE_HTMLDrag *htmlDrag=new XFE_HTMLDrag(widget,context);
  49.         XtAddCallback(widget,XmNdestroyCallback,HTMLDragDestroyCb,(XtPointer)htmlDrag);
  50.     }
  51. }
  52.  
  53. // auto-cleanup of classes created with C API
  54. static void HTMLDragDestroyCb(Widget widget,XtPointer cd, XtPointer)
  55. {
  56.     XDEBUG(printf("HTMLDragDestroyCb(%x)\n",widget));
  57.     if (cd) {
  58.         XFE_HTMLDrag *htmlDrag=(XFE_HTMLDrag*)cd;
  59.         delete htmlDrag;
  60.     }
  61. }
  62.  
  63. // constructor
  64.  
  65. XFE_HTMLDrag::XFE_HTMLDrag(Widget w,MWContext *context) : XFE_DragNetscape(w)
  66. {
  67.     _context=context;
  68. }
  69.  
  70. // destructor
  71.  
  72. XFE_HTMLDrag::~XFE_HTMLDrag()
  73. {
  74. }
  75.  
  76. // Called  by xfe.c, in the Layer event handler when a link
  77. // is armed by a Button1Down.
  78. // (Motif DND needs a hook into the Layer event mgmt in order
  79. // to process drags on links within layers.)
  80.  
  81. static CL_Layer *_dragLayer=NULL;
  82.  
  83. extern "C" void fe_HTMLDragSetLayer(CL_Layer *layer)
  84. {
  85.     // record layer of Button1 press on a link in a layer
  86.     _dragLayer=layer;
  87. }
  88.  
  89.  
  90. // Extract URL from context, layer, x, y
  91. // (caller must free the returned URL_Struct)
  92. // Note: XFE_HTMLView has similar code, but FE_HTMLDrag doesn't
  93. // have an XFE_HTMLView*, only an MWContext*.
  94.  
  95. URL_Struct *
  96. XFE_HTMLDrag::urlAtPosition(int x, int y, CL_Layer *layer)
  97. {
  98.     URL_Struct *urlStruct = NULL;
  99.  
  100.     if (!_context)
  101.         return NULL;
  102.  
  103.     // adjust for document origin
  104.     int docX = x + CONTEXT_DATA(_context)->document_x;
  105.     int docY = y + CONTEXT_DATA(_context)->document_y;
  106.  
  107.     // adjust layer origin
  108.     if (layer) {
  109.         docX -= CL_GetLayerXOrigin(layer);
  110.         docY -= CL_GetLayerYOrigin(layer);
  111.     }    
  112.  
  113.     LO_Element *le=LO_XYToElement(_context,docX,docY,layer);
  114.  
  115.     if (!le)
  116.         return NULL;
  117.  
  118.     switch (le->type) {
  119.     case LO_TEXT:
  120.         if (le->lo_text.anchor_href && le->lo_text.anchor_href->anchor)
  121.             urlStruct = NET_CreateURLStruct ((char *)le->lo_text.anchor_href->anchor,
  122.                                              NET_DONT_RELOAD);
  123.         break;
  124.     case LO_IMAGE:
  125.         {
  126.         long ix = le->lo_image.x + le->lo_image.x_offset;
  127.         long iy = le->lo_image.y + le->lo_image.y_offset;
  128.         long mx = docX - ix - le->lo_image.border_width;
  129.         long my = docY - iy - le->lo_image.border_width;                    
  130.         // check for client-side image map
  131.         if (le->lo_image.image_attr->usemap_name != NULL) {
  132.             LO_AnchorData *anchorData=LO_MapXYToAreaAnchor(_context,
  133.                                                            (LO_ImageStruct *)le,
  134.                                                            mx, my);
  135.             if (anchorData && anchorData->anchor)
  136.                 urlStruct=NET_CreateURLStruct ((char *)anchorData->anchor,
  137.                                                NET_DONT_RELOAD);
  138.         }
  139.         // check for regular image or server-side image map
  140.         else if (le->lo_image.anchor_href && le->lo_image.anchor_href->anchor) {
  141.             urlStruct=NET_CreateURLStruct ((char *)le->lo_image.anchor_href->anchor,
  142.                                            NET_DONT_RELOAD);
  143.             // if this is an image map (and not an about: link), add the
  144.             //coordinates to the URL
  145.             if (XP_STRNCASECMP(urlStruct->address, "about:",6)!=0 &&
  146.                 le->lo_image.image_attr->attrmask & LO_ATTR_ISMAP) {
  147.                 NET_AddCoordinatesToURLStruct (urlStruct,
  148.                                                ((mx < 0) ? 0 : mx),
  149.                                                ((my < 0) ? 0 : my));
  150.             }
  151.         }
  152.         }
  153.         break;
  154.     default:
  155.         urlStruct=NULL;
  156.         break;
  157.     }
  158.  
  159.     return urlStruct;
  160. }
  161.  
  162. //
  163. //  drag virtual methods - derived class can override
  164. //
  165.  
  166. // decide if this drag is interesting
  167.  
  168. int XFE_HTMLDrag::dragStart(int x,int y)
  169. {
  170.     XDEBUG(printf("XFE_HTMLDrag::dragStart(%d,%d)\n",x,y));
  171.  
  172.     _dragURLStruct=urlAtPosition(x,y,_dragLayer);
  173.  
  174.     // clean up drag layer for next click
  175.     _dragLayer=NULL;
  176.     
  177.     if (!_dragURLStruct || !_dragURLStruct->address || strlen(_dragURLStruct->address)==0)
  178.         return FALSE;
  179.  
  180.     // reject URL's which don't point to document:
  181.     //  addbook:add URL's
  182.     //  mailbox:displayattachments URL
  183.     //  javascript code
  184.     //  about: urls
  185.     //  mailto: urls
  186.     if (XP_STRNCASECMP(_dragURLStruct->address,"addbook:add",11)==0 ||
  187.         XP_STRNCASECMP(_dragURLStruct->address,"about:",6)==0 ||
  188.         XP_STRNCASECMP(_dragURLStruct->address,"mailto:",7)==0 ||
  189.         XP_STRNCASECMP(_dragURLStruct->address,"mailbox:displayattachments",26)==0 ||
  190.         XP_STRNCASECMP(_dragURLStruct->address,"javascript:",11)==0)
  191.         return FALSE;
  192.  
  193.     // disarm link and clear selection, since XmDragStart() will steal the Btn1Up
  194.     XtCallActionProc(_widget,"DisarmLink",(XEvent*)&_dragButtonEvent,NULL,0);
  195.     LO_ClearSelection(_context);
  196.     // files get dragged to desktop as a symbolic link
  197.     if (isFileURL(_dragURLStruct->address))
  198.         dragFilesAsLinks(TRUE);
  199.     // try to be sensitive to type of URL
  200. #ifdef MOZ_MAIL_NEWS
  201.     setDragIconForType(guessUrlMimeType(_dragURLStruct->address));
  202. #endif
  203.  
  204.     return TRUE;
  205. }
  206.  
  207. // specify types for this particular drag
  208.  
  209. void XFE_HTMLDrag::targets()
  210. {
  211.     _numTargets=2;
  212.     _targets=new Atom[_numTargets];
  213.  
  214.     _targets[0]=_XA_NETSCAPE_URL;
  215.     _targets[1]=XA_STRING;
  216.  
  217.     setFileTarget(_XA_NETSCAPE_URL);
  218. }
  219.  
  220. // specify operations for this particualr drag
  221. void XFE_HTMLDrag::operations()
  222. {
  223.     _operations=XmDROP_COPY;
  224. }
  225.  
  226. // provide data for requested target from targets() list
  227. char *XFE_HTMLDrag::getTargetData(Atom target)
  228. {
  229.     // WARNING - data *must* be allocated with Xt malloc API, since Xt
  230.     // will free the data with XtFree()
  231.     
  232.     if (target==_XA_NETSCAPE_URL) {
  233.         // translate drag data to NetscapeURL format
  234.         XFE_URLDesktopType urlData;
  235.  
  236.         urlData.createItemList(1);
  237.         urlData.url(0,_dragURLStruct->address);
  238.         return (char*)XtNewString(urlData.getString());
  239.     }
  240.  
  241.     if (target==XA_STRING) {
  242.         // return the URL
  243.         return (char*)XtNewString(_dragURLStruct->address);
  244.     }
  245.  
  246.     return NULL;
  247. }
  248.  
  249. // clean up after drag
  250. void XFE_HTMLDrag::dragComplete()
  251. {
  252.     if (_dragURLStruct) {
  253.         NET_FreeURLStruct(_dragURLStruct);
  254.         _dragURLStruct=NULL;
  255.     }
  256. }
  257.  
  258.