home *** CD-ROM | disk | FTP | other *** search
/ Tools / WinSN5.0Ver.iso / NETSCAP.50 / WIN1998.ZIP / ns / cmd / xfe / src / SearchRuleView.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1998-04-08  |  39.8 KB  |  1,444 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.    SearchRuleView.h -- creates each rule statement.
  20.    Created: Dora Hsu <dora@netscape.com>, 15-Dec-96 
  21.  */
  22.  
  23.  
  24.  
  25. #include "MNSearchView.h"
  26. #include "SearchRuleView.h"
  27. #include "EditHdrDialog.h"
  28.  
  29. #include <Xm/Xm.h>
  30. #include <Xm/Form.h>
  31. #include <Xm/Frame.h>
  32. #include <Xm/LabelG.h>
  33. #include <Xm/RowColumn.h>
  34. #include <Xm/TextF.h>
  35. #include <Xm/Frame.h>
  36. #include <Xm/PushBG.h>
  37. #include <time.h> // For search date
  38. #include <xpgetstr.h> /* for XP_GetString() */
  39.  
  40. #include <Xfe/Xfe.h>
  41.  
  42. #include <felocale.h>
  43. #include "xp_time.h"
  44. #include "xplocale.h"
  45.  
  46.  
  47. extern int XFE_SEARCH_INVALID_DATE;
  48. extern int XFE_SEARCH_INVALID_MONTH;
  49. extern int XFE_SEARCH_INVALID_DAY;
  50. extern int XFE_SEARCH_INVALID_YEAR;
  51.  
  52.  
  53. //--- notification ---
  54. const char *XFE_SearchRuleView::activateSearch = "XFE_SearchRuleView::activateSearch";
  55. //--- C utilities function ---
  56.  
  57. extern "C" Widget 
  58. fe_make_option_menu(Widget toplevel, Widget parent, char* widgetName, Widget *popup)
  59. {
  60.   Cardinal ac;
  61.   Arg      av[10];
  62.   Widget option_menu;
  63.   Visual*  v = 0;
  64.   Colormap cmap = 0;
  65.   Cardinal depth = 0;
  66.  
  67.   XtVaGetValues(toplevel, XtNvisual, &v, XtNcolormap, &cmap,
  68.         XtNdepth, &depth, 0);
  69.  
  70.   ac = 0;
  71.   XtSetArg(av[ac], XmNvisual, v); ac++;
  72.   XtSetArg(av[ac], XmNdepth, depth); ac++;
  73.   XtSetArg(av[ac], XmNcolormap, cmap); ac++;
  74.   *popup= XmCreatePulldownMenu(parent, widgetName, av, ac);
  75.  
  76.   ac = 0;
  77.   XtSetArg(av[ac], XmNsubMenuId, *popup); ac++;
  78.   XtSetArg(av[ac], XmNmarginWidth, 0); ac++;
  79.   option_menu = XmCreateOptionMenu(parent, widgetName, av, ac);
  80.   XtUnmanageChild(XmOptionLabelGadget(option_menu));
  81.  
  82.   return option_menu;
  83. }
  84.  
  85. extern "C" void
  86. fe_get_option_size ( Widget optionMenu,
  87.                         Dimension *retWidth, Dimension *retHeight )
  88. {
  89.    Dimension width = 0, height = 0;
  90.    Dimension mh=0, mw=0, ml=0, mr=0, mt=0, mb=0 ; /*margin*/
  91.    Dimension st=0, bw=0, ht=0;
  92.    Dimension space=0;
  93.    WidgetList children;
  94.    Cardinal numChildren;
  95.    Widget popupW;
  96.    Widget btn;
  97.    
  98.    *retWidth = 0;
  99.    *retHeight = 0;
  100.  
  101.    XtVaGetValues(optionMenu, 
  102.                 XmNsubMenuId, &popupW, 0);
  103.  
  104.    XtVaGetValues(popupW,
  105.         XmNchildren, &children, 
  106.         XmNnumChildren, &numChildren, 0);
  107.  
  108.     if ( numChildren > 0 )
  109.     {
  110.     btn = children[0];
  111.     XtVaGetValues(btn, XmNwidth, &width,
  112.                 XmNheight, &height,
  113.                 XmNmarginHeight, &mh,
  114.                 XmNmarginWidth, &mw,
  115.                 XmNmarginLeft, &ml,
  116.                 XmNmarginRight, &mr,
  117.                 XmNmarginBottom, &mb,
  118.                 XmNmarginTop, &mt,
  119.                 XmNhighlightThickness, &ht,
  120.                 XmNshadowThickness, &st,
  121.                 XmNborderWidth, &bw,
  122.                 0);
  123.  
  124.    XtVaGetValues(optionMenu, XmNspacing, &space, 0);
  125.  
  126.    *retHeight = height + (mh+mt+mb+bw+st+ht + space ) * 2;
  127.    *retWidth= width + (mw+ml+mr+bw+st+ht + space) * 2;
  128.   }
  129.  
  130. }
  131.  
  132. extern "C" Boolean
  133. fe_set_current_attribute_option(Widget parent, int btnPos )
  134. {
  135.    unsigned char type;
  136.    WidgetList children;
  137.    Cardinal     numChildren;
  138.    Widget       pulldownW;
  139.  
  140.    if ( XmIsRowColumn(parent) )
  141.    {
  142.         XtVaGetValues(parent, XmNrowColumnType, &type,
  143.                         XmNsubMenuId, &pulldownW,
  144.                         0);
  145.  
  146.         if ( type == XmMENU_OPTION && pulldownW)
  147.         {
  148.                 XtVaGetValues(pulldownW,
  149.                         XmNchildren, &children,
  150.                         XmNnumChildren, &numChildren,0 );
  151.  
  152.                 if ( (int)numChildren > btnPos && btnPos >= 0)
  153.                 {
  154.                         XtVaSetValues(parent, XmNmenuHistory,
  155.                                 children[btnPos], 0);
  156.                         return True;
  157.                 }
  158.         }
  159.    }
  160.    return False;
  161. }
  162.  
  163. /*---------------------------------------------------------------
  164.  This part should be belonging to libmsg. This part is
  165.  copied from winfe
  166. ----------------------------------------------------------------*/
  167. extern "C"
  168. MSG_SearchError MSG_GetValuesForAttribute( MSG_ScopeAttribute /*scope*/, 
  169.    MSG_SearchAttribute attrib, 
  170.    MSG_SearchMenuItem *items, 
  171.    uint16 *maxItems)
  172. {
  173.    int32 status;
  174.         const int32 aiStatiValues[] = { MSG_FLAG_READ,
  175.                                         MSG_FLAG_REPLIED,
  176.                                         MSG_FLAG_FORWARDED};
  177.  
  178.         const MSG_PRIORITY aiPriorityValues[] = { 
  179.                                                 MSG_LowestPriority,
  180.                                                 MSG_LowPriority,
  181.                                                 MSG_NormalPriority,
  182.                                                 MSG_HighPriority,
  183.                                                 MSG_HighestPriority };
  184.  
  185.         uint16 nStati = sizeof(aiStatiValues) / sizeof(int32);
  186.         uint16 nPriorities = sizeof(aiPriorityValues) / sizeof(MSG_PRIORITY);
  187.         uint16 i;
  188.  
  189.         switch (attrib) {
  190.         case attribPriority:
  191.                 for ( i = 0; i < nPriorities && i < *maxItems; i++ ) {
  192.                         items[i].attrib = (int16) aiPriorityValues[i];
  193.                         MSG_GetPriorityName( (MSG_PRIORITY) items[i].attrib, 
  194.                                  items[i].name, 
  195.                  sizeof( items[i].name) / sizeof(char) );
  196.                         items[i].isEnabled = TRUE;
  197.                 }
  198.                 *maxItems = i;
  199.                 if ( i == nPriorities ) {
  200.                         return SearchError_Success;
  201.                 } else {
  202.                         return SearchError_ListTooSmall;
  203.                 }
  204.  
  205.         case attribMsgStatus:
  206.                 for ( i = 0; i < nStati &&  i< *maxItems; i++ ) {
  207.  
  208.                         items[i].attrib = (int16) aiStatiValues[i];
  209.             status = (int32) items[i].attrib;
  210.                         MSG_GetStatusName( status, 
  211.                                            items[i].name, 
  212.                      sizeof( items[i].name) / sizeof(char) );
  213.                         items[i].isEnabled = TRUE;
  214.                 }
  215.                 *maxItems = i;
  216.                 if ( i == nStati ) {
  217.                         return SearchError_Success;
  218.                 } else {
  219.                         return SearchError_ListTooSmall;
  220.                 }
  221.         
  222.         default:
  223.                 *maxItems = 0;
  224.                 return SearchError_InvalidAttribute;
  225.         }
  226. }
  227.  
  228. // --------- Constructor 
  229.  
  230. XFE_SearchRuleView::XFE_SearchRuleView(XFE_Component *toplevel_component,
  231.                                  Widget parent,
  232.                                  XFE_View *parent_view,
  233.                  MWContext *context,
  234.                                  MSG_Pane *p,
  235.                   char *title,
  236.                  void *folderInfo,
  237.                  MSG_ScopeAttribute curScope,
  238.                      uint16 curAttrib)
  239.   : XFE_MNView(toplevel_component, parent_view, context, p)
  240. {
  241.   XP_ASSERT(p!= NULL);
  242.   {
  243.  
  244.     initializeDataMember();
  245.     m_curScope = curScope;
  246.     m_curAttribIndex = curAttrib;
  247.     m_ruleTitle = (char*)XP_STRDUP(title);
  248.   }
  249.  
  250.   {
  251.   /* Get Visual, Colormap, and Depth */
  252.   XtVaGetValues(getToplevel()->getBaseWidget(),
  253.                  XmNvisual, &m_visual,
  254.                  XmNcolormap, &m_cmap,
  255.                  XmNdepth, &m_depth,
  256.                  NULL);
  257.   }
  258.   m_opt_valueField = NULL;
  259.   m_date_valueField = NULL;
  260.   m_date_textField = NULL;
  261.   m_text_valueField = NULL;
  262.   if ( curScope == scopeLdapDirectory )
  263.     m_dir = (DIR_Server*)folderInfo;
  264.   else 
  265.     m_folderInfo = (MSG_FolderInfo*)folderInfo; 
  266.   createWidgets(parent);
  267.   getToplevel()->registerInterest(
  268.                 XFE_MNSearchView::scopeChanged, this,
  269.                 (XFE_FunctionNotification)scopeChanged_cb);
  270.  
  271.   getToplevel()->registerInterest(XFE_Component::afterRealizeCallback,
  272.              this,
  273.              (XFE_FunctionNotification)afterRealizeWidget_cb); 
  274.  
  275. }
  276.  
  277. XFE_SearchRuleView::~XFE_SearchRuleView()
  278. {
  279.   getToplevel()->unregisterInterest(
  280.                 XFE_MNSearchView::scopeChanged, this,
  281.                 (XFE_FunctionNotification)scopeChanged_cb);
  282.  
  283.   getToplevel()->unregisterInterest(XFE_Component::afterRealizeCallback,
  284.              this,
  285.              (XFE_FunctionNotification)afterRealizeWidget_cb);
  286. }
  287.  
  288. void
  289. XFE_SearchRuleView:: initializeDataMember()
  290. {
  291.     // Init data here
  292.   m_height = 0;
  293. }
  294.  
  295. void
  296. XFE_SearchRuleView::createWidgets(Widget parent)
  297. {
  298.   MSG_SearchMenuItem *attrItems;
  299.   MSG_SearchMenuItem *opItems;
  300.   MSG_SearchValueWidget valueType;
  301.   MSG_SearchError err;
  302.   uint16 attrNum;
  303.   uint16 opNum;
  304.   DIR_Server *dirs[1];
  305.   MSG_FolderInfo *folderInfos[1];
  306.  
  307.   opItems = (MSG_SearchMenuItem*)
  308.             XP_CALLOC(kNumOperators, sizeof(MSG_SearchMenuItem));        
  309.   opNum = kNumOperators;
  310.  
  311.  
  312.   if ( m_curScope != scopeLdapDirectory )
  313.   {
  314.       folderInfos[0]= (MSG_FolderInfo *)m_folderInfo;
  315.     MSG_GetNumAttributesForSearchScopes(fe_getMNMaster(),
  316.                                         m_curScope,
  317.                                         (void**)folderInfos, 1,
  318.                                         &attrNum); 
  319.     attrItems = (MSG_SearchMenuItem *)XP_CALLOC(attrNum,
  320.                                                 sizeof(MSG_SearchMenuItem));
  321.  
  322.       err = MSG_GetAttributesForSearchScopes(fe_getMNMaster(), m_curScope, 
  323.                 (void**)folderInfos, 1, attrItems, &attrNum);
  324.  
  325.   }
  326.   else
  327.   {
  328.     if ( m_dir ) 
  329.         { 
  330.           dirs[0]= (DIR_Server*) m_dir;
  331.         MSG_GetNumAttributesForSearchScopes(fe_getMNMaster(),
  332.                                             m_curScope,
  333.                                             (void**)dirs, 1,
  334.                                             &attrNum); 
  335.         attrItems = (MSG_SearchMenuItem *)XP_CALLOC(attrNum,
  336.                                                    sizeof(MSG_SearchMenuItem));
  337.           err = MSG_GetAttributesForSearchScopes(fe_getMNMaster(), m_curScope, 
  338.                 (void**)dirs, 1, attrItems, &attrNum);
  339.     }
  340.     else return;
  341.  
  342.   }
  343.   if ( err != SearchError_Success ) return;
  344.  
  345.   // water fall display, display the next attribute 
  346.  
  347.   // Caller needs to garuntee that m_curAttrib is less than attrNum
  348.  
  349.   if ((uint16)m_curAttribIndex >= attrNum ) m_curAttribIndex =0 ; 
  350.  
  351.   if (m_curScope != scopeLdapDirectory )
  352.   {
  353.  
  354.       err = MSG_GetOperatorsForSearchScopes(fe_getMNMaster(), m_curScope, 
  355.             (void**)folderInfos, 1,
  356.             (MSG_SearchAttribute)(attrItems[m_curAttribIndex].attrib),
  357.                         opItems, &opNum);
  358.   }
  359.   else
  360.   {
  361.       err = MSG_GetOperatorsForSearchScopes(fe_getMNMaster(), m_curScope, 
  362.             (void**)dirs, 1,
  363.             (MSG_SearchAttribute)(attrItems[m_curAttribIndex].attrib),
  364.                         opItems, &opNum);
  365.   }
  366.  
  367.   if ( err == SearchError_Success ) 
  368.   {
  369.  
  370.   err = MSG_GetSearchWidgetForAttribute(
  371.                         (MSG_SearchAttribute)(attrItems[m_curAttribIndex].attrib),
  372.                         &valueType);
  373.  
  374.   if ( err == SearchError_Success ) 
  375.   {
  376.  
  377.   buildRules(parent, m_curScope,  m_curAttribIndex, attrItems, attrNum,
  378.              opItems, opNum, valueType );
  379.  
  380.  
  381.   fe_set_current_attribute_option( m_attr_opt, m_curAttribIndex);
  382.   fe_set_current_attribute_option( m_op_opt, 0);
  383.   }
  384.   }
  385.  
  386.   /* FREE CALLOC data */
  387.   XP_FREE(attrItems);
  388.  
  389.   XP_FREE(opItems);
  390. }
  391.  
  392.  
  393. void
  394. XFE_SearchRuleView::setLabelWidth(Dimension width)
  395. {
  396.  // This method should be called after view
  397.  // is created so that the layout would be fine
  398.  
  399.  if (m_label)
  400.   XtVaSetValues(m_label, XmNwidth, width,
  401.           XmNalignment, XmALIGNMENT_END, 
  402.           XmNrecomputeSize, False,
  403.           0 );
  404.  
  405.   if ( m_attr_opt )
  406.   XtVaSetValues( m_attr_opt, XmNleftOffset, width, 0);
  407. }
  408.  
  409. void
  410. XFE_SearchRuleView::buildRules(Widget parent,
  411.          MSG_ScopeAttribute curScope,
  412.           uint16 newAttr,   
  413.         MSG_SearchMenuItem attrItems[], uint16 attrNum,
  414.         MSG_SearchMenuItem opItems[], uint16 opNum,
  415.         MSG_SearchValueWidget valueType )
  416. {
  417.   Arg      av[20];
  418.   Widget formW;
  419.  
  420.   m_curScope = curScope;
  421.   m_attr = (MSG_SearchAttribute)(attrItems[newAttr].attrib);
  422.   m_op = (MSG_SearchOperator)(opItems[0].attrib);
  423.   m_type = valueType;
  424.  
  425.   if ( !getBaseWidget() )
  426.   {
  427.     formW = XmCreateForm(parent, "searchRulesForm", av, 0);
  428.     setBaseWidget(formW);
  429.   }
  430.   else formW = getBaseWidget();
  431.  
  432.   m_label = XtVaCreateManagedWidget( 
  433.             m_ruleTitle, 
  434.             xmLabelGadgetClass, 
  435.             formW,
  436.             NULL ); 
  437.  
  438.   /* Attrib */
  439.   m_attr_opt = fe_make_option_menu(getToplevel()->getBaseWidget(),
  440.             formW, "searchAttrOpt", &m_attr_pop);
  441.   buildPulldownMenu(m_attr_pop,
  442.                  attrItems, attrNum,
  443.                  attribOptionCallback, 
  444.                  (XtPointer)this);
  445.  
  446.   /* Operator */
  447.   m_op_opt = fe_make_option_menu(getToplevel()->getBaseWidget(),
  448.                 formW, "searchOpOpt", &m_op_pop);
  449.  
  450.   buildPulldownMenu(m_op_pop,
  451.         opItems, opNum,
  452.         operatorOptionCallback, 
  453.         (XtPointer)this);
  454.  
  455.  
  456.   /* Calculate form size */
  457.   calculateSize(); 
  458.  
  459.   /* Values */
  460.   m_value = replaceValueField(NULL,
  461.                 formW,
  462.                 valueType,
  463.                 NULL, NULL);
  464.   //XtManageChild(m_value);
  465.   m_type = valueType;
  466.  
  467.   /* Doing layout */
  468.   if ( m_label )
  469.   XtVaSetValues( m_label,
  470.     XmNheight, m_height,
  471.         XmNtopAttachment, XmATTACH_FORM,
  472.         XmNbottomAttachment, XmATTACH_NONE,
  473.         XmNleftAttachment, XmATTACH_FORM,
  474.         XmNrightAttachment, XmATTACH_NONE, 0);
  475.  
  476.         
  477.   if ( m_attr_opt )
  478.   XtVaSetValues( m_attr_opt,
  479.         XmNtopAttachment, XmATTACH_FORM,
  480.         XmNbottomAttachment, XmATTACH_NONE,
  481.         XmNleftAttachment, XmATTACH_FORM,
  482.         XmNrightAttachment, XmATTACH_NONE,
  483.         0);
  484.  
  485.   if ( m_op_opt )
  486.   XtVaSetValues( m_op_opt,
  487.         XmNtopAttachment, XmATTACH_FORM,
  488.         XmNbottomAttachment, 
  489.       (m_attr_opt? XmATTACH_OPPOSITE_WIDGET: XmATTACH_NONE),
  490.         XmNbottomWidget, m_attr_opt,
  491.         XmNleftAttachment, 
  492.       (m_attr_opt? XmATTACH_WIDGET: XmATTACH_NONE),
  493.         XmNleftWidget, m_attr_opt,
  494.         XmNrightAttachment, XmATTACH_NONE, 0);
  495.  
  496.   if ( m_value )
  497.   {
  498.   XtVaSetValues( m_value,
  499.         XmNtopAttachment, 
  500.       (m_op_opt? XmATTACH_OPPOSITE_WIDGET: XmATTACH_NONE),
  501.         XmNtopWidget, m_op_opt,
  502.         XmNbottomAttachment, 
  503.       (m_op_opt? XmATTACH_OPPOSITE_WIDGET: XmATTACH_NONE),
  504.         XmNbottomWidget, m_op_opt,
  505.         XmNleftAttachment, 
  506.       (m_op_opt? XmATTACH_WIDGET: XmATTACH_NONE),
  507.         XmNleftWidget, m_op_opt,
  508.         XmNrightAttachment, XmATTACH_FORM, 0);
  509.  
  510.   }
  511.   XtVaSetValues(formW, XmNheight, m_height, 
  512.                 XmNtopAttachment, XmATTACH_NONE,
  513.                 XmNbottomAttachment, XmATTACH_NONE,
  514.                 XmNleftAttachment, XmATTACH_FORM,
  515.                 XmNrightAttachment, XmATTACH_FORM, 
  516.                 0); 
  517.  
  518.   XtManageChild(m_attr_opt);
  519.   XtManageChild(m_op_opt);
  520.   XtManageChild(formW);
  521. }
  522.  
  523. void XFE_SearchRuleView::changeLabel(char* newlabel)
  524. {
  525.     XmString xmlabl = XmStringCreateSimple(newlabel);
  526.     XtVaSetValues(m_label, XmNlabelString, xmlabl, 0);
  527.     XmStringFree(xmlabl);
  528. }
  529.  
  530. void
  531. XFE_SearchRuleView::buildPulldownMenu(Widget pulldownParent,
  532.                         MSG_SearchMenuItem items[], uint16 itemNum,
  533.                         XtCallbackProc activeCB, XtPointer clientData)
  534. {
  535.   int i;
  536.   XmString xmStr;
  537.   Arg av[20];
  538.   int ac;
  539.   Widget btn;
  540.   WidgetList childrenList;
  541.   int numChildren;
  542.   int attribData;
  543.   int iitemNum = (int)itemNum;
  544.  
  545.   /* Clean up first */
  546.  
  547.   XtVaGetValues( pulldownParent, XmNchildren, &childrenList,
  548.                 XmNnumChildren, &numChildren, 0);
  549.  
  550.   for ( i = 0; i < numChildren; i++ )
  551.   {
  552.         XtDestroyWidget(childrenList[i]);
  553.   }
  554.  
  555.   /* Create new ones... */
  556.  
  557.   Boolean otherHdrs = FALSE;
  558.   for ( i = 0; i < iitemNum; i++ )
  559.   {
  560.     attribData = (int)(items[i].attrib);
  561.  
  562.     if (!otherHdrs && attribData == attribOtherHeader)
  563.     {
  564.         XtVaCreateManagedWidget("sep", xmSeparatorGadgetClass, pulldownParent,
  565.                                 0);
  566.         otherHdrs = TRUE;
  567.     }
  568.  
  569.     xmStr = XmStringCreateSimple(items[i].name);
  570.  
  571.     ac = 0;
  572.     XtSetArg(av[ac], XmNuserData, attribData); ac++;
  573.     XtSetArg(av[ac], XmNlabelString, xmStr); ac++;
  574.     btn = XmCreatePushButtonGadget(pulldownParent, "ruleBtn", av, ac);
  575.     XtAddCallback(btn, XmNactivateCallback, activeCB, clientData);
  576.     XtManageChild(btn);
  577.  
  578.     XmStringFree(xmStr);
  579.   }
  580.  
  581.   if (pulldownParent == m_attr_pop)
  582.   {
  583.       // Add the "Edit Custom Hdr" button:
  584.       XtVaCreateManagedWidget("sep", xmSeparatorGadgetClass, pulldownParent,
  585.                               0);
  586.       btn = XtVaCreateManagedWidget("editHdrBtn", xmPushButtonGadgetClass,
  587.                                     pulldownParent,
  588.                                     0);
  589.       XtAddCallback(btn, XmNactivateCallback, editHdrCallback, this);
  590.   }
  591. }
  592.  
  593. void
  594. XFE_SearchRuleView::attribOptionCallback(Widget w, 
  595.             XtPointer clientData, XtPointer /*callData*/)
  596. {
  597.    XFE_SearchRuleView *obj = (XFE_SearchRuleView*)clientData;
  598.    XtPointer attribData;
  599.    int16 n;
  600.  
  601.    XtVaGetValues(w, XmNuserData, &attribData, 0);
  602.    int iattribData = (int)attribData;
  603.    n = (int16)iattribData;
  604.    obj->setAttribOption(n);
  605. }
  606.  
  607. void
  608. XFE_SearchRuleView::createValueWidgetSet(Widget /*parent*/)
  609. {
  610. }
  611.  
  612. void
  613. XFE_SearchRuleView::setAttribOption(int16 attrib)
  614. {
  615.    MSG_SearchError err;
  616.    MSG_SearchValueWidget valueType;
  617.    MSG_SearchMenuItem *opItems;
  618.    uint16 opNum = kNumOperators; /* XP relies on this value to know array size */
  619.  
  620.  
  621.   XtUnmanageChild(getBaseWidget());
  622.   opItems = (MSG_SearchMenuItem*)
  623.             XP_CALLOC(kNumOperators, sizeof(MSG_SearchMenuItem));        
  624.    if ( m_attr != attrib)
  625.    {
  626.      XtUnmanageChild(m_attr_opt);
  627.      XtUnmanageChild(m_op_opt);
  628.  
  629.      m_attr = (MSG_SearchAttribute)attrib;
  630.      m_curAttribIndex = (uint16) m_attr;
  631.  
  632.      if (m_curScope != scopeLdapDirectory )
  633.      {
  634.          MSG_FolderInfo *folderInfos[1];
  635.          folderInfos[0]= (MSG_FolderInfo *)m_folderInfo;
  636.          err = MSG_GetOperatorsForSearchScopes(fe_getMNMaster(), 
  637.             m_curScope, (void**)folderInfos, 1,
  638.             (MSG_SearchAttribute)m_attr,
  639.                         opItems, &opNum);
  640.      }
  641.      else
  642.      {
  643.       DIR_Server *dirs[1];
  644.  
  645.       dirs[0]= (DIR_Server*) m_dir;
  646.          err = MSG_GetOperatorsForSearchScopes(fe_getMNMaster(), 
  647.             m_curScope, (void**)dirs, 1,
  648.             (MSG_SearchAttribute)m_attr,
  649.                         opItems, &opNum);
  650.  
  651.      }
  652.  
  653.      if (err == SearchError_Success ) 
  654.      {
  655.  
  656.      err = MSG_GetSearchWidgetForAttribute(m_attr, &valueType);
  657.      if ( err == SearchError_Success  )
  658.      {
  659.  
  660.      if ( needNewMenu(m_op_pop, opItems, opNum ))
  661.      {
  662.     XtUnmanageChild(m_op_opt);
  663.     XtDestroyWidget(m_op_opt);
  664.         m_op_opt = fe_make_option_menu(getToplevel()->getBaseWidget(),
  665.                 getBaseWidget(), "searchOpOpt", &m_op_pop);
  666.  
  667.         buildPulldownMenu(m_op_pop, opItems, opNum,
  668.                     operatorOptionCallback, 
  669.                     (XtPointer)this);
  670.         fe_set_current_attribute_option( m_op_opt, 0);
  671.         /* Operator may have been changed */
  672.         m_op = (MSG_SearchOperator)(opItems[0].attrib); /* Use the new one */
  673.   XtVaSetValues( m_op_opt,
  674.         XmNtopAttachment, XmATTACH_FORM,
  675.         XmNbottomAttachment, 
  676.       (m_attr_opt? XmATTACH_OPPOSITE_WIDGET: XmATTACH_NONE),
  677.         XmNbottomWidget, m_attr_opt,
  678.         XmNleftAttachment, 
  679.       (m_attr_opt? XmATTACH_WIDGET: XmATTACH_NONE),
  680.         XmNleftWidget, m_attr_opt,
  681.         XmNrightAttachment, XmATTACH_NONE, 0);
  682.      }
  683.  
  684.     XtManageChild(m_attr_opt);
  685.     XtManageChild(m_op_opt);
  686.      /* Build new value */
  687.      m_value = replaceValueField(m_value, getBaseWidget(),
  688.                                 //XtParent(m_value),
  689.                                 valueType, NULL, (XtPointer)NULL);
  690.      } /* success */
  691.      } /* success*/
  692.    }
  693.  
  694.     XtManageChild(getBaseWidget());
  695.     if (valueType == widgetText)
  696.         XmProcessTraversal(m_text_valueField, XmTRAVERSE_CURRENT);
  697.     else if (valueType == widgetDate)
  698.         XmProcessTraversal(m_date_textField, XmTRAVERSE_CURRENT);
  699.  
  700.   /* FREE CALLOC data */
  701.   XP_FREE(opItems);
  702. }
  703.  
  704. Boolean 
  705. XFE_SearchRuleView::needNewMenu(Widget pulldownParent,
  706.                         MSG_SearchMenuItem *opItems,
  707.                         uint16 opNum )
  708. {
  709.   int numChildren;
  710.   WidgetList childrenList;
  711.   XtPointer data;
  712.   int idata;
  713.   uint16 data16;
  714.   int i, j;
  715.   Boolean found;
  716.   int iopNum = (int)opNum;
  717.  
  718.   XtVaGetValues( pulldownParent, XmNchildren, &childrenList,
  719.                 XmNnumChildren, &numChildren, 0);
  720.  
  721. //  if ( numChildren != opNum ) return True;
  722.  
  723.   for ( i = 0; i < numChildren; i++ )
  724.   {
  725.         XtVaGetValues( childrenList[i], XmNuserData, &data, 0 );
  726.     idata = (int)data;
  727.     data16= (uint16)idata;
  728.  
  729.         found = True;
  730.         for ( j = 0; j < iopNum; j++ )
  731.         {
  732.           if ( data16 != opItems[j].attrib )
  733.           {
  734.                 found = False;
  735.                 break;
  736.           }
  737.         }
  738.         if ( !found ) return True;
  739.   }
  740.   return False;
  741. }
  742.  
  743. void
  744. XFE_SearchRuleView::operatorOptionCallback(Widget w, 
  745.             XtPointer clientData, XtPointer /*callData*/)
  746. {
  747.    XFE_SearchRuleView *obj = (XFE_SearchRuleView*)clientData;
  748.    XtPointer opData;
  749.    int iopData;
  750.    int16 n;
  751.  
  752.    XtVaGetValues(w, XmNuserData, &opData, 0);
  753.    iopData = (int)opData;
  754.  
  755.    n = (int16)iopData;
  756.    obj->m_op= (MSG_SearchOperator)n;
  757. }
  758.  
  759. void
  760. XFE_SearchRuleView::valueOptionCallback(Widget w, 
  761.             XtPointer clientData, XtPointer /*callData*/)
  762. {
  763.    XFE_SearchRuleView *obj = (XFE_SearchRuleView*)clientData;
  764.    XtPointer valueData;
  765.    int ivalueData;
  766.    uint16 n;
  767.  
  768.    XtVaGetValues(w, XmNuserData, &valueData, 0);
  769.    ivalueData = (int)valueData;
  770.    n = (int16)ivalueData;
  771.    obj->m_value_option = n;
  772. }
  773.  
  774. void
  775. XFE_SearchRuleView::calculateSize()
  776. {
  777.   Dimension width, height;
  778.   WidgetList childrenList;
  779.   int numChildren;
  780.  
  781.   XtVaGetValues( m_attr_pop,
  782.                 XmNchildren, &childrenList,
  783.                 XmNnumChildren, &numChildren, 0 );
  784.  
  785.   if ( numChildren > 0 )
  786.   {
  787.       fe_get_option_size(m_attr_opt, 
  788.                         &width, &height );
  789.  
  790.       if (width > m_width) m_width = width;
  791.       if (height > m_height) m_height = height;
  792.   }
  793.  
  794.   XtVaGetValues( m_op_pop,
  795.                 XmNchildren, &childrenList,
  796.                 XmNnumChildren, &numChildren, 0 );
  797.  
  798.   if ( numChildren > 0 )
  799.   {
  800.       fe_get_option_size(m_op_opt,
  801.                         &width, &height );
  802.  
  803.       if (width > m_width) m_width = width+20;
  804.       if (height > m_height) m_height = height+20;
  805.   }
  806. }
  807.  
  808.  
  809.  
  810. Widget
  811. XFE_SearchRuleView::replaceValueField ( Widget valueField, 
  812.         Widget parent,
  813.                 MSG_SearchValueWidget valueType,
  814.                 XtCallbackProc callback, XtPointer clientData)
  815. {
  816.   Arg av[20];
  817.   int ac;
  818.   Widget newField = NULL;
  819.   MSG_SearchMenuItem *items;
  820.   uint16 maxItems = 16;
  821.   Widget lblField;
  822.   Visual*  v = 0;
  823.   Colormap cmap = 0;
  824.   Cardinal depth = 0;
  825.   if (!valueField) 
  826.   {
  827.    // Create everything for the first time...
  828.  
  829.    // Create Menu Widget
  830.    Widget popup;
  831.  
  832.    m_opt_valueField = fe_make_option_menu(getToplevel()->getBaseWidget(),
  833.                 parent,
  834.                                 "op_valueField", &popup);
  835.    
  836.    // Create Date Widget
  837.    ac = 0;
  838.    m_date_valueField = XmCreateForm(parent, "date_valueField", av, ac );
  839.    m_date_textField= fe_CreateTextField(m_date_valueField, "textValueField", av, ac );
  840.    XtAddCallback(m_date_textField, XmNactivateCallback, typeActivateCallback, this);
  841.    lblField = XmCreateLabelGadget(m_date_valueField, "labelValueField", av, ac);
  842.    XtVaSetValues(m_date_textField,
  843.        XmNtopAttachment, XmATTACH_FORM,
  844.        XmNbottomAttachment, XmATTACH_FORM,
  845.        XmNleftAttachment, XmATTACH_FORM,
  846.        XmNrightAttachment, XmATTACH_FORM,
  847.        XmNrightOffset, XfeWidth(lblField) + 6,
  848.        0 );
  849.    XtVaSetValues(lblField,
  850.        XmNtopAttachment, XmATTACH_FORM,
  851.        XmNbottomAttachment, XmATTACH_FORM,
  852.        XmNleftAttachment, XmATTACH_NONE,
  853.        XmNrightAttachment, XmATTACH_FORM,
  854.        0 );
  855.   XtManageChild(m_date_textField);
  856.   XtManageChild(lblField);
  857.  
  858.    // Widget Text
  859.    ac = 0;
  860.    m_text_valueField= fe_CreateTextField(parent, "text_valueField", av, ac );
  861.  
  862.    XtAddCallback(m_text_valueField, XmNactivateCallback, typeActivateCallback, this);
  863.    // set up attachment
  864. #if 0
  865.     XtVaSetValues( m_opt_valueField,
  866.         XmNleftWidget, m_op_opt,
  867.         XmNleftAttachment, XmATTACH_WIDGET,
  868.         XmNrightAttachment, XmATTACH_FORM,
  869.         XmNbottomWidget, m_op_opt,
  870.         XmNbottomAttachment, XmATTACH_OPPOSITE_WIDGET,
  871.         XmNtopWidget, m_op_opt, 
  872.         XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET,
  873.         0);
  874.     XtVaSetValues( m_date_valueField,
  875.         XmNleftWidget, m_op_opt,
  876.         XmNleftAttachment, XmATTACH_WIDGET,
  877.         XmNrightAttachment, XmATTACH_FORM,
  878.         XmNbottomWidget, m_op_opt,
  879.         XmNbottomAttachment, XmATTACH_OPPOSITE_WIDGET,
  880.         XmNtopWidget, m_op_opt, 
  881.         XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET,
  882.         0);
  883.     XtVaSetValues( m_text_valueField,
  884.         XmNleftWidget, m_op_opt,
  885.         XmNleftAttachment, XmATTACH_WIDGET,
  886.         XmNrightAttachment, XmATTACH_FORM,
  887.         XmNbottomWidget, m_op_opt,
  888.         XmNbottomAttachment, XmATTACH_OPPOSITE_WIDGET,
  889.         XmNtopWidget, m_op_opt, 
  890.         XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET,
  891.         0);
  892. #endif
  893.   }
  894.   else 
  895.   {
  896. #if 0
  897.      ac = 0;
  898.     XtSetArg(av[ac], XmNleftAttachment, XmATTACH_NONE); ac++;
  899.     XtSetArg(av[ac], XmNbottomAttachment, XmATTACH_NONE); ac++;
  900.     XtSetArg(av[ac], XmNrightAttachment, XmATTACH_NONE); ac++;
  901.     XtSetArg(av[ac], XmNtopAttachment, XmATTACH_NONE); ac++;
  902.       XtSetValues(valueField, av, ac);
  903. #endif
  904.     XtUnmanageChild(valueField);
  905.   }
  906.  
  907.   m_type = valueType;
  908.   switch(valueType )
  909.   {
  910.         case widgetMenu:
  911.     {
  912.     if ( m_opt_valueField)
  913.         {
  914.     // Get the popup widget, and destroy them for creating new ones
  915.  
  916. #if 0
  917.      ac = 0;
  918.     XtSetArg(av[ac], XmNleftAttachment, XmATTACH_NONE); ac++;
  919.     XtSetArg(av[ac], XmNbottomAttachment, XmATTACH_NONE); ac++;
  920.     XtSetArg(av[ac], XmNrightAttachment, XmATTACH_NONE); ac++;
  921.     XtSetArg(av[ac], XmNtopAttachment, XmATTACH_NONE); ac++;
  922.         XtSetValues(m_opt_valueField, av,ac);
  923. #endif
  924.         Widget popup;
  925.  
  926.     XtUnmanageChild(m_opt_valueField);
  927.     XtDestroyWidget(m_opt_valueField);
  928.         m_opt_valueField = fe_make_option_menu(getToplevel()->getBaseWidget(),
  929.                 parent,
  930.                                 "op_valueField", &popup);
  931.  
  932.     popup = NULL;
  933.     XtVaGetValues(m_opt_valueField, XmNsubMenuId, &popup, 0 );
  934.     if ( popup ) XtDestroyWidget(popup);
  935.     XtVaSetValues(m_opt_valueField, XmNsubMenuId, NULL, 0 );
  936.     XtVaGetValues(getToplevel()->getBaseWidget(), 
  937.     XtNvisual, &v, XtNcolormap, &cmap,
  938.         XtNdepth, &depth, 0);
  939.  
  940.   ac = 0;
  941.   XtSetArg(av[ac], XmNvisual, v); ac++;
  942.   XtSetArg(av[ac], XmNdepth, depth); ac++;
  943.   XtSetArg(av[ac], XmNcolormap, cmap); ac++;
  944.   popup= XmCreatePulldownMenu(parent, "Pulldown", av, ac);
  945.  
  946.   items = (MSG_SearchMenuItem*) XP_CALLOC(maxItems, sizeof(MSG_SearchMenuItem));        
  947.   MSG_GetValuesForAttribute(m_curScope,
  948.                                 m_attr, items, &maxItems );
  949.  
  950.   buildPulldownMenu(popup, items, maxItems,
  951.         valueOptionCallback, 
  952.     (XtPointer)this);
  953.  
  954.   XtVaSetValues(m_opt_valueField, XmNsubMenuId, popup, 0);
  955.   /* FREE CALLOC data */
  956.   XP_FREE(items);
  957.                 }
  958.     }
  959.  
  960.     newField = m_opt_valueField;
  961.         break;
  962.         case widgetDate:
  963.         {
  964. /* Create default date time */
  965.         char dateStr[40], tmp[16];
  966.                 time_t now = XP_TIME();
  967.                 XP_StrfTime(m_contextData,
  968.                                         dateStr, sizeof(dateStr),
  969.                                         XP_DATE_TIME_FORMAT,
  970.                                         localtime(&now));
  971.         XP_STRNCPY_SAFE(tmp, dateStr, 9);
  972.  
  973.                 fe_SetTextField(m_date_textField, tmp);
  974.       
  975.       if ( callback )
  976.                  XtAddCallback(m_date_textField, XmNvalueChangedCallback, callback, clientData);
  977.                 }
  978.     newField = m_date_valueField;
  979.             break;
  980.         case widgetText:
  981.         if ( callback )
  982.                 XtAddCallback(m_text_valueField, XmNvalueChangedCallback,
  983.                         callback, clientData);
  984.         newField = m_text_valueField;
  985.             break;
  986.  
  987.       case widgetInt:
  988.         if ( callback )
  989.                 XtAddCallback(m_text_valueField, XmNvalueChangedCallback,
  990.                         callback, clientData);
  991.         newField = m_text_valueField;
  992.             break;
  993.     default:
  994.         XP_ASSERT (0);
  995.         return 0;
  996.   }
  997.  
  998.      ac = 0;
  999.     XtSetArg(av[ac], XmNbottomAttachment, XmATTACH_OPPOSITE_WIDGET); ac++;
  1000.     XtSetArg(av[ac], XmNbottomWidget, m_op_opt); ac++;
  1001.     XtSetArg(av[ac], XmNrightAttachment, XmATTACH_FORM); ac++;
  1002.     XtSetArg(av[ac], XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET); ac++;
  1003.     XtSetArg(av[ac], XmNtopWidget, m_op_opt); ac++;
  1004.     XtSetValues(newField,av,ac);
  1005.   XtSetMappedWhenManaged(newField, TRUE);
  1006.     ac = 0;
  1007.     XtSetArg(av[ac], XmNleftAttachment, XmATTACH_WIDGET); ac++;
  1008.     XtSetArg(av[ac], XmNleftWidget, m_op_opt); ac++;
  1009.     XtSetArg(av[ac], XmNleftOffset, 0);ac++;
  1010.     XtSetValues(newField,av,ac);
  1011.   XtSetMappedWhenManaged(newField, TRUE);
  1012.   XtManageChild(newField);
  1013.  
  1014.   return newField;
  1015. }
  1016.  
  1017. XFE_CALLBACK_DEFN(XFE_SearchRuleView,afterRealizeWidget)(XFE_NotificationCenter *,
  1018.                                  void *, void*)
  1019. {
  1020.     // put focus in text field:
  1021.     XmProcessTraversal(m_text_valueField, XmTRAVERSE_CURRENT);
  1022. }
  1023.  
  1024. void
  1025. XFE_SearchRuleView::resetSearchValue()
  1026. {
  1027.    
  1028.    if ( m_date_textField )
  1029.    { /* Reset date */
  1030.       char dateStr[40], tmp[16];
  1031.       time_t now = XP_TIME();
  1032.       XP_StrfTime(m_contextData,
  1033.                   dateStr, sizeof(dateStr),
  1034.                   XP_DATE_TIME_FORMAT,
  1035.                   localtime(&now));
  1036.       XP_STRNCPY_SAFE(tmp, dateStr, 9);
  1037.  
  1038.       fe_SetTextField(m_date_textField, tmp);
  1039.  
  1040.    }
  1041.    
  1042.    if ( m_text_valueField )
  1043.    { /* Reset text value */
  1044.     fe_SetTextFieldAndCallBack(m_text_valueField, "");
  1045.  
  1046.    }
  1047.  
  1048. #if 0
  1049.     /* Reset all the search rules */
  1050.     if ( m_type == widgetText )
  1051.     {
  1052.       if (m_value && XmIsTextField(m_value))
  1053.          fe_SetTextFieldAndCallBack(m_value, "");
  1054.     }
  1055.     else if ( m_type == widgetDate)
  1056.     {   Widget textW;
  1057.  
  1058.         textW = XtNameToWidget(m_value, "textValueField");
  1059.         fe_SetTextFieldAndCallBack(textW, "");
  1060.     }
  1061. /* Don't change the option back at all ...
  1062.    Need to check with HI about this...
  1063.          else
  1064.        fe_search_set_current_attribute_option(curlist->value, 0);
  1065. */
  1066. #endif
  1067. }
  1068.     
  1069.  
  1070. XP_Bool
  1071. fe_getDate (char *string, int* mm, int* dd, int* yyyy)
  1072. {
  1073.   char *cp;
  1074.  
  1075.   cp = strtok(string, "/");
  1076.   if (cp && strspn(cp, "0123456789") == strlen(cp))
  1077.   { 
  1078.     *mm = atoi(cp);
  1079.     if (*mm > 12 || *mm < 1) *mm = -1;
  1080.   }
  1081.   else
  1082.   {
  1083.     *mm = -1;
  1084. #ifdef DEBUG_dora
  1085.     printf("error in month\n");
  1086. #endif
  1087.   }
  1088.  
  1089.   cp = strtok(NULL, "/");
  1090.   if (cp && strspn(cp, "0123456789") == strlen(cp))
  1091.   {
  1092.         *dd = atoi(cp);
  1093.     if (*dd > 31 || *dd < 1) *dd = -1;
  1094.   }
  1095.   else
  1096.   {
  1097.     *dd = -1;
  1098. #ifdef DEBUG_dora
  1099.     printf ("error in day\n");
  1100. #endif
  1101.   }
  1102.  
  1103.   cp = strtok(NULL, "\0");
  1104.   if (cp && strspn(cp, "0123456789") == strlen(cp))
  1105.   {
  1106.         *yyyy = atoi(cp);
  1107.     if (*yyyy < 1900) *yyyy = -1;
  1108.   }
  1109.   else
  1110.   {
  1111.     *yyyy = -1;
  1112. #ifdef DEBUG_dora
  1113.     printf("error in year\n");
  1114. #endif
  1115.   }
  1116.  
  1117. #ifdef DEBUG_dora
  1118.   printf("mon = %d, day = %d, year = %d\n", *mm, *dd, *yyyy);
  1119. #endif
  1120.  
  1121.   if ( *mm == -1 || *dd == -1 || *yyyy == -1)
  1122.      return False;
  1123.   return True;
  1124.  
  1125. }
  1126.  
  1127. time_t 
  1128. fe_mkTime(int mon, int day, int year)
  1129. {
  1130.   time_t t;
  1131.   struct tm time_str;
  1132.  
  1133.           time_str.tm_year    = year - 1900;
  1134.           time_str.tm_mon     = mon-1;
  1135.           time_str.tm_mday    = day;
  1136.           time_str.tm_hour    = 0;
  1137.           time_str.tm_min     = 0;
  1138.           time_str.tm_sec     = 1;
  1139.           time_str.tm_isdst   = -1; // ignore daylight saving 
  1140.  
  1141.   t = mktime(&time_str);
  1142. #ifdef DEBUG_dora
  1143.   if (t == -1)
  1144.    printf("mktime error\n");
  1145.   else
  1146.    printf("time = %d\n", t);
  1147. #endif
  1148.   return t;
  1149. }
  1150.  
  1151. XP_Bool
  1152. XFE_SearchRuleView::getSearchTerm( MSG_SearchAttribute *attr, 
  1153.                 MSG_SearchOperator *op, MSG_SearchValue *value,
  1154.                                    char* customHdr)
  1155. {
  1156.   Widget textW;
  1157.   char *string = 0;
  1158.   char *label;
  1159.   XP_Bool no_err = True;
  1160.  
  1161.  
  1162.        if ( m_type == widgetText || m_type == widgetInt )
  1163.             string = fe_GetTextField(m_value);
  1164.        else if ( m_type == widgetDate)
  1165.        {
  1166.         string = NULL;
  1167.         textW = XtNameToWidget(m_value, "textValueField");
  1168.               string = fe_GetTextField(textW);
  1169.         
  1170.         
  1171.                }
  1172.  
  1173.        value->attribute = m_attr;
  1174.        switch (m_attr)
  1175.        {
  1176.         case attribDate:
  1177.         {
  1178.                   value->u.date = XP_ParseTimeString(string, False);
  1179.           XtFree(string);
  1180.         }
  1181.         break;
  1182.         case attribPriority:
  1183.             value->u.priority = (MSG_PRIORITY)(m_value_option);
  1184.         break;
  1185.         case attribMsgStatus:
  1186.             value->u.msgStatus = m_value_option;
  1187.         break;
  1188.         case attribAgeInDays:
  1189.             value->u.age = XP_ATOI(string);
  1190.         break;
  1191.         case attribOtherHeader:
  1192.             value->u.string = string;
  1193.             label = getAttribLabel();
  1194.             strcpy(customHdr, label);
  1195.             XtFree(label);
  1196.         break;
  1197.         default:
  1198.                 value->u.string = XP_STRDUP(string);
  1199.        }
  1200.  
  1201.        if (string)
  1202.            XtFree(string);
  1203.  
  1204.     *attr = m_attr;
  1205.     *op = m_op;
  1206.  
  1207.    return no_err;
  1208. }
  1209.  
  1210. // Result of getAttribLabel should be XtFree()ed
  1211. char*
  1212. XFE_SearchRuleView::getAttribLabel()
  1213. {
  1214.     Widget lablW;
  1215.     XtVaGetValues(m_attr_opt, XmNmenuHistory, &lablW, 0);
  1216.     XmString xmstr;
  1217.     XtVaGetValues(lablW, XmNlabelString, &xmstr, 0);
  1218.     char* lablstr;
  1219.     XmStringGetLtoR(xmstr, XmSTRING_DEFAULT_CHARSET, &lablstr);
  1220.     return lablstr;
  1221. }
  1222.  
  1223. void
  1224. XFE_SearchRuleView::editHeaders()
  1225. {
  1226. #undef DEFEAT_RACE_CONDITION        // BE API not ready yet
  1227. #ifdef DEFEAT_RACE_CONDITION
  1228.     // Defeat race condition between this dialog and the search view
  1229.     MSG_Master* master = fe_getMNMaster();
  1230.     if (!master->AcquireEditHeadersSemaphore(this))
  1231.     {
  1232. #ifdef DEBUG_akkana
  1233.         printf("SearchRuleView: Couldn't get semaphore!  Punting ...\n");
  1234. #endif
  1235.         return;
  1236.     }
  1237. #endif /* DEFEAT_RACE_CONDITION */
  1238.  
  1239.     XFE_EditHdrDialog* d
  1240.         = new XFE_EditHdrDialog(getToplevel()->getBaseWidget(),
  1241.                                 "editHdrDialog", getContext());
  1242.     char* newhdr = d->post();
  1243.  
  1244. #ifdef DEFEAT_RACE_CONDITION
  1245.     if (!master->ReleaseEditHeadersSemaphore(this))
  1246.     {
  1247. #ifdef DEBUG_akkana
  1248.         printf("SearchRuleView: Couldn't release semaphore!\n");
  1249. #endif
  1250.         return;
  1251.     }
  1252. #endif /* DEFEAT_RACE_CONDITION */
  1253.  
  1254.     //
  1255.     // Set our option menu to something reasonable,
  1256.     // since it can't stay on "Customize..."
  1257.     // Future work: notify our parent so it updates the menus of
  1258.     // all the other SearchRuleViews as well (like the Filter UI does).
  1259.  
  1260.     resetHeaderOptions(newhdr);
  1261.     if (newhdr) free(newhdr);
  1262. }
  1263.  
  1264. void
  1265. XFE_SearchRuleView::resetHeaderOptions(char* newhdr)
  1266. {
  1267.     if ( m_curScope == scopeLdapDirectory )
  1268.         return;
  1269.  
  1270.     // Get the list of attributes again from the backend:
  1271.     MSG_FolderInfo *folderInfos[1];
  1272.       folderInfos[0]= (MSG_FolderInfo *)m_folderInfo;
  1273.     uint16 attrNum = 0;
  1274.     MSG_GetNumAttributesForSearchScopes(fe_getMNMaster(),
  1275.                                         m_curScope,
  1276.                                         (void**)folderInfos, 1,
  1277.                                         &attrNum); 
  1278.     MSG_SearchMenuItem* attrItems
  1279.         = (MSG_SearchMenuItem *)XP_CALLOC(attrNum,
  1280.                                           sizeof(MSG_SearchMenuItem));
  1281.  
  1282.       int err = MSG_GetAttributesForSearchScopes(fe_getMNMaster(), m_curScope, 
  1283.                                                (void**)folderInfos, 1,
  1284.                                                attrItems, &attrNum);
  1285.     if (err != SearchError_Success)
  1286.         return;
  1287.  
  1288.     buildPulldownMenu(m_attr_pop,
  1289.                       attrItems, attrNum,
  1290.                       attribOptionCallback, 
  1291.                       (XtPointer)this);
  1292.  
  1293.     // Get the new menu items:
  1294.     int numChildren;
  1295.     WidgetList childrenList;
  1296.     XtVaGetValues(m_attr_pop,
  1297.                   XmNchildren, &childrenList,
  1298.                   XmNnumChildren, &numChildren,
  1299.                   0);
  1300.  
  1301.     if (newhdr == 0)
  1302.     {
  1303.         XtVaSetValues(m_attr_opt,
  1304.                       XmNmenuHistory, childrenList[0],
  1305.                       0);
  1306.         attribOptionCallback(childrenList[0], (XtPointer)this, NULL);
  1307.         return;
  1308.     }
  1309.  
  1310.     // Loop over the option menu's options and make sure they match
  1311.     // the current set of arbitrary headers:
  1312.     char* thisbtn = 0;
  1313.     for (int num = 0; num < numChildren; ++num)
  1314.     {
  1315.         XmString xmstr;
  1316.         XtVaGetValues(childrenList[num], XmNlabelString, &xmstr, 0);
  1317.         XmStringGetLtoR(xmstr, XmFONTLIST_DEFAULT_TAG, &thisbtn);
  1318.         if (thisbtn && !XP_STRCMP(thisbtn, newhdr))
  1319.         {
  1320.             // Set the option menu to show that string
  1321.             XtVaSetValues(m_attr_opt,
  1322.                           XmNmenuHistory, childrenList[num],
  1323.                           0);
  1324.             attribOptionCallback(childrenList[num], (XtPointer)this, NULL);
  1325.             break;
  1326.         }
  1327.     }
  1328.     if (thisbtn) XtFree(thisbtn);
  1329. }
  1330.  
  1331. void
  1332. XFE_SearchRuleView::changeScope(MSG_FolderInfo *folderInfo)
  1333. {
  1334.   /* Find out what scope this folder is ++ */
  1335.  
  1336.   if ( m_curScope != scopeLdapDirectory)
  1337.   {
  1338.       m_folderInfo = folderInfo;
  1339.  
  1340.       MSG_FolderLine folderLine;
  1341.       MSG_GetFolderLineById(XFE_MNView::getMaster(), folderInfo, &folderLine);
  1342.  
  1343.       if (folderLine.flags &
  1344.           (MSG_FOLDER_FLAG_NEWSGROUP | MSG_FOLDER_FLAG_NEWS_HOST))
  1345.       { /* News */
  1346.         m_curScope = scopeNewsgroup;
  1347.       }
  1348.       else m_curScope = scopeMailFolder;
  1349.   }
  1350.  
  1351.   /* Find out what scope this folder is  -- */
  1352.  
  1353.   /* destroyRules */
  1354.   Widget form = getBaseWidget();
  1355.   Widget parent = XtParent(form);
  1356.   int i, numChildren;
  1357.   WidgetList childrenList;
  1358.   Dimension leadingWidth;
  1359.  
  1360.   XtVaGetValues(form, XmNnumChildren, &numChildren,
  1361.         XmNchildren, &childrenList, 0);
  1362.  
  1363.   leadingWidth = getLeadingWidth();
  1364.   for ( i = 0; i < numChildren; i++ )
  1365.   {
  1366.     XtDestroyWidget(childrenList[i]);
  1367.   }
  1368.   createWidgets(parent);
  1369.   adjustLeadingWidth(leadingWidth);
  1370.   
  1371. }
  1372.  
  1373. XFE_CALLBACK_DEFN(XFE_SearchRuleView, scopeChanged)(XFE_NotificationCenter*,
  1374.  
  1375.                            void *, void *calldata)
  1376. {
  1377.  
  1378.    if ( m_curScope == scopeLdapDirectory )
  1379.    {
  1380.     m_dir = (DIR_Server *)calldata;
  1381.         changeScope(NULL);
  1382.    }
  1383.    else
  1384.    {
  1385.         MSG_FolderInfo* folder = (MSG_FolderInfo*)calldata;
  1386.  
  1387.         changeScope(folder);
  1388.    }
  1389. }
  1390.  
  1391. uint16
  1392. XFE_SearchRuleView::getAttributeIndex()
  1393. {
  1394.     return m_curAttribIndex;
  1395. }
  1396.  
  1397. Dimension 
  1398. XFE_SearchRuleView::getLeadingWidth()
  1399. {
  1400.     Dimension width;
  1401.  
  1402.     XtVaGetValues(m_label, XmNwidth, &width, NULL);
  1403.     return width;
  1404. }
  1405.  
  1406. void
  1407. XFE_SearchRuleView::adjustLeadingWidth(Dimension width)
  1408. {
  1409.    XtVaSetValues(m_attr_opt, XmNleftOffset, width, 0);
  1410.  
  1411.    XtVaSetValues(m_label,
  1412.             XmNwidth, width, XmNrecomputeSize, False, 0 );
  1413.  
  1414. }
  1415.  
  1416.  
  1417. Dimension
  1418. XFE_SearchRuleView::getHeight()
  1419. {
  1420.     return m_height;
  1421. }
  1422.  
  1423.  
  1424. void
  1425. XFE_SearchRuleView::typeActivateCallback(Widget /* w */,
  1426.                                    XtPointer clientData,
  1427.                                    XtPointer /* callData */)
  1428. {
  1429.   XFE_SearchRuleView *obj = (XFE_SearchRuleView*) clientData;
  1430.    
  1431.    obj->getToplevel()->notifyInterested(
  1432.     XFE_SearchRuleView::activateSearch, (void*) NULL);
  1433. }
  1434.  
  1435. void
  1436. XFE_SearchRuleView::editHdrCallback(Widget,
  1437.                                     XtPointer clientData,
  1438.                                     XtPointer /*calldata*/ )
  1439. {
  1440.     XFE_SearchRuleView* srv = (XFE_SearchRuleView *) clientData;
  1441.     srv->editHeaders();
  1442. }
  1443.  
  1444.