home *** CD-ROM | disk | FTP | other *** search
- /* -*- 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.
- */
- /*
- AttachPanel.cpp -- panel for displaying icon view of attached files.
- Created: Alastair Gourlay(SGI) c/o Dora Hsu<dora@netscape.com>, 26 Nov 1996
- */
-
-
-
- // Classes in this file:
- // XFE_AttachPanel
- // XFE_AttachPanelItem
- //
-
-
- #include "AttachPanel.h"
- #include <stdlib.h>
- #include <Xm/XmAll.h>
- #include <X11/cursorfont.h>
- #include "mozilla.h"
- #include "xfe.h"
- #include "net.h"
- #include "icons.h"
- #include "icondata.h"
- #include "DragDrop.h"
-
- #ifdef DEBUG_sgidev
- #define XDEBUG(x) x
- #else
- #define XDEBUG(x)
- #endif
-
- //
- // XFE_AttachPanel
- //
-
- // static initialization
-
- const int XFE_AttachPanel::_allocIncrement=50; // item list management
- const int XFE_AttachPanel::_marginWidth=5; // panel margin
- const int XFE_AttachPanel::_marginHeight=5; // panel margin
- const int XFE_AttachPanel::_horizSpacing=10; // panel spacing
-
- #define ATTACH_ICON_NAME "attachItemImage"
- #define ATTACH_LABEL_NAME "attachItemLabel"
-
- // callback stubs
-
- void XFE_AttachPanel::ExposeCb(Widget,XtPointer cd,XtPointer) {
- XFE_AttachPanel *ad=(XFE_AttachPanel*)cd;
- if (ad && ad->_firstExpose) {
- ad->_firstExpose=FALSE;
- ad->realize();
- }
- }
-
- void XFE_AttachPanel::InputCb(Widget,XtPointer cd,XtPointer cb) {
- XFE_AttachPanel *ad=(XFE_AttachPanel*)cd;
-
- if (ad && cb) {
- XmDrawingAreaCallbackStruct *dcb=(XmDrawingAreaCallbackStruct*)cb;
- ad->inputCb(dcb->event);
- }
- }
-
- void XFE_AttachPanel::ScrollTraversalCb(Widget,XtPointer cd,XtPointer cb) {
- XFE_AttachPanel *ad=(XFE_AttachPanel*)cd;
- XmTraverseObscuredCallbackStruct *scb=(XmTraverseObscuredCallbackStruct*)cb;
- if (ad && ad->_traversalProcId==0 &&
- scb && scb->reason==XmCR_OBSCURED_TRAVERSAL) {
- // delay scroll until after completion of armCb(). Of course :)
- // if only Motif passed a valid cb->event, all this would be unecessary
- ad->_traversalWidget=scb->traversal_destination;
- ad->_traversalProcId=XtAppAddTimeOut(XtWidgetToApplicationContext(ad->_top),
- 0,ScrollTraversalProc,cd);
- }
- }
-
- void XFE_AttachPanel::ScrollTraversalProc(XtPointer cd, XtIntervalId *id) {
- XFE_AttachPanel *ad=(XFE_AttachPanel*)cd;
- if (ad) {
- if (ad->_traversalProcId==*id)
- ad->_traversalProcId=0;
- if (ad->_traversalWidget) {
- ad->scrollTraversalProc(ad->_traversalWidget);
- ad->_traversalWidget=NULL;
- }
- }
- }
-
- void XFE_AttachPanel::ScrollResizeCb(Widget,XtPointer cd,XtPointer) {
- XFE_AttachPanel *ad=(XFE_AttachPanel*)cd;
- if (ad && ad->_resizeProcId==0) {
- // delay resize until after completion of resize callback. Of course :)
- ad->_resizeProcId=XtAppAddTimeOut(XtWidgetToApplicationContext(ad->_top),
- 0,ScrollResizeProc,cd);
- }
- }
- void XFE_AttachPanel::ScrollResizeProc(XtPointer cd, XtIntervalId *id) {
- XFE_AttachPanel *ad=(XFE_AttachPanel*)cd;
- if (ad) {
- if (ad->_resizeProcId==*id)
- ad->_resizeProcId=0;
- ad->scrollResizeProc();
- }
- }
-
-
- void XFE_AttachPanel::PopupProc(Widget,XtPointer cd,XEvent *event,Boolean*)
- {
- XFE_AttachPanel *ad=(XFE_AttachPanel*)cd;
-
- if (!ad->_popupMenu) return;
- if (event->xany.type!=ButtonPress) return;
- if (((XButtonEvent *)event)->button != Button3) return;
- if (((XButtonEvent *)event)->time <= ad->_popupLastEventTime) return;
- XmMenuPosition(ad->_popupMenu,(XButtonEvent*)event);
- XtManageChild (ad->_popupMenu);
- }
-
- /* By default, cancelling a popup menu with Button 3 will cause the
- * popup to be reposted at the location of the cancelling click.
- *
- * To switch off this behavior, remember when the menu was popped down.
- * In PopupHandler, don't repost the menu if the posting click just
- * cancelled a popup menu.
- */
- void XFE_AttachPanel::PopdownCb(Widget w,XtPointer cd,XtPointer)
- {
- XFE_AttachPanel *ad=(XFE_AttachPanel*)cd;
-
- ad->_popupLastEventTime = XtLastTimestampProcessed (XtDisplay(w));
- }
-
-
-
- // constructor
-
- XFE_AttachPanel::XFE_AttachPanel(MWContext* context) : XFE_Component()
- {
- _context=context;
-
- _inDestructor=FALSE;
- _parent=NULL;
- _top=NULL;
- _topClip=NULL;
- _topScrollBar=NULL;
- _pane=NULL;
- _resizeProcId=0;
- _traversalProcId=0;
- _firstExpose=TRUE;
- _popupParent=NULL;
- _popupMenu=NULL;
- _popupLastEventTime=0;
- _armedWidget=NULL;
- _traversalWidget=NULL;
- _multiClickEnabled=FALSE;
- _iconTranslations=NULL;
- _prefHeight=0;
-
- _items=NULL;
- _numItems=0;
- _allocItems=0;
- _currentSelection=NULL;
- }
-
- XFE_AttachPanel::~XFE_AttachPanel()
- {
- _inDestructor=TRUE;
-
- if (_resizeProcId!=0)
- XtRemoveTimeOut(_resizeProcId);
-
- if (_traversalProcId!=0)
- XtRemoveTimeOut(_traversalProcId);
-
- // XFE_Component will destroy the widget tree
- }
-
- void XFE_AttachPanel::createWidgets(Widget parent)
- {
- _parent=parent;
-
- Arg args[10];
-
- // toplevel scrolled window
-
- XtSetArg(args[0],XmNscrollingPolicy, XmAUTOMATIC);
- _top=XmCreateScrolledWindow(_parent,"attach",args,1);
- XtAddCallback(_top,XmNtraverseObscuredCallback,ScrollTraversalCb,(XtPointer)this);
- //XtManageChild(_top);
- Widget vsb;
- XtVaGetValues(_top,XmNverticalScrollBar,&vsb,NULL);
- if (vsb) XtVaSetValues(vsb,XmNtraversalOn,False,NULL);
-
- // attachment pane
- _pane=XmCreateDrawingArea(_top,"pane",NULL,0);
- XtVaSetValues(_pane,
- XmNmarginWidth,0,
- XmNmarginHeight,0,
- NULL);
- // nyi - best way to avoid multiple redraw?
- XtAddCallback(_pane,XmNexposeCallback,ExposeCb,(XtPointer)this);
- XtAddCallback(_pane,XmNinputCallback,InputCb,(XtPointer)this);
- XtManageChild(_pane);
-
- // only want vertical scrolling - make form track width of outer window
- Widget hsb;
- XtVaGetValues(_top,
- XmNclipWindow,&_topClip,
- XmNverticalScrollBar,&_topScrollBar,
- XmNhorizontalScrollBar,&hsb,
- NULL);
- if (XmIsDrawingArea(_topClip)) { // it better be!
- XtAddCallback(_topClip,XmNresizeCallback,ScrollResizeCb,(XtPointer)this);
- XtAddCallback(_topClip,XmNinputCallback,InputCb,(XtPointer)this);
- }
-
- // hide horizontal scrollbar - prevent it flickering on during resize
- if (hsb) {
- XtVaSetValues(hsb,
- XmNheight,1,
- XmNmappedWhenManaged,FALSE,
- NULL);
- }
-
- // make scroller background match child
- Pixel bg;
- XtVaGetValues(_pane,XmNbackground,&bg,NULL);
- XtVaSetValues(_topClip,XmNbackground,bg,NULL);
-
- _popupParent=_top;
-
- setBaseWidget(_top);
- }
-
- void XFE_AttachPanel::initializePopupMenu()
- {
- if (!_popupMenu || !_popupParent)
- return;
-
- XtAddEventHandler (_popupParent,ButtonPressMask,False,PopupProc,this);
- //XtAddCallback(XtParent(_popupMenu),XmNpopdownCallback,PopdownCb,this);
-
- updateSelectionUI();
- }
-
- //
- // item list management
- //
-
- void XFE_AttachPanel::addItem(const char *itemData,const char *itemLabel,const char *itemType,int pos)
- {
- if (!itemData || strlen(itemData)==0)
- return;
-
- XFE_AttachPanelItem *ai=new XFE_AttachPanelItem(this,itemData,itemLabel,itemType);
- addItem(ai,pos);
- }
-
-
- void XFE_AttachPanel::addItem(XFE_AttachPanelItem *newItem,int pos)
- {
- int i;
-
- if (pos==-1)
- pos=_numItems;
-
- if (pos<0 || pos>_numItems)
- return;
-
- // save pointer to passed item.
- // adopt it, and delete in removeItem(), destructor
- if (_numItems >= _allocItems) {
- _allocItems+=_allocIncrement;
- XFE_AttachPanelItem **newList=new XFE_AttachPanelItem*[_allocItems];
- for (i=0;i<_numItems;i++) {
- newList[i]=_items[i];
- _items[i]=NULL;
- }
- if (_items)
- delete _items;
- _items=newList;
- }
-
- for (i=_numItems;i>pos;i--) {
- _items[i]=_items[i-1];
- }
- _items[pos]=newItem;
- _numItems++;
- }
-
- int XFE_AttachPanel::findItem(XFE_AttachPanelItem *ai)
- {
- if (ai==NULL)
- return -1;
-
- for (int i=0;i<_numItems;i++) {
- if (_items[i]==ai) {
- return i;
- }
- }
- return -1;
- }
-
-
- void XFE_AttachPanel::removeItem(XFE_AttachPanelItem *item)
- {
- int pos=findItem(item);
-
- if (pos>=0)
- removeItem(pos);
- }
-
-
- void XFE_AttachPanel::removeItem(int r)
- {
- // Warning: never decreases list alloc'd size
- // if XFE_AttachPanel object is long-lived, then it should.
- // use removeAllItems() method to force a cleanup.
-
- if (r<0 || r>=_numItems)
- return;
-
- if (_items[r]) {
- // if focus is on last item, move it to last-but-one item
- // to ensure that attach panel keeps focus after delete.
- if (r==_numItems-1 && r>0) {
- Widget focusWidget=XmGetFocusWidget(getBaseWidget());
- Widget lastButOne=NULL;
- if (_items[r-1])
- lastButOne=_items[r-1]->image();
- if (focusWidget &&
- focusWidget==_items[r]->image() &&
- lastButOne!=NULL) {
- XmProcessTraversal(lastButOne,XmTRAVERSE_CURRENT);
- }
- }
-
- delete _items[r];
- }
-
- for (int i=r; i<_numItems-1;i++)
- _items[i]=_items[i+1];
- _items[_numItems-1]=NULL;
- _numItems--;
- }
-
-
- void XFE_AttachPanel::removeAllItems()
- {
- if (_items) {
- for (int i=0; i<_numItems;i++) {
- if (_items[i]) {
- if (_inDestructor)
- _items[i]->inParentDestructor();
- delete _items[i];
- _items[i]=NULL;
- }
- }
- delete _items;
- _items=NULL;
- _numItems=0;
- _allocItems=0;
- }
- }
-
-
- XFE_AttachPanelItem **XFE_AttachPanel::items()
- {
- return _items;
- }
-
-
- int XFE_AttachPanel::numItems()
- {
- return _numItems;
- }
-
- void XFE_AttachPanel::selectItem(XFE_AttachPanelItem* item)
- {
- if (!item || item->beingDestroyed())
- return;
-
- if (_currentSelection && item!=_currentSelection)
- _currentSelection->select(FALSE);
-
- item->select(TRUE);
- _currentSelection=item;
-
- updateSelectionUI();
- }
-
- void XFE_AttachPanel::deselectItem(XFE_AttachPanelItem* item)
- {
- if (!item || item!=_currentSelection)
- return;
-
- if (!item->beingDestroyed())
- item->select(FALSE);
-
- _currentSelection=NULL;
-
- updateSelectionUI();
- }
-
- //
- // display management
- //
-
- void XFE_AttachPanel::updateDisplay()
- {
- layout();
- }
-
- void XFE_AttachPanel::traverseItem(int pos)
- {
- if (pos<0 || pos >=_numItems)
- return;
-
- _items[pos]->traverse();
- }
-
- void XFE_AttachPanel::scrollToItem(int pos)
- {
- if (pos<0 || pos >=_numItems)
- return;
-
- _items[pos]->scrollVisible();
- }
-
- int XFE_AttachPanel::getPreferredHeight()
- {
- if (_prefHeight>0)
- return _prefHeight;
- else
- return 20;
- }
-
- //#define DEBUG_LAYOUT
- void XFE_AttachPanel::layout()
- {
- #if 0
- if (_firstExpose)
- return;
- #endif
-
- if (_items==NULL || _numItems==0)
- return;
-
- // examine items
- int i;
- int maxWidth=0;
- int maxHeight=0;
- for (i=0;i<_numItems;i++) {
- if (_items[i] && !_items[i]->beingDestroyed()) {
- _items[i]->calculatePrefGeometry();
- if (_items[i]->prefWidth()>maxWidth) maxWidth=_items[i]->prefWidth();
- if (_items[i]->prefHeight()>maxHeight) maxHeight=_items[i]->prefHeight();
-
- }
- }
-
- if (maxWidth==0 || maxHeight==0)
- return;
-
- // calculate basic parameters
- Position wd;
- XtVaGetValues(_topClip,XmNwidth,&wd,NULL);
- unsigned int availWidth=(unsigned int)(wd>2*_marginWidth ?
- (wd-2*_marginWidth) : 1);
- unsigned int vSpacing=(_items[0] ? _items[0]->labelHeight()/2 : 10);
- //nyi - need a good way to calc cell width - deal with large, rare cases
- unsigned int cellWidth=maxWidth+_horizSpacing;
- if (cellWidth<1) cellWidth=1;
- unsigned int cellHeight=maxHeight;
- int cellsPerRow=availWidth/cellWidth;
- if (cellsPerRow<1) cellsPerRow=1;
-
- // lay out row by row.
- // give each item enough cells to prevent overlap
- #ifdef DEBUG_LAYOUT
- printf("\nlayout()\n\n");
- printf(" availWidth=%d\n",availWidth);
- printf(" cellWidth=%d\n",cellWidth);
- printf(" cellHeight=%d\n",cellHeight);
- printf(" cellsPerRow=%d\n",cellsPerRow);
- printf("\n");
- #endif
-
- int itemPos=0;
- int cellNum=0;
- int row=0;
-
- // if an icon has focus, restore it when we remap the pane
- Widget focusWidget=XmGetFocusWidget(_top);
- if (focusWidget && XtParent(focusWidget)!=_pane)
- focusWidget=NULL;
-
- unmapPane();
-
- // calculate ideal height for this layout + border
- Dimension st;
- XtVaGetValues(_top,XmNshadowThickness,&st,NULL);
- _prefHeight=2*st + 2*_marginHeight + cellHeight + vSpacing;
-
- // do layout
- while (itemPos<_numItems) {
- #ifdef DEBUG_LAYOUT
- printf("[%d]\n",itemPos);
- #endif
- if (_items[itemPos] && !_items[itemPos]->beingDestroyed()) {
- int numCells=_items[itemPos]->prefWidth()/cellWidth + 1;
- if (numCells>cellsPerRow) numCells=cellsPerRow;
- #ifdef DEBUG_LAYOUT
- printf(" numCells=%d\n",numCells);
- #endif
- // see if it makes sense to move to a new row
- if (numCells>cellsPerRow-cellNum && cellNum!=0) {
- row++;
- _prefHeight+=cellHeight+vSpacing;
- cellNum=0;
- }
- #ifdef DEBUG_LAYOUT
- printf(" row:%d-%d (%d,%d) %dx%d\n",
- row,cellNum,
- cellNum*cellWidth,row*cellHeight,
- numCells*cellWidth,cellHeight);
- #endif
-
- //do layout
- _items[itemPos]->layout(_marginWidth+cellNum*cellWidth,
- _marginHeight+row*(cellHeight+vSpacing),
- numCells*cellWidth,
- cellHeight);
- cellNum+=numCells;
- }
- itemPos++;
- }
-
- mapPane();
-
- // restore focus if we had it before the unmapPane()
- if (focusWidget)
- XmProcessTraversal(focusWidget,XmTRAVERSE_CURRENT);
- }
-
- void XFE_AttachPanel::mapPane()
- {
- if (_pane)
- XtSetMappedWhenManaged(_pane,TRUE);
- if (_topScrollBar)
- XtSetMappedWhenManaged(_topScrollBar,TRUE);
- }
-
- void XFE_AttachPanel::unmapPane()
- {
- if (_pane)
- XtSetMappedWhenManaged(_pane,FALSE);
- if (_topScrollBar)
- XtSetMappedWhenManaged(_topScrollBar,FALSE);
- }
-
- int XFE_AttachPanel::isAttachPanelWidget(Widget w)
- {
- if (w==NULL)
- return FALSE;
-
- if (w==_top ||
- w==_topClip ||
- w==_topScrollBar ||
- w==_pane ||
- XtParent(w)==_pane)
- return TRUE;
-
- return FALSE;
- }
-
-
- //
- // callback methods
- //
-
- void XFE_AttachPanel::realize()
- {
- // realize processing for existing items
- if (_items) {
- for (int i=0;i<_numItems;i++)
- _items[i]->realize();
- layout();
- }
- }
-
- void XFE_AttachPanel::doubleClickCb(int)
- {
- // no default double-click action - it's for the derived classes.
- }
-
- void XFE_AttachPanel::inputCb(XEvent *event)
- {
- // button up on panel background cancels selection
- if (_currentSelection!=NULL &&
- event &&
- event->xany.type==ButtonRelease &&
- event->xbutton.button==1) {
- deselectItem(_currentSelection);
- }
- }
-
-
- void XFE_AttachPanel::scrollTraversalProc(Widget dest)
- {
- // let disarmCb handle scrolling for button click
- if (!dest || dest==_armedWidget)
- return;
-
- char *destName=XtName(dest);
- if (!destName || strcmp(destName,ATTACH_ICON_NAME)!=0)
- return;
-
- // if this is the icon of XFE_AttachItem, scroll it into view.
- XtPointer userData;
- XtVaGetValues(dest,XmNuserData,&userData,NULL);
- if (!userData)
- return;
-
- XFE_AttachPanelItem *ai=(XFE_AttachPanelItem*)userData;
-
- ai->scrollVisible();
- }
-
- void XFE_AttachPanelItem::scrollVisible()
- {
- // scroll to icon, with enough margin to show label
-
- XmScrollVisible(_attachPanel->getBaseWidget(),_image,0,labelHeight()+2);
- XmScrollVisible(_attachPanel->getBaseWidget(),_label,0,0);
- }
-
- void XFE_AttachPanel::scrollResizeProc()
- {
- const int rspace=10; // must be >= 2, or window will oscillate
- Dimension width;
-
- if (!_topClip || !_pane)
- return;
-
- XtVaGetValues(_topClip,XmNwidth,&width,NULL);
- if (width<rspace+1)
- width=rspace+1;
- XtVaSetValues(_pane,XmNwidth,width-rspace,NULL);
-
- layout();
- }
-
- //
- // XFE_AttachPanelItem
- //
-
- // static initialization
-
- Pixmap XFE_AttachPanelItem::_audioPixmap=XmUNSPECIFIED_PIXMAP;
- Pixmap XFE_AttachPanelItem::_binaryPixmap=XmUNSPECIFIED_PIXMAP;
- Pixmap XFE_AttachPanelItem::_imagePixmap=XmUNSPECIFIED_PIXMAP;
- Pixmap XFE_AttachPanelItem::_messagePixmap=XmUNSPECIFIED_PIXMAP;
- Pixmap XFE_AttachPanelItem::_moviePixmap=XmUNSPECIFIED_PIXMAP;
- Pixmap XFE_AttachPanelItem::_textPixmap=XmUNSPECIFIED_PIXMAP;
- Pixmap XFE_AttachPanelItem::_unknownPixmap=XmUNSPECIFIED_PIXMAP;
- Pixmap XFE_AttachPanelItem::_vcardPixmap=XmUNSPECIFIED_PIXMAP;
- Pixmap XFE_AttachPanelItem::_urlPixmap=XmUNSPECIFIED_PIXMAP;
- Cursor XFE_AttachPanelItem::_cursor=None;
-
-
- // callback stubs
-
- void XFE_AttachPanelItem::ActivateCb(Widget,XtPointer cd,XtPointer cb) {
- XFE_AttachPanelItem *ad=(XFE_AttachPanelItem*)cd;
- XmPushButtonCallbackStruct *pcb=(XmPushButtonCallbackStruct*)cb;
-
- if (ad && pcb) {
- if (ad->_attachPanel->multiClickEnabled()) {
- switch(pcb->click_count) {
- case 1: ad->activateCb(); break;
- case 2: ad->doubleClickCb(); break;
- default: break;
- }
- }
- else {
- ad->activateCb();
- }
- }
- }
-
- void XFE_AttachPanelItem::ArmCb(Widget w,XtPointer cd,XtPointer) {
- XFE_AttachPanelItem *ad=(XFE_AttachPanelItem*)cd;
- if (ad)
- ad->armCb(w);
- }
-
- void XFE_AttachPanelItem::DisarmCb(Widget,XtPointer cd,XtPointer) {
- XFE_AttachPanelItem *ad=(XFE_AttachPanelItem*)cd;
- if (ad)
- ad->disarmCb();
- }
-
-
- // constructor
-
- XFE_AttachPanelItem::XFE_AttachPanelItem(XFE_AttachPanel *attach,
- const char *data,
- const char *dataLabel,
- const char *dataType)
- {
- _attachPanel=attach;
-
- _inParentDestructor=FALSE;
- _beingDestroyed=FALSE;
-
- if (data)
- _data=strdup(data);
- else
- _data=NULL;
-
- if (dataLabel)
- _dataLabel=strdup(dataLabel);
- else
- _dataLabel=(_data ? strdup(_data) : (char*)NULL);
-
- if (dataType) {
- // app specified a mime type for this data
- _dataType=strdup(dataType);
- }
- else {
- // try to determine type of attachment
- _dataType=strdup(XFE_DragBase::guessUrlMimeType(data));
- }
-
- _parent=_attachPanel->pane();
-
- _image=NULL;
- _label=NULL;
- _prefWidth=1;
- _prefHeight=1;
-
- // use link cursor over attach icons to indicate that they are active
- if (_cursor==None)
- _cursor=CONTEXT_DATA(_attachPanel->context())->link_cursor;
-
- // create widgets
-
- Arg args[10];
-
- Pixel bg;
- XtVaGetValues(_parent,XmNbackground,&bg,NULL);
-
- // image
-
- XtSetArg(args[0],XmNbackground,bg);
- _image=XmCreatePushButton(_parent,ATTACH_ICON_NAME,args,1);
- XtVaSetValues(_image,
- XmNalignment,XmALIGNMENT_CENTER,
- XmNshadowThickness,0,
- XmNmarginWidth,0,
- XmNmarginHeight,0,
- XmNlabelType,XmPIXMAP,
- XmNlabelPixmap,iconPixmap(),
- XmNarmColor,bg,
- XmNmultiClick,XmMULTICLICK_KEEP,
- XmNuserData,(XtPointer)this, // scrollTraversalProc needs to get to item class
- NULL);
- XtAddCallback(_image,XmNactivateCallback,ActivateCb,(XtPointer)this);
- XtAddCallback(_image,XmNarmCallback,ArmCb,(XtPointer)this);
- XtAddCallback(_image,XmNdisarmCallback,DisarmCb,(XtPointer)this);
- if (_attachPanel->iconTranslations())
- XtOverrideTranslations(_image,_attachPanel->iconTranslations());
-
- // label
-
- XtSetArg(args[0],XmNbackground,bg);
- _label=XmCreateLabel(_parent,ATTACH_LABEL_NAME,args,1);
- XmString xms=XmStringCreateLocalized(_dataLabel ? _dataLabel : "");
- XtVaSetValues(_label,
- XmNalignment,XmALIGNMENT_CENTER,
- XmNshadowThickness,0,
- //XmNmarginWidth,0,
- //XmNmarginHeight,0,
- XmNlabelString,xms,
- XmNuserData,FALSE, // selection marker for AttachPanelItem::select()
- NULL);
- XmStringFree(xms);
-
- show();
- calculatePrefGeometry();
- if (XtWindow(_image)) {
- XDefineCursor(XtDisplay(_image),XtWindow(_image),_cursor);
- }
- }
-
- // destructor
-
- XFE_AttachPanelItem::~XFE_AttachPanelItem()
- {
- _beingDestroyed=TRUE;
-
- if (this==_attachPanel->currentSelection())
- _attachPanel->deselectItem(this);
-
- if (_data)
- free((void*)_data);
-
- if (_dataLabel)
- free((void*)_dataLabel);
-
- if (_dataType)
- free((void*)_dataType);
-
- if (_image) {
- XtUnmanageChild(_image);
- if (!_inParentDestructor)
- XtDestroyWidget(_image);
- }
-
- if (_label) {
- XtUnmanageChild(_label);
- if (!_inParentDestructor)
- XtDestroyWidget(_label);
- }
- }
-
- void XFE_AttachPanelItem::inParentDestructor()
- {
- _inParentDestructor=TRUE;
- }
-
- void XFE_AttachPanelItem::realize()
- {
- if (_image) {
- XtVaSetValues(_image,XmNlabelPixmap,iconPixmap(),NULL);
- calculatePrefGeometry();
- XDefineCursor(XtDisplay(_image),XtWindow(_image),_cursor);
- }
-
- if (this==_attachPanel->currentSelection())
- select(TRUE);
- else
- select(FALSE);
- }
-
-
- // this method should only be called when creating item.
-
- Pixmap XFE_AttachPanelItem::iconPixmap()
- {
- if (!XtIsRealized(_parent))
- return XmUNSPECIFIED_PIXMAP;
-
- XDEBUG(printf("iconPixmap(%s)\n",_dataType?_dataType:"NULL"));
-
- // return pixmap matching item's mime type
- // create Pixmaps on first request
-
- MWContext *context=_attachPanel->context();
-
- Pixel bg;
- XtVaGetValues(_parent,XmNbackground,&bg,NULL);
-
- if (!_dataType ||
- strcmp(_dataType,UNKNOWN_CONTENT_TYPE)==0) {
- if (_unknownPixmap==XmUNSPECIFIED_PIXMAP) {
- fe_icon icon={ 0 };
- fe_MakeIcon(context,bg, &icon, NULL,
- GUnknown.width, GUnknown.height,
- GUnknown.mono_bits, GUnknown.color_bits, GUnknown.mask_bits,
- FALSE);
- _unknownPixmap=icon.pixmap;
- }
- return _unknownPixmap;
- }
-
- // internal type name - used for attached document URL's
- if (strncmp(_dataType,"_url",5)==0){
- if (_urlPixmap==XmUNSPECIFIED_PIXMAP) {
- fe_icon icon={ 0 };
- fe_MakeIcon(context,bg, &icon, NULL,
- LocationProxy.width, LocationProxy.height,
- LocationProxy.mono_bits, LocationProxy.color_bits, LocationProxy.mask_bits,
- FALSE);
- _urlPixmap=icon.pixmap;
- }
- return _urlPixmap;
- }
-
- if (strncmp(_dataType,"audio",5)==0){
- if (_audioPixmap==XmUNSPECIFIED_PIXMAP) {
- fe_icon icon={ 0 };
- fe_MakeIcon(context,bg, &icon, NULL,
- GAudio.width, GAudio.height,
- GAudio.mono_bits, GAudio.color_bits, GAudio.mask_bits,
- FALSE);
- _audioPixmap=icon.pixmap;
- }
- return _audioPixmap;
- }
-
- if (strncmp(_dataType,"application",11)==0) {
- if (_binaryPixmap==XmUNSPECIFIED_PIXMAP) {
- fe_icon icon={ 0 };
- fe_MakeIcon(context,bg, &icon, NULL,
- GBinary.width, GBinary.height,
- GBinary.mono_bits, GBinary.color_bits, GBinary.mask_bits,
- FALSE);
- _binaryPixmap=icon.pixmap;
- }
- return _binaryPixmap;
- }
-
- if (strncmp(_dataType,"image",5)==0) {
- if (_imagePixmap==XmUNSPECIFIED_PIXMAP) {
- fe_icon icon={ 0 };
- fe_MakeIcon(context,bg, &icon, NULL,
- GImage.width, GImage.height,
- GImage.mono_bits, GImage.color_bits, GImage.mask_bits,
- FALSE);
- _imagePixmap=icon.pixmap;
- }
- return _imagePixmap;
- }
-
- if (strncmp(_dataType,"message",7)==0) {
- if (_messagePixmap==XmUNSPECIFIED_PIXMAP) {
- fe_icon icon={ 0 };
- fe_MakeIcon(context,bg, &icon, NULL,
- MNTB_Forward.width, MNTB_Forward.height,
- MNTB_Forward.mono_bits, MNTB_Forward.color_bits, MNTB_Forward.mask_bits,
- FALSE);
- _messagePixmap=icon.pixmap;
- }
- return _messagePixmap;
- }
-
- if (strncmp(_dataType,"video",5)==0) {
- if (_moviePixmap==XmUNSPECIFIED_PIXMAP) {
- fe_icon icon={ 0 };
- fe_MakeIcon(context,bg, &icon, NULL,
- GMovie.width, GMovie.height,
- GMovie.mono_bits, GMovie.color_bits, GMovie.mask_bits,
- FALSE);
- _moviePixmap=icon.pixmap;
- }
- return _moviePixmap;
- }
-
- if (strcmp(_dataType,"text/x-vcard")==0) {
- if (_vcardPixmap==XmUNSPECIFIED_PIXMAP) {
- fe_icon icon={ 0 };
- fe_MakeIcon(context,bg, &icon, NULL,
- MNAB_NewPerson.width, MNAB_NewPerson.height,
- MNAB_NewPerson.mono_bits, MNAB_NewPerson.color_bits, MNAB_NewPerson.mask_bits,
- FALSE);
- _vcardPixmap=icon.pixmap;
- }
- return _vcardPixmap;
- }
-
- if (strncmp(_dataType,"text",4)==0) {
- if (_textPixmap==XmUNSPECIFIED_PIXMAP) {
- fe_icon icon={ 0 };
- fe_MakeIcon(context,bg, &icon, NULL,
- GText.width, GText.height,
- GText.mono_bits, GText.color_bits, GText.mask_bits,
- FALSE);
- _textPixmap=icon.pixmap;
- }
- return _textPixmap;
- }
-
- // fallback to generic document pixmap
-
- if (_unknownPixmap==XmUNSPECIFIED_PIXMAP) {
- fe_icon icon={ 0 };
- fe_MakeIcon(context,bg, &icon, NULL,
- GUnknown.width, GUnknown.height,
- GUnknown.mono_bits, GUnknown.color_bits, GUnknown.mask_bits,
- FALSE);
- _unknownPixmap=icon.pixmap;
- }
- return _unknownPixmap;
- }
-
-
- const char *XFE_AttachPanelItem::data()
- {
- return _data;
- }
-
- const char *XFE_AttachPanelItem::dataLabel()
- {
- return _dataLabel;
- }
-
- const char *XFE_AttachPanelItem::dataType()
- {
- return _dataType;
- }
-
- void XFE_AttachPanelItem::select(int selected)
- {
- // Hack to do selection highlight.
- // May need to do real X drawing in AttachPanel[Item]::exposeCb()
-
- if (_label) {
- Pixel fg;
- Pixel bg;
- XtPointer userData;
-
- XtVaGetValues(_label,
- XmNbackground,&bg,
- XmNforeground,&fg,
- XmNuserData,&userData,
- NULL);
-
- int labelHighlighted=(int)userData;
-
- if (selected && !labelHighlighted) {
- XtVaSetValues(_label,
- XmNbackground,fg,
- XmNforeground,bg,
- XmNuserData,1,
- NULL);
- }
-
- if (!selected && labelHighlighted) {
- XtVaSetValues(_label,
- XmNbackground,fg,
- XmNforeground,bg,
- XmNuserData,0,
- NULL);
- }
- }
- }
-
- void XFE_AttachPanelItem::calculatePrefGeometry()
- {
- Dimension iw,ih,lw,lh;
-
- XtVaGetValues(_image,
- XmNwidth,&iw,
- XmNheight,&ih,
- NULL);
- XtVaGetValues(_label,
- XmNwidth,&lw,
- XmNheight,&lh,
- NULL);
-
- _imageWidth=iw;
- _imageHeight=ih;
- _labelWidth=lw;
- _labelHeight=lh;
-
- // ? save image plus label geometry
- _prefWidth=(unsigned int)(iw>lw ? iw : lw);
- _prefHeight=(unsigned int)(ih+lh);
- }
-
- void XFE_AttachPanelItem::layout(int x, int y, unsigned int width, unsigned int height)
- {
- if (_label==NULL || _image==NULL ||
- _prefWidth==0 || _prefHeight==0 ||
- width==0 || height==0 )
- return;
-
- int imageX;
- int imageY;
- int labelX;
- int labelY;
-
- imageX=x+(width-_imageWidth)/2;
- imageY=y+height-_labelHeight-_imageHeight;
- labelX=x+(width-_labelWidth)/2;
- labelY=y+height-_labelHeight;
-
- XtVaSetValues(_image,
- XmNx,imageX,
- XmNy,imageY,
- NULL);
- XtVaSetValues(_label,
- XmNx,labelX,
- XmNy,labelY,
- NULL);
- }
-
-
- void XFE_AttachPanelItem::show()
- {
- if (_image)
- XtManageChild(_image);
- if (_label)
- XtManageChild(_label);
- }
-
- void XFE_AttachPanelItem::hide()
- {
- if (_image)
- XtUnmanageChild(_image);
- if (_label)
- XtUnmanageChild(_label);
- }
-
- void XFE_AttachPanelItem::traverse()
- {
- if (_image)
- XmProcessTraversal(_image,XmTRAVERSE_CURRENT);
- }
-
- //
- // callback methods
- //
-
- void XFE_AttachPanelItem::activateCb()
- {
- if (this!=_attachPanel->currentSelection())
- _attachPanel->selectItem(this);
- else
- _attachPanel->deselectItem(this);
- }
-
- void XFE_AttachPanelItem::doubleClickCb()
- {
- _attachPanel->doubleClickCb(_attachPanel->findItem(this));
- }
-
- void XFE_AttachPanelItem::armCb(Widget w)
- {
- // flag button as down, use to discard ScrollTraversalCb calls for button press
- // (since the event field in the traverseObscuredCallbackStruct is useless.)
-
- _attachPanel->armedWidget(w);
- }
-
- void XFE_AttachPanelItem::disarmCb()
- {
- _attachPanel->armedWidget(NULL);
-
- // make sure label is visible after BtnUp on icon
- scrollVisible();
- }
-
-
-