home *** CD-ROM | disk | FTP | other *** search
/ Tools / WinSN5.0Ver.iso / NETSCAP.50 / WIN1998.ZIP / ns / cmd / xfe / src / ABMListView.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1998-04-08  |  22.2 KB  |  910 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. /*
  20.  * ABMListView.cpp --
  21.  * Superclass for all mail news views (folder, thread, and message.)
  22.  * Created: Tao Cheng <tao@netscape.com>, Nov/27/1996.
  23.  */
  24.  
  25. #include "ABMListView.h"
  26.  
  27. #include "AddrBookView.h"
  28.  
  29. // icons
  30. fe_icon XFE_ABMListView::m_personIcon = { 0 };
  31. fe_icon XFE_ABMListView::m_listIcon = { 0 };
  32.  
  33. #include "felocale.h"
  34. #include "xpgetstr.h"
  35.  
  36. extern int XFE_ADDR_ADD_PERSON_TO_ABOOK;
  37. extern int MK_ADDR_ADD_PERSON_TO_ABOOK;
  38. extern int XFE_AB_NAME_CONTACT_TAB;
  39. extern int XFE_AB_NAME_GENERAL_TAB;
  40. extern int MK_ADDR_LAST_FIRST_SEP;
  41. extern int XFE_DND_NO_EMAILADDRESS;
  42.  
  43. #define OUTLINER_GEOMETRY_PREF "addressbook.listpane.outliner_geometry"
  44.  
  45. #define MULTI_SELECT_ON   1
  46.  
  47. //
  48. static void TableTraverse(
  49.     Widget w,
  50.          XEvent *event,
  51.          String *params,
  52.          Cardinal *nparam)
  53.  
  54. {
  55.    XtPointer client;
  56.    XFE_ABMListView *obj ;
  57.  
  58.    XtVaGetValues( w, XmNuserData, &client, 0);
  59.  
  60.    obj = (XFE_ABMListView *) client;
  61.    obj->tableTraverse(w, event, params, nparam);
  62. }
  63.  
  64. // Customized Traversal Actions
  65.  
  66. static XtActionsRec actions[] =
  67. { {"TableTraverse",     TableTraverse     },};
  68.  
  69. extern XtAppContext fe_XtAppContext;
  70. //
  71. XFE_ABMListView::XFE_ABMListView(XFE_Component *toplevel_component, 
  72.                  Widget         parent,
  73.                  DIR_Server    *dir, 
  74.                  ABook         *pABook,
  75.                  XFE_View      *parent_view,
  76.                  MWContext     *context,
  77.                  MSG_Master    *master): 
  78.   XFE_MNView(toplevel_component, parent_view, context,
  79.              (MSG_Pane *)NULL),
  80.  
  81.   m_master(master),
  82.   m_dir(dir),
  83.   m_mListPane(NULL),
  84.   m_AddrBook(pABook),
  85.   m_listID(MSG_VIEWINDEXNONE),
  86.   m_entryID(MSG_VIEWINDEXNONE),
  87.   m_memberID(MSG_VIEWINDEXNONE),
  88.   m_count(0),
  89.   m_textF(0)
  90. {
  91.   /* initialize m_directroies
  92.    */
  93.   m_directories = FE_GetDirServers();
  94.  
  95.   m_preStr[0] = '\0';
  96.  
  97.   // Add actions
  98.   XtAppAddActions( fe_XtAppContext, actions,  XtNumber(actions));
  99.  
  100.   /* For outliner
  101.    */
  102.   int num_columns = 2;
  103.   static int column_widths[] = {6, 50};
  104.  
  105.   m_outliner = new XFE_Outliner("mailingList",
  106.                                 this,
  107.                                 toplevel_component,
  108.                                 parent,
  109.                                 False, // constantSize
  110.                                 False,  //hasHeadings
  111.                                 num_columns,
  112.                                 num_columns,
  113.                                 column_widths,
  114.                                 OUTLINER_GEOMETRY_PREF);
  115.   /* BEGIN_3P: XmLGrid
  116.    */
  117.   XtVaSetValues(m_outliner->getBaseWidget(),
  118.                 XtVaTypedArg, XmNblankBackground, XmRString, "white", 6,
  119.                 XmNselectionPolicy, XmSELECT_MULTIPLE_ROW,
  120.                 XmNvisibleRows, 10,
  121.                 NULL);
  122.   XtVaSetValues(m_outliner->getBaseWidget(),
  123.                 XmNcellDefaults, True,
  124.                 XtVaTypedArg, XmNcellBackground, XmRString, "white", 6,
  125.                 NULL);
  126.   // editable
  127.   XtVaSetValues(m_outliner->getBaseWidget(),
  128.                 XmNcellDefaults, True,
  129.                 XmNcolumn, 1,
  130.                 XmNcellEditable, True,
  131.                 NULL);
  132.   /* END_3P: XmLGrid
  133.    */
  134.  
  135.   // create drop site for internal drop
  136.   fe_dnd_CreateDrop(m_outliner->getBaseWidget(),AddressDropCb,this);
  137.  
  138.   
  139.   /* XFE_Outliner constructor does not allocate any content row
  140.    * XFE_Outliner::change(int first, int length, int newnumrows)
  141.    */
  142.   m_outliner->show();
  143.   setBaseWidget(m_outliner->getBaseWidget());
  144.   // initialize the icons if they haven't already been
  145.   {
  146.     Pixel bg_pixel;
  147.     
  148.     XtVaGetValues(m_outliner->getBaseWidget(), XmNbackground, &bg_pixel, 0);
  149.     if (!m_personIcon.pixmap)
  150.       fe_NewMakeIcon(getToplevel()->getBaseWidget(),
  151.              /* umm. fix me
  152.               */
  153.              BlackPixelOfScreen(XtScreen(m_outliner->getBaseWidget())),
  154.              bg_pixel,
  155.              &m_personIcon,
  156.              NULL, 
  157.              MN_Person.width, 
  158.              MN_Person.height,
  159.              MN_Person.mono_bits, 
  160.              MN_Person.color_bits, 
  161.              MN_Person.mask_bits, 
  162.              FALSE);
  163.  
  164.     if (!m_listIcon.pixmap)
  165.       fe_NewMakeIcon(getToplevel()->getBaseWidget(),
  166.              /* umm. fix me
  167.               */
  168.              BlackPixelOfScreen(XtScreen(m_outliner->getBaseWidget())),
  169.              bg_pixel,
  170.              &m_listIcon,
  171.              NULL, 
  172.              MN_People.width, 
  173.              MN_People.height,
  174.              MN_People.mono_bits, 
  175.              MN_People.color_bits, 
  176.              MN_People.mask_bits, 
  177.              FALSE);
  178.  
  179.   }
  180. }
  181.  
  182. XFE_ABMListView::~XFE_ABMListView()
  183. {
  184.   /* close the pane
  185.    */
  186.     if (m_mListPane)
  187.         AB_CloseMailingListPane(&m_mListPane);
  188.  
  189. }
  190.  
  191. ABID XFE_ABMListView::setValues(ABID listID)
  192. {
  193.   m_listID = listID;
  194.  
  195.   /* Initialize mailing list pane
  196.    */
  197.   m_mListPane = NULL;
  198.   AB_InitMailingListPane(&m_mListPane,
  199.              &m_listID,
  200.              m_dir,
  201.              m_AddrBook,
  202.              m_contextData,
  203.              m_master,
  204.              ABFullName,
  205.              True);
  206.  
  207.   /* Tao_04dec96: use XFE_MNListView
  208.    * connect pane and view
  209.    * MSG_SetFEData((MSG_Pane *)m_abPane, this);
  210.    * 
  211.    */
  212.   setPane((MSG_Pane *)m_mListPane);
  213.   /* Get # of existing entry
  214.    */
  215.   AB_GetEntryCountInMailingList(m_mListPane, &m_count);
  216.  
  217.   m_outliner->change(0, m_count, m_count);
  218.   return  m_listID;
  219. }
  220.  
  221. /* Methods for the outlinable interface.
  222.  */
  223. char *XFE_ABMListView::getCellTipString(int row, int column)
  224. {
  225.     char *tmp = 0;
  226.     static char tipstr[128];
  227.     tipstr[0] = '\0';
  228.  
  229.     if (row < 0) {
  230.         /* header
  231.          */
  232.         tmp = getColumnHeaderText(column);
  233.     }/* if */
  234.     else {
  235.         ABID orgID = m_entryID;
  236.  
  237.         /* content 
  238.          */
  239.         m_entryID = AB_GetEntryIDAt((AddressPane *) m_mListPane, 
  240.                                     (uint32) row);
  241.         tmp = getColumnText(column);
  242.  
  243.         /* reset
  244.          */
  245.         m_entryID = orgID;
  246.     }/* else */
  247.     if (tmp && 
  248.         (!m_outliner->isColTextFit(tmp, row, column)))
  249.         XP_STRCPY(tipstr,tmp);
  250.     return tipstr;
  251. }
  252.  
  253. char *XFE_ABMListView::getCellDocString(int /* row */, int /* column */)
  254. {
  255.     return NULL;
  256. }
  257.  
  258. // Converts between an index and some non positional data type.
  259. // Used to maintain selection when the list is reordered.
  260. void *
  261. XFE_ABMListView::ConvFromIndex(int /*index*/)
  262. {
  263.   return 0;
  264. }
  265.  
  266. // Converts between an index and some non positional data type.
  267. // Used to maintain selection when the list is reordered.
  268. int
  269. XFE_ABMListView::ConvToIndex(void */*item*/)
  270. {
  271.   return 0;
  272. }
  273.  
  274. /* This method acquires one line of data: entryID is set for getColumnText
  275.  */
  276. void*
  277. XFE_ABMListView::acquireLineData(int line)
  278. {
  279.   m_entryID = AB_GetEntryIDAt((AddressPane *) m_mListPane, (uint32) line);
  280.  
  281.   static char tmp[8];
  282.   tmp[0] = '\0';
  283.   return tmp;
  284. }
  285.  
  286. /* The Outlinable interface.
  287.  */
  288.  
  289. char*
  290. XFE_ABMListView::getColumnName(int column)
  291. {
  292.   switch (column) {
  293.   case XFE_AddrBookView::OUTLINER_COLUMN_TYPE:
  294.       return XP_GetString(XFE_AB_NAME_CONTACT_TAB);
  295.  
  296.   case XFE_AddrBookView::OUTLINER_COLUMN_NAME:
  297.       return XP_GetString(XFE_AB_NAME_GENERAL_TAB);
  298.   }/* switch */
  299.  
  300.   return "unDefined";
  301. }
  302.  
  303. /* Returns the text and/or icon to display at the top of the column.
  304.  */
  305. char*
  306. XFE_ABMListView::getColumnHeaderText(int /* column */)
  307. {
  308.   return 0;
  309. }
  310.  
  311. // Returns the text and/or icon to display at the top of the column.
  312. fe_icon*
  313. XFE_ABMListView::getColumnHeaderIcon(int /*column*/)
  314. {
  315.   return 0;
  316. }
  317.  
  318. // Returns the text and/or icon to display at the top of the column.
  319. EOutlinerTextStyle 
  320. XFE_ABMListView::getColumnHeaderStyle(int /*column*/)
  321. {
  322.   return OUTLINER_Default;
  323. }
  324.  
  325. /*
  326.  * The following 4 requests deal with the currently acquired line.
  327.  */
  328. EOutlinerTextStyle 
  329. XFE_ABMListView::getColumnStyle(int /*column*/)
  330. {
  331.   /* To be refined
  332.    */
  333.   return OUTLINER_Default;
  334. }
  335.  
  336. char*
  337. XFE_ABMListView::getColumnText(int column)
  338. {
  339.   static char a_line[AB_MAX_STRLEN];
  340.   a_line[0] = '\0';
  341.   switch (column) {
  342.   case XFE_AddrBookView::OUTLINER_COLUMN_TYPE:
  343.     break;
  344.  
  345.   case XFE_AddrBookView::OUTLINER_COLUMN_NAME:
  346.     {
  347.         char *expandedName = NULL;
  348.         AB_GetExpandedName(m_dir, m_AddrBook, m_entryID, &expandedName);
  349.         if (expandedName)
  350.             XP_STRCPY(a_line, expandedName);
  351.     }
  352.     break;
  353.  
  354.   }/* switch () */
  355.   return a_line;
  356. }
  357.  
  358. fe_icon*
  359. XFE_ABMListView::getColumnIcon(int column)
  360. {
  361.   fe_icon *myIcon = 0;
  362.   switch (column) {
  363.   case OUTLINER_COLUMN_TYPE:
  364.     {
  365.       ABID type;
  366.       AB_GetType(m_dir, m_AddrBook, m_entryID, &type);
  367.       if (type == ABTypePerson)
  368.     myIcon = &m_personIcon; /* shall call make/initialize icons */
  369.       else if (type == ABTypeList)
  370.     myIcon = &m_listIcon;
  371.     }
  372.     break;
  373.   }/* switch () */
  374.   return myIcon;
  375. }
  376.  
  377. //
  378. void
  379. XFE_ABMListView::getTreeInfo(XP_Bool */*expandable*/,
  380.                    XP_Bool */*is_expanded*/, 
  381.                    int *depth, 
  382.                    OutlinerAncestorInfo **/*ancestor*/)
  383. {
  384.   depth = 0;
  385. }
  386.  
  387. //
  388. void 
  389. XFE_ABMListView::Buttonfunc(const OutlineButtonFuncData *data)
  390. {
  391.   int row = data->row,
  392.       clicks = data->clicks;
  393.  
  394.   if (row < 0) {
  395.     return;
  396.   } 
  397.   else {
  398.     /* content row 
  399.      */
  400.     ABID type;
  401.     ABID entry;
  402.  
  403.     entry = AB_GetEntryIDAt((AddressPane *) m_mListPane, (uint32) row);
  404.     
  405.     if (entry == MSG_VIEWINDEXNONE) 
  406.       return;
  407.     
  408.     AB_GetType(m_dir, m_AddrBook, entry, &type);
  409.     
  410.     if (clicks == 2) {
  411.         m_outliner->selectItemExclusive(data->row);
  412.     }/* clicks == 2 */
  413.     else if (clicks == 1) {
  414. #if MULTI_SELECT_ON
  415.         if (data->shift) {
  416.             // select the range.
  417.             const int *selected;
  418.             int count;
  419.   
  420.             m_outliner->getSelection(&selected, &count);
  421.     
  422.             if (count == 0) { /* there wasn't anything selected yet. */
  423.       
  424.                 m_outliner->selectItemExclusive(data->row);
  425.             }/* if count == 0 */
  426.             else if (count == 1) {
  427.                 /* there was only one, so we select the range from
  428.                    that item to the new one. */
  429.                 
  430.                 m_outliner->selectRangeByIndices(selected[0], data->row);
  431.             }/* count == 1 */
  432.             else {
  433.                 /* we had a range of items selected, 
  434.                  * so let's do something really
  435.                  * nice with them. 
  436.                  */
  437.       
  438.                 m_outliner->trimOrExpandSelection(data->row);
  439.             }/* else */
  440.         }/* if */
  441.         else {
  442.             m_outliner->selectItemExclusive(data->row);
  443.         }/* else */
  444. #else
  445.         m_outliner->selectItemExclusive(data->row);
  446. #endif
  447.         getToplevel()->notifyInterested(XFE_View::chromeNeedsUpdating);
  448.     }/* clicks == 1 */
  449.   }/* else */
  450.  
  451. }/* XFE_ABMListView::Buttonfunc() */
  452.  
  453. void 
  454. XFE_ABMListView::Flippyfunc(const OutlineFlippyFuncData */*data*/)
  455. {
  456. }
  457.  
  458. /* Tells the Outlinable object that the line data is no
  459.  * longer needed, and it can free any storage associated with it.
  460.  */ 
  461. void
  462. XFE_ABMListView::releaseLineData()
  463. {
  464. }
  465.  
  466. /* return the outliner associated with this outlinable.
  467.  *
  468.  */
  469. XFE_Outliner*
  470. XFE_ABMListView::getOutliner()
  471. {
  472.   return m_outliner;
  473. }
  474.  
  475.  
  476. /*
  477.  * Callbacks for outside world
  478.  */
  479. void XFE_ABMListView::entryTTYActivateCallback(Widget w, 
  480.                            XtPointer clientData, 
  481.                            XtPointer callData)
  482. {
  483.   XFE_ABMListView *obj = (XFE_ABMListView *) clientData;
  484.   obj->entryTTYActivateCB(w, callData);
  485. }
  486.  
  487. void
  488. XFE_ABMListView::entryTTYActivateCB(Widget w, XtPointer /* callData */)
  489. {
  490.   const char *str;
  491.   str = fe_GetTextField(w);
  492.  
  493.   if (!str || XP_STRLEN(str) == 0)
  494.       return;
  495.  
  496.   /* if the name does not match/get expanded:
  497.    * we break down every token
  498.    */
  499.   if (m_memberID == MSG_VIEWINDEXNONE) {
  500.       int len = XP_STRLEN(str);
  501.       char *pStr = (char *) XP_CALLOC(len+1, sizeof(char));
  502.  
  503.       XP_SAFE_SPRINTF(pStr, len+1,
  504.                       "%s\0",
  505.                       str);
  506.  
  507.       char *tok = 0,
  508.            *last = 0;
  509.       int   count = 0;
  510.       char *sep = XP_GetString(MK_ADDR_LAST_FIRST_SEP);
  511.  
  512.       while (((tok=XP_STRTOK_R(count?nil:pStr, sep, &last)) != NULL)&&
  513.              XP_STRLEN(tok) &&
  514.              count < len) {
  515.  
  516.           /* new one; no email address is attached
  517.            */
  518.           PersonEntry *person = new PersonEntry;
  519.           person->Initialize();
  520.           person->WinCSID = m_contextData->fe.data->xfe_doc_csid;
  521.           person->pGivenName = XP_STRDUP(tok);
  522.           person->pEmailAddress = XP_STRDUP(tok);
  523.  
  524.           ABID entryID;
  525.           AB_AddPersonToMailingListAt(m_mListPane, 
  526.                                       person, 
  527.                                       m_count++, 
  528.                                       &entryID);
  529.           delete person;
  530.  
  531.           count++;
  532.       }/* while */
  533.   }/* if */
  534.   else
  535.     AB_AddIDToMailingListAt(m_mListPane, m_memberID, m_count++);
  536.  
  537.   //AB_GetEntryCountInMailingList(m_mListPane, &m_count);
  538.   /* backend does not update list view
  539.    */
  540.   m_outliner->change(0, m_count, m_count);
  541.  
  542.   /* reset 
  543.    */
  544.   m_memberID = MSG_VIEWINDEXNONE;
  545.   XP_FREE((void *)str);
  546.   fe_SetTextFieldAndCallBack(w, "");
  547. }
  548.  
  549. void XFE_ABMListView::entryTTYValChgCallback(Widget w, 
  550.                            XtPointer clientData, 
  551.                            XtPointer callData)
  552. {
  553.   XFE_ABMListView *obj = (XFE_ABMListView *) clientData;
  554.   obj->entryTTYValChgCB(w, callData);
  555. }
  556.  
  557. void
  558. XFE_ABMListView::entryTTYValChgCB(Widget w, XtPointer /* callData */)
  559. {
  560.  
  561.   m_textF = w;
  562.  
  563.   const char *str;
  564.   str = fe_GetTextField(w);
  565.  
  566.   int curPos = XmTextFieldGetCursorPosition(w);
  567.  
  568.   if (m_preStr && XP_STRCMP(str, (const char*)m_preStr) == 0)
  569.     return;
  570.  
  571.   ABID entryID;
  572.   ABID field;
  573.   XP_Bool setV = False;
  574. #if 1
  575.   DIR_Server* pab  = NULL;
  576.   DIR_GetComposeNameCompletionAddressBook(m_directories, &pab);
  577.   if (pab && 
  578.       AB_GetIDForNameCompletion(m_AddrBook, 
  579.                                 pab,
  580.                                 &entryID, 
  581.                                 &field, 
  582.                                 str) != MSG_VIEWINDEXNONE) {
  583. #else
  584.   if (AB_GetIDForNameCompletion(m_AddrBook, 
  585.                  m_dir,
  586.                  &entryID, 
  587.                  &field, 
  588.                  str) != MSG_VIEWINDEXNONE) {
  589. #endif
  590.       char a_line[AB_MAX_STRLEN];
  591.       a_line[0] = '\0';
  592.  
  593.       if (field == ABNickname) {
  594.           AB_GetNickname(m_dir, m_AddrBook, entryID, a_line);
  595.       }/* ABNickname */
  596.       else if (field == ABFullName) {
  597.           AB_GetFullName(m_dir, m_AddrBook, entryID, a_line);
  598.       }/* else if ABFullName */
  599.  
  600.       int len = strlen(a_line);
  601.       if (len) {
  602.         XP_STRCPY(m_preStr, a_line);
  603.  
  604.         /* shal be a valid id
  605.          */
  606.         m_memberID = entryID;
  607.         setV = True;
  608.       }/* if len */
  609.       else {
  610.           m_memberID = MSG_VIEWINDEXNONE;
  611.           XP_STRCPY(m_preStr, str);
  612.       }/* else */
  613.  
  614.   }/* if */
  615.   else {
  616. #if defined(DEBUG_tao)
  617.       printf("\n  entryTTYValChgCB:set m_memberID = MSG_VIEWINDEXNONE");
  618. #endif
  619.       m_memberID = MSG_VIEWINDEXNONE;
  620.       strcpy(m_preStr, str);
  621.   }/* else */
  622.   if (setV) {
  623.       int lastPos = m_preStr?XP_STRLEN(m_preStr):0;
  624.  
  625.       fe_SetTextFieldAndCallBack(w, m_preStr);
  626. #if defined(DEBUG_tao)
  627.       printf("\n *** str=%s, curPos=%d, lastPos=%d, m_preStr=%s",
  628.              str?str:"", curPos, lastPos, m_preStr?m_preStr:"");
  629. #endif
  630.       /* set selection
  631.        */
  632.       if (curPos > 0 && lastPos > curPos) {
  633.           Time time = XtLastTimestampProcessed(XtDisplay(w));
  634.  
  635.           XmTextFieldSetSelection(w, curPos, lastPos, time);
  636.           /* set cursor position
  637.            */
  638.       }/* if */
  639.       XmTextFieldSetCursorPosition(w, curPos);
  640.   }/* if */
  641. }
  642.  
  643. void XFE_ABMListView::remove()
  644. {
  645.   /* check which is selected
  646.    */
  647.   uint32 num = 0; // = XmLGridGetSelectedRowCount(w);
  648.   const int *indices = 0;
  649.   m_outliner->getSelection(&indices, (int *) &num);
  650.   if (num > 0 && indices) {
  651.       int curInd =  indices[0];
  652. #if MULTI_SELECT_ON
  653.       /* indices is an internal buffer and
  654.        * may be modified in the process of deletion 
  655.        */
  656.       int *buf = (int *) XP_CALLOC(num, sizeof(int));
  657.       buf = (int *) memcpy(buf, indices, num*sizeof(int));
  658.  
  659.       for (int i=num-1; i >=0; i--) {
  660.           AB_RemoveIDFromMailingListAt(m_mListPane, buf[i]);
  661.       }/* for i */
  662.       XP_FREEIF(buf);
  663. #else
  664.     AB_RemoveIDFromMailingListAt(m_mListPane, indices[0]);
  665. #endif
  666.  
  667.     AB_GetEntryCountInMailingList(m_mListPane, &m_count);
  668.  
  669.     /* select next
  670.      */
  671.     if (m_count) {
  672.         if (curInd >= m_count)
  673.             curInd = m_count-1;
  674.         if(m_outliner && curInd >=0) {
  675.             m_outliner->selectItemExclusive(curInd);
  676.             m_outliner->makeVisible(curInd);
  677.         }/* if */
  678.     }/* if m_count */
  679.   }/* if num > 0 && indices */
  680. }/* remove() */
  681.  
  682. int XFE_ABMListView::apply(char *pNickName, char *pFullName, char *pInfo)
  683. {
  684.     // TODO: Add your specialized code here and/or call the base class
  685.     if (m_textF)
  686.         entryTTYActivateCB(m_textF, NULL);
  687.  
  688.     MailingListEntry  list;
  689.     ABID              tempID = MSG_MESSAGEIDNONE;
  690.     int               errorID = 0;
  691.     MSG_ViewIndex     index = 0;
  692.     uint32            count = 0;
  693.     uint              i = 0;
  694.   
  695.     // UpdateData();
  696.     list.Initialize();
  697.  
  698.     // assign win_csid
  699.     list.WinCSID = m_contextData->fe.data->xfe_doc_csid;
  700.  
  701.     // get the values from the dialog box
  702.     if (pNickName)
  703.         list.pNickName = XP_STRDUP(pNickName);
  704.     if (pFullName)
  705.         list.pFullName = XP_STRDUP(pFullName);
  706.     if (pInfo)
  707.         list.pInfo = XP_STRDUP(pInfo);
  708.  
  709.     // get the count that is now in the list in the pane
  710.     AB_GetEntryCountInMailingList(m_mListPane, &count);
  711.     
  712.     // run through all the entries to see if there are
  713.     // going to be any errors
  714.     do {
  715.         if ((errorID =
  716.              AB_ModifyMailingListAndEntriesWithChecks(m_mListPane, &list,
  717.                                                       &index, i)) != 0) {
  718.             // if the error was that this entry isn't in the database 
  719.             // then we are going to prompt them
  720.             // do you want to add them 
  721.             // defined in allxpstr.h
  722.             if (MK_ADDR_ADD_PERSON_TO_ABOOK == errorID) {
  723.                 // bunch of formatting stuff for the dialog
  724.                 char * fullname = NULL;
  725.                 // set the selection to the one that's in error
  726.                 m_outliner->selectItemExclusive(index);
  727.                 m_outliner->makeVisible(index);
  728.                 tempID = AB_GetEntryIDAt((AddressPane*) m_mListPane,
  729.                                              index);
  730.                 AB_GetExpandedName (m_dir, m_AddrBook, tempID, &fullname);
  731.                 char* tmp = 
  732.                     PR_smprintf(XP_GetString(XFE_ADDR_ADD_PERSON_TO_ABOOK),
  733.                                 fullname);
  734.                 if (tmp && fullname) {
  735.                     // if they dont respond yes then return because
  736.                     // i dont know what to do
  737.                     // Boolean fe_Confirm_2 (Widget parent, const char *message);
  738.                     if (!fe_Confirm_2(getBaseWidget(), tmp)) {
  739.                         XP_FREEIF (tmp);
  740.                         XP_FREEIF (fullname);
  741.                         return errorID;
  742.                     }/* if */
  743.                     else
  744.                         // if they did respond yes then reset the error
  745.                         // update the count of where we are in the list
  746.                         errorID = 0;
  747.  
  748.                     i = index;
  749.                     // if we prompt them on the last one
  750.                     // then add it there might be a better way to write this
  751.                     // do loop
  752.                     if (i == count - 1) {
  753.                         errorID =
  754.                             AB_ModifyMailingListAndEntriesWithChecks(m_mListPane,
  755.                                                                      &list,
  756.                                                                      &index,
  757.                                                                      MSG_VIEWINDEXNONE);
  758.                     }/* if */
  759.                 }/* if tmp && fullname */
  760.                 XP_FREEIF (tmp);
  761.                 XP_FREEIF (fullname);
  762.             }/* if MK_ADDR_ADD_PERSON_TO_ABOOK */
  763.             else {
  764.                 m_outliner->selectItemExclusive(index);
  765.                 m_outliner->makeVisible(index);
  766.                 break;
  767.             }/* else */
  768.         }/* if errorID != 0 */
  769.         i++;
  770.     } while (i < count && errorID == 0); 
  771.     
  772.     return errorID;
  773. }
  774.  
  775. void 
  776. XFE_ABMListView::tableTraverse(Widget /*w*/,
  777.                                XEvent *  event,
  778.                                String *  params,
  779.                                Cardinal* nparam)
  780.  
  781. {
  782.     XrmQuark q;
  783.     static int quarksValid = 0;
  784.     static XrmQuark qBACKSPACE;
  785.     
  786.     if (*nparam != 1)
  787.         return;
  788.  
  789.     if (!quarksValid) {
  790.         qBACKSPACE = XrmStringToQuark("BACKSPACE");
  791.         quarksValid = 1;
  792.     }/* if */
  793.  
  794.     q = XrmStringToQuark(params[0] );
  795.  
  796.     if ( q == qBACKSPACE )
  797.         doBackSpace(event);
  798. }
  799.  
  800. void
  801. XFE_ABMListView::doBackSpace(XEvent *event)
  802. {
  803.   XmTextPosition cpos;
  804.   XmTextPosition pos;
  805.  
  806.   XtVaGetValues(m_textF, XmNcursorPosition, &cpos, 0);
  807.   pos = XmTextFieldGetLastPosition(m_textF);
  808.  
  809.   if (pos > 0 && m_textF) { 
  810.       // Hack text widget action
  811.       XtCallActionProc(m_textF, "delete-previous-character",
  812.                        event, NULL, 0 );
  813.   } /* pos > 0 */
  814. }
  815.  
  816.  
  817. // Address field drop site handler
  818. void
  819. XFE_ABMListView::AddressDropCb(Widget,void* cd,
  820.                                fe_dnd_Event type,fe_dnd_Source *source,
  821.                                XEvent*) {
  822.     XFE_ABMListView *ad=(XFE_ABMListView*)cd;
  823.     
  824.     if (type==FE_DND_DROP && ad && source)
  825.         ad->addressDropCb(source);
  826. }
  827.  
  828. void
  829. XFE_ABMListView::addressDropCb(fe_dnd_Source *source)
  830. {
  831.     switch (source->type) {
  832.  
  833.     case FE_DND_ADDRESSBOOK:
  834.         {
  835.         // add addressbook drop to address panel
  836.         XFE_ABListSearchView* addrView=( XFE_ABListSearchView*)source->closure;
  837.         if (addrView)
  838.             processAddressBookDrop(addrView->getOutliner(),
  839.                                    addrView->getDir(),
  840.                                    addrView->getAddrBook(),
  841.                                    (AddressPane*)addrView->getABPane());
  842.         break;
  843.         }
  844.     case FE_DND_BOOKS_DIRECTORIES:
  845.         {
  846. #if defined(DEBUG_tao)
  847.             printf("\nXFE_ABMListView::addressDropCb:FE_DND_BOOKS_DIRECTORIES\n");
  848. #endif
  849.         
  850.             break;
  851.         }
  852.     default:
  853.         break;
  854.     }
  855. }
  856.  
  857. void
  858. XFE_ABMListView::processAddressBookDrop(XFE_Outliner *outliner,
  859.                                         DIR_Server *abDir,
  860.                                         ABook *abBook,
  861.                                         AddressPane *abPane)
  862. {
  863.     if (!m_mListPane ||
  864.         abBook != m_AddrBook ||
  865.         abDir != m_dir)
  866.         return;
  867.  
  868.     // add dropped entries to end of mailing list
  869.     const int *selectedList=NULL;
  870.     int numSelected=0;
  871.     if (outliner->getSelection(&selectedList, &numSelected)) {
  872.         int i;
  873.         XP_Bool noEmails = False;
  874.         for (i=0; i<numSelected; i++) {
  875.             ABID entry = AB_GetEntryIDAt(abPane,(uint32)selectedList[i]);
  876.     
  877.             if (entry == MSG_VIEWINDEXNONE) 
  878.                 continue;
  879.  
  880.             /* check if email address exist
  881.              */
  882.             char a_line[AB_MAX_STRLEN];
  883.             a_line[0] = '\0';
  884.             AB_GetEmailAddress(m_dir, m_AddrBook, entry, a_line);
  885.             if (!a_line ||
  886.                 !XP_STRLEN(a_line)) {
  887.                 ABID type;
  888.                 AB_GetType(m_dir, m_AddrBook, entry, &type);
  889.                 if (type == ABTypePerson) {
  890.                     noEmails = True;
  891.                     continue;
  892.                 }/* if */
  893.             }/* if */
  894.             
  895.             uint32 count=0;
  896.             AB_GetEntryCountInMailingList(m_mListPane,&count);
  897.             AB_AddIDToMailingListAt(m_mListPane,entry,count);
  898.         }
  899.         if (noEmails) {
  900.           // Prompt the user to enter the email address
  901.           char tmp[1024];
  902.           XP_SAFE_SPRINTF(tmp, sizeof(tmp),
  903.                           "%s",
  904.                           XP_GetString(XFE_DND_NO_EMAILADDRESS));
  905.           FE_Alert(m_contextData, tmp);
  906.         }/* if */
  907.  
  908.     }
  909. }
  910.