home *** CD-ROM | disk | FTP | other *** search
/ Tools / WinSN5.0Ver.iso / NETSCAP.50 / WIN1998.ZIP / ns / cmd / xfe / src / LdapSearchView.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1998-04-08  |  19.3 KB  |  680 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.    LdapSearchView.h -- user's mail search view.
  20.    Created: Dora Hsu <dora@netscape.com>, 15-Dec-96.
  21. */
  22.  
  23. #include "MozillaApp.h"
  24. #include "LdapSearchView.h"
  25. #include "MsgFrame.h"
  26. #include "MsgView.h"
  27. #include "BrowserFrame.h"
  28. #include "ViewGlue.h"
  29.  
  30. #include "ComposeView.h"
  31. #include "ComposeFolderView.h"
  32. #include "addrbk.h"
  33. #include "icondata.h"
  34.  
  35. #include <Xm/Form.h>
  36. #include <Xm/LabelG.h>
  37. #include <Xm/RowColumn.h>
  38. #include <Xm/TextF.h>
  39. #include <Xm/SelectioB.h>
  40. #include <Xm/Frame.h>
  41. #include <Xm/LabelG.h>
  42. #include <Xm/PushBG.h>
  43. #include <Xm/DrawnB.h>
  44.  
  45. // For Column Header to use
  46.  
  47. const char * XFE_LdapSearchView::CloseLdap = "XFE_LdapSearchView::closeLdap";
  48. const int XFE_LdapSearchView::SEARCH_OUTLINER_COLUMN_NAME= 0;
  49. const int XFE_LdapSearchView::SEARCH_OUTLINER_COLUMN_EMAIL= 1;
  50. const int XFE_LdapSearchView::SEARCH_OUTLINER_COLUMN_COMPANY= 2;
  51. const int XFE_LdapSearchView::SEARCH_OUTLINER_COLUMN_PHONE= 3;
  52. const int XFE_LdapSearchView::SEARCH_OUTLINER_COLUMN_LOCALITY= 4;
  53.  
  54. #define OUTLINER_GEOMETRY_PREF "mail.ldapsearchpane.outliner_geometry"
  55.  
  56. static fe_icon m_personIcon = { 0 };
  57.  
  58. extern "C" Widget
  59. fe_make_option_menu(Widget toplevel,
  60.         Widget parent, char* widgetName, Widget *popup);
  61.  
  62. extern "C" void
  63. fe_get_option_size ( Widget optionMenu,
  64.                         Dimension *retWidth, Dimension *retHeight );
  65.  
  66. XFE_LdapSearchView::XFE_LdapSearchView(XFE_Component *toplevel_component,
  67.                                        Widget parent,
  68.                                        XFE_Frame * parent_frame,
  69.                                        XFE_MNView *mn_parentView,
  70.                                        MWContext *context, MSG_Pane *p)
  71.     : XFE_MNSearchView(toplevel_component, 
  72.                        parent, 
  73.                        parent_frame,
  74.                        mn_parentView, 
  75.                        context, 
  76.                        p, 
  77.                        NULL, 
  78.                        False)
  79. {
  80.   initialize();
  81. }
  82.  
  83. XFE_LdapSearchView::~XFE_LdapSearchView()
  84. {
  85. }
  86.  
  87. void
  88. XFE_LdapSearchView::initialize()
  89. {
  90.   // LDAP Specific
  91.   m_rules.scope = (MSG_ScopeAttribute)scopeLdapDirectory;
  92.   m_toAddrBook  = NULL;
  93.   m_toCompose  = NULL;
  94.   m_browserFrame = NULL;
  95.   m_directories = FE_GetDirServers();
  96.   int nDirs = XP_ListCount(m_directories);
  97.   if ( nDirs )
  98.       m_dir = (DIR_Server *) XP_ListGetObjectNum(m_directories, 1);
  99.   else m_dir = NULL;
  100. }
  101.  
  102.  
  103. void
  104. XFE_LdapSearchView::createWidgets (Widget formParent)
  105. {
  106.    XFE_MNSearchView::createWidgets(formParent);
  107.    createResultArea();
  108. }
  109.  
  110.  
  111. // Override
  112. void
  113. XFE_LdapSearchView::changeScope ()
  114. {
  115.   // Should do nothing because the scope should always be LdapDirectory 
  116.   m_dir = getDirServer();
  117.   getToplevel()->notifyInterested( XFE_MNSearchView::scopeChanged, m_dir);
  118. }
  119.  
  120. //fe_search_folder_option_cb
  121. void
  122. XFE_LdapSearchView::folderOptionCallback(Widget /*w*/,
  123.                                         XtPointer clientData, XtPointer)
  124. {
  125.    XFE_LdapSearchView* obj = (XFE_LdapSearchView*)clientData;
  126.    obj->changeScope();
  127. }
  128.  
  129.  
  130. // Override
  131. void
  132. XFE_LdapSearchView::addDefaultFolders()
  133. {
  134.   int i;
  135.   Widget popupW;
  136.   Cardinal ac = 0;
  137.   Arg av[10];
  138.   XP_List    *directories = FE_GetDirServers();
  139.   int nDirs = XP_ListCount(directories);
  140.  
  141.   XtVaGetValues(m_rules.scopeOptW, XmNsubMenuId, &popupW, 0);
  142.   /* Hopefully: Get Number of Scope Names from MSG */ 
  143.   for ( i = 0; i < nDirs; i++)
  144.   {
  145.     Widget btn;
  146.     XmString xmStr;
  147.  
  148.     DIR_Server *dir = (DIR_Server*)XP_ListGetObjectNum(directories,i+1);
  149.  
  150.     if ( dir && dir->dirType == LDAPDirectory )
  151.     {
  152.  
  153.        xmStr = XmStringCreateLtoR(dir->description,
  154.                                 XmSTRING_DEFAULT_CHARSET);
  155.  
  156.        ac = 0;
  157.        XtSetArg(av[ac], XmNuserData, i); ac++;
  158.        XtSetArg(av[ac], XmNlabelString, xmStr); ac++;
  159.        btn = XmCreatePushButtonGadget(popupW, "ldapDirectory", av, ac);
  160.  
  161.        XtAddCallback(btn, XmNactivateCallback, 
  162.             XFE_LdapSearchView::folderOptionCallback, 
  163.             this);
  164.  
  165.        XtManageChild(btn);
  166.        XmStringFree(xmStr);
  167.     }
  168.    }
  169. }
  170.  
  171. // Override
  172. void
  173. XFE_LdapSearchView::buildHeaderOption()
  174. {
  175.   Cardinal ac;
  176.   Arg av[20];
  177.   Widget popupW;
  178.   Dimension width, height;
  179.  
  180.   ac = 0;
  181.   m_rules.searchLabel = XmCreateLabelGadget(m_header,
  182.                                 "ldapSearchFolderLabel", av, ac);
  183.   m_rules.scopeOptW = fe_make_option_menu(getToplevel()->getBaseWidget(),
  184.                         m_header, "ldapSearchScopeOpt", &popupW);
  185.  
  186.   // Add folders...
  187.   addDefaultFolders();
  188.   fe_get_option_size ( m_rules.scopeOptW, &width, &height);
  189.  
  190.   ac = 0;
  191.   m_rules.whereLabel = XmCreateLabelGadget(m_header, "where", av, ac);
  192.   XtVaSetValues(m_rules.searchLabel, XmNheight, height, 0 );
  193.   XtVaSetValues(m_rules.whereLabel, XmNheight, height, 0 );
  194. }
  195.  
  196. // Override
  197.  
  198.  
  199. DIR_Server* 
  200. XFE_LdapSearchView::getDirServer()
  201. {
  202.   Widget btn;
  203.   int folderNum;
  204.  
  205.   XtVaGetValues(m_rules.scopeOptW, XmNmenuHistory, &btn, 0 );
  206.   XtVaGetValues(btn, XmNuserData, &folderNum, 0);
  207.  
  208.   // Ldap search start ...
  209.   if ( m_numsubviews <= 0 ) return 0; // This should never happen
  210.  
  211.   int nDirs = XP_ListCount(m_directories);
  212.   DIR_Server *dir = (DIR_Server *) XP_ListGetObjectNum(m_directories,
  213.             folderNum+1);
  214.   m_dir = dir;
  215.   return dir;
  216. }
  217.  
  218. void
  219. XFE_LdapSearchView::prepSearchScope()
  220. {
  221.  
  222.   DIR_Server *dir = getDirServer();
  223.   XP_ASSERT(dir!= NULL);
  224.   MSG_AddLdapScope( getPane(), dir);
  225. }
  226.  
  227.  
  228. //fe_search_save_as_cb(Widget w, XtPointer clientData, XtPointer callData)
  229. void
  230. XFE_LdapSearchView::miscCmd()
  231. {
  232. }
  233.  
  234. char *
  235. XFE_LdapSearchView::getColumnHeaderText(int column) 
  236. {
  237.     /* Server ?
  238.      */
  239.     DIR_Server *pServer = getDirServer();
  240.     XP_ASSERT(pServer != NULL);
  241.     /* attrib
  242.      */
  243.     MSG_SearchAttribute  attrib;
  244.     switch (column) {
  245.     case SEARCH_OUTLINER_COLUMN_NAME:
  246.         attrib = attribCommonName;
  247.         break;
  248.  
  249.     case SEARCH_OUTLINER_COLUMN_EMAIL:
  250.         attrib = attrib822Address;
  251.         break;
  252.  
  253.     case SEARCH_OUTLINER_COLUMN_COMPANY:
  254.         attrib = attribOrganization;
  255.         break;
  256.         
  257.     case SEARCH_OUTLINER_COLUMN_PHONE:
  258.         attrib = attribPhoneNumber;
  259.         break;
  260.     case SEARCH_OUTLINER_COLUMN_LOCALITY:
  261.         attrib = attribLocality;
  262.         break;
  263.         
  264.     default:
  265.         XP_ASSERT(0);
  266.         return 0;
  267.     }/* switch */
  268.     DIR_AttributeId id;
  269.     MSG_SearchAttribToDirAttrib(attrib, &id);
  270.     const char *text = DIR_GetAttributeName(pServer, id);
  271.     static char header[128];
  272.     header[0] = '\0';
  273.     XP_STRCPY(header, text);
  274.     return header;
  275. }
  276.  
  277. char *
  278. XFE_LdapSearchView::getColumnText(int column)
  279. {
  280.  MSG_SearchValue *result;
  281.  MSG_SearchError err = SearchError_NullPointer; 
  282.     // Fill in the text for this particular column
  283.   if (!m_resultLine )  return NULL;
  284.   switch (column)
  285.   {
  286.     case SEARCH_OUTLINER_COLUMN_NAME:
  287.       err = MSG_GetResultAttribute(m_resultLine, attribCommonName, &result);
  288.     break;
  289.     case SEARCH_OUTLINER_COLUMN_EMAIL:
  290.       err = MSG_GetResultAttribute(m_resultLine, attrib822Address, &result);
  291.     break;
  292.     case SEARCH_OUTLINER_COLUMN_COMPANY:
  293.       err = MSG_GetResultAttribute(m_resultLine, attribOrganization, &result);
  294.     break;
  295.     case SEARCH_OUTLINER_COLUMN_PHONE:
  296.       err = MSG_GetResultAttribute(m_resultLine, attribPhoneNumber, &result);
  297.     break;
  298.     case SEARCH_OUTLINER_COLUMN_LOCALITY:
  299.       err = MSG_GetResultAttribute(m_resultLine, attribLocality, &result);
  300.     break;
  301.     default:
  302. #ifdef DEBUG
  303.       printf("XFE_LdapSearchView::getColumnText()Invalid column type.\n");
  304. #endif
  305.     break;
  306.   }
  307.  
  308.   return XP_STRDUP(((err == SearchError_Success) && result && result->u.string?
  309.       result->u.string:""));
  310.  
  311. }
  312.  
  313. fe_icon *
  314. XFE_LdapSearchView::getColumnIcon(int column)
  315. {
  316.    // Fill in the text for this particular column
  317.    if ( column == SEARCH_OUTLINER_COLUMN_NAME)
  318.    {
  319.     return 0; // Suppose to return people icon
  320.    }
  321.  
  322.    return 0;
  323. }
  324.  
  325. void 
  326. XFE_LdapSearchView::doubleClick(const OutlineButtonFuncData *data)
  327. {
  328.    MSG_ViewIndex index;
  329.    MSG_ResultElement *elem = NULL;
  330.    // Do nothing
  331.    if (data->clicks == 2 )
  332.    {
  333.     m_outliner->selectItemExclusive(data->row);
  334.     toggleActionButtonState(True);
  335.     index = (MSG_ViewIndex)(data->row);
  336.         MSG_GetResultElement(getPane(), index, &elem );
  337.  
  338.     // Always create a new frame for each result
  339.     m_browserFrame = new XFE_BrowserFrame(
  340.             XtParent(getToplevel()->getBaseWidget()), 
  341.                ViewGlue_getFrame(m_contextData), NULL);
  342.         m_searchpane = ((XFE_MsgView*)(m_browserFrame->getView()))->getPane();
  343.         MSG_OpenResultElement(elem, m_browserFrame->getContext());
  344.     m_browserFrame->show();
  345.    }
  346. }
  347.  
  348. void
  349. XFE_LdapSearchView::buildResultTable()
  350. {
  351.   int num_columns =  5;
  352.   int visible_num_columns =  4;
  353.   static int column_widths[] = {10, 20, 20, 10, 10};
  354.   m_outliner = new XFE_Outliner("addressList",
  355.                                 this,
  356.                                 getToplevel(),
  357.                                 m_result.container,
  358.                                 False, // constantSize
  359.                                 True,  // hasHeadings
  360.                                 num_columns,
  361.                                 visible_num_columns,
  362.                                 column_widths,
  363.                                 OUTLINER_GEOMETRY_PREF);
  364.  
  365.   Pixel bg;
  366.   XtVaGetValues(m_outliner->getBaseWidget(), XmNbackground, &bg, 0);
  367.   if (!m_personIcon.pixmap)
  368.       fe_NewMakeIcon(getToplevel()->getBaseWidget(),
  369.              BlackPixelOfScreen(XtScreen(m_outliner->getBaseWidget())),
  370.              bg,
  371.              &m_personIcon,
  372.              NULL, 
  373.              MN_Person.width, 
  374.              MN_Person.height,
  375.              MN_Person.mono_bits, 
  376.              MN_Person.color_bits, 
  377.              MN_Person.mask_bits, 
  378.              FALSE);
  379.   m_outliner->setMultiSelectAllowed(True);
  380.  
  381. #if !defined(USE_MOTIF_DND)
  382.   m_outliner->setDragType(FE_DND_LDAP_ENTRY, &m_personIcon, this);
  383. #endif /* USE_MOTIF_DND */
  384.  
  385.   m_outliner->setHideColumnsAllowed(True);
  386.  
  387. }
  388.  
  389. void
  390. XFE_LdapSearchView::buildResult()
  391. {
  392.   Widget ldapCommands;
  393.   Arg argv[10];
  394.   Cardinal ac = 0;
  395.  
  396.     XFE_MNSearchView::buildResult();
  397.  
  398.     ac = 0;
  399.     XtSetArg(argv[ac], XmNorientation, XmHORIZONTAL); ac++;
  400.     ldapCommands = XmCreateRowColumn(m_result.container, "ldapCommands", argv, ac);
  401.  
  402.     XtVaSetValues(ldapCommands, 
  403.                   XmNtopAttachment, XmATTACH_NONE,
  404.                   XmNbottomAttachment, XmATTACH_FORM,
  405.                   XmNleftAttachment, XmATTACH_FORM,
  406.                   XmNrightAttachment, XmATTACH_FORM,
  407.                   0);
  408.  
  409.     ac = 0;
  410.     m_toCompose =  XmCreatePushButtonGadget(ldapCommands, "toCompose", argv,ac);
  411.     m_toAddrBook =  XmCreatePushButtonGadget(ldapCommands, "toAddrBook", argv,ac);
  412.     XtSetSensitive(m_toAddrBook, False);
  413.     XtSetSensitive(m_toCompose,False);
  414.  
  415.     XtManageChild(m_toAddrBook);
  416.     XtManageChild(m_toCompose);
  417.  
  418.     XtAddCallback(m_toAddrBook, XmNactivateCallback, 
  419.                   XFE_LdapSearchView::toAddrBookCallback, 
  420.                   this);
  421.     XtAddCallback(m_toCompose, XmNactivateCallback, 
  422.                   XFE_LdapSearchView::toComposeCallback, 
  423.                   this);
  424.  
  425.     Dimension h, mh;
  426.  
  427.     XtVaGetValues(m_toAddrBook, XmNheight, &h, 0 );
  428.  
  429.     XtVaGetValues(ldapCommands, XmNmarginHeight, &mh, 0 );
  430.  
  431.     h = h + mh *2;
  432.  
  433.     XtVaSetValues(m_outliner->getBaseWidget(),
  434.                   XmNbottomOffset, h,
  435.                   0);
  436.     XtManageChild(ldapCommands);
  437. }
  438.  
  439. void
  440. XFE_LdapSearchView::clickHeader(const OutlineButtonFuncData */*data*/)
  441. {
  442. }
  443.  
  444. void
  445. XFE_LdapSearchView::handleClose()
  446. {
  447.   /* hide the frame for now*/
  448.   getToplevel()->notifyInterested(XFE_LdapSearchView::CloseLdap);
  449.   //XtDestroyWidget(obj->getToplevel()->getBaseWidget());
  450. }
  451.  
  452. void 
  453. XFE_LdapSearchView::toAddrBookCallback(Widget w, 
  454.                                        XtPointer clientData, 
  455.                                        XtPointer callData)
  456. {
  457.     XFE_LdapSearchView *obj = (XFE_LdapSearchView *) clientData;
  458.     obj->toAddrBookCB(w, callData);
  459. }/* XFE_LdapSearchView::toAddrBookCallback() */
  460.  
  461. void 
  462. XFE_LdapSearchView::toAddrBookCB(Widget /* w */, XtPointer /* callData */)
  463. {
  464.     /* need to check if selections are in personal address book
  465.      * already 
  466.      */
  467.   int count = 0; // = XmLGridGetSelectedRowCount(w);
  468.   const int *indices = 0;
  469.   m_outliner->getSelection(&indices, &count);
  470.   if (!count)
  471.     return;
  472.  
  473.   if (SearchError_Success !=
  474.       MSG_AddLdapResultsToAddressBook(getPane(), 
  475.                                       (MSG_ViewIndex *) indices, 
  476.                                       count))
  477.       XP_ASSERT(0);
  478.  
  479. }/* XFE_LdapSearchView::toAddrBookCB() */
  480.  
  481. void 
  482. XFE_LdapSearchView::toComposeCallback(Widget w, 
  483.                                       XtPointer clientData, 
  484.                                       XtPointer callData)
  485. {
  486.     XFE_LdapSearchView *obj = (XFE_LdapSearchView *) clientData;
  487.     obj->toComposeCB(w, callData);
  488. }/* XFE_LdapSearchView::toComposeCallback() */
  489.  
  490. void 
  491. XFE_LdapSearchView::toComposeCB(Widget /* w */, XtPointer /* callData */)
  492. {
  493.  
  494.     /* Get all selections; pack them and ..
  495.      *  AddrBookFrame::
  496.      */
  497.   /* Need to mimic ...
  498.    */
  499.   int count = 0; // = XmLGridGetSelectedRowCount(w);
  500.   const int *indices = 0;
  501.   m_outliner->getSelection(&indices, &count);
  502.   if (!count)
  503.     return;
  504.  
  505.   if (SearchError_Success != 
  506.       MSG_ComposeFromLdapResults(getPane(), 
  507.                                  (MSG_ViewIndex *) indices, 
  508.                                  count))
  509.       XP_ASSERT(0);
  510. }/* XFE_LdapSearchView::toComposeCB() */
  511.  
  512. void
  513. XFE_LdapSearchView::doLayout()
  514. {
  515.   XtVaSetValues(m_rules.searchLabel,                    /* Search for Header*/
  516.                 XmNalignment, XmALIGNMENT_END,
  517.                 XmNtopAttachment, XmATTACH_FORM,
  518.                 XmNbottomAttachment, XmATTACH_NONE,
  519.                 XmNleftAttachment, XmATTACH_FORM,
  520.                 XmNrightAttachment, XmATTACH_NONE,
  521.                 0);
  522.  
  523.   XtVaSetValues(m_rules.scopeOptW,      /* Search for Scope */
  524.                 XmNtopAttachment, XmATTACH_FORM,
  525.                 XmNbottomAttachment, XmATTACH_OPPOSITE_WIDGET,
  526.                 XmNbottomWidget, m_rules.searchLabel,
  527.                 XmNleftAttachment, XmATTACH_WIDGET,
  528.                 XmNleftWidget, m_rules.searchLabel,
  529.                 XmNrightAttachment, XmATTACH_NONE,
  530.                 0);
  531.  
  532.   XtVaSetValues(m_rules.whereLabel,                     /* Search for Where */
  533.                 XmNalignment, XmALIGNMENT_BEGINNING,
  534.                 XmNtopAttachment, XmATTACH_FORM,
  535.                 XmNbottomAttachment, XmATTACH_OPPOSITE_WIDGET,
  536.                 XmNbottomWidget, m_rules.searchLabel,
  537.                 XmNleftAttachment, XmATTACH_WIDGET,
  538.                 XmNleftWidget, m_rules.scopeOptW,
  539.                 XmNrightAttachment, XmATTACH_FORM,
  540.                 0);
  541.   doViewLayout();
  542.  
  543.   XtVaSetValues(m_rules.commandGroup,   /* More/Less */
  544.                                 XmNnoResize, True,
  545.                 XmNtopAttachment, XmATTACH_WIDGET,
  546.                                 XmNtopWidget, m_subviews[0]->getBaseWidget(),
  547.                 XmNbottomAttachment, XmATTACH_NONE,
  548.                                 XmNbottomOffset, 0,
  549.                 XmNleftAttachment, XmATTACH_FORM,
  550.                 XmNrightAttachment, XmATTACH_WIDGET,
  551.                 XmNrightWidget, m_rules.searchCommand,
  552.                 0);
  553.  
  554.  
  555.  
  556.   XtManageChild(m_rules.searchLabel);
  557.   XtManageChild(m_rules.scopeOptW);
  558.   XtManageChild(m_rules.whereLabel);
  559.   XtManageChild(m_rules.commandGroup);
  560.  
  561.   XtManageChild (m_ruleContent);
  562.   XtManageChild (m_content);
  563. }
  564.  
  565. /* Backend is not calling FE_PaneChanged on Ldap Directory change right
  566.    now, therefore, this method is not in use. However, the backend should
  567.    really call FE_PaneChanged when directory order is changed in the prefs.
  568.    That notification is hooked up for address book not for ldap search.
  569.    Has filed a bug to phil */
  570. void
  571. XFE_LdapSearchView::paneChanged(XP_Bool /*asynchronous*/,
  572.                                 MSG_PANE_CHANGED_NOTIFY_CODE /* notify_code */,
  573.                                 int32 /*value*/)
  574. {
  575.  
  576.         /* Shall we free existing list ?
  577.          */
  578.         m_directories = FE_GetDirServers();
  579.         int nDirs = XP_ListCount(m_directories);
  580.         XP_Bool found = False;
  581.         for (int i=0; i < nDirs; i++) {
  582.                 DIR_Server *dir = 
  583.                         (DIR_Server *) XP_ListGetObjectNum(m_directories,i+1);
  584.                 if (dir == m_dir ||
  585.                         (dir && m_dir &&
  586.                          (dir->dirType == m_dir->dirType))) {
  587.                         if ((dir->serverName==NULL && m_dir->serverName==NULL) ||
  588.                                 (dir->serverName && m_dir->serverName &&
  589.                                  !XP_STRCMP(dir->serverName, m_dir->serverName))) {
  590.                                 found = True;
  591.                                 break;
  592.                         }/* if */
  593.                 }/* if */
  594.         }/* for i*/
  595.         if (!found) {
  596.                 /* m_dir got deleted
  597.                  */
  598.         m_dir = NULL;
  599.         if ( !m_dir && nDirs )
  600.         {
  601.         /* there are still some directories installed, pick the
  602.            first one for best guess */
  603.         m_dir = (DIR_Server *) XP_ListGetObjectNum(m_directories, 1 );
  604.         }
  605.     }
  606.     if (!m_dir) /* non-directory left.... close search dialog*/
  607.       handleClose();
  608. }
  609.  
  610. /*
  611.  * Append selected search results to an address folder view.
  612.  * This is called as result of dragging from the LDAP search view
  613.  * to a compose window address area.
  614.  */
  615. void
  616. XFE_LdapSearchView::addSelectedToAddressPane(XFE_AddressFolderView* addr, SEND_STATUS fieldStatus)
  617. {
  618.   int count = 0;
  619.   const int *indices = 0;
  620.   m_outliner->getSelection(&indices, &count);
  621.  
  622.   if (count==0)
  623.     return;
  624.  
  625.   /* pack selected
  626.    */
  627.   ABAddrMsgCBProcStruc *pairs =
  628.       (ABAddrMsgCBProcStruc *) XP_CALLOC(1,sizeof(ABAddrMsgCBProcStruc));
  629.   pairs->m_pairs = (StatusID_t **) XP_CALLOC(count, sizeof(StatusID_t*));
  630.  
  631.   MSG_ResultElement *resultLine = NULL;
  632.   for (int i=0; i < count; i++) {
  633.       if (SearchError_Success != 
  634.           MSG_GetResultElement(getPane(), indices[i], &resultLine)) 
  635.           continue;
  636.  
  637.       StatusID_t *pair;
  638.       pair = (StatusID_t *) XP_CALLOC(1, sizeof(StatusID_t));
  639.       pair->status = fieldStatus;
  640.       pair->type = ABTypePerson;
  641.  
  642.       // email
  643.       MSG_SearchValue *result;
  644.       if ((SearchError_Success == MSG_GetResultAttribute(resultLine,attrib822Address,&result))&&
  645.           result &&
  646.           result->u.string) {
  647.           pair->emailAddr = XP_STRDUP(result->u.string);
  648.           MSG_DestroySearchValue(result);
  649.       }
  650.  
  651.       // fullname
  652.       MSG_GetResultAttribute(resultLine, attribCommonName, &result);
  653.       
  654.       // assemble
  655.       if (strlen(pair->emailAddr) && 
  656.           result && 
  657.           result->u.string) {
  658.           char tmp[AB_MAX_STRLEN];
  659.           sprintf(tmp, "%s <%s>", result->u.string, pair->emailAddr);
  660.           pair->dplyStr = XP_STRDUP(tmp);
  661.           MSG_DestroySearchValue(result);
  662.       }
  663.       else
  664.           pair->dplyStr = XP_STRDUP(result->u.string);
  665.       
  666.       pairs->m_pairs[pairs->m_count] = pair;
  667.       (pairs->m_count)++;
  668.   }
  669.   if (pairs && pairs->m_count) {
  670.       addr->addrMsgCB(pairs);
  671.   }
  672. }
  673.  
  674. void 
  675. XFE_LdapSearchView::toggleActionButtonState(Boolean on)
  676. {
  677.   XtSetSensitive(m_toAddrBook, on);
  678.   XtSetSensitive(m_toCompose, on);
  679. }
  680.