Mozilla/mozilla/cmd/xfe/src/ComposeAttachFolderView.cpp
akkana%netscape.com 4659274e32 Remove vcards from MOZ_MAIL_COMPOSE; fix unresolved symbols
git-svn-id: svn://10.0.0.236/trunk@9516 18797224-902f-48f8-a5cc-f745e15eee43
1998-09-08 19:32:10 +00:00

1039 lines
28 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.
*/
/*
ComposeAttachFolderView.cpp -- compose window folder containing attachment panel
Created: Alastair Gourlay(SGI) c/o Dora Hsu<dora@netscape.com>, 26 Nov 1996
*/
// Classes in this file:
// XFE_ComposeAttachFolderView
// XFE_ComposeAttachPanel
// XFE_ComposeAttachDrop
//
#include "ComposeAttachFolderView.h"
#include <stdlib.h>
#include <unistd.h>
#include "xfe.h"
#include "net.h"
#include "msgcom.h"
#include "xp_mem.h"
#include <xpgetstr.h>
#include <Xm/Xm.h>
#include <Xm/XmP.h> // need widget-writer call _XmSetDestination()
#include <Xm/XmAll.h>
#include <Xfe/Xfe.h>
#include "ThreadView.h"
#include "BrowserFrame.h"
#ifdef MOZ_MAIL_NEWS
// from lib/libmsg
extern "C" XP_Bool MSG_RequiresMailMsgWindow(const char*);
extern "C" XP_Bool MSG_RequiresNewsMsgWindow(const char*);
#endif /* MOZ_MAIL_NEWS */
// Use API from XmP.h - moderately naughty, but implicitly supported for
// widget-writers and happy hackers everywhere.
extern "C" void _XmSetDestination(Display*,Widget);
static int IsWebJumper(const char*);
//
// XFE_ComposeAttachFolderView
//
#ifdef DEBUG_sgidev
#define XDEBUG(x) x
#else
#define XDEBUG(x)
#endif
// error messages
extern int XFE_INVALID_FILE_ATTACHMENT_IS_A_DIRECTORY;
extern int XFE_INVALID_FILE_ATTACHMENT_NOT_READABLE;
extern int XFE_INVALID_FILE_ATTACHMENT_DOESNT_EXIST;
extern int XFE_MN_TOO_MANY_ATTACHMENTS;
extern int XFE_MN_ITEM_ALREADY_ATTACHED;
extern int XFE_MN_DELIVERY_IN_PROGRESS;
extern int XFE_MN_INVALID_ATTACH_URL;
// popup menu for attach panel
static MenuSpec attachPopupMenuSpec[] = {
{ xfeCmdAttachFile, PUSHBUTTON },
{ xfeCmdAttachWebPage, PUSHBUTTON },
{ xfeCmdDeleteAttachment, PUSHBUTTON },
MENU_SEPARATOR,
{ xfeCmdAttachAddressBookCard, TOGGLEBUTTON },
{ NULL }
};
// intialize static members
char *XFE_ComposeAttachFolderView::_lastAttachmentType=NULL;
const int XFE_ComposeAttachFolderView::_maxAttachments=128;
#if !defined(USE_MOTIF_DND)
// callback stubs
void XFE_ComposeAttachFolderView::AttachDropCb(Widget,void* cd,fe_dnd_Event type,fe_dnd_Source *source,XEvent*) {
XFE_ComposeAttachFolderView *ad=(XFE_ComposeAttachFolderView*)cd;
if (type==FE_DND_DROP && ad && source)
ad->attachDropCb(source);
}
#endif /* USE_MOTIF_DND */
// constructor
XFE_ComposeAttachFolderView::XFE_ComposeAttachFolderView(
XFE_Component *toplevel_component,
XFE_View *parent_view,
MSG_Pane *p,
MWContext *context)
: XFE_MNView(toplevel_component, parent_view, context, p)
{
setParent(parent_view);
_attachPanel=NULL;
_attachLocationDialog=NULL;
_attachFileDialog=NULL;
_xfePopup=NULL;
_context=context;
_attachments=new struct MSG_AttachmentData[_maxAttachments];
_numAttachments=0;
_folderVisible=FALSE;
_deleteAttachButton=NULL;
_addedExistingAttachments=FALSE;
}
// destructor
XFE_ComposeAttachFolderView::~XFE_ComposeAttachFolderView()
{
if (_attachPanel)
delete _attachPanel;
if (_attachLocationDialog)
delete _attachLocationDialog;
if (_attachFileDialog)
delete _attachFileDialog;
if (_xfePopup)
delete _xfePopup;
if (_attachments) {
for (int i=0;i<_numAttachments;i++)
if (_attachments[i].url)
XP_FREE(_attachments[i].url);
delete [] _attachments;
}
}
// create UI
void XFE_ComposeAttachFolderView::createWidgets(Widget parent)
{
// create attachment folder form
Widget form=XmCreateForm(parent,"attachForm",NULL,0);
// create attachment panel
_attachPanel=new XFE_ComposeAttachPanel(this,_context);
_attachPanel->createWidgets(form);
_attachPanel->show();
XtVaSetValues(_attachPanel->getBaseWidget(),
XmNleftAttachment,XmATTACH_FORM,
XmNrightAttachment,XmATTACH_FORM,
XmNtopAttachment,XmATTACH_FORM,
XmNbottomAttachment,XmATTACH_FORM,
NULL);
#if !defined(USE_MOTIF_DND)
// create drop site for internal drop (message,news etc.)
fe_dnd_CreateDrop(_attachPanel->getBaseWidget(),AttachDropCb,this);
#endif /* USE_MOTIF_DND */
// create popup menu
_xfePopup = new XFE_PopupMenu("popup",(XFE_Frame*)m_toplevel,_attachPanel->pane(),NULL);
_xfePopup->addMenuSpec(attachPopupMenuSpec);
// Remove the osfLeft and osfRight translations of the popup's children.
// For bug 71620. See the bug description for details. Basically, for
// some strange reason, motif assumes that either a left or a right
// naviation widget exists for this popup menu and core dumps trying
// to dereference a NULL widget.
_xfePopup->removeLeftRightTranslations();
setBaseWidget(form);
// Register this widget to have a tooltip.
fe_WidgetAddToolTips(form);
// add existing attachments to the panel (e.g. for Forward)
addExistingAttachments();
}
void XFE_ComposeAttachFolderView::show()
{
XFE_MNView::show();
// enable attachment panel's drop site
if (_attachPanel)
_attachPanel->show();
}
void XFE_ComposeAttachFolderView::hide()
{
XFE_MNView::hide();
// disable attachment panel's drop site
if (_attachPanel)
_attachPanel->hide();
}
// track viewable state of attachment folder tab
void XFE_ComposeAttachFolderView::folderVisible(int visible)
{
_folderVisible=visible;
if (visible) {
// make sure pre-exisiting attachments are added
addExistingAttachments();
// take Motif 'active' status away from Subject/text area so
// that xfeCmdDelete gets routed appropriately.
_XmSetDestination(XtDisplay(getBaseWidget()),NULL);
}
}
Boolean
XFE_ComposeAttachFolderView::isCommandEnabled(CommandType command, void*,
XFE_CommandInfo*)
{
// return True for all the commands that are handled in this class
if (command==xfeCmdAttachFile ||
command==xfeCmdAttachWebPage ||
command==xfeCmdShowPopup) {
return True;
}
if ((command==xfeCmdDelete || command==xfeCmdDeleteAttachment) &&
_folderVisible &&
_attachPanel &&
_attachPanel->currentSelection()) {
return True;
}
// If we don't hande any command here, return False. Don't call parent
// because the container will decide who to dispatch this command to
return False;
}
Boolean
XFE_ComposeAttachFolderView::handlesCommand(CommandType command, void*,
XFE_CommandInfo*)
{
// return True for all the commands that are handled in this class
if (command==xfeCmdAttachFile ||
command==xfeCmdAttachWebPage ||
command==xfeCmdDeleteAttachment ||
command==xfeCmdDelete ||
command==xfeCmdShowPopup) {
return True;
}
// If we don't hande any command here, return False. Don't call parent
// because the container will decide who to dispatch this command to
return False;
}
void XFE_ComposeAttachFolderView::doCommand(CommandType command, void*,XFE_CommandInfo* info)
{
if (command==xfeCmdAttachFile) {
attachFile();
} else if (command==xfeCmdAttachWebPage) {
attachLocation();
} else if ((command==xfeCmdDelete || command==xfeCmdDeleteAttachment) &&
_folderVisible) {
deleteAttach();
} else if (command==xfeCmdShowPopup) {
// Handle popup menu
XEvent *event = info->event;
Widget w = XtWindowToWidget(event->xany.display, event->xany.window);
if (w == NULL) w=getBaseWidget();
if (_xfePopup) {
_xfePopup->position(event);
_xfePopup->show();
}
}
}
// update UI in response to selection change
void XFE_ComposeAttachFolderView::updateSelectionUI()
{
// take Motif 'active' status away from Subject/text area so
// that xfeCmdDelete gets routed appropriately.
if (getBaseWidget())
_XmSetDestination(XtDisplay(getBaseWidget()),NULL);
// update Delete menu entry
getToplevel()->notifyInterested(XFE_View::chromeNeedsUpdating);
}
//
// attachment management
//
void XFE_ComposeAttachFolderView::addExistingAttachments()
{
// we're only going to do this once per window
if (_addedExistingAttachments)
return;
// add pre-existing attachments to the icon panel (e.g. during msg forward)
const struct MSG_AttachmentData *al=MSG_GetAttachmentList(getPane());
if (al) {
while(al->url) {
addAttachment(al->url,TRUE); // set 'pre_exisiting' flag - don't add to internal list
al++;
}
}
}
void XFE_ComposeAttachFolderView::updateAttachments()
{
if (!getPane())
return;
// abort if attachment adding or delivery is in progress
if (!verifySafeToAttach())
return;
// add to list
_attachments[_numAttachments].url=NULL;
MSG_SetAttachmentList(getPane(),_attachments);
}
int XFE_ComposeAttachFolderView::addAttachment(const char *itemData,int pre_existing,Boolean attach_binary)
{
// abort if attachment adding or delivery is in progress
// (and not adding a pre_exisiting attachment)
if (!pre_existing && !verifySafeToAttach())
return FALSE;
int addStatus=FALSE;
const char **items=new const char*[1];
items[0]=itemData;
addStatus=addAttachments(items,1,pre_existing,attach_binary);
delete items;
return addStatus;
}
int XFE_ComposeAttachFolderView::addAttachments(const char **items,int numItems,int pre_existing,Boolean attach_binary)
{
// lock out addition of existing attachments after first time through
_addedExistingAttachments=TRUE;
// abort if attachment adding or delivery is in progress
// (and not adding pre_exisiting attachments)
if (!pre_existing && !verifySafeToAttach())
return FALSE;
if (!items || numItems==0)
return FALSE;
int addStatus=FALSE;
// desired type is NULL == as-is (used to read from format toggle buttons.)
char *desiredType=NULL;
// if an icon has focus, restore it when we remap the pane
Widget focusWidget=XmGetFocusWidget(getBaseWidget());
if (focusWidget && XtParent(focusWidget)!=_attachPanel->pane())
focusWidget=NULL;
_attachPanel->unmapPane();
for (int i=0;i<numItems;i++) {
// is there space in the list?
if (_numAttachments>=_maxAttachments) {
char *msg=PR_smprintf(XP_GetString(XFE_MN_TOO_MANY_ATTACHMENTS));
if (msg) {
fe_Alert_2(getBaseWidget(),msg);
XP_FREE(msg);
}
break;
}
// is the item already attached?
int duplicate=FALSE;
for (int j=0;j<_numAttachments;j++) {
if (strcmp(items[i],_attachments[j].url)==0) {
char *msg=PR_smprintf(XP_GetString(XFE_MN_ITEM_ALREADY_ATTACHED),items[i]);
if (msg) {
fe_Alert_2(getBaseWidget(),msg);
XP_FREE(msg);
}
duplicate=TRUE;
break;
}
}
if (duplicate)
continue;
// nyi - hack "addbook:add?vcard=" URL to be vcard data, and accept as attachment
// (then turn back on dragging of addbook:add URL's in XFE_HTMLDrag)
// WinFE does this already.
// is it a valid attachment?
if ((!pre_existing) && (!validateAttachment(getBaseWidget(),items[i])))
continue;
// at least one attachment was accepted, return success status
addStatus=TRUE;
// add to internal attachment list
struct MSG_AttachmentData m = { 0 };
m.url=XP_STRDUP(items[i]);
m.desired_type=desiredType;
if (attach_binary)
m.real_type= "application/octet-stream";
else if (IsWebJumper(m.url))
m.real_type= "text/webjumper";
else
m.real_type=NULL;
_attachments[_numAttachments]=m;
_numAttachments++;
char *itemLabel=parseItemLabel(items[i]);
// add icon to attachment panel
_attachPanel->addItem(items[i],itemLabel);
XP_FREE(itemLabel);
}
// always select last-added item
if (addStatus && _attachPanel->numItems()>0) {
_attachPanel->selectItem(_attachPanel->items()[_attachPanel->numItems()-1]);
if (!pre_existing) {
focusWidget=_attachPanel->items()[_attachPanel->numItems()-1]->image();
}
}
// update attachment panel
_attachPanel->updateDisplay();
_attachPanel->mapPane();
// restore focus if we had it before the unmapPane()
if (focusWidget)
XmProcessTraversal(focusWidget,XmTRAVERSE_CURRENT);
// update internal attachment list, if not adding pre-exisiting attachments
if (addStatus && !pre_existing)
updateAttachments();
// pop attachment folder to top, if not adding pre-exisiting attachments
if (!pre_existing) {
getParent()->doCommand(xfeCmdViewAttachments);
}
return addStatus;
}
void XFE_ComposeAttachFolderView::deleteAttachment(int pos)
{
if (pos<0 || pos>=_numAttachments)
return;
// abort if attachment adding or delivery is in progress
if (!verifySafeToAttach())
return;
if (_attachments[pos].url)
XP_FREE(_attachments[pos].url);
// remove from internal attachment list
for (int i=pos;i<_numAttachments-1;i++)
_attachments[i]=_attachments[i+1];
_numAttachments--;
updateAttachments();
// remove icon from attach panel
if (_attachPanel) {
_attachPanel->removeItem(pos);
_attachPanel->updateDisplay();
}
}
int XFE_ComposeAttachFolderView::validateAttachment(Widget widget,const char *url)
{
if (!url)
return FALSE;
// strip off any file: prefix before validating
const char *data=url;
if (XP_STRNCASECMP(url,"file:",5)==0)
data=url+5;
if (strlen(data)==0)
return FALSE;
// accept only URL's that resolve to a document
// reject mailto:, mailbox: folders etc.
if (NET_URL_Type(data)!=0) {
#ifdef MOZ_MAIL_NEWS
// reject addressbook add command, without error dialog
if (XP_STRNCASECMP(url,"addbook:add?vcard=",18)==0)
return FALSE;
// accept regular address book cards
if (XP_STRNCASECMP(url,"addbook:",8)==0)
return TRUE;
// accept anything we know how to display as a document
if (MSG_RequiresMailMsgWindow(url) ||
MSG_RequiresNewsMsgWindow(url) ||
MSG_RequiresBrowserWindow(url))
return TRUE;
else
#endif /* MOZ_MAIL_NEWS */
{
char *msg=PR_smprintf(XP_GetString(XFE_MN_INVALID_ATTACH_URL),data);
if (msg) {
fe_Alert_2(widget,msg);
XP_FREE(msg);
}
return FALSE;
}
}
// file must exist
if (!fe_isFileExist((char*)data)) {
char *msg=PR_smprintf(XP_GetString(XFE_INVALID_FILE_ATTACHMENT_DOESNT_EXIST),data);
if (msg) {
fe_Alert_2(widget,msg);
XP_FREE(msg);
}
return FALSE;
}
// file must be readable
if (!fe_isFileReadable((char*)data)) {
char *msg=PR_smprintf(XP_GetString(XFE_INVALID_FILE_ATTACHMENT_NOT_READABLE),data);
if (msg) {
fe_Alert_2(widget,msg);
XP_FREE(msg);
}
return FALSE;
}
// cannot attach directory
if (fe_isDir((char*)data)) {
char *msg=PR_smprintf(XP_GetString( XFE_INVALID_FILE_ATTACHMENT_IS_A_DIRECTORY ),data);
if (msg) {
fe_Alert_2(widget,msg);
if (msg) XP_FREE(msg);
}
return FALSE;
}
return TRUE;
}
void XFE_ComposeAttachFolderView::scrollToItem(int pos)
{
if (_attachPanel)
_attachPanel->scrollToItem(pos);
}
// create short icon label from full path/url
char *XFE_ComposeAttachFolderView::parseItemLabel(const char *url)
{
// (alastair) code taken from libmsg/msgsend.cpp - be nice just to call into libmsg
// modified slightly to avoid bug of trailing / generating empty name
// modified to return truncated label for mail/news URL's
if (!url || strlen(url)==0)
return XP_STRDUP("(null)");
char *s;
char *s2;
char *s3;
/* If we know the URL doesn't have a sensible file name in it,
don't bother emitting a content-disposition. */
if (!strncasecomp (url, "news:", 5))
return XP_STRDUP("news:");
if (!strncasecomp (url, "snews:", 6))
return XP_STRDUP("snews:");
if (!strncasecomp (url, "mailbox:", 8))
return XP_STRDUP("mailbox:");
char *tmpLabel = XP_STRDUP(url);
s=tmpLabel;
/* remove trailing / or \ */
int len=strlen(s);
if (s[len-1]=='/' || s[len-1]=='\\')
s[len-1]='\0';
s2 = XP_STRCHR (s, ':');
if (s2) s = s2 + 1;
/* Take the part of the file name after the last / or \ */
s2 = XP_STRRCHR (s, '/');
if (s2) s = s2+1;
s2 = XP_STRRCHR (s, '\\');
if (s2) s = s2+1;
/* if it's a non-file url, strip off any named anchors or search data */
if (XP_STRNCASECMP(url,"file:",5)!=0 && url[0]!='/') {
/* Now trim off any named anchors or search data. */
s3 = XP_STRCHR (s, '?');
if (s3) *s3 = 0;
s3 = XP_STRCHR (s, '#');
if (s3) *s3 = 0;
}
/* Now lose the %XX */
NET_UnEscape (s);
char *retLabel=XP_STRDUP(s);
XP_FREE(tmpLabel);
return retLabel;
}
extern "C" XP_Bool MSG_DeliveryInProgress(MSG_Pane * composepane);
int XFE_ComposeAttachFolderView::verifySafeToAttach()
{
#if 0
// this check is no longer needed - back end can handle
// multiple simultaneous attachment operations
if (MSG_DeliveryInProgress(getPane())) {
char *msg=PR_smprintf(XP_GetString(XFE_MN_DELIVERY_IN_PROGRESS));
if (msg) {
fe_Alert_2(getBaseWidget(),msg);
XP_FREE(msg);
}
return FALSE;
}
#endif
return TRUE;
}
//
// entry points for external objects to control attachments
//
void XFE_ComposeAttachFolderView::attachFile()
{
if (_attachFileDialog==NULL) {
_attachFileDialog=new XFE_ComposeAttachFileDialog(this);
_attachFileDialog->createWidgets(getBaseWidget());
}
_attachFileDialog->show();
}
void XFE_ComposeAttachFolderView::attachLocation()
{
if (_attachLocationDialog==NULL) {
_attachLocationDialog=new XFE_ComposeAttachLocationDialog(this);
_attachLocationDialog->createWidgets(getBaseWidget());
}
_attachLocationDialog->show();
}
void XFE_ComposeAttachFolderView::deleteAttach()
{
int pos=_attachPanel->currentSelectionPos();
if (pos>=0)
deleteAttachment(pos);
}
void XFE_ComposeAttachFolderView::openAttachment(int pos)
{
if (pos<0 || pos>=_attachPanel->numItems())
return;
// Disable preview of previously attached item. Need to resolve
// inconsistency when attaching URL pointing to cgi. Preview
// will reload the URL, and the return data may differ from the
// data previously loaded by the mail back-end. i.e. it will
// not be a useful preview.
#if 0
// ensure clicked item is selected
if (pos!=_attachPanel->currentSelectionPos() && _attachPanel->items())
_attachPanel->selectItem(_attachPanel->items()[pos]);
XFE_AttachPanelItem *item=_attachPanel->currentSelection();
if (!item || !item->data())
return;
URL_Struct *url = NET_CreateURLStruct (item->data(),NET_DONT_RELOAD);
if (!MSG_RequiresBrowserWindow(url->address))
fe_GetURL(_context,url,FALSE);
else
fe_MakeWindow(XtParent(CONTEXT_WIDGET (_context)), _context, url, NULL,
MWContextBrowser, FALSE);
fe_UserActivity(_context);
#endif
}
//
// XFE_ComposeAttachPanel
//
// constructor
XFE_ComposeAttachPanel::XFE_ComposeAttachPanel(XFE_ComposeAttachFolderView *folder,MWContext *context) :
XFE_AttachPanel(context)
{
_attachFolder=folder;
_dropSite=NULL;
_iconTranslations=fe_globalData.mailcompose_global_translations;
}
// destructor
XFE_ComposeAttachPanel::~XFE_ComposeAttachPanel()
{
if (_dropSite)
delete _dropSite;
}
// create Motif UI
void XFE_ComposeAttachPanel::createWidgets(Widget parent)
{
// create panel UI
XFE_AttachPanel::createWidgets(parent);
// register drop site
_dropSite=new XFE_ComposeAttachDrop(_topClip,this);
}
// manage button state
void XFE_ComposeAttachPanel::updateSelectionUI()
{
// update attach folder UI - Delete menu item state depends on selection
_attachFolder->updateSelectionUI();
}
// handle double-click - open selected attachment
void XFE_ComposeAttachPanel::doubleClickCb(int pos)
{
_attachFolder->openAttachment(pos);
}
// panel management
void XFE_ComposeAttachPanel::show()
{
XFE_AttachPanel::show();
if (_dropSite) _dropSite->enable();
}
void XFE_ComposeAttachPanel::hide()
{
XFE_AttachPanel::hide();
if (_dropSite) _dropSite->disable();
}
void XFE_ComposeAttachPanel::setSensitive(Boolean sensitive)
{
XFE_AttachPanel::setSensitive(sensitive);
if (sensitive)
if (_dropSite) _dropSite->enable();
else
if (_dropSite) _dropSite->disable();
}
// drop management - pass through to XFE_ComposeAttachFolderView
int XFE_ComposeAttachPanel::dropAttachments(const char **item,int numItems)
{
int dropStatus=_attachFolder->addAttachments(item,numItems);
// ensure last-added item is visible
if (dropStatus)
scrollToItem(_numItems-1);
return dropStatus;
}
int XFE_ComposeAttachPanel::dropAttachment(const char *item)
{
int dropStatus=_attachFolder->addAttachment(item);
// ensure last item is visible
// ensure last-added item is visible
if (dropStatus)
scrollToItem(_numItems-1);
return dropStatus;
}
static int IsWebJumper(const char *url)
{
const char *filename=url;
// make sure it's a file
if (XP_STRNCASECMP(url,"file:",5)==0)
filename=url+5;
if (strlen(filename)==0 || filename[0]!='/')
return FALSE;
// check for SGI WebJumper
FILE *fp;
int retval=FALSE;
if (fp=fopen(filename,"r")) {
const int MAX_LENGTH=4000;
char line[MAX_LENGTH+1];
line[MAX_LENGTH]='\0';
line[0]='\0'; // ensure string will be null-terminated
fgets(line,MAX_LENGTH,fp);
if (XFE_WebJumperDesktopType::isDesktopType(line)) {
retval=TRUE;
}
fclose(fp);
}
return retval;
}
//
// XFE_ComposeAttachDrop
//
// constructor
XFE_ComposeAttachDrop::XFE_ComposeAttachDrop(Widget parent,XFE_ComposeAttachPanel *attach)
: XFE_DropNetscape(parent)
{
_attachPanel=attach;
}
// destructor
XFE_ComposeAttachDrop::~XFE_ComposeAttachDrop()
{
}
//
// methods below override DragFile defaults
//
// set _operations
void XFE_ComposeAttachDrop::operations()
{
// restrict attachment drop site to copy-only
_operations=(unsigned int)XmDROP_COPY;
}
// set _targets
void XFE_ComposeAttachDrop::targets()
{
_numTargets=2;
_targets=new Atom[_numTargets];
_targets[0]=_XA_NETSCAPE_URL;
_targets[1]=XA_STRING;
acceptFileTargets();
}
// process drop
int XFE_ComposeAttachDrop::processTargets(Atom *targets,const char **data,int numItems)
{
XDEBUG(printf("XFE_ComposeAttachDrop::processTargets()\n"));
if (!targets || !data || numItems==0)
return FALSE;
// pass dropped data to attachment panel
char **dropInfo=new char*[numItems];
int numDropInfo=0;
int i;
for (i=0;i<numItems;i++) {
if (targets[i]==None || data[i]==NULL || strlen(data[i])==0)
continue;
XDEBUG(printf(" [%d] %s: \"%s\"\n",i,XmGetAtomName(XtDisplay(_widget),targets[i]),data[i]));
if (targets[i]==_XA_FILE_NAME) {
dropInfo[numDropInfo++]=XP_STRDUP(data[i]);
}
if (targets[i]==_XA_NETSCAPE_URL) {
XFE_URLDesktopType urlData(data[i]);
for (int j=0;j<urlData.numItems();j++) {
dropInfo[numDropInfo++]=XP_STRDUP(urlData.url(j));
}
}
if (targets[i]==XA_STRING) {
dropInfo[numDropInfo++]=XP_STRDUP(data[i]);
}
}
int dropStatus=_attachPanel->dropAttachments((const char **)dropInfo,numDropInfo);
// free drop info
for(i=0;i<numDropInfo; i++)
if (dropInfo[i])
XP_FREE(dropInfo[i]);
delete dropInfo;
return dropStatus;
}
#if !defined(USE_MOTIF_DND)
//
// callback methods
//
void XFE_ComposeAttachFolderView::processMessageDrop(fe_dnd_Source *source)
{
#ifdef MOZ_MAIL_NEWS
XFE_ThreadView *threadView=(XFE_ThreadView*)source->closure;
XFE_Outliner *outliner=threadView->getOutliner();
const int *selectedList;
int numSelected;
if (outliner->getSelection(&selectedList, &numSelected)) {
char **items=new char*[numSelected];
int numItems=0;
int i;
for (i=0; i<numSelected; i++) {
MessageKey key=MSG_GetMessageKey(threadView->getPane(),selectedList[i]);
URL_Struct *messageURL=MSG_ConstructUrlForMessage(threadView->getPane(),key);
if (messageURL && messageURL->address) {
XDEBUG(printf(" %d:%s\n",selectedList[i],messageURL->address));
items[numItems++]=XP_STRDUP(messageURL->address);
}
if (messageURL)
NET_FreeURLStruct(messageURL);
}
if (numItems>0)
addAttachments((const char **) items,numItems);
for (i=0; i<numItems; i++)
XP_FREE(items[i]);
delete items;
}
#endif /* MOZ_MAIL_NEWS */
}
// internal drop management
void XFE_ComposeAttachFolderView::attachDropCb(fe_dnd_Source *source)
{
XDEBUG(printf("XFE_ComposeAttachFolderView::attachDropCb()\n"));
switch (source->type) {
// Interesting
case FE_DND_MAIL_MESSAGE:
case FE_DND_NEWS_MESSAGE:
processMessageDrop(source);
break;
case FE_DND_BOOKMARK:
/*xxxslamm: ripped out old bookmarks. To be replaced by RDF*/
break;
case FE_DND_HISTORY:
/*xxxslamm: ripped out old history. To be replaced by RDF*/
break;
// maybe interesting
case FE_DND_ADDRESSBOOK:
XDEBUG(printf(" AddressBook\n"));
break;
case FE_DND_URL:
XDEBUG(printf(" URL\n"));
break;
// Not interesting
case FE_DND_MAIL_FOLDER:
XDEBUG(printf(" Mail Folder\n"));
break;
case FE_DND_NEWS_FOLDER:
XDEBUG(printf(" News Folder\n"));
break;
case FE_DND_NONE:
XDEBUG(printf(" None\n"));
break;
case FE_DND_COLUMN:
XDEBUG(printf(" Column\n"));
break;
default:
XDEBUG(printf(" unknown type:%d\n",source->type));
break;
}
}
#endif /* !USE_MOTIF_DND */