home *** CD-ROM | disk | FTP | other *** search
/ Tools / WinSN5.0Ver.iso / NETSCAP.50 / WIN1998.ZIP / ns / cmd / xfe / src / BrowserDrop.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1998-04-08  |  6.8 KB  |  236 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.    BrowserDrop.cpp -- class definition for the browser drop class
  20.    Created: Alastair Gourlay <sgidev@netscape.com>, 1-Jan-96.
  21.  */
  22.  
  23.  
  24.  
  25. #include "BrowserDrop.h"
  26.  
  27. #ifdef DEBUG_sgidev
  28. #define XDEBUG(x) x
  29. #else
  30. #define XDEBUG(x)
  31. #endif
  32.  
  33. //
  34. // XFE_BrowserDrop class
  35. //
  36.  
  37. // constructor
  38.  
  39. XFE_BrowserDrop::XFE_BrowserDrop(Widget parent,XFE_BrowserFrame *browserFrame)
  40.     : XFE_DropNetscape(parent)
  41. {
  42.     _browserFrame=browserFrame;
  43.     _jsList=NULL;
  44.     _sameDragSource=False;
  45. }
  46.  
  47. XFE_BrowserDrop::~XFE_BrowserDrop()
  48. {
  49.     if (_jsList)
  50.         cleanupJsList();
  51. }
  52.  
  53. void XFE_BrowserDrop::targets()
  54. {
  55.     _numTargets=2;
  56.     _targets=new Atom[_numTargets];
  57.  
  58.     _targets[0]=_XA_NETSCAPE_URL;
  59.     _targets[1]=XA_STRING;
  60.  
  61.     acceptFileTargets();
  62. }
  63.  
  64. void XFE_BrowserDrop::operations()
  65. {
  66.     // always copy - move/link irrelevant
  67.     _operations=(unsigned int)XmDROP_COPY;
  68. }
  69.  
  70. // wrapper for JavaScript event callback
  71. void XFE_BrowserDrop::JsDropEventCb(MWContext*,LO_Element*,int32,void* closure, ETEventStatus status)
  72. {
  73.     if (closure) {
  74.         XFE_BrowserDrop *bd=(XFE_BrowserDrop*)closure;
  75.         bd->jsDropEventCb(status);
  76.     }
  77. }
  78.  
  79. int XFE_BrowserDrop::processTargets(Atom *targets,const char **data,int numItems)
  80. {
  81.     int i;
  82.  
  83.     XDEBUG(printf("XFE_BrowserDrop::processTargets()\n"));
  84.  
  85.     _sameDragSource=False;
  86.     
  87.     if (!targets || !data || numItems==0)
  88.         return FALSE;
  89.     
  90.     // build list of dropped URLs for event JS dragdrop handler
  91.     
  92.     // count # of items in list (need to expand multi-item NetscapeURL data)
  93.     int urlCount=0;
  94.     for (i=0;i<numItems;i++) {
  95.         if (targets[i]==None || data[i]==NULL || strlen(data[i])==0)
  96.             continue;
  97.         if (targets[i]==_XA_FILE_NAME) urlCount++;
  98.         else if (targets[i]==XA_STRING) urlCount++;
  99.         else if (targets[i]==_XA_NETSCAPE_URL) {
  100.             XFE_URLDesktopType urlData(data[i]);
  101.             urlCount+=urlData.numItems();
  102.         }
  103.     }
  104.  
  105.     _jsList=new char*[urlCount+1];
  106.     int listSize=0;
  107.     
  108.     for (i=0;i<numItems;i++) {
  109.         if (targets[i]==None || data[i]==NULL || strlen(data[i])==0)
  110.             continue;
  111.  
  112.         XDEBUG(printf("  [%d] %s: \"%s\"\n",i,XmGetAtomName(XtDisplay(_widget),targets[i]),data[i]));
  113.  
  114.         if (targets[i]==_XA_FILE_NAME) {
  115.             char *address=(char*)XP_ALLOC(5+strlen(data[i])+1); // "file:" + filename + \0
  116.             sprintf(address,"file:%s",data[i]);
  117.             _jsList[listSize++]=address;
  118.         }
  119.         
  120.         if (targets[i]==_XA_NETSCAPE_URL) {
  121.             XFE_URLDesktopType urlData(data[i]);
  122.             for (int j=0;j<urlData.numItems();j++) {
  123.                 _jsList[listSize++]=XP_STRDUP(urlData.url(j));
  124.             }
  125.         }
  126.         if (targets[i]==XA_STRING) {
  127.                 _jsList[listSize++]=XP_STRDUP(data[i]);
  128.         }
  129.     }
  130.     _jsList[listSize]=NULL;
  131.  
  132.     // bail if there are no valid URL's
  133.     if (listSize==0) {
  134.         cleanupJsList();
  135.         return FALSE;
  136.     }
  137.     
  138.     // detect drag from the same browser window
  139.     if (XFE_DragBase::_activeDragShell) {
  140.         Widget shell=_widget;
  141.         while (!XtIsShell(shell)) shell=XtParent(shell);
  142.         if (shell==XFE_DragBase::_activeDragShell) {
  143.             _sameDragSource=True;
  144.         }
  145.     }
  146.     
  147.     // build JavaScript DRAGDROP event struct
  148.  
  149.     MWContext *context=_browserFrame->getContext();
  150.     if (context) {
  151.         JSEvent *jsEvent = XP_NEW_ZAP(JSEvent);
  152.         jsEvent->type = EVENT_DRAGDROP;
  153.         jsEvent->x=_dropEventX;
  154.         jsEvent->y=_dropEventY;
  155.         jsEvent->docx=_dropEventX + CONTEXT_DATA(context)->document_x;
  156.         jsEvent->docy=_dropEventY + CONTEXT_DATA(context)->document_y;
  157.         Position rootX=0;Position rootY=0;
  158.         XtTranslateCoords(_widget,_dropEventX,_dropEventY,&rootX,&rootY);
  159.         jsEvent->screenx=rootX;
  160.         jsEvent->screeny=rootY;
  161.         jsEvent->which=0; // Motif drag and drop doesn't give us the Button events
  162.         jsEvent->modifiers=0; // Motif drag and drop doesn't give us the Button events
  163.         jsEvent->data=_jsList;
  164.         jsEvent->dataSize=listSize;
  165.         
  166.         ET_SendEvent(context, NULL, jsEvent, JsDropEventCb, (void*)this);
  167.     }
  168.  
  169.     // URL's will be loaded by event handler, if approved by page's JavaScript handler.
  170.  
  171.     return TRUE;
  172. }
  173.  
  174. void XFE_BrowserDrop::jsDropEventCb(int status)
  175. {
  176.     XDEBUG(printf("XFE_BrowserDrop::jsDropEventCb(%d)\n",status));
  177.  
  178.     // Load URLs if no event handler present, or if event handler said ok.
  179.     // Note: We ignore the drop if it originated from the same browser window.
  180.     // (We let JavaScript have it, but if it's not interested then the default UI
  181.     // is to disallow it.)
  182.     if (_jsList && status==0 && !_sameDragSource) {
  183.         // open dropped URLs in browser
  184.         int i=0;
  185.         while (_jsList[i]) {
  186.             loadURL(_jsList[i], i!=0);
  187.             i++;
  188.         }
  189.     }
  190.  
  191.     // free the drop data
  192.     cleanupJsList();
  193.     
  194.     return;
  195. }
  196.  
  197.  
  198. // defined in mozilla.c - cancels timer which loads homepage after sploosh screen
  199. extern "C" void plonk_cancel();
  200.  
  201. void XFE_BrowserDrop::loadURL(const char *url,int newFrame)
  202. {
  203.     if (!url)
  204.         return;
  205.  
  206.     // cancel initial sploosh-screen loader timeout
  207.     plonk_cancel();
  208.     
  209.     URL_Struct *urlStruct = NET_CreateURLStruct (url,NET_DONT_RELOAD);
  210.     if (!newFrame
  211. #ifdef MOZ_MAIL_NEWS
  212.         || !MSG_RequiresBrowserWindow(urlStruct->address)
  213. #endif
  214.     ) {
  215.         _browserFrame->getURL(urlStruct, (urlStruct == NULL));
  216.         fe_UserActivity(_browserFrame->getContext());
  217.     }
  218.     else {
  219.         XFE_BrowserFrame *newFrame=new XFE_BrowserFrame(XtParent(_browserFrame->getBaseWidget()), _browserFrame, NULL);
  220.         newFrame->show();
  221.         newFrame->getURL(urlStruct, (urlStruct == NULL));
  222.         fe_UserActivity(newFrame->getContext());
  223.     }
  224. }
  225.  
  226. void XFE_BrowserDrop::cleanupJsList()
  227. {
  228.     if (_jsList) {
  229.         int i=0;
  230.         while (_jsList[i])
  231.             XP_FREE(_jsList[i++]);
  232.         delete _jsList;
  233.         _jsList=NULL;
  234.     }
  235. }
  236.