Mozilla/mozilla/cmd/xfe/src/ReadAttachPanel.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

465 lines
14 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.
*/
/*
ReadAttachPanel.cpp -- read window attachment panel
Created: Alastair Gourlay(SGI) c/o Dora Hsu<dora@netscape.com>, 26 Nov 1996
*/
// Classes in this file:
// XFE_ReadAttachPanel
//
#include "ReadAttachPanel.h"
#include <stdlib.h>
#include <Xm/XmAll.h>
#include "mozilla.h"
#include "xfe.h"
#include "net.h"
#include "icons.h"
#include "icondata.h"
#include "PopupMenu.h"
//
// XFE_ReadAttachPanel
//
// callback stubs
void XFE_ReadAttachPanel::OpenCb(Widget,XtPointer cd,XtPointer) {
XFE_ReadAttachPanel *ad=(XFE_ReadAttachPanel*)cd;
if (ad)
ad->openCb();
}
void XFE_ReadAttachPanel::SaveCb(Widget,XtPointer cd,XtPointer) {
XFE_ReadAttachPanel *ad=(XFE_ReadAttachPanel*)cd;
if (ad)
ad->saveCb();
}
void XFE_ReadAttachPanel::PropertiesCb(Widget,XtPointer cd,XtPointer) {
XFE_ReadAttachPanel *ad=(XFE_ReadAttachPanel*)cd;
if (ad)
ad->propertiesCb();
}
// constructor
XFE_ReadAttachPanel::XFE_ReadAttachPanel(MWContext* context)
: XFE_AttachPanel(context)
{
_attachments=NULL;
_pane=NULL;
_propertiesDialog=NULL;
_attachDrag=NULL;
multiClickEnabled(TRUE);
}
// destructor
XFE_ReadAttachPanel::~XFE_ReadAttachPanel()
{
// this may be causing double-free.. investigate MSG_Pane
// removeAllAttachments();
if (_attachDrag) {
delete _attachDrag;
_attachDrag=NULL;
}
}
// create Motif UI
void XFE_ReadAttachPanel::createWidgets(Widget parent)
{
// create panel UI
XFE_AttachPanel::createWidgets(parent);
// set up drag handler
Widget dragWidget=XtNameToWidget(getBaseWidget(),"*pane");
if (dragWidget)
_attachDrag=new XFE_ReadAttachDrag(dragWidget,this);
// create popup
Arg args[10];
int n=0;
// disable keyboard accelerators and naviagtion in popup - they cause
// crashes. In future, use XFE_PopupMenu when the menu items become real
// xfeCmd's - it is more robust.
XtSetArg(args[n],XmNtraversalOn,False);n++;
_popupMenu = XFE_PopupMenu::CreatePopupMenu(_popupParent,
"msgViewAttachPopup",args,n);
_open=XmCreatePushButtonGadget(_popupMenu,"open",NULL,0);
XtAddCallback(_open,XmNactivateCallback,OpenCb,this);
XtManageChild(_open);
_save=XmCreatePushButtonGadget(_popupMenu,"save",NULL,0);
XtAddCallback(_save,XmNactivateCallback,SaveCb,this);
XtManageChild(_save);
_properties=XmCreatePushButtonGadget(_popupMenu,"properties",NULL,0);
XtAddCallback(_properties,XmNactivateCallback,PropertiesCb,this);
XtManageChild(_properties);
initializePopupMenu();
}
void XFE_ReadAttachPanel::setPaneHeight(int height)
{
if (!getBaseWidget() || height<1 || height==getPaneHeight())
return;
int wasShown=isShown();
// if panel is shown, we need to hide/show to force XmPanedWindow to
// notice the height change
if (wasShown)
hide();
// XmPaned window hack to set height of a pane
XtVaSetValues(getBaseWidget(),
XmNpaneMinimum, height,
XmNpaneMaximum, height,
NULL);
if (wasShown)
show();
XtVaSetValues(getBaseWidget(),
XmNpaneMinimum, 1,
XmNpaneMaximum, 10000,
NULL);
}
int XFE_ReadAttachPanel::getPaneHeight()
{
if (!getBaseWidget())
return 0;
Dimension height;
XtVaGetValues(getBaseWidget(),
XmNheight, &height,
NULL);
return (int)height;
}
void XFE_ReadAttachPanel::addAttachments(MSG_Pane *pane,MSG_AttachmentData* data)
{
// adopt storage of backend attachment list, free in removeAllAttachments
_pane=pane;
_attachments=data;
MSG_AttachmentData* tmp;
for (tmp = data ; tmp->url ; tmp++) {
char *itemLabel=NULL;
// Hack around back-end not naming the sent v-card. Use
// description field: "Card for ...", to provide some
// uniqueness among received vcards.
if (tmp->real_name && XP_STRCASECMP(tmp->real_name,"vcard.vcf")==0 &&
tmp->description && strlen(tmp->description)>0) {
itemLabel=(char*)XP_ALLOC(strlen(tmp->description)+4+1);
sprintf(itemLabel,"%s.vcf",tmp->description);
}
// find a label for the attachment
else if (tmp->real_name && strlen(tmp->real_name)>0) {
itemLabel=XP_STRDUP(tmp->real_name);
} else if (tmp->description && strlen(tmp->description)>0) {
itemLabel=XP_STRDUP(tmp->description);
} else if (tmp->real_type && strlen(tmp->real_type)>0) {
itemLabel=XP_STRDUP(tmp->real_type);
} else {
itemLabel=XP_STRDUP("attachment");
}
// translate problem characters in label to '_'
char *s=itemLabel;
while (*s) {
if (*s==' ' || *s=='/' || *s=='\\')
*s='_';
s++;
}
XFE_AttachPanelItem *item = new
XFE_AttachPanelItem(this,
tmp->url,
itemLabel,
tmp->real_type);
addItem(item);
// add to drag handler
if (_attachDrag && item->image()) {
_attachDrag->addDragWidget(item->image());
}
if (itemLabel)
XP_FREE(itemLabel);
}
// select first attachment by default
if (_numItems>0)
selectItem(_items[0]);
}
void XFE_ReadAttachPanel::removeAllAttachments()
{
removeAllItems();
if (_pane && _attachments) {
MSG_FreeAttachmentList(_pane, _attachments);
_attachments=NULL;
}
// pop down attachment properties dialog, if it's managed
if (_propertiesDialog)
XtUnmanageChild(_propertiesDialog);
// unlock frame, just in case this call caused an in-progress
// drag to cancel without exiting fe_SaveSynchronousURL()
if (_attachDrag)
_attachDrag->unlockFrame();
}
void XFE_ReadAttachPanel::updateSelectionUI()
{
if (!_popupMenu)
return;
if (_currentSelection) {
XtSetSensitive(_open,TRUE);
XtSetSensitive(_save,TRUE);
XtSetSensitive(_properties,TRUE);
}
else {
XtSetSensitive(_open,FALSE);
XtSetSensitive(_save,FALSE);
XtSetSensitive(_properties,FALSE);
}
// if attachment properties dialog is already being displayed, update it.
if (_propertiesDialog && XtIsManaged(_propertiesDialog)) {
if (_currentSelection)
displayAttachmentProperties(currentSelectionPos());
}
}
void XFE_ReadAttachPanel::displayAttachmentProperties(int pos)
{
if (pos<0 || pos>=_numItems)
return;
if (!_propertiesDialog) {
// create properties dialog
Arg args[20];
int n;
Visual *v=0;
Colormap cmap=0;
Cardinal depth=0;
Widget shell=getBaseWidget();
while (!XtIsShell(shell)) shell=XtParent(shell);
XtVaGetValues(shell,XtNvisual,&v,XtNcolormap,&cmap,XtNdepth,&depth,NULL);
Pixel bg;
XtVaGetValues(getBaseWidget(),XmNbackground,&bg,NULL);
fe_icon attachIcon={ 0 };
fe_MakeIcon(_context,bg, &attachIcon, NULL,
M_ToggleAttach.width, M_ToggleAttach.height,
M_ToggleAttach.mono_bits, M_ToggleAttach.color_bits, M_ToggleAttach.mask_bits,
FALSE);
n=0;
XtSetArg(args[n],XmNvisual,v); n++;
XtSetArg(args[n],XmNdepth,depth); n++;
XtSetArg(args[n],XmNcolormap,cmap); n++;
XtSetArg(args[n],XmNdeleteResponse,XmUNMAP);n++;
XtSetArg(args[n],XmNautoUnmanage,TRUE);n++;
XtSetArg(args[n],XmNdialogStyle,XmDIALOG_MODELESS);n++;
XtSetArg(args[n],XmNmwmFunctions,MWM_FUNC_MOVE|MWM_FUNC_CLOSE);n++;
XtSetArg(args[n],XmNmwmDecorations,MWM_DECOR_BORDER|MWM_DECOR_TITLE|MWM_DECOR_MENU);n++;
if (attachIcon.pixmap) {
XtSetArg(args[n],XmNsymbolPixmap,attachIcon.pixmap);n++;
}
_propertiesDialog=XmCreateTemplateDialog(getBaseWidget(),"attachmentProps",args,n);
fe_HackDialogTranslations(_propertiesDialog);
fe_NukeBackingStore(_propertiesDialog);
Widget form=XmCreateForm(_propertiesDialog,"form",NULL,0);
XtManageChild(form);
n=0;
XtSetArg(args[n],XmNpacking,XmPACK_COLUMN); n++;
XtSetArg(args[n],XmNnumColumns,1); n++;
XtSetArg(args[n],XmNisAligned,FALSE); n++;
XtSetArg(args[n],XmNalignment,XmVERTICAL); n++;
XtSetArg(args[n],XmNleftAttachment,XmATTACH_FORM); n++;
XtSetArg(args[n],XmNtopAttachment,XmATTACH_FORM); n++;
XtSetArg(args[n],XmNbottomAttachment,XmATTACH_FORM); n++;
Widget labelRC=XmCreateRowColumn(form,"labelRC",args,n);
XtManageChild(labelRC);
n=0;
XtSetArg(args[n],XmNalignment,XmALIGNMENT_END);n++;
_nameLabel=XmCreateLabelGadget(labelRC,"nameLabel",args,n);
_typeLabel=XmCreateLabelGadget(labelRC,"typeLabel",args,n);
_encLabel=XmCreateLabelGadget(labelRC,"encLabel",args,n);
_descLabel=XmCreateLabelGadget(labelRC,"descLabel",args,n);
n=0;
XtSetArg(args[n],XmNpacking,XmPACK_COLUMN); n++;
XtSetArg(args[n],XmNnumColumns,1); n++;
XtSetArg(args[n],XmNisAligned,FALSE); n++;
XtSetArg(args[n],XmNalignment,XmVERTICAL); n++;
XtSetArg(args[n],XmNleftAttachment,XmATTACH_WIDGET); n++;
XtSetArg(args[n],XmNleftWidget,labelRC); n++;
XtSetArg(args[n],XmNrightAttachment,XmATTACH_FORM); n++;
XtSetArg(args[n],XmNtopAttachment,XmATTACH_FORM); n++;
XtSetArg(args[n],XmNbottomAttachment,XmATTACH_FORM); n++;
Widget valueRC=XmCreateRowColumn(form,"valueRC",args,n);
XtManageChild(valueRC);
n=0;
XtSetArg(args[n],XmNalignment,XmALIGNMENT_BEGINNING);n++;
_nameValue=XmCreateLabelGadget(valueRC,"nameValue",args,n);
_typeValue=XmCreateLabelGadget(valueRC,"typeValue",args,n);
_encValue=XmCreateLabelGadget(valueRC,"encValue",args,n);
_descValue=XmCreateLabelGadget(valueRC,"descValue",args,n);
}
// set value of data fields, manage/unmanage relevent fields
XmString xs;
// file name
char *name=_attachments[pos].real_name;
if (name) {
xs=XmStringCreateLocalized(name);
XtVaSetValues(_nameValue,XmNlabelString,xs,NULL);
XmStringFree(xs);
XtManageChild(_nameLabel);
XtManageChild(_nameValue);
}
else {
XtUnmanageChild(_nameLabel);
XtUnmanageChild(_nameValue);
}
// mime type
char *type=_attachments[pos].real_type;
if (type) {
xs=XmStringCreateLocalized(type);
XtVaSetValues(_typeValue,XmNlabelString,xs,NULL);
XmStringFree(xs);
XtManageChild(_typeLabel);
XtManageChild(_typeValue);
}
else {
XtUnmanageChild(_typeLabel);
XtUnmanageChild(_typeValue);
}
// encoding
char *enc=_attachments[pos].real_encoding;
if (enc) {
xs=XmStringCreateLocalized(enc);
XtVaSetValues(_encValue,XmNlabelString,xs,NULL);
XmStringFree(xs);
XtManageChild(_encLabel);
XtManageChild(_encValue);
}
else {
XtUnmanageChild(_encLabel);
XtUnmanageChild(_encValue);
}
// long description
char *desc=_attachments[pos].description;
if (desc) {
xs=XmStringCreateLocalized(desc);
XtVaSetValues(_descValue,XmNlabelString,xs,NULL);
XmStringFree(xs);
XtManageChild(_descLabel);
XtManageChild(_descValue);
}
else {
XtUnmanageChild(_descLabel);
XtUnmanageChild(_descValue);
}
// manage widget if not already managed
XtManageChild(_propertiesDialog);
}
// internal callback methods
void XFE_ReadAttachPanel::doubleClickCb(int pos)
{
// ensure clicked item is selected
if (pos!=currentSelectionPos() && _items && pos >=0 && pos < _numItems)
selectItem(_items[pos]);
openCb();
}
void XFE_ReadAttachPanel::openCb()
{
if (!currentSelection())
return;
const char *selData=currentSelection()->data();
if (!selData || strlen(selData)==0)
return;
URL_Struct *url = NET_CreateURLStruct (selData,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);
}
void XFE_ReadAttachPanel::saveCb()
{
if (!currentSelection() || !currentSelection()->data())
return;
URL_Struct *url = NET_CreateURLStruct (currentSelection()->data(),NET_DONT_RELOAD);
if (url)
fe_SaveURL(_context,url);
}
void XFE_ReadAttachPanel::propertiesCb()
{
int pos=currentSelectionPos();
if (pos<0 || pos>=_numItems)
return;
displayAttachmentProperties(pos);
}