home *** CD-ROM | disk | FTP | other *** search
/ Tools / WinSN5.0Ver.iso / NETSCAP.50 / WIN1998.ZIP / ns / cmd / xfe / src / AddressFolderView.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1998-04-08  |  42.6 KB  |  1,566 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.    AddressFolderView.cpp -- presents view for addressing and attachment .
  20.    Created: Dora Hsu <dora@netscape.com>, 23-Sept-96.
  21.    */
  22.  
  23.  
  24.  
  25. #include "AddressFolderView.h"
  26. #include "AddressOutliner.h"
  27. #include "ABListSearchView.h"
  28. #include "ComposeFolderView.h"
  29. #include "ComposeAttachFolderView.h"
  30. #include "LdapSearchView.h"
  31. #include "xfe.h"
  32. #include "icondata.h"
  33. #include "msgcom.h"
  34. #include "xp_mem.h"
  35. #include "IconGroup.h"
  36. #include "Button.h"
  37.  
  38. #include <Xm/Xm.h>
  39. #include <XmL/Grid.h>
  40. #include "ComposeView.h"
  41. #include <xpgetstr.h> /* for XP_GetString() */
  42.  
  43. extern int XFE_MNC_ADDRESS_TO;
  44. extern int XFE_MNC_ADDRESS_CC;
  45. extern int XFE_MNC_ADDRESS_BCC;
  46. extern int XFE_MNC_ADDRESS_NEWSGROUP;
  47. extern int XFE_MNC_ADDRESS_REPLY;
  48. extern int XFE_MNC_ADDRESS_FOLLOWUP;
  49.  
  50. #ifdef DEBUG_dora
  51. #define XDEBUG(x) x
  52. #else
  53. #define XDEBUG(x)
  54. #endif
  55.  
  56. #define OUTLINER_GEOMETRY_PREF "mail.composition.addresspane.outliner_geometry"
  57.  
  58. static MSG_HEADER_SET standard_header_set[] = {
  59.     MSG_TO_HEADER_MASK,
  60.     MSG_CC_HEADER_MASK,
  61.     MSG_BCC_HEADER_MASK,
  62.     MSG_REPLY_TO_HEADER_MASK,
  63.     MSG_NEWSGROUPS_HEADER_MASK,
  64.     MSG_FOLLOWUP_TO_HEADER_MASK
  65.     };
  66.  
  67. #define TOTAL_HEADERS (sizeof(standard_header_set)/sizeof(MSG_HEADER_SET))
  68.  
  69. extern "C" char *fe_StringTrim (char *string);
  70. extern "C" char * xfe_ExpandName(char * pString, int* iconType, short* security);
  71.  
  72. extern "C"
  73. {
  74. XP_List* FE_GetDirServers();
  75. ABook*   fe_GetABook(MWContext *context);
  76. };
  77.  
  78.  
  79. const char *XFE_AddressFolderView::tabPrev = "XFE_AddressFolderView::tabPrev";
  80. const char *XFE_AddressFolderView::tabNext = "XFE_AddressFolderView::tabNext";
  81.  
  82. const char *XFE_AddressFolderView::TO = NULL;
  83. const char *XFE_AddressFolderView::CC = NULL;
  84. const char *XFE_AddressFolderView::BCC = NULL; 
  85. const char *XFE_AddressFolderView::NEWSGROUP = NULL;
  86. const char *XFE_AddressFolderView::REPLY = NULL;
  87. const char *XFE_AddressFolderView::FOLLOWUP =  NULL;
  88.  
  89. const int XFE_AddressFolderView::ADDRESS_OUTLINER_COLUMN_BTN = 0;
  90. const int XFE_AddressFolderView::ADDRESS_OUTLINER_COLUMN_TYPE = 1;
  91. const int XFE_AddressFolderView::ADDRESS_OUTLINER_COLUMN_ICON = 2;
  92. const int XFE_AddressFolderView::ADDRESS_OUTLINER_COLUMN_RECEIPIENT= 3;
  93.  
  94. #ifdef HAVE_ADDRESS_SECURITY_COLUMN
  95. const int XFE_AddressFolderView::ADDRESS_OUTLINER_COLUMN_SECURITY = 4;
  96. #endif
  97.  
  98. const int XFE_AddressFolderView::ADDRESS_ICON_PERSON = 0;
  99. const int XFE_AddressFolderView::ADDRESS_ICON_LIST = 1;
  100. const int XFE_AddressFolderView::ADDRESS_ICON_NEWS = 2;
  101.  
  102.  
  103. fe_icon XFE_AddressFolderView::arrowIcon = { 0 };
  104. fe_icon XFE_AddressFolderView::personIcon = { 0 };
  105. fe_icon XFE_AddressFolderView::listIcon = { 0 };
  106. fe_icon XFE_AddressFolderView::newsIcon = { 0 };
  107.  
  108. fe_icon XFE_AddressFolderView::securityIcon = { 0 };
  109.  
  110.  
  111. typedef enum {
  112.   AddressFolder_Add,
  113.   AddressFolder_Remove,
  114.   AddressFolder_Select,
  115.   AddressFolder_None
  116. } EAddressFolderActionState;
  117.  
  118.  
  119. extern "C" Widget
  120. fe_MailComposeAddress_CreateManaged(MWContext* context, Widget parent);
  121.  
  122.  
  123. extern XtAppContext fe_XtAppContext;
  124.  
  125. // Constructor
  126. XFE_AddressFolderView::XFE_AddressFolderView(
  127.             XFE_Component *toplevel_component, 
  128.             XFE_View *parent_view,
  129.             MSG_Pane *p,
  130.             MWContext *context) 
  131.   : XFE_MNListView(toplevel_component, parent_view, context, p)
  132. {
  133.   setParent(parent_view);
  134.  
  135.   // Initialize necessary data
  136.   m_fieldData = NULL;
  137.   m_fieldList = XP_ListNew();
  138.  
  139.   m_clearAddressee = True;
  140.  
  141.   setupAddressHeadings();
  142. }
  143.  
  144.  
  145. Boolean
  146. XFE_AddressFolderView::isCommandEnabled(CommandType, void*, XFE_CommandInfo*)
  147. {
  148.   return False;
  149. }
  150.  
  151. Boolean
  152. XFE_AddressFolderView::handlesCommand(CommandType command,
  153.                                       void*, XFE_CommandInfo*)
  154. {
  155.   if (command == xfeCmdGetNewMessages
  156.       || command == xfeCmdAddNewsgroup
  157.       || command == xfeCmdDelete
  158.       || command == xfeCmdViewSecurity
  159.       || command == xfeCmdStopLoading)
  160.     return True;
  161.  
  162.   return False;
  163. }
  164.  
  165. void XFE_AddressFolderView::purgeAll()
  166. {
  167.     if (!m_fieldList)
  168.         return;
  169.  
  170.     int count = (int) XP_ListCount(m_fieldList);
  171.     if (count == 0)
  172.         return;
  173.  
  174.     for (int i=count-1; i >=0; i--)
  175.         removeDataAt(i);
  176. }
  177.  
  178. ABAddrMsgCBProcStruc* XFE_AddressFolderView::exportAddressees()
  179. {
  180.     /* flush the buf
  181.      */
  182.     updateHeaderInfo();
  183.  
  184.     if (!m_fieldList)
  185.         return NULL;
  186.  
  187.     int count = (int) XP_ListCount(m_fieldList);
  188.     if (count == 0)
  189.         return NULL;
  190.  
  191.     ABAddrMsgCBProcStruc *package = 
  192.         (ABAddrMsgCBProcStruc *) XP_CALLOC(1, sizeof(ABAddrMsgCBProcStruc));
  193.     package->m_pairs = (StatusID_t **) XP_CALLOC(count, sizeof(StatusID_t*)); 
  194.  
  195.     XFE_AddressFieldData *fieldData = NULL;
  196.     StatusID_t *pair = NULL;
  197.     for (int i=0; i < count; i++) {
  198.         fieldData = (XFE_AddressFieldData*) XP_ListGetObjectNum(m_fieldList, i+1);
  199.         if (!fieldData ||
  200.             !fieldData->receipient ||
  201.             !XP_STRLEN(fieldData->receipient))
  202.             continue;
  203.  
  204.         // calloc
  205.         pair = (StatusID_t *) XP_CALLOC(1, sizeof(StatusID_t));
  206.  
  207.         // dplyStr
  208.         pair->dplyStr = XP_STRDUP(fieldData->receipient);
  209.  
  210.         // status
  211.         if (XP_STRCMP(fieldData->type, XFE_AddressFolderView::CC) == 0)
  212.             pair->status = ::CC;
  213.         else if (XP_STRCMP(fieldData->type, XFE_AddressFolderView::BCC) == 0)
  214.             pair->status = ::BCC;
  215.         else
  216.             pair->status = ::TO;
  217.  
  218.         // type
  219.         if (fieldData->icon == ADDRESS_ICON_PERSON)
  220.             pair->type = ABTypePerson;
  221.         else if (fieldData->icon == ADDRESS_ICON_LIST)
  222.             pair->type = ABTypeList;
  223.         else
  224.             pair->type = ABTypePerson;
  225.  
  226.         package->m_pairs[package->m_count++] = pair;
  227.     }/* for i */
  228.     return package;
  229. }
  230.  
  231. void XFE_AddressFolderView::addrMsgCallback(ABAddrMsgCBProcStruc* clientData, 
  232.                         void*                 callData)
  233. {
  234.   XP_ASSERT(clientData && callData);
  235.   XFE_AddressFolderView *obj = (XFE_AddressFolderView *) callData;
  236.   obj->addrMsgCB(clientData);
  237. }/* XFE_AddressFolderView::addrMsgCallback */
  238.  
  239. void XFE_AddressFolderView::addrMsgCB(ABAddrMsgCBProcStruc* clientData)
  240. {
  241.  
  242.     if (m_clearAddressee)
  243.         /* clean the list
  244.          */
  245.         purgeAll();
  246.  
  247.   /* let me append these entries at the end for the moment
  248.    */
  249.   int npairs = clientData->m_count;
  250.   int count = 0;
  251.   char *firstR = 0;
  252.   for (int i=0; i < npairs; i++) {
  253.     count = (int) XP_ListCount(m_fieldList);
  254.     StatusID_t *addressee = clientData->m_pairs[i];
  255.  
  256.     /* m_fieldData is the newly created entry
  257.      */
  258.     if (count == 0 || !m_fieldData) {
  259.       /* brand new
  260.        * Add new record
  261.        */ 
  262.       m_fieldData = new XFE_AddressFieldData;
  263.       initializeData(m_fieldData);
  264.       m_fieldData->type = MSG_HeaderMaskToString(MSG_TO_HEADER_MASK);
  265.       m_fieldData->receipient = NULL;
  266.       XP_ListAddObjectToEnd(m_fieldList, m_fieldData);
  267.       count++;
  268.     }/* else */
  269.  
  270.     /* type: to, cc, bcc
  271.      */
  272.     switch(addressee->status) {
  273.     case ::TO:
  274.       m_fieldData->type = MSG_HeaderMaskToString(MSG_TO_HEADER_MASK);
  275.       break;
  276.  
  277.     case ::CC:
  278.       m_fieldData->type = MSG_HeaderMaskToString(MSG_CC_HEADER_MASK);
  279.       break;
  280.  
  281.     case ::BCC:
  282.       m_fieldData->type = MSG_HeaderMaskToString(MSG_BCC_HEADER_MASK);
  283.       break;
  284.     }/*switch */
  285.  
  286.     /* receipient
  287.      */
  288.     m_fieldData->receipient = XP_STRDUP(addressee->dplyStr?
  289.                                         addressee->dplyStr:
  290.                                         "");
  291.     if (!firstR)
  292.         firstR = m_fieldData->receipient;
  293.     /* type: person, list
  294.      */
  295.     switch(addressee->type) {
  296.     case ABTypePerson:
  297.       m_fieldData->icon = ADDRESS_ICON_PERSON;
  298.       break;
  299.  
  300.     case ABTypeList:
  301.       m_fieldData->icon = ADDRESS_ICON_LIST;
  302.       break;
  303.     }/* switch */
  304.  
  305.     /* add new record
  306.      */
  307.     if (count)
  308.         insertNewDataAfter(count-1);
  309.     else {
  310.         printf("\n HOW DO I GET INTO THIS??\n");
  311.         /* brand new
  312.          * Add new record
  313.          */ 
  314.         m_fieldData = new XFE_AddressFieldData;
  315.         initializeData(m_fieldData);
  316.         XP_ListAddObjectToEnd(m_fieldList, m_fieldData);
  317.     }/* else */
  318.  
  319.     XP_FREE((StatusID_t *)addressee);
  320.   }/* for i */
  321.   XP_FREE((StatusID_t **)clientData->m_pairs);
  322.   XP_FREE((ABAddrMsgCBProcStruc *)clientData);
  323.   
  324.   count = (int) XP_ListCount(m_fieldList);
  325.   m_outliner->change(0, count, count);
  326.     /* move focus to last row
  327.      * void 
  328.      * XFE_AddressOutliner::PlaceText(int row, int col, 
  329.      *                                Boolean doUpdate)
  330.      */
  331.     ((XFE_AddressOutliner *) m_outliner)->fillText(firstR);
  332.     ((XFE_AddressOutliner *) m_outliner)->
  333.         PlaceText(count-1, ADDRESS_OUTLINER_COLUMN_RECEIPIENT, 
  334.                   False);
  335. }/* XFE_AddressFolderView::addrMsgCB */
  336.  
  337. XFE_CALLBACK_DEFN(XFE_AddressFolderView, openAddrBk)(XFE_NotificationCenter */*obj*/,
  338.                                           void */*clientData*/,
  339.                                           void */*callData*/)
  340. {
  341.  
  342.       fe_showAddrMSGDlg(getToplevel()->getBaseWidget(), 
  343.                         XFE_AddressFolderView::addrMsgCallback, this, 
  344.                         m_contextData);
  345.       return;
  346. }
  347.  
  348. void
  349. XFE_AddressFolderView::doCommand(CommandType command, void *, XFE_CommandInfo*)
  350. {
  351.     if (command == xfeCmdAddresseePicker)
  352.         fe_showAddrMSGDlg(getToplevel()->getBaseWidget(), 
  353.                           XFE_AddressFolderView::addrMsgCallback, this, 
  354.                           m_contextData);
  355.  
  356. }
  357.  
  358. // Outlinable Interface starts here 
  359.  
  360. void*
  361. XFE_AddressFolderView::ConvFromIndex(int)
  362. {
  363.   return NULL;
  364. }
  365.  
  366. int
  367. XFE_AddressFolderView::ConvToIndex(void*)
  368. {
  369.   return 0;
  370. }
  371.  
  372. char *
  373. XFE_AddressFolderView::getColumnName(int column)
  374. {
  375.   switch (column)
  376.     {
  377.     case ADDRESS_OUTLINER_COLUMN_BTN:
  378.       return "Btn";
  379.     case ADDRESS_OUTLINER_COLUMN_TYPE:
  380.       return "Type";
  381.     case ADDRESS_OUTLINER_COLUMN_ICON:
  382.       return "Icon";
  383. #ifdef HAVE_ADDRESS_SECURITY_COLUMN
  384.     case ADDRESS_OUTLINER_COLUMN_SECURITY:
  385.       return "Security";
  386. #endif
  387.     case ADDRESS_OUTLINER_COLUMN_RECEIPIENT:
  388.       return "Receipient";
  389.     default:
  390.       XP_ASSERT(0);
  391.       return 0;
  392.     }
  393. }
  394.  
  395. char *
  396. XFE_AddressFolderView::getColumnHeaderText(int column)
  397. {
  398.   switch (column)
  399.     {
  400.     case ADDRESS_OUTLINER_COLUMN_BTN:
  401.       return "";
  402.     case ADDRESS_OUTLINER_COLUMN_TYPE:
  403.       return "Type";
  404.     case ADDRESS_OUTLINER_COLUMN_ICON:
  405.       return "";
  406. #ifdef HAVE_ADDRESS_SECURITY_COLUMN
  407.     case ADDRESS_OUTLINER_COLUMN_SECURITY:
  408.       return "";
  409. #endif
  410.     case ADDRESS_OUTLINER_COLUMN_RECEIPIENT:
  411.       return "Receipient";
  412.     default:
  413.       XP_ASSERT(0);
  414.       return 0;
  415.     }
  416. }
  417.  
  418. fe_icon*
  419. XFE_AddressFolderView::getColumnHeaderIcon(int /*column*/)
  420. {
  421.   return NULL;
  422. }
  423.  
  424. EOutlinerTextStyle 
  425. XFE_AddressFolderView::getColumnHeaderStyle(int /*column*/)
  426. {
  427.    return OUTLINER_Bold;
  428. }
  429.  
  430.  
  431.  
  432. // line starts with 0 to mean the first row
  433. Boolean
  434. XFE_AddressFolderView::removeDataAt(int line)
  435. {
  436.  
  437.   XFE_AddressFieldData *data;
  438.   Boolean removed = False;
  439.   int count = (int) XP_ListCount(m_fieldList);
  440.  
  441.   if ( count == 0 ) 
  442.       return False;
  443.  
  444.   if (line > (count-2))
  445.       return False;
  446.  
  447.   data = (XFE_AddressFieldData*)XP_ListGetObjectNum(m_fieldList, line+1);
  448.   if (!data)
  449.       return False;
  450.  
  451.   if ( count  == 1 ) 
  452.   {
  453.  
  454.      delete data->receipient;
  455.      initializeData(data);
  456.      m_fieldData = data;
  457.   }
  458.   else
  459.   {
  460.     removed = (Boolean)XP_ListRemoveObject(m_fieldList, data);
  461.     delete data->receipient;
  462.     delete data;
  463.     data = NULL;
  464.  
  465.     if ( line + 1  <= (count-1) )
  466.       m_fieldData = (XFE_AddressFieldData*)XP_ListGetObjectNum(m_fieldList, line+1);
  467.     else  if ( line > 0 )
  468.       m_fieldData = (XFE_AddressFieldData*)XP_ListGetObjectNum(m_fieldList, line);
  469.     else 
  470.       XP_ASSERT(0);
  471.   }
  472.   return removed;
  473.  
  474. }
  475.  
  476. // line starts with 0 to mean the first row
  477. void
  478. XFE_AddressFolderView::getDataAt(int line, int column, char **textstr)
  479. {
  480.   XFE_AddressFieldData *data;
  481.   
  482.   *textstr = NULL;
  483.   if ( XP_ListCount(m_fieldList) == 0 ) *textstr = NULL;
  484.   else
  485.   {
  486.      data = (XFE_AddressFieldData*)XP_ListGetObjectNum(m_fieldList, line+1);
  487.      if ( !data) return;
  488.      switch(column)
  489.      {
  490.     case ADDRESS_OUTLINER_COLUMN_BTN:
  491.     break;
  492.     case ADDRESS_OUTLINER_COLUMN_TYPE:
  493.           if (data->type )
  494.       {
  495.         *textstr = new char[strlen(data->type)+1];
  496.         strcpy(*textstr, data->type);
  497.           }
  498.  
  499.     break;
  500.     case ADDRESS_OUTLINER_COLUMN_RECEIPIENT:
  501.           if ( data->receipient )
  502.           {
  503.         *textstr = new char[strlen(data->receipient)+1];
  504.         strcpy(*textstr, data->receipient);
  505.       }
  506.     break;
  507.         default:
  508.     break;
  509.   }
  510.   }
  511. }
  512.  
  513.  
  514. Boolean
  515. XFE_AddressFolderView::hasDataAt(int line)
  516. {
  517.    Boolean hasData = True;
  518.    XFE_AddressFieldData *tmp_fieldData;
  519.  
  520.    tmp_fieldData = (XFE_AddressFieldData*)XP_ListGetObjectNum(m_fieldList, line+1);
  521.    
  522.    if (!tmp_fieldData ) hasData = False;
  523.    
  524.    return hasData;
  525. }
  526.  
  527. void
  528. XFE_AddressFolderView::insertNewDataAfter(int line)
  529. {
  530.     XFE_AddressFieldData *tmp_fieldData;
  531.  
  532.     tmp_fieldData = (XFE_AddressFieldData*)XP_ListGetObjectNum(m_fieldList, line+1);
  533.  
  534.     XP_ASSERT(tmp_fieldData);
  535.  
  536.     m_fieldData = new XFE_AddressFieldData;
  537.     initializeData(m_fieldData);
  538.  
  539.     XP_ASSERT(tmp_fieldData->type);
  540.     m_fieldData->type = tmp_fieldData->type;
  541.  
  542.     XP_ListInsertObjectAfter( m_fieldList, tmp_fieldData, m_fieldData);
  543. }
  544.  
  545. int
  546. XFE_AddressFolderView::getHeader(int line)
  547. {
  548.   XFE_AddressFieldData *m_tmpData;
  549.   MSG_HEADER_SET mask;
  550.   int i;
  551.   
  552.   if ( XP_ListCount(m_fieldList) == 0 ) XP_ASSERT(0);
  553.  
  554.   m_tmpData = (XFE_AddressFieldData*)XP_ListGetObjectNum(m_fieldList, line+1);
  555.  
  556.   if (!m_tmpData) XP_ASSERT(0);
  557.  
  558.   mask = MSG_HeaderStringToMask(m_tmpData->type);
  559.  
  560.   for ( i = 0; i < (int)TOTAL_HEADERS; i++ )
  561.     if ( standard_header_set[i] == mask ) break;
  562.  
  563.   return (int)i;
  564. }
  565.  
  566. void 
  567. XFE_AddressFolderView::setHeader(int line, MSG_HEADER_SET header)
  568. {
  569.   Boolean brandnew = False;
  570.  
  571.   if ( XP_ListCount(m_fieldList) == 0 )
  572.   {
  573.     // Add new record
  574.     m_fieldData = new XFE_AddressFieldData;
  575.     initializeData(m_fieldData);
  576.     brandnew = True;
  577.   }
  578.   else 
  579.   {
  580.      m_fieldData = (XFE_AddressFieldData*)XP_ListGetObjectNum(m_fieldList, line+1);
  581.      if ( !m_fieldData ) return;
  582.   }
  583.   
  584.   m_fieldData->type = MSG_HeaderMaskToString(header);
  585.  
  586.   if ( header == MSG_NEWSGROUPS_HEADER_MASK )
  587.    {
  588.       m_fieldData->icon = XFE_AddressFolderView::ADDRESS_ICON_NEWS;
  589.    }
  590.    else if ( m_fieldData->icon != XFE_AddressFolderView::ADDRESS_ICON_LIST)
  591.    {
  592.        m_fieldData->icon = XFE_AddressFolderView::ADDRESS_ICON_PERSON;
  593.    }
  594.  
  595.   if ( brandnew ){
  596.      XP_ListAddObjectToEnd(m_fieldList, m_fieldData);
  597.   }
  598. }
  599.  
  600. const char *
  601. XFE_AddressFolderView::setData(int line, char *recipient)
  602. {
  603.   Boolean brandnew = False;
  604.   char *expandedStr = NULL;
  605.   int iconType = 0;
  606.   
  607.  
  608.   if ( XP_ListCount(m_fieldList) == 0 )
  609.   {
  610.     // Add new record
  611.     m_fieldData = new XFE_AddressFieldData;
  612.     initializeData(m_fieldData);
  613.     brandnew = True;
  614.   }
  615.   else 
  616.   {
  617.      m_fieldData = (XFE_AddressFieldData*)XP_ListGetObjectNum(m_fieldList, line+1);
  618.      if ( !m_fieldData ) return 0;
  619.   }
  620.   if ( m_fieldData->receipient )
  621.     delete [] m_fieldData->receipient;
  622.  
  623.   m_fieldData->receipient = NULL;
  624.  
  625.   if ( recipient && strlen(recipient))
  626.   {
  627.      expandedStr = changedItem(recipient, &iconType, &m_fieldData->security);
  628.  
  629.      if ( strcmp(m_fieldData->type, XFE_AddressFolderView::NEWSGROUP) ) // If it's newsgroup, then, don't change it's icon
  630.         m_fieldData->icon = iconType;
  631.  
  632.      if ( expandedStr )
  633.      {
  634.        m_fieldData->receipient = new char[strlen(expandedStr)+1];
  635.        strcpy(m_fieldData->receipient, expandedStr);
  636.      }
  637.      else
  638.      {
  639.        m_fieldData->receipient = new char[strlen(recipient)+1];
  640.        strcpy(m_fieldData->receipient, recipient);
  641.      }
  642.  
  643.      // Created by XP_ALLOC
  644.      XP_FREE(expandedStr);
  645.   }
  646.  
  647.   // Reminder: Don't need to free the recipient here because
  648.   // Caller to setRecipient is in charge of freeing since
  649.   // some time recipient might be dynamically set.
  650.   
  651.   // May need to break up to add several uid rows
  652.   if ( brandnew ){
  653.      XP_ListAddObjectToEnd(m_fieldList, m_fieldData);
  654.   }
  655.   return m_fieldData->type;
  656. }
  657.  
  658. // in AddressOutliner.cpp:
  659. extern "C" char* xfe_ExpandForNameCompletion(char*);
  660.  
  661. // We no longer free the textstr here
  662. int
  663. XFE_AddressFolderView::setReceipient(int line, char *textstr)
  664. {
  665.   // Special case: if it's a null string, don't do any matching
  666.   if (textstr == 0 || ( XP_STRLEN(textstr) == 0))
  667.   {
  668.       setData(line, textstr);
  669.       return 1;
  670.   }
  671.  
  672.   // Try completion first; MSG_ParseRFC822Addresses() may get the count
  673.   // wrong, especially when completing firstname_lastname w/spaces.
  674.   char* completestr = xfe_ExpandForNameCompletion(textstr);
  675.   if (completestr)
  676.   {
  677.       setData(line, completestr);
  678.       XP_FREE(completestr);
  679.       return 1;
  680.   }
  681.  
  682.   // RFC822 parsing:
  683.   char* pNames = NULL;
  684.   char* pAddresses = NULL;
  685.   int count = MSG_ParseRFC822Addresses(textstr, &pNames, &pAddresses);
  686.   if (count > 0)
  687.   {
  688.       const char *msgtype;
  689.       int newline = line;
  690.       char* pn = pNames;
  691.       char* pa = pAddresses;
  692.  
  693.       for (int i=0; i<count; ++i)
  694.       {
  695.           MSG_HEADER_SET header;
  696.           char* fullname = MSG_MakeFullAddress(pn, pa);
  697.           XP_ASSERT(fullname);
  698.           while (*pn != '\0')
  699.               ++pn;
  700.           ++pn;
  701.           while (*pa != '\0')
  702.               ++pa;
  703.           ++pa;
  704.           if (i > 0)
  705.           {
  706.               insertNewDataAfter(newline++);
  707.               (void)setHeader(newline, header);
  708.           }
  709.           msgtype = setData(newline, fullname);
  710.           if (i == 0)
  711.               header = MSG_HeaderStringToMask(msgtype);
  712.           XP_FREE(fullname);
  713.       }
  714.  
  715.       if (pNames)
  716.           XP_FREE(pNames);
  717.       if (pAddresses)
  718.           XP_FREE(pAddresses);
  719.   }
  720.  
  721.   return count;
  722. }
  723.  
  724.  
  725. void
  726. XFE_AddressFolderView::updateReceipient(int line)
  727. {
  728.   XFE_AddressFieldData *pAddress = 0;
  729.   MSG_HEADER_SET msgtype = 0;
  730.   char *newvalue = 0;
  731.  
  732.   if ( XP_ListCount(m_fieldList) == 0 )    return;
  733.  
  734.   pAddress = (XFE_AddressFieldData*)XP_ListGetObjectNum(m_fieldList, line+1);
  735.  
  736.   if ( !pAddress ) return;
  737.  
  738.   if ( pAddress->receipient)
  739.      msgtype = MSG_HeaderStringToMask(pAddress->type);
  740.  
  741.    newvalue = MSG_UpdateHeaderContents(getPane(), 
  742.             msgtype, pAddress->receipient);
  743.   
  744.   if (newvalue) {
  745.     delete pAddress->receipient;
  746.     pAddress->receipient = new char[strlen(newvalue)+1];
  747.     strcpy(pAddress->receipient, newvalue);
  748.     MSG_SetCompHeader(getPane(), msgtype, newvalue);
  749.     XP_FREE(newvalue);
  750.   }
  751. }
  752.  
  753.  
  754. void
  755. XFE_AddressFolderView:: getTreeInfo(XP_Bool * /*expandable*/, 
  756.             XP_Bool */*is_expanded*/, int */*depth*/,
  757.                            OutlinerAncestorInfo **/*ancestor*/)
  758. {
  759. // Do nothing, there is no tree here
  760. }
  761.  
  762. void *
  763. XFE_AddressFolderView::acquireLineData(int line) 
  764. {
  765.   int count;
  766.  
  767.   count = XP_ListCount(m_fieldList);
  768.  
  769.   if ( count == 0 && line == 0 )
  770.   {
  771.     // New Table, create a TO field by default
  772.     m_fieldData = new XFE_AddressFieldData;
  773.     initializeData(m_fieldData);
  774.     m_fieldData->type = MSG_HeaderMaskToString(MSG_TO_HEADER_MASK);
  775.     m_fieldData->receipient = NULL;
  776.     XP_ListAddObjectToEnd(m_fieldList, m_fieldData);
  777.   }
  778.   else if ( count-1 >= line )
  779.   {
  780.      m_fieldData = (XFE_AddressFieldData*)XP_ListGetObjectNum(m_fieldList, line+1);
  781.   } else if ( line > count-1 )
  782.   {
  783.      XFE_AddressFieldData *tmp_fieldData;
  784.      tmp_fieldData = (XFE_AddressFieldData*)XP_ListGetObjectNum(m_fieldList, count);
  785.  
  786.      m_fieldData = new XFE_AddressFieldData;
  787.     initializeData(m_fieldData);
  788.      XP_ASSERT(tmp_fieldData->type);
  789.      // copy previous header to empty new line:
  790.      if (!XP_STRCMP(tmp_fieldData->type, BCC)
  791.          || !XP_STRCMP(tmp_fieldData->type, REPLY))
  792.          m_fieldData->type = MSG_HeaderMaskToString(MSG_TO_HEADER_MASK);
  793.      else
  794.          m_fieldData->type = tmp_fieldData->type;
  795.      XP_ListAddObjectToEnd(m_fieldList, m_fieldData);
  796.  
  797.   }
  798.   return m_fieldData;
  799. }
  800.  
  801.  
  802. EOutlinerTextStyle 
  803. XFE_AddressFolderView::getColumnStyle(int /*column*/)
  804. {
  805.   return OUTLINER_Default;
  806. }
  807.  
  808. // Caller has to free the return value
  809. char *
  810. XFE_AddressFolderView::getColumnText(int column)
  811. {
  812.    char* data = NULL;
  813.  
  814.     if (!m_fieldData) return NULL;
  815.     switch (column) 
  816.     {
  817.     case ADDRESS_OUTLINER_COLUMN_BTN:
  818.     case ADDRESS_OUTLINER_COLUMN_ICON:
  819.     break;
  820.     case ADDRESS_OUTLINER_COLUMN_TYPE:
  821.        data = new char[strlen(m_fieldData->type)+1];
  822.        strcpy(data, m_fieldData->type);
  823.     break;
  824.     case ADDRESS_OUTLINER_COLUMN_RECEIPIENT:
  825.            if ( m_fieldData->receipient )
  826.        {
  827.        data = new char[strlen(m_fieldData->receipient)+1];
  828.        strcpy(data, m_fieldData->receipient);
  829.            }
  830.     break;
  831.     default:
  832.     break;
  833.     }
  834.     return data;
  835. }
  836.  
  837. fe_icon *
  838. XFE_AddressFolderView::getColumnIcon(int column)
  839. {
  840.  
  841.   switch(column)
  842.   {
  843.     case ADDRESS_OUTLINER_COLUMN_BTN:
  844.       return &arrowIcon;
  845.     case ADDRESS_OUTLINER_COLUMN_ICON:
  846.     {
  847.            if ( m_fieldData->icon == ADDRESS_ICON_PERSON )
  848.           return &personIcon;
  849.        else if ( m_fieldData->icon == ADDRESS_ICON_LIST)
  850.           return &listIcon;
  851.            else if ( m_fieldData->icon == ADDRESS_ICON_NEWS)
  852.           return &newsIcon;
  853.        else if ( m_fieldData->icon == 8 )
  854.           return &newsIcon;
  855.     }
  856.     break;
  857. #ifdef HAVE_ADDRESS_SECURITY_COLUMN
  858.     case ADDRESS_OUTLINER_COLUMN_SECURITY:
  859.         if (m_fieldData->security != 0)
  860.             return &securityIcon;
  861.         else
  862.             return 0;
  863.         break;
  864. #endif
  865.   }
  866.   return 0;
  867. }
  868.  
  869. void
  870. XFE_AddressFolderView::releaseLineData()
  871. {
  872. // Not needed to free anything here.
  873. // We only make a reference to an element in the array. We don't want to
  874. // set anything free.
  875.  
  876. }
  877.  
  878. void
  879. XFE_AddressFolderView::Buttonfunc(const OutlineButtonFuncData */*data*/)
  880. {
  881. }
  882.  
  883. void
  884. XFE_AddressFolderView::Flippyfunc(const OutlineFlippyFuncData * /*data*/)
  885. {
  886. }
  887.  
  888. void 
  889. XFE_AddressFolderView::setupAddressHeadings()
  890. {
  891. XFE_AddressFolderView::TO = XP_GetString(XFE_MNC_ADDRESS_TO);
  892. XFE_AddressFolderView::CC = XP_GetString(XFE_MNC_ADDRESS_CC);
  893. XFE_AddressFolderView::BCC = XP_GetString(XFE_MNC_ADDRESS_BCC); 
  894. XFE_AddressFolderView::NEWSGROUP = XP_GetString(XFE_MNC_ADDRESS_NEWSGROUP);
  895. XFE_AddressFolderView::REPLY = XP_GetString(XFE_MNC_ADDRESS_REPLY);
  896. XFE_AddressFolderView::FOLLOWUP =  XP_GetString(XFE_MNC_ADDRESS_FOLLOWUP);
  897. }
  898.  
  899. void
  900. XFE_AddressFolderView::setupIcons()
  901. {
  902.   Widget base = getToplevel()->getBaseWidget();
  903.   // Initialize Icons if they have not been
  904.   if (!personIcon.pixmap )
  905.   {
  906.     Pixel bg_pixel;
  907.  
  908.     XtVaGetValues(base,  XmNbackground, &bg_pixel, 0);
  909.  
  910.     // AddressBook
  911.     IconGroup_createAllIcons(&MNC_Address_group,
  912.                             getToplevel()->getBaseWidget(),
  913.                             BlackPixelOfScreen(XtScreen(base)), // hack. :(
  914.                             bg_pixel);
  915.  
  916.     // Arrow
  917.         fe_NewMakeIcon(getToplevel()->getBaseWidget(),
  918.                      BlackPixelOfScreen(XtScreen(base)), // umm. fix me
  919.                      bg_pixel,
  920.                      &arrowIcon,
  921.                      NULL,
  922.                      HFolderO.width, HFolderO.height,
  923.                      HFolderO.mono_bits, HFolderO.color_bits, HFolderO.mask_bits, FALSE);
  924.  
  925.  
  926.     // Person 
  927.         fe_NewMakeIcon(getToplevel()->getBaseWidget(),
  928.                      BlackPixelOfScreen(XtScreen(base)), // umm. fix me
  929.                      bg_pixel,
  930.                      &personIcon,
  931.                      NULL,
  932.                      MN_Person.width, MN_Person.height,
  933.                      MN_Person.mono_bits, MN_Person.color_bits, 
  934.              MN_Person.mask_bits, FALSE);
  935.  
  936.     // List 
  937.         fe_NewMakeIcon(getToplevel()->getBaseWidget(),
  938.                      BlackPixelOfScreen(XtScreen(base)), // umm. fix me
  939.                      bg_pixel,
  940.                      &listIcon,
  941.                      NULL,
  942.                      MN_People.width, MN_People.height,
  943.                      MN_People.mono_bits, MN_People.color_bits, 
  944.              MN_People.mask_bits, FALSE);
  945.  
  946.  
  947.  
  948.     // News 
  949.         fe_NewMakeIcon(getToplevel()->getBaseWidget(),
  950.                      BlackPixelOfScreen(XtScreen(base)), // umm. fix me
  951.                      bg_pixel,
  952.                      &newsIcon,
  953.                      NULL,
  954.                      MN_Newsgroup.width, MN_Newsgroup.height,
  955.                      MN_Newsgroup.mono_bits, MN_Newsgroup.color_bits, 
  956.              MN_Newsgroup.mask_bits, FALSE);
  957.  
  958.  
  959.     // Security
  960.         fe_NewMakeIcon(getToplevel()->getBaseWidget(),
  961.                        BlackPixelOfScreen(XtScreen(base)), // umm. fix me
  962.                        bg_pixel,
  963.                        &securityIcon,
  964.                        NULL,
  965.                        MN_CertIndicator.width, 
  966.                        MN_CertIndicator.height,
  967.                        MN_CertIndicator.mono_bits, 
  968.                        MN_CertIndicator.color_bits, 
  969.                        MN_CertIndicator.mask_bits, 
  970.                        FALSE);
  971.   }
  972. }
  973.  
  974. void
  975. XFE_AddressFolderView::createWidgets(Widget parent_widget)
  976. {
  977.   Widget formW;
  978.   //static const char *addressBook = "addressBook";
  979.  
  980. #ifdef HAVE_ADDRESS_SECURITY_COLUMN
  981.   static int column_widths[] = {4,15,4,4,25}; // outliner column size
  982.   int dbTableNumColumns = 5;
  983. #else
  984.   static int column_widths[] = {0,15,0,25}; // outliner column size
  985.   int dbTableNumColumns = 4;
  986. #endif
  987.  
  988.   Widget gridW;
  989.  
  990.   formW = XtVaCreateManagedWidget("addressFolderBaseWidget",
  991.         xmFormWidgetClass, parent_widget, 0);
  992.   setBaseWidget(formW);
  993.  
  994.   setupIcons();
  995.  
  996.   getParent()->getToplevel()->registerInterest(
  997.     XFE_ComposeView::tabNext, this,
  998.         (XFE_FunctionNotification)tabToButton_cb);
  999.    
  1000.   getParent()->getToplevel()->registerInterest(
  1001.     XFE_AddressOutliner::tabPrev, this,
  1002.         (XFE_FunctionNotification)tabToButton_cb);
  1003.  
  1004.    // Initialize the necessary info on the AddressFolderView
  1005.    initialize();
  1006.  
  1007.    // Create Table
  1008.  
  1009.     m_outliner = new XFE_AddressOutliner( "grid",
  1010.         this,
  1011.         this,
  1012.         formW,
  1013.         False,
  1014.         dbTableNumColumns,
  1015.         column_widths,
  1016.         OUTLINER_GEOMETRY_PREF);
  1017.  
  1018.     // Arrow Button
  1019.     m_outliner->setColumnResizable(ADDRESS_OUTLINER_COLUMN_BTN, False);
  1020.     m_outliner->setColumnWidth(ADDRESS_OUTLINER_COLUMN_BTN, 
  1021.                                HFolderO.width + 2 /* for the outliner's shadow */);
  1022.  
  1023.     // Followup To:  (etc..)
  1024.     m_outliner->setColumnResizable(ADDRESS_OUTLINER_COLUMN_TYPE, False);
  1025.  
  1026.     // AB Person icon
  1027.     m_outliner->setColumnResizable(ADDRESS_OUTLINER_COLUMN_ICON, False);
  1028.     m_outliner->setColumnWidth(ADDRESS_OUTLINER_COLUMN_ICON, 
  1029.                                MN_Person.width + 2 /* for the outliner's shadow */);
  1030.  
  1031. #ifdef HAVE_ADDRESS_SECURITY_COLUMN
  1032.     // Security thing, didn't make 4.0
  1033.     m_outliner->setColumnResizable(ADDRESS_OUTLINER_COLUMN_SECURITY, False);
  1034. #endif
  1035.  
  1036.     gridW= ( (XFE_AddressOutliner*)m_outliner)->getBaseWidget();
  1037.     XtVaSetValues( gridW,
  1038.                 XmNtopAttachment, XmATTACH_FORM,
  1039.                 XmNbottomAttachment, XmATTACH_FORM,
  1040.                 XmNleftAttachment, XmATTACH_FORM,
  1041.                 XmNrightAttachment, XmATTACH_FORM,
  1042.         XmNtraversalOn, True,
  1043.         XmNhighlightOnEnter, True,
  1044.         0);
  1045.     ((XFE_AddressOutliner*)m_outliner)->show();
  1046.  
  1047.         // create drop site for internal drop
  1048.         fe_dnd_CreateDrop(m_outliner->getBaseWidget(),AddressDropCb,this);
  1049.  
  1050. }
  1051.  
  1052. void
  1053. XFE_AddressFolderView::btnActivateCallback(Widget w, XtPointer clientData, XtPointer callData)
  1054. {
  1055.   XFE_AddressFolderView *obj = (XFE_AddressFolderView*)clientData;
  1056.  
  1057.   obj->btnActivate(w, callData);
  1058. }
  1059.  
  1060. void
  1061. XFE_AddressFolderView::btnActivate(Widget w, XtPointer)
  1062. {
  1063.   EAddressFolderActionState  state;
  1064.  
  1065.   XtVaGetValues(w, XmNuserData, &state, 0);
  1066.  
  1067.   switch (state)
  1068.   {
  1069.     case AddressFolder_Add:
  1070.       XDEBUG(printf("add in XFE_AddressFolderView::btnActivate\n");)
  1071.       break;
  1072.     case AddressFolder_Remove:
  1073.       XDEBUG(printf("remove in XFE_AddressFolderView::btnActivate\n");)
  1074.       break;
  1075.     case AddressFolder_Select:
  1076.       XDEBUG(printf("select in XFE_AddressFolderView::btnActivate\n");)
  1077.       break;
  1078.     default:
  1079.       XDEBUG(printf("not handled in XFE_AddressFolderView::btnActivate\n");)
  1080.       break;
  1081.   }
  1082. }
  1083.  
  1084. XFE_CALLBACK_DEFN(XFE_AddressFolderView,tabToButton)(XFE_NotificationCenter*, void*, void*)
  1085. {
  1086.   XmProcessTraversal(m_addBtnW, XmTRAVERSE_CURRENT);
  1087.  
  1088. }
  1089.  
  1090. //------------ NEW code -------------------------
  1091.  
  1092. // Inserting initial addressing field value
  1093. void
  1094. XFE_AddressFolderView::initialize()
  1095. {
  1096.    MSG_Pane *pane = getPane(); // Get it from MNView
  1097.  
  1098.    MSG_HeaderEntry * entry;
  1099.    int nCount;
  1100.  
  1101.    nCount = MSG_RetrieveStandardHeaders(pane,&entry);
  1102.  
  1103.    if (nCount > 0)
  1104.    {
  1105.       int i;
  1106.       for (i=0; i<nCount; i++)
  1107.       {
  1108.           XFE_AddressFieldData *data = new XFE_AddressFieldData;
  1109.           initializeData(data);
  1110.  
  1111.           data->type = MSG_HeaderMaskToString(entry[i].header_type);
  1112.       if ( entry[i].header_value )
  1113.       data->receipient = (char*)XP_CALLOC(strlen(entry[i].header_value)+1,
  1114.                 sizeof(char));
  1115.       XP_STRCPY(data->receipient, entry[i].header_value);
  1116.           data->icon = ADDRESS_ICON_PERSON;
  1117.  
  1118.       XP_ListAddObjectToEnd(m_fieldList, data);
  1119.           XP_FREE(entry[i].header_value);
  1120.       }
  1121.  
  1122.       if (entry) // Need to check for free
  1123.                 XP_FREE(entry);
  1124.    }
  1125. }
  1126.  
  1127. int
  1128. XFE_AddressFolderView::getTotalData()
  1129. {
  1130.    int count = 0;
  1131.   
  1132.    if ( m_fieldList )
  1133.        count = XP_ListCount(m_fieldList);
  1134.    return count;
  1135. }
  1136.  
  1137.  
  1138. void XFE_AddressFolderView::updateHeaderInfo ( void )
  1139. {
  1140.     // Make sure the address outliner has gotten the last address typed in:
  1141.     ((XFE_AddressOutliner*)m_outliner)->updateAddresses();
  1142.  
  1143.     MSG_Pane *pComposePane = getPane();
  1144.     int i, j;
  1145.  
  1146.     if (m_fieldList)
  1147.     {
  1148.         MSG_HeaderEntry * entry = NULL;
  1149.         XFE_AddressFieldData *address;
  1150.  
  1151.         MSG_ClearComposeHeaders(pComposePane);
  1152.  
  1153.         int count = XP_ListCount(m_fieldList);
  1154.  
  1155.         if (count)
  1156.             entry = (MSG_HeaderEntry*)XP_ALLOC(sizeof(MSG_HeaderEntry)*count);
  1157.  
  1158.         if (entry == NULL)
  1159.             return;
  1160.  
  1161.     i = 0; 
  1162.     j = i;
  1163.     while ( j < count )
  1164.         {
  1165.             if( (address = (XFE_AddressFieldData*)XP_ListGetObjectNum(m_fieldList, j+1) ))
  1166.             {
  1167.         entry[i].header_value = NULL;
  1168.         if ( address->receipient )
  1169.                   entry[i].header_value = XP_STRDUP(address->receipient);
  1170.                 if (!strcmp(address->type,TO))
  1171.                     entry[i].header_type = MSG_TO_HEADER_MASK;
  1172.                 else if(!strcmp(address->type,REPLY))
  1173.                     entry[i].header_type = MSG_REPLY_TO_HEADER_MASK;
  1174.                 else if(!strcmp(address->type,CC))
  1175.                     entry[i].header_type = MSG_CC_HEADER_MASK;
  1176.                 else if(!strcmp(address->type,BCC))
  1177.                     entry[i].header_type = MSG_BCC_HEADER_MASK;
  1178.                 else if(!strcmp(address->type,NEWSGROUP))
  1179.                     entry[i].header_type = MSG_NEWSGROUPS_HEADER_MASK;
  1180.                 else if(!strcmp(address->type,FOLLOWUP))
  1181.                     entry[i].header_type = MSG_FOLLOWUP_TO_HEADER_MASK;
  1182.         if ( entry[i].header_value ) i++;
  1183.             }
  1184.         j++;
  1185.         }
  1186.  
  1187.         MSG_HeaderEntry * list;
  1188.         count = MSG_CompressHeaderEntries(entry,i,&list);
  1189.  
  1190.         if ((count != -1)&&(list!=NULL))
  1191.         {
  1192.             for (i=0; i<count; i++)
  1193.             {
  1194.                 XP_ASSERT(list[i].header_value);
  1195.                 MSG_SetCompHeader(pComposePane,list[i].header_type,list[i].header_value);
  1196.                 XP_FREE(list[i].header_value);
  1197.             }
  1198.         XP_FREE(list);
  1199.         }
  1200.         for (i=0; i<count; i++)
  1201.         {
  1202.         XP_FREE(entry[i].header_value);
  1203.     }
  1204.     XP_FREE(entry);
  1205.     }
  1206.  
  1207. }
  1208.  
  1209. // This method should be called from Activate Callback
  1210. char *
  1211. XFE_AddressFolderView::changedItem(char *pString, int*  iconType,
  1212.                                    short* securityp)
  1213. {
  1214.    return  xfe_ExpandName(pString, iconType, securityp);
  1215. }
  1216.  
  1217.  
  1218. //----------- Address Book stuff here ------------
  1219.  
  1220. extern "C" char * xfe_ExpandName(char * pString, int* iconID, short* security)
  1221. {
  1222.         ABID entryID;
  1223.         ABID field;
  1224.         char * fullname;
  1225.         ABook *pAddrBook;
  1226.         XP_List *pDirectories = FE_GetDirServers();
  1227.         ABID type;
  1228.  
  1229. #if defined(DEBUG_tao)
  1230.         printf("\n  xfe_ExpandName");
  1231. #endif
  1232.         DIR_Server* pDirServer = NULL;
  1233.         pAddrBook = fe_GetABook(0);
  1234.         DIR_GetComposeNameCompletionAddressBook(pDirectories, &pDirServer);
  1235.         AB_GetIDForNameCompletion(pAddrBook,
  1236.                                   pDirServer,
  1237.                                   &entryID,
  1238.                                   &field,
  1239.                                   pString);
  1240.         if (entryID != (unsigned long)-1)
  1241.         {
  1242.        AB_GetType(pDirServer, pAddrBook, entryID, &type);
  1243.  
  1244.        if ( type == ABTypePerson )
  1245.        {
  1246.           *iconID = XFE_AddressFolderView::ADDRESS_ICON_PERSON;
  1247.        }
  1248.        else if ( type == ABTypeList)
  1249.        {
  1250.            *iconID = XFE_AddressFolderView::ADDRESS_ICON_LIST;
  1251.        }
  1252.         
  1253.        AB_GetSecurity(pDirServer, pAddrBook, entryID, security);
  1254.  
  1255.           AB_GetExpandedName(
  1256.                         (DIR_Server*)XP_ListGetObjectNum(pDirectories,1),
  1257.                         pAddrBook, entryID, &fullname);
  1258.           if (fullname) return fullname;  
  1259.        }
  1260.        return NULL; 
  1261. }
  1262.  
  1263.  
  1264.  
  1265. //------------ Begin of MSG code -------------------------
  1266. int MSG_TotalHeaderCount()
  1267. {
  1268.     return TOTAL_HEADERS;
  1269. }
  1270.  
  1271. MSG_HEADER_SET 
  1272. MSG_HeaderValue( int pos )
  1273. {
  1274.   if( pos >= (int) TOTAL_HEADERS) XP_ASSERT(0);
  1275.  
  1276.   return standard_header_set[pos];
  1277. }
  1278.  
  1279. MSG_HEADER_SET 
  1280. MSG_HeaderStringToMask(const char * strheader)
  1281. {
  1282.    MSG_HEADER_SET header = 0;
  1283.    
  1284.    if ( !strcmp(strheader, XFE_AddressFolderView::TO) ) 
  1285.         header = MSG_TO_HEADER_MASK; 
  1286.    else if ( !strcmp(strheader, XFE_AddressFolderView::CC) ) 
  1287.         header = MSG_CC_HEADER_MASK; 
  1288.    else if ( !strcmp(strheader, XFE_AddressFolderView::BCC) ) 
  1289.         header = MSG_BCC_HEADER_MASK; 
  1290.    else if ( !strcmp(strheader, XFE_AddressFolderView::REPLY) ) 
  1291.         header = MSG_REPLY_TO_HEADER_MASK; 
  1292.    else if ( !strcmp(strheader, XFE_AddressFolderView::NEWSGROUP) ) 
  1293.         header = MSG_NEWSGROUPS_HEADER_MASK; 
  1294.    else if ( !strcmp(strheader, XFE_AddressFolderView::FOLLOWUP) ) 
  1295.         header = MSG_FOLLOWUP_TO_HEADER_MASK; 
  1296.  
  1297.    return header;
  1298. }
  1299.  
  1300. const char * MSG_HeaderMaskToString(MSG_HEADER_SET header)
  1301. {
  1302.     const char *retval = NULL;
  1303.     switch (header)
  1304.     {
  1305.         case MSG_TO_HEADER_MASK:
  1306.             retval = XFE_AddressFolderView::TO;
  1307.             break;
  1308.         case MSG_CC_HEADER_MASK:
  1309.             retval = XFE_AddressFolderView::CC;
  1310.             break;
  1311.         case MSG_BCC_HEADER_MASK:
  1312.             retval = XFE_AddressFolderView::BCC;
  1313.             break;
  1314.         case MSG_REPLY_TO_HEADER_MASK:
  1315.             retval = XFE_AddressFolderView::REPLY;
  1316.             break;
  1317.         case MSG_NEWSGROUPS_HEADER_MASK:
  1318.             retval = XFE_AddressFolderView::NEWSGROUP;
  1319.             break;
  1320.         case MSG_FOLLOWUP_TO_HEADER_MASK:
  1321.             retval = XFE_AddressFolderView::FOLLOWUP;
  1322.             break;
  1323.         default:
  1324.             XP_ASSERT(0);
  1325.     }
  1326.     return retval;
  1327. }
  1328.  
  1329. void
  1330. XFE_AddressFolderView::initializeData(XFE_AddressFieldData *data)
  1331. {
  1332.  
  1333.   data->type = NULL;
  1334.   data->receipient = NULL;
  1335.   data->icon = ADDRESS_ICON_PERSON;
  1336.   data->currStr = NULL;
  1337.   data->insertPos = 0;
  1338.   data->security = 0;
  1339. }
  1340.  
  1341.  
  1342. void
  1343. XFE_AddressFolderView::setCurrentString(int line, const char *newStr)
  1344. {
  1345.   char *tmpStr;
  1346.   XFE_AddressFieldData *data;
  1347.   
  1348.   if ( XP_ListCount(m_fieldList) == 0 ) return;
  1349.   else
  1350.   {
  1351.      data = (XFE_AddressFieldData*)XP_ListGetObjectNum(m_fieldList, line+1);
  1352.      if (!data) return;
  1353.   }
  1354.  
  1355.   if ( newStr && strlen(newStr) > 0 )
  1356.   {
  1357.     if ( data->currStr)
  1358.     tmpStr = (char*)XP_CALLOC(strlen(data->currStr)+strlen(newStr)+1, sizeof(char));
  1359.     else 
  1360.       tmpStr = (char*)XP_CALLOC(strlen(newStr)+1, sizeof(char));
  1361.         if ( data->currStr )
  1362.         {
  1363.        // delete old value
  1364.        delete data->currStr;
  1365.        data->currStr = NULL;
  1366.         }
  1367.        strcpy(tmpStr, newStr);
  1368.        data->currStr = tmpStr;
  1369.   }
  1370.   else 
  1371.   {
  1372.     delete data->currStr;
  1373.     data->currStr = NULL;
  1374.   }
  1375. }
  1376.  
  1377. void
  1378. XFE_AddressFolderView::getCurrentString(int line, char **textstr)
  1379. {
  1380.   XFE_AddressFieldData *data;
  1381.   
  1382.   *textstr = NULL;
  1383.   if ( XP_ListCount(m_fieldList) == 0 ) *textstr = NULL;
  1384.   else
  1385.   {
  1386.      data = (XFE_AddressFieldData*)XP_ListGetObjectNum(m_fieldList, line+1);
  1387.      if (!data) return;
  1388.      if ( data->currStr && strlen(data->currStr))
  1389.      {
  1390.     *textstr = (char*)XP_CALLOC(strlen(data->currStr)+1, sizeof(char));
  1391.     strcpy(*textstr, data->currStr);
  1392.      }
  1393.   }
  1394. }
  1395.  
  1396. XFE_AddressFolderView::~XFE_AddressFolderView()
  1397. {
  1398. }
  1399.  
  1400. // Address field drop site handler
  1401. void
  1402. XFE_AddressFolderView::AddressDropCb(Widget,void* cd,
  1403.                                      fe_dnd_Event type,fe_dnd_Source *source,
  1404.                                      XEvent*) {
  1405.     XFE_AddressFolderView *ad=(XFE_AddressFolderView*)cd;
  1406.     
  1407.     if (type==FE_DND_DROP && ad && source)
  1408.         ad->addressDropCb(source);
  1409. }
  1410.  
  1411. void
  1412. XFE_AddressFolderView::addressDropCb(fe_dnd_Source *source)
  1413. {
  1414.     XDEBUG(printf("XFE_AddressFolderView::addressDropCb()\n"));
  1415.     
  1416.     switch (source->type) {
  1417.  
  1418.     case FE_DND_ADDRESSBOOK:
  1419.         {
  1420.         // add addressbook drop to address panel
  1421.         XFE_ABListSearchView* addrView=( XFE_ABListSearchView*)source->closure;
  1422.         if (addrView)
  1423.             processAddressBookDrop(addrView->getOutliner(),
  1424.                                    addrView->getDir(),
  1425.                                    addrView->getAddrBook(),
  1426.                                    (AddressPane*)addrView->getABPane());
  1427.         break;
  1428.         }
  1429.     case FE_DND_LDAP_ENTRY:
  1430.         {
  1431.         if (source->closure)
  1432.             processLDAPDrop(source);
  1433.         break;
  1434.         }
  1435.     default:
  1436.         {
  1437. #if !defined(USE_MOTIF_DND)
  1438.         // pass non-addressbook drops to attachment panel
  1439.         XFE_ComposeFolderView* parent=(XFE_ComposeFolderView*)getParent();
  1440.         if (parent) {
  1441.             XFE_ComposeAttachFolderView* attachView=parent->getAttachFolderView();
  1442.             if (attachView)
  1443.                 attachView->attachDropCb(source);
  1444.         }
  1445. #endif /* !defined(USE_MOTIF_DND) */
  1446.         }
  1447.         break;
  1448.     }
  1449. }
  1450.  
  1451. void
  1452. XFE_AddressFolderView::processAddressBookDrop(XFE_Outliner *outliner,
  1453.                                               DIR_Server *abDir,
  1454.                                               ABook *abBook,
  1455.                                               AddressPane *abPane)
  1456. {
  1457.     // Make sure insert happens at end of list - drag-over will have moved
  1458.     // text field position around under mouse.
  1459.     SEND_STATUS fieldStatus=::TO;
  1460.     int fieldCount=XP_ListCount(m_fieldList);
  1461.     if (fieldCount>0) {
  1462.         ((XFE_AddressOutliner*)m_outliner)->PlaceText(fieldCount-1,
  1463.                                                       ADDRESS_OUTLINER_COLUMN_RECEIPIENT, 
  1464.                                                       True);
  1465.         
  1466.         // Set field status to match that of last field in list - allows drop
  1467.         // of several TO's, then switch to drop of several CC's etc.
  1468.         XFE_AddressFieldData *tmpData = (XFE_AddressFieldData*)XP_ListGetObjectNum(m_fieldList, fieldCount);
  1469.         if (tmpData) {
  1470.             if (tmpData->type==TO) fieldStatus=::TO;
  1471.             if (tmpData->type==CC) fieldStatus=::CC;
  1472.             if (tmpData->type==BCC) fieldStatus=::BCC;
  1473.         }
  1474.     }
  1475.  
  1476.     const int *selectedList=NULL;
  1477.     int numSelected=0;
  1478.     if (outliner->getSelection(&selectedList, &numSelected)) {
  1479.         StatusID_t **itemList=(StatusID_t**)XP_ALLOC(numSelected*sizeof(StatusID_t*));
  1480.         int numItems=0;
  1481.  
  1482.         int i;
  1483.         for (i=0; i<numSelected; i++) {
  1484.             ABID entry = AB_GetEntryIDAt(abPane,(uint32)selectedList[i]);
  1485.     
  1486.             if (entry == MSG_VIEWINDEXNONE) 
  1487.                 continue;
  1488.  
  1489.             // entry type
  1490.             ABID type;
  1491.             AB_GetType(abDir, abBook, entry, &type);
  1492.  
  1493.             //email
  1494.             char email[AB_MAX_STRLEN];
  1495.             email[0] = '\0';
  1496.             AB_GetEmailAddress(abDir,abBook,entry,email);
  1497.  
  1498.             // name
  1499.             char *expName=NULL;
  1500.             AB_GetExpandedName(abDir,abBook,entry,&expName);
  1501.             if (!expName) {
  1502.                 char fullName[AB_MAX_STRLEN];
  1503.                 fullName[0] = '\0';
  1504.                 AB_GetFullName(abDir,abBook,entry,fullName);
  1505.                 expName=XP_STRDUP(fullName);
  1506.             }
  1507.  
  1508.             // add to address list via AddressFolder Address Picker callback
  1509.  
  1510.             StatusID_t *item=(StatusID_t*)XP_ALLOC(sizeof(StatusID_t));
  1511.  
  1512.             item->type=type;
  1513.             item->status=fieldStatus;
  1514.             item->dir=abDir;
  1515.             item->id=entry;
  1516.             item->emailAddr=XP_STRDUP(email);
  1517.             item->dplyStr=expName;
  1518.             
  1519.             itemList[numItems++]=item;
  1520.         }
  1521.         
  1522.         if (numItems>0) {
  1523.             ABAddrMsgCBProcStruc *cbStruct=(ABAddrMsgCBProcStruc*)XP_ALLOC(sizeof(ABAddrMsgCBProcStruc));
  1524.             cbStruct->m_pairs=itemList;
  1525.             cbStruct->m_count=numItems;
  1526.  
  1527.             m_clearAddressee = False;
  1528.             addrMsgCB(cbStruct);    // Add to address panel. This call frees the item list
  1529.             m_clearAddressee = True;
  1530.             
  1531.         }
  1532.     }
  1533. }
  1534.  
  1535. void
  1536. XFE_AddressFolderView::processLDAPDrop(fe_dnd_Source* source)
  1537. {
  1538.     XFE_LdapSearchView *ldapView=(XFE_LdapSearchView *)source->closure;
  1539.  
  1540.     // Make sure insert happens at end of list - drag-over will have moved
  1541.     // text field position around under mouse.
  1542.     SEND_STATUS fieldStatus=::TO;
  1543.     int fieldCount=XP_ListCount(m_fieldList);
  1544. #ifdef DEBUG_sgidev
  1545.     printf("XFE_AddressFolderView::processLDAPDrop(%d)\n",fieldCount);
  1546. #endif    
  1547.     if (fieldCount>0) {
  1548.         ((XFE_AddressOutliner*)m_outliner)->PlaceText(fieldCount-1,
  1549.                                                       ADDRESS_OUTLINER_COLUMN_RECEIPIENT, 
  1550.                                                       True);
  1551.         // Set field status to match that of last field in list - allows drop
  1552.         // of several TO's, then switch to drop of several CC's etc.
  1553.         XFE_AddressFieldData *tmpData = (XFE_AddressFieldData*)XP_ListGetObjectNum(m_fieldList, fieldCount);
  1554.         if (tmpData) {
  1555.             if (tmpData->type==TO) fieldStatus=::TO;
  1556.             if (tmpData->type==CC) fieldStatus=::CC;
  1557.             if (tmpData->type==BCC) fieldStatus=::BCC;
  1558.         }
  1559.     }
  1560.  
  1561.     m_clearAddressee = False;
  1562.     ldapView->addSelectedToAddressPane(this,fieldStatus);
  1563.     m_clearAddressee = True;
  1564. }
  1565.  
  1566.