home *** CD-ROM | disk | FTP | other *** search
/ Tools / WinSN5.0Ver.iso / NETSCAP.50 / WIN1998.ZIP / ns / cmd / winfe / srchobj.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1998-04-08  |  27.6 KB  |  1,010 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. // srchobj.cpp : implementation file
  19. //
  20.  
  21.  
  22. #include "stdafx.h"
  23. #include "srchobj.h"
  24. #include "dirprefs.h"
  25. #include "xp_time.h"
  26. #include "xplocale.h"
  27. #include "template.h"
  28. #include "dateedit.h"
  29. #include "intl_csi.h"
  30. #include "msg_srch.h"
  31. #include "advopdlg.h"
  32. #include "wfemsg.h"
  33. #include "edhdrdlg.h"
  34. #include "numedit.h"
  35.  
  36.  
  37. static int ChoicesTable[][4] =
  38.     {{IDC_COMBO_ATTRIB1, IDC_COMBO_OP1, IDC_EDIT_VALUE1, IDC_STATIC_THE1},
  39.      {IDC_COMBO_ATTRIB2, IDC_COMBO_OP2, IDC_EDIT_VALUE2, IDC_STATIC_THE2},
  40.      {IDC_COMBO_ATTRIB3, IDC_COMBO_OP3, IDC_EDIT_VALUE3, IDC_STATIC_THE3},
  41.      {IDC_COMBO_ATTRIB4, IDC_COMBO_OP4, IDC_EDIT_VALUE4, IDC_STATIC_THE4},
  42.      {IDC_COMBO_ATTRIB5, IDC_COMBO_OP5, IDC_EDIT_VALUE5, IDC_STATIC_THE5}};
  43.  
  44. #define COL_ATTRIB              0
  45. #define COL_OP                  1
  46. #define COL_VALUE               2
  47. #define COL_COUNT               4
  48.  
  49. static _TCHAR szResultText[64];
  50.  
  51.  
  52.  
  53. MSG_SearchError MSG_GetValuesForAttribute( MSG_ScopeAttribute scope, 
  54.                                            MSG_SearchAttribute attrib, 
  55.                                            MSG_SearchMenuItem *items, 
  56.                                            uint16 *maxItems)
  57. {
  58.     const int32 aiStatiValues[] = { MSG_FLAG_READ,
  59.                                     MSG_FLAG_REPLIED,
  60.                                     MSG_FLAG_FORWARDED,
  61.                                     MSG_FLAG_NEW,
  62.                                     MSG_FLAG_MARKED };
  63.  
  64.     const MSG_PRIORITY aiPriorityValues[] = {
  65.                                        MSG_LowestPriority,
  66.                                        MSG_LowPriority,
  67.                                        MSG_NormalPriority,
  68.                                        MSG_HighPriority,
  69.                                        MSG_HighestPriority };
  70.  
  71.     uint16 nStati = sizeof(aiStatiValues) / sizeof(int32);
  72.     uint16 nPriorities = sizeof(aiPriorityValues) / sizeof(MSG_PRIORITY);
  73.     uint16 i;
  74.  
  75.     switch (attrib) {
  76.     case attribPriority:
  77.         for ( i = 0; i < nPriorities && i < *maxItems; i++ ) {
  78.             items[i].attrib = (int16) aiPriorityValues[i];
  79.             MSG_GetPriorityName( (MSG_PRIORITY) items[i].attrib, 
  80.                                  items[i].name, 
  81.                                  sizeof( items[i].name ) / sizeof(char) );
  82.             items[i].isEnabled = TRUE;
  83.         }
  84.         *maxItems = i;
  85.         if ( i == nPriorities ) {
  86.             return SearchError_Success;
  87.         } else {
  88.             return SearchError_ListTooSmall;
  89.         }
  90.  
  91.     case attribMsgStatus:
  92.         for ( i = 0; i < nStati && i < *maxItems; i++ ) {
  93.  
  94.             // XXX WHS Watch them int sizes!
  95.             // if a message status flag > 16 bits comes out,
  96.             // we'll need to resize MSG_SearchMenuItem.attrib
  97.  
  98.             items[i].attrib = (int16) aiStatiValues[i];
  99.             MSG_GetStatusName( (int32) items[i].attrib, 
  100.                                items[i].name, 
  101.                                sizeof( items[i].name ) / sizeof(char) );
  102.             items[i].isEnabled = TRUE;
  103.         }
  104.         *maxItems = i;
  105.         if ( i == nStati ) {
  106.             return SearchError_Success;
  107.         } else {
  108.             return SearchError_ListTooSmall;
  109.         }
  110.     
  111.     default:
  112.         *maxItems = 0;
  113.         return SearchError_InvalidAttribute;
  114.     }
  115. }
  116.  
  117.  
  118. static void SlideWindow( CWnd *pWnd, int dx, int dy )
  119. {
  120.     CRect rect;
  121.     CWnd *parent;
  122.  
  123.     if (pWnd)
  124.     {
  125.         pWnd->GetWindowRect(&rect);
  126.         if (parent = pWnd->GetParent())
  127.             parent->ScreenToClient(&rect);
  128.  
  129.         rect.top += dy;
  130.         rect.left += dx;
  131.         rect.bottom += dy;
  132.         rect.right += dx;
  133.  
  134.         pWnd->MoveWindow(&rect, TRUE);
  135.     }
  136. }
  137.  
  138. static void GrowWindow( CWnd *pWnd, int dx, int dy )
  139. {
  140.     CRect rect;
  141.     CWnd *parent;
  142.  
  143.     if (pWnd)
  144.     {
  145.         pWnd->GetWindowRect(&rect);
  146.         if (parent = pWnd->GetParent())
  147.             parent->ScreenToClient(&rect);
  148.  
  149.         rect.bottom += dy;
  150.         rect.right += dx;
  151.  
  152.         pWnd->MoveWindow(&rect, TRUE);
  153.     }
  154. }
  155.  
  156. CSearchObject::CSearchObject()
  157. {
  158.     m_wnd = NULL;
  159. }
  160.  
  161. CSearchObject::~CSearchObject()
  162. {
  163. }
  164.  
  165. CComboBox * CSearchObject::GetColumnOneAttributeWidget(int iRow)
  166. {
  167.     if (m_wnd)
  168.         return (CComboBox *)m_wnd->GetDlgItem( ChoicesTable[iRow][COL_ATTRIB] );
  169.     else 
  170.         return NULL;
  171. }
  172.  
  173. int CSearchObject::InitializeLDAPSearchWindow (MSG_Pane* searchPane, DIR_Server* curServer, int* iMoreCount, BOOL bLogicType)
  174. {
  175.     MSG_SearchAttribute attrib;
  176.     MSG_SearchOperator op;
  177.     MSG_SearchValue value;
  178.     int numTerms = 0;
  179.     int numItems;
  180.     CComboBox *combo;
  181.     int i, j, k = 0;
  182.     DWORD dwItemData = (DWORD) -1L;
  183.     BOOL found = FALSE;
  184.     int dy = 0;
  185.  
  186.     MSG_CountSearchTerms (searchPane, &numTerms);
  187.  
  188.     // set the window to the right number of rows
  189.     if (numTerms) {
  190.         if ((*iMoreCount) <= numTerms - 1) {
  191.             for (j = (*iMoreCount); j < numTerms - 1; j++)
  192.                 dy += More (iMoreCount, bLogicType);
  193.         }
  194.         else {
  195.             for (j = (*iMoreCount); j > numTerms - 1; j--)
  196.                 dy += Fewer (iMoreCount, bLogicType);
  197.         }
  198.     }
  199.     
  200.     // reset values back to null string
  201.     for (i = 0; i <= (*iMoreCount); i++)
  202.     {
  203.         (m_wnd->GetDlgItem( ChoicesTable[i][COL_VALUE]))->SetWindowText("");
  204.     }
  205.  
  206.     for (i = 0; i < numTerms; i++)
  207.     {
  208.         MSG_GetNthSearchTerm (searchPane, i, &attrib, &op, &value);
  209.         // set the attribute
  210.         j = 0;
  211.         found = FALSE;
  212.         combo = (CComboBox *) m_wnd->GetDlgItem( ChoicesTable[i][COL_ATTRIB] );
  213.         numItems = combo->GetCount();
  214.         while (j < numItems && !found) {
  215.             dwItemData = combo->GetItemData(j);
  216.             if (dwItemData != (DWORD)attrib)
  217.                 j++;
  218.             else 
  219.                 found = TRUE;
  220.         }
  221.  
  222.         combo->SetCurSel (j);
  223.  
  224.         if (found) {
  225.             // if the attribute is found make sure that 
  226.             // it hasn't been remaped from customization of a different server
  227.             int numScopes = 0;
  228.             DIR_Server* server = NULL;
  229.             uint16 maxItems = 16;
  230.             MSG_SearchMenuItem items[16];
  231.             MSG_ScopeAttribute scope = scopeLdapDirectory;
  232.             MSG_CountSearchScopes (searchPane, &numScopes);
  233.             BOOL found2 = FALSE;
  234.             
  235.             if (numScopes) {
  236.                 ASSERT (numScopes == 1);
  237.                 MSG_GetNthSearchScope (searchPane, 0, &scope, (void**) &server);
  238.                 if (server && !DIR_AreServersSame (server, curServer)) {                    
  239.                     MSG_GetAttributesForSearchScopes (WFE_MSGGetMaster(), scopeLdapDirectory, 
  240.                         (void**) &server, 1, items, &maxItems);
  241.                 
  242.                     while (k < maxItems && !found2) {
  243.                         if (items [k].attrib != attrib)
  244.                             k++;
  245.                         else 
  246.                             found2 = TRUE;
  247.                     }
  248.                     if (found2) {
  249.                         char label [kSearchMenuLength]; 
  250.                         combo->GetLBText(j, label );
  251.                         if (strcmp (items [k].name, label ) != 0) {
  252.                             found = FALSE;
  253.                             combo->SetCurSel (0);
  254.                         }
  255.                     }
  256.                 }
  257.             }
  258.         }
  259.         // set the operator
  260.         if (found)
  261.         {
  262.             j = 0;
  263.             found = FALSE;
  264.             combo = (CComboBox *) m_wnd->GetDlgItem( ChoicesTable[i][COL_OP] );
  265.             numItems = combo->GetCount();
  266.             while (j < numItems && !found) {
  267.                 dwItemData = combo->GetItemData(j);
  268.                 if (dwItemData != (DWORD)op)
  269.                     j++;
  270.                 else 
  271.                     found = TRUE;
  272.             }
  273.             combo->SetCurSel (j);    
  274.             // set the value
  275.             (m_wnd->GetDlgItem( ChoicesTable[i][COL_VALUE]))->SetWindowText(value.u.string);
  276.         }
  277.     }
  278.     return dy;
  279. }
  280.  
  281. void CSearchObject::UpdateAttribList(MSG_ScopeAttribute scope, DIR_Server* pServer)
  282. {
  283.     CComboBox *combo;
  284.     int i, j, iCurSel = -1;
  285.     DWORD dwItemData = (DWORD) -1L;
  286.  
  287.     combo = (CComboBox *) m_wnd->GetDlgItem( IDC_COMBO_SCOPE );
  288.     if (combo) {
  289.         iCurSel = combo->GetCurSel();
  290.         dwItemData = combo->GetItemData(iCurSel); 
  291.     }
  292.  
  293.     //defines required for custom hearder vars
  294.     MSG_FolderInfo *folderInfos[1];
  295.     BOOL bUsesCustomHeaders;
  296.     folderInfos[0]= (MSG_FolderInfo *) dwItemData;
  297.     uint16 numItems = 0;
  298.     MSG_SearchMenuItem * HeaderItems = NULL;
  299.     CString strEditCustom;
  300.     //ldap searching define
  301.     uint16 maxItems = 16;
  302.     MSG_SearchMenuItem items[16];
  303.     
  304.     if (scope != scopeLdapDirectory) {
  305.         MSG_GetNumAttributesForSearchScopes (WFE_MSGGetMaster(), scopeMailFolder, (void**)folderInfos, 1, &numItems); 
  306.         bUsesCustomHeaders = MSG_ScopeUsesCustomHeaders(WFE_MSGGetMaster(), scopeMailFolder, folderInfos[0], FALSE);
  307.         HeaderItems = new MSG_SearchMenuItem [numItems+1];
  308.         if (!HeaderItems ) 
  309.             return;  //something bad happened here!!
  310.         MSG_GetAttributesForSearchScopes (WFE_MSGGetMaster(), scope, (void **)folderInfos, 1, HeaderItems, &numItems);
  311.         //setup custom header combo selection text
  312.         strEditCustom.LoadString(IDS_EDIT_CUSTOM);
  313.         strcpy( HeaderItems[numItems].name,  strEditCustom);
  314.         HeaderItems[numItems].attrib = -1;  //identifies a command to launch the Edit headers dialog
  315.         HeaderItems[numItems].isEnabled = FALSE;
  316.     }
  317.     else {
  318.         DIR_Server *server = pServer;
  319.         if (iCurSel != -1) {
  320.             XP_List *ldapDirectories = XP_ListNew();
  321.             if (ldapDirectories) {
  322.                 DIR_GetLdapServers (theApp.m_directories, ldapDirectories);
  323.                 if (XP_ListCount(ldapDirectories))
  324.                     server = (DIR_Server*) XP_ListGetObjectNum (ldapDirectories, iCurSel + 1);
  325.                 XP_ListDestroy (ldapDirectories);
  326.             }
  327.         }
  328.         if (server)
  329.             MSG_GetAttributesForSearchScopes (WFE_MSGGetMaster(), scope, (void**)&server, 1, items, &maxItems);
  330.     }
  331.  
  332.  
  333.     for (i = 0; i < 5; i++) {
  334.         DWORD dwOldAttrib = (DWORD) -1L;
  335.  
  336.         combo = (CComboBox *) m_wnd->GetDlgItem( ChoicesTable[i][COL_ATTRIB] );
  337.         int idx = combo->GetCurSel();
  338.         if (combo->GetCurSel() != -1)
  339.             dwOldAttrib = combo->GetItemData(idx);
  340.         combo->ResetContent();
  341.  
  342.         if ( scope == scopeLdapDirectory)
  343.         {
  344.             for (j = 0; j < maxItems; j++) {
  345.                 combo->AddString(items[j].name);
  346.                 combo->SetItemData(j, items[j].attrib);
  347.                 if (items[j].attrib == (MSG_SearchAttribute) dwOldAttrib)
  348.                     combo->SetCurSel(j);
  349.             }
  350.         }
  351.         else
  352.         {   //do extra work to handle custom headers.  We only do this for searching messages.
  353.  
  354.             for (j = 0; j < numItems; j++) {
  355.                 combo->AddString(HeaderItems[j].name);
  356.                 combo->SetItemData(j, HeaderItems[j].attrib);
  357.                 if (HeaderItems[j].attrib == (MSG_SearchAttribute) dwOldAttrib)
  358.                     combo->SetCurSel(j);
  359.             }
  360.             if (j == numItems && bUsesCustomHeaders)
  361.             {   //place the edit text in the last position of the combo box
  362.                 combo->AddString(HeaderItems[j].name);
  363.                 combo->SetItemData(j, HeaderItems[j].attrib);
  364.             }
  365.         }
  366.         if (combo->GetCurSel() == -1)
  367.             combo->SetCurSel(i % combo->GetCount());
  368.     }
  369.     if (HeaderItems) 
  370.         delete HeaderItems; //free the memory to the header array since it's now in the combo box
  371. }
  372.  
  373. void CSearchObject::UpdateOpList(MSG_ScopeAttribute scope, DIR_Server* pServer)
  374. {
  375.     for (int i = 0; i < 5; i++) {
  376.         UpdateOpList(i, scope, pServer);
  377.     }
  378. }
  379.  
  380. void CSearchObject::UpdateOpList(int iRow, MSG_ScopeAttribute scope, DIR_Server* pServer)
  381. {
  382.     CComboBox *combo;
  383.     CWnd *widget, *widgetPrior;
  384.     CEdit *edit;
  385.     CNSNumEdit *AgeInDays;
  386.     CNSDateEdit *date;
  387.     DWORD dwItemData = (DWORD) -1L;
  388.  
  389.     int j, iAttribCurSel, iScopeCurSel = -1;
  390.     MSG_SearchAttribute attrib;
  391.  
  392.     combo = (CComboBox *) m_wnd->GetDlgItem( IDC_COMBO_SCOPE );
  393.     if (combo) {
  394.         iScopeCurSel = combo->GetCurSel();
  395.         dwItemData = combo->GetItemData(iScopeCurSel);    
  396.     }
  397.  
  398.     combo = (CComboBox *) m_wnd->GetDlgItem( ChoicesTable[iRow][COL_ATTRIB] );
  399.     iAttribCurSel = combo->GetCurSel();
  400.     attrib = (MSG_SearchAttribute) combo->GetItemData(iAttribCurSel);
  401.  
  402.     DWORD dwOldOp = (DWORD) -1L;
  403.     MSG_SearchMenuItem items[16];
  404.     uint16 maxItems = 16;
  405.  
  406.     combo = (CComboBox *) m_wnd->GetDlgItem( ChoicesTable[iRow][COL_OP] );
  407.     int idx = combo->GetCurSel();
  408.     if (idx != -1)
  409.         dwOldOp = combo->GetItemData(idx);
  410.     combo->ResetContent();
  411.  
  412.     if (scope != scopeLdapDirectory) {
  413.         MSG_FolderInfo *folderInfos[1];
  414.         folderInfos[0]= (MSG_FolderInfo *) dwItemData;
  415.         MSG_GetOperatorsForSearchScopes(WFE_MSGGetMaster(), scope, (void **) folderInfos, 1, attrib, items, &maxItems);
  416.     } else {
  417.         DIR_Server *server = pServer;
  418.         if (iScopeCurSel != -1) {
  419.             XP_List *ldapDirectories = XP_ListNew();
  420.             if (ldapDirectories) {
  421.                 DIR_GetLdapServers (theApp.m_directories, ldapDirectories);
  422.                 if (XP_ListCount(ldapDirectories))
  423.                     server = (DIR_Server*) XP_ListGetObjectNum (ldapDirectories, iScopeCurSel + 1);
  424.                 XP_ListDestroy (ldapDirectories);
  425.             }
  426.         }
  427.         if (server)
  428.             MSG_GetOperatorsForSearchScopes(WFE_MSGGetMaster(), scope, (void **) &server, 1, attrib, items, &maxItems);
  429.     }
  430.  
  431.     for (j = 0; j < maxItems; j++) {
  432.         combo->AddString(items[j].name);
  433.         combo->SetItemData(j, items[j].attrib);
  434.         if (items[j].attrib == (MSG_SearchOperator) dwOldOp)
  435.             combo->SetCurSel(j);
  436.     }
  437.     if (combo->GetCurSel() == -1)
  438.         combo->SetCurSel(0);
  439.  
  440.     // Calculate a dialog unit 
  441.     RECT rect = {0, 0, 1, 1};
  442.     ::MapDialogRect(m_wnd->m_hWnd, &rect);
  443.     int iDialogUnit = rect.right;
  444.  
  445.     POINT ptUs = {0,0};
  446.     m_wnd->ClientToScreen(&ptUs);
  447.  
  448.     //
  449.     // Substitute a happy new widget based on the search attribute
  450.     //
  451.  
  452.     if ( attrib == AttribWas [iRow] ) {
  453.         return;
  454.     }
  455.  
  456.     AttribWas[iRow] = attrib;
  457.  
  458.     MSG_SearchValueWidget valueWidget;
  459.     MSG_GetSearchWidgetForAttribute ( attrib, &valueWidget );
  460.  
  461.     if (( WidgetWas[iRow] == valueWidget ) && ( valueWidget != widgetMenu) ) {
  462.         return;
  463.     }
  464.     widget = m_wnd->GetDlgItem( ChoicesTable[iRow][COL_VALUE] );
  465.     widgetPrior = m_wnd->GetDlgItem( ChoicesTable[iRow][COL_OP] );
  466.  
  467.     RECT rectWidget;
  468.     widget->GetWindowRect(&rectWidget);
  469.     ::OffsetRect( &rectWidget, -ptUs.x, -ptUs.y );
  470.  
  471.     DWORD dwStyle = widget->GetStyle() &
  472.                     (WS_CHILD|WS_VISIBLE|WS_DISABLED|WS_GROUP|WS_TABSTOP);
  473.  
  474.     DWORD dwExStyle = 0;
  475.     widget->DestroyWindow();
  476.  
  477.     switch( valueWidget ) {
  478.     case widgetMenu:
  479.         rectWidget.bottom = rectWidget.top + 60 * iDialogUnit;
  480.         dwStyle |= WS_VSCROLL|CBS_DROPDOWNLIST;
  481.         combo = new CComboBox;
  482.         maxItems = 16;
  483.         combo->Create( dwStyle, rectWidget, m_wnd, ChoicesTable[iRow][COL_VALUE] );
  484.         combo->SetFont(m_wnd->GetFont());
  485.         MSG_GetValuesForAttribute( scope, attrib, items, &maxItems );
  486.         for (j = 0; j < maxItems; j++) {
  487.             combo->AddString( items[j].name );
  488.             combo->SetItemData( j, items[j].attrib );
  489.         }
  490.         combo->SetCurSel(0);
  491.         combo->SetWindowPos( widgetPrior, 0, 0, 0, 0, SWP_NOSIZE|SWP_NOMOVE);
  492.         break;
  493.  
  494.     case widgetDate:
  495. #ifdef _WIN32
  496.         dwExStyle |= WS_EX_CLIENTEDGE;
  497.         if ( !sysInfo.m_bWin4 )
  498. #endif
  499.         {
  500.             dwStyle |= WS_BORDER;
  501.         }
  502.         dwStyle |= WS_CLIPCHILDREN;
  503.  
  504.         date = new CNSDateEdit;
  505. #ifdef _WIN32
  506.         date->CreateEx( dwExStyle, _T("STATIC"), "", dwStyle, 
  507.                         rectWidget.left, rectWidget.top, 
  508.                         rectWidget.right - rectWidget.left, 
  509.                         rectWidget.bottom - rectWidget.top,
  510.                         m_wnd->m_hWnd, (HMENU) ChoicesTable[iRow][COL_VALUE]);
  511. #else
  512.         date->Create( "", dwStyle|SS_SIMPLE, rectWidget, m_wnd, ChoicesTable[iRow][COL_VALUE] );
  513. #endif
  514.         date->SetFont(m_wnd->GetFont() );
  515.         date->SetDate( CTime( time( NULL ) ) );
  516.         date->SetWindowPos( widgetPrior, 0, 0, 0, 0, SWP_NOSIZE|SWP_NOMOVE);
  517.         break;
  518.  
  519.     case widgetInt:
  520.         // TODO!!! Add edit class that takes only numbers
  521.         dwStyle |= ES_AUTOHSCROLL;
  522. #ifdef _WIN32
  523.         dwExStyle |= WS_EX_CLIENTEDGE;
  524.         if ( !sysInfo.m_bWin4 )
  525. #endif
  526.         {
  527.             dwStyle |= WS_BORDER;
  528.         }
  529.         AgeInDays = new CNSNumEdit;
  530. #ifdef _WIN32
  531.         AgeInDays->CreateEx( dwExStyle, _T("EDIT"), "", dwStyle, 
  532.                         rectWidget.left, rectWidget.top, 
  533.                         rectWidget.right - rectWidget.left, 
  534.                         rectWidget.bottom - rectWidget.top,
  535.                         m_wnd->m_hWnd, (HMENU) ChoicesTable[iRow][COL_VALUE]);
  536. #else
  537.         AgeInDays->Create( dwStyle, rectWidget, m_wnd, ChoicesTable[iRow][COL_VALUE] );
  538. #endif
  539.         AgeInDays->SetFont(m_wnd->GetFont());
  540.         //AgeInDays->SetWindowText(_T(""));            
  541.         AgeInDays->SetValue(0);
  542.         AgeInDays->SetWindowPos( widgetPrior, 0, 0, 0, 0, SWP_NOSIZE|SWP_NOMOVE);
  543.         break;
  544.  
  545.     case widgetText:
  546.     default:
  547.         dwStyle |= ES_AUTOHSCROLL;
  548. #ifdef _WIN32
  549.         dwExStyle |= WS_EX_CLIENTEDGE;
  550.         if ( !sysInfo.m_bWin4 )
  551. #endif
  552.         {
  553.             dwStyle |= WS_BORDER;
  554.         }
  555.         edit = new CEdit;
  556. #ifdef _WIN32
  557.         edit->CreateEx( dwExStyle, _T("EDIT"), "", dwStyle, 
  558.                         rectWidget.left, rectWidget.top, 
  559.                         rectWidget.right - rectWidget.left, 
  560.                         rectWidget.bottom - rectWidget.top,
  561.                         m_wnd->m_hWnd, (HMENU) ChoicesTable[iRow][COL_VALUE]);
  562. #else
  563.         edit->Create( dwStyle, rectWidget, m_wnd, ChoicesTable[iRow][COL_VALUE] );
  564. #endif
  565.         edit->SetFont(m_wnd->GetFont());
  566.         edit->SetWindowText(_T(""));            
  567.         edit->SetWindowPos( widgetPrior, 0, 0, 0, 0, SWP_NOSIZE|SWP_NOMOVE);
  568.         break;
  569.     }
  570.     WidgetWas[iRow] = valueWidget;
  571. }
  572.  
  573. int CSearchObject::More(int* moreCount, BOOL bLogicType)
  574. {
  575.     CWnd *widget;
  576.     int dy = 0;
  577.     CRect rect, rect2;
  578.  
  579.     if (*moreCount < 4)
  580.     {
  581.         (*moreCount)++;
  582.  
  583.         CString strLogicText;
  584.         int nID = 0;
  585.         for (int i = 0; i < COL_COUNT; i++) {
  586.             nID = ChoicesTable[(*moreCount)][i];
  587.             widget = m_wnd->GetDlgItem(nID);
  588.             if (i == 3 && bLogicType)
  589.             {
  590.                 strLogicText.LoadString(IDS_ORTHE);
  591.                 widget->SetWindowText(strLogicText);
  592.             }
  593.             else if ( i==3 && !bLogicType)
  594.             {   //jump to another set up resource id's
  595.                 strLogicText.LoadString(IDS_ANDTHE);
  596.                 widget->SetWindowText(strLogicText);
  597.             }
  598.             widget->ShowWindow(SW_SHOW);
  599.         }
  600.  
  601.         widget = m_wnd->GetDlgItem(ChoicesTable[(*moreCount)][0]);
  602.         widget->GetWindowRect(&rect);
  603.         dy = rect.bottom;
  604.         widget = m_wnd->GetDlgItem(ChoicesTable[(*moreCount) - 1][0]);
  605.         widget->GetWindowRect(&rect);
  606.         dy -= rect.bottom;
  607.         widget = m_wnd->GetDlgItem(IDC_MORE);
  608.         SlideWindow(widget, 0, dy);
  609.         widget = m_wnd->GetDlgItem(IDC_FEWER);
  610.         SlideWindow(widget, 0, dy);
  611.  
  612.         widget = m_wnd->GetDlgItem(IDC_NEW);
  613.         SlideWindow(widget, 0, dy);
  614.  
  615.         widget = m_wnd->GetDlgItem(IDC_CLEAR_SEARCH);
  616.         SlideWindow(widget, 0, dy);
  617.         widget = m_wnd->GetDlgItem(IDC_STATIC_DESC);
  618.         SlideWindow(widget, 0, dy);
  619.     }
  620.  
  621.     return dy;
  622. }
  623.  
  624. void CSearchObject::OnAndOr(int iMoreCount, BOOL* bLogicType)
  625. {
  626.     CComboBox *combo;
  627.     int iCurSel = 0;
  628.  
  629.     combo = (CComboBox *) m_wnd->GetDlgItem( IDC_COMBO_AND_OR );
  630.     if (!combo) return;
  631.     iCurSel = combo->GetCurSel();
  632.     *bLogicType = (iCurSel == 0 ? 0 : 1);
  633.     ChangeLogicText(iMoreCount, *bLogicType);
  634. }
  635.  
  636. int CSearchObject::ChangeLogicText(int iMoreCount, BOOL bLogicType)
  637. {
  638.     if (iMoreCount <= 4)
  639.     {
  640.         CWnd *widget;
  641.  
  642.         CString strLogicText;
  643.         int nID = 0;
  644.         for (int Row = 1; Row <= iMoreCount; Row++) 
  645.         {
  646.             widget = m_wnd->GetDlgItem(ChoicesTable[Row][3]);
  647.             if (!widget) return 0;
  648.             if (bLogicType)
  649.             {   //Display OR logic text
  650.                 strLogicText.LoadString(IDS_ORTHE);
  651.                 widget->SetWindowText(strLogicText);
  652.             }
  653.             else 
  654.             {   //Display AND logic text
  655.                 strLogicText.LoadString(IDS_ANDTHE);
  656.                 widget->SetWindowText(strLogicText);
  657.             }
  658.             widget->ShowWindow(SW_SHOW);
  659.         }
  660.     }
  661.  
  662.     return 1;
  663. }
  664.  
  665.  
  666. int CSearchObject::Fewer(int* iMoreCount, BOOL bLogicTyp)
  667. {
  668.     CWnd *widget;
  669.     int dy = 0;
  670.  
  671.     if (*iMoreCount > 0) {
  672.         for (int i = 0; i < COL_COUNT; i++) {
  673.             widget = m_wnd->GetDlgItem(ChoicesTable[*iMoreCount][i]);
  674.             widget->ShowWindow(SW_HIDE);
  675.         }
  676.         (*iMoreCount)--;
  677.  
  678.         CRect rect;
  679.         widget = m_wnd->GetDlgItem(ChoicesTable[*iMoreCount][0]);
  680.         widget->GetWindowRect(&rect);
  681.         dy = rect.bottom;
  682.         widget = m_wnd->GetDlgItem(ChoicesTable[*iMoreCount + 1][0]);
  683.         widget->GetWindowRect(&rect);
  684.         dy -= rect.bottom;
  685.  
  686.         widget = m_wnd->GetDlgItem(IDC_MORE);
  687.         SlideWindow(widget, 0, dy);
  688.         widget = m_wnd->GetDlgItem(IDC_FEWER);
  689.         SlideWindow(widget, 0, dy);
  690.         widget = m_wnd->GetDlgItem(IDC_NEW);
  691.         SlideWindow(widget, 0, dy);
  692.  
  693.         widget = m_wnd->GetDlgItem(IDC_CLEAR_SEARCH);
  694.         SlideWindow(widget, 0, dy);
  695.         widget = m_wnd->GetDlgItem(IDC_STATIC_DESC);
  696.         SlideWindow(widget, 0, dy);
  697.     }                      
  698.  
  699.         return dy;
  700. }
  701.  
  702.  
  703. int CSearchObject::ClearSearch(int* iMoreCount, BOOL bIsLDAPSearch)
  704. {
  705.     CWnd *widget;
  706.     int dy = 0, res = 0;
  707.  
  708.     while (*iMoreCount > 0) {
  709.         for (int j = 0; j < COL_COUNT; j++) {
  710.             widget = m_wnd->GetDlgItem(ChoicesTable[*iMoreCount][j]);
  711.             widget->ShowWindow(SW_HIDE);
  712.         }
  713.         (*iMoreCount)--;
  714.  
  715.         CRect rect;
  716.         widget = m_wnd->GetDlgItem(ChoicesTable[*iMoreCount][0]);
  717.         widget->GetWindowRect(&rect);
  718.         dy = rect.bottom;
  719.         widget = m_wnd->GetDlgItem(ChoicesTable[*iMoreCount + 1][0]);
  720.         widget->GetWindowRect(&rect);
  721.         dy -= rect.bottom;
  722.  
  723.         widget = m_wnd->GetDlgItem(IDC_MORE);
  724.         SlideWindow(widget, 0, dy);
  725.         widget = m_wnd->GetDlgItem(IDC_FEWER);
  726.         SlideWindow(widget, 0, dy);
  727.         widget = m_wnd->GetDlgItem(IDC_NEW);
  728.         SlideWindow(widget, 0, dy);
  729.  
  730.  
  731.         widget = m_wnd->GetDlgItem(IDC_CLEAR_SEARCH);
  732.         SlideWindow(widget, 0, dy);
  733.         widget = m_wnd->GetDlgItem(IDC_STATIC_DESC);
  734.         SlideWindow(widget, 0, dy);
  735.  
  736.         //if ((bIsLDAPSearch && (*iMoreCount) >= 0) || (*iMoreCount) > 0)
  737.         if ((*iMoreCount) >= 0)
  738.             res += dy;
  739.     }
  740.  
  741.     return res;
  742. }
  743.  
  744. void CSearchObject::OnSize( UINT nType, int cx, int cy, int dx )
  745. {
  746.     CWnd *widget;
  747.  
  748.     for (int i = 0; i < 5; i++) {
  749.         widget = m_wnd->GetDlgItem(ChoicesTable[i][COL_VALUE]);
  750.         GrowWindow(widget, dx, 0);
  751.         if (WidgetWas[i] == widgetMenu) {
  752.             RECT rect = {0, 0, 1, 1};
  753.             ::MapDialogRect(m_wnd->GetSafeHwnd(), &rect);
  754.             int iDialogUnit = rect.right;
  755.             int dy = 60 * iDialogUnit;
  756.             GrowWindow(widget, 0, dy);
  757.         }
  758.     }
  759. }
  760.  
  761. void CSearchObject::BuildQuery (MSG_Pane* searchPane, int iMoreCount, BOOL bLogicType)
  762. {
  763.     MSG_SearchAttribute attrib;
  764.     MSG_SearchOperator op;
  765.     MSG_SearchValue value;
  766.     CNSDateEdit *date = NULL;
  767.     CNSNumEdit *AgeInDays = NULL;
  768.     CComboBox * combo = NULL;
  769.     int iCurSel = 0;
  770.     CWnd * widget = NULL;
  771.     char szArbitraryHeader[70];
  772.  
  773.     for (int i = 0; i <= iMoreCount; i++) {
  774.         combo = (CComboBox *) m_wnd->GetDlgItem(ChoicesTable[i][COL_ATTRIB]);
  775.         iCurSel = combo->GetCurSel();
  776.         attrib = (MSG_SearchAttribute) combo->GetItemData(iCurSel);
  777.  
  778.         combo = (CComboBox *) m_wnd->GetDlgItem(ChoicesTable[i][COL_OP]);
  779.         iCurSel = combo->GetCurSel();
  780.         op = (MSG_SearchOperator) combo->GetItemData(iCurSel);
  781.  
  782.         widget = m_wnd->GetDlgItem(ChoicesTable[i][COL_VALUE]);
  783.         widget->GetWindowText(szResultText, sizeof(szResultText));
  784.  
  785.         value.attribute = attrib;
  786.         XP_Bool freeValueStr = FALSE;  
  787.  
  788.         switch (attrib)
  789.         {
  790.         case attribAgeInDays:
  791.             {
  792.                 AgeInDays = (CNSNumEdit *) m_wnd->GetDlgItem(ChoicesTable[i][COL_VALUE]);
  793.                 value.u.age = AgeInDays->GetValue();  
  794.             }
  795.             break;
  796.         case attribDate: 
  797.             {
  798.                 CTime ctime;
  799.                 date = (CNSDateEdit *) m_wnd->GetDlgItem(ChoicesTable[i][COL_VALUE]);
  800.                 date->GetDate(ctime);
  801.                 value.u.date = ctime.GetTime();
  802.             }
  803.             break;
  804.         case attribPriority:
  805.             combo = (CComboBox *) m_wnd->GetDlgItem(ChoicesTable[i][COL_VALUE]);
  806.             iCurSel = combo->GetCurSel();
  807.             value.u.priority = (MSG_PRIORITY) combo->GetItemData(iCurSel);
  808.             break;
  809.         case attribMsgStatus:
  810.             combo = (CComboBox *) m_wnd->GetDlgItem(ChoicesTable[i][COL_VALUE]);
  811.             iCurSel = combo->GetCurSel();
  812.             value.u.msgStatus = combo->GetItemData(iCurSel);
  813.             break;
  814.  
  815.         case attribOtherHeader:
  816.             combo = (CComboBox *) m_wnd->GetDlgItem(ChoicesTable[i][COL_ATTRIB]);
  817.             iCurSel = combo->GetCurSel();
  818.             combo->GetLBText(iCurSel, szArbitraryHeader);
  819.  
  820.         default:
  821.             value.u.string = XP_STRDUP (szResultText);
  822.             freeValueStr = TRUE;
  823.             break;
  824.         }
  825.  
  826.         MSG_AddSearchTerm(searchPane, attrib, op, &value, !bLogicType, 
  827.                          (attrib != attribOtherHeader ? NULL : szArbitraryHeader) );
  828.  
  829.         if (freeValueStr)    
  830.             XP_FREE(value.u.string);
  831.     }
  832.     
  833. }
  834.  
  835. void CSearchObject::InitializeAttributes (MSG_SearchValueWidget widgetValue, MSG_SearchAttribute attribValue)
  836. {
  837.     for (int i = 0; i < 5; i++ ) {
  838.         WidgetWas[i] = widgetValue;
  839.         AttribWas[i] = attribValue;
  840.     } 
  841. }
  842.  
  843. int CSearchObject::New(CWnd* window)
  844. {
  845.     CRect rect, rect2;
  846.     CWnd *widget;
  847.     int dy = 0;
  848.  
  849.     m_wnd = window;
  850.     widget = m_wnd->GetDlgItem(IDC_FEWER);
  851.     ASSERT(widget); 
  852.     widget->GetWindowRect(&rect);
  853.     widget = m_wnd->GetDlgItem(ChoicesTable[0][0]);
  854.     ASSERT(widget);
  855.     widget->GetWindowRect(&rect2);
  856.     dy = rect2.bottom - rect.top;
  857.     widget = m_wnd->GetDlgItem(ChoicesTable[4][0]);
  858.     ASSERT(widget);
  859.     widget->GetWindowRect(&rect2);
  860.     dy += rect.top - rect2.bottom;
  861.                 
  862.     // Hide all the advanced lines
  863.     for (int j = 1; j < 5; j++) {
  864.         for (int i = 0; i < COL_COUNT; i++) {
  865.             widget = m_wnd->GetDlgItem(ChoicesTable[j][i]);
  866.             ASSERT(widget);
  867.             widget->ShowWindow(SW_HIDE);
  868.         }
  869.     }
  870.  
  871.     CComboBox *comboAndOr = (CComboBox*) m_wnd->GetDlgItem(IDC_COMBO_AND_OR);
  872.     if (comboAndOr)
  873.     {    //Default to AND logic for display in the combobox
  874.         comboAndOr->SetCurSel(0);
  875.     }
  876.  
  877.  
  878.     // Move more and fewer and disable fewer
  879.     widget = m_wnd->GetDlgItem(IDC_FEWER);
  880.     SlideWindow(widget, 0, dy);
  881.     widget->EnableWindow (FALSE);
  882.     widget = m_wnd->GetDlgItem(IDC_MORE);
  883.     SlideWindow(widget, 0, dy);
  884.     widget = m_wnd->GetDlgItem(IDC_NEW);
  885.     SlideWindow(widget, 0, dy);
  886.  
  887.     widget = m_wnd->GetDlgItem(IDC_CLEAR_SEARCH);
  888.     SlideWindow(widget, 0, dy);
  889.     widget = m_wnd->GetDlgItem(IDC_STATIC_DESC);
  890.     SlideWindow(widget, 0, dy);
  891.  
  892.     return dy;
  893. }
  894.  
  895. void CSearchObject::ReInitializeWidgets()
  896. {
  897.  
  898.     CWnd *widget;
  899.  
  900.     for (int i = 0; i < 5; i++) {
  901.         widget = m_wnd->GetDlgItem( ChoicesTable[i][COL_VALUE] );
  902.  
  903.         switch (WidgetWas[i]) {
  904.         case widgetMenu:
  905.             ((CComboBox *) widget)->SetCurSel(0);
  906.             break;
  907.  
  908.         case widgetDate:
  909.             ((CNSDateEdit *) widget)->SetDate(CTime(time(NULL)));
  910.             break;
  911.         
  912.         case widgetInt:
  913.             ((CNSNumEdit *) widget)->SetValue(0);
  914.             break;
  915.  
  916.         case widgetText:
  917.         default:
  918.             widget->SetWindowText("");
  919.             break;
  920.         }
  921.     }
  922.  
  923.     widget = m_wnd->GetDlgItem( ChoicesTable[0][COL_VALUE] );
  924.     widget->SetFocus();
  925.  
  926. }
  927.  
  928. void CSearchObject::UpdateColumn1Attributes()
  929. {
  930.     int i, j;
  931.     CWnd *widget = NULL;
  932.     uint16 numItems;
  933.     CComboBox *combo = NULL;
  934.  
  935.     MSG_FolderInfo *pInbox = NULL;
  936.     MSG_GetFoldersWithFlag (WFE_MSGGetMaster(), MSG_FOLDER_FLAG_INBOX, &pInbox, 1);
  937.     MSG_GetNumAttributesForSearchScopes (WFE_MSGGetMaster(), scopeMailFolder, (void**)&pInbox, 1, &numItems); 
  938.     MSG_SearchMenuItem * HeaderItems = new MSG_SearchMenuItem [numItems+1];
  939.     
  940.     if (!HeaderItems) 
  941.         return;  //something bad happened here!!
  942.  
  943.     //we are getting the list of Headers and updating controls in column 1 
  944.     MSG_GetAttributesForSearchScopes (WFE_MSGGetMaster(), scopeMailFolder, (void**)&pInbox, 1, HeaderItems, &numItems);
  945.  
  946.     CString strEditCustom;
  947.     strEditCustom.LoadString(IDS_EDIT_CUSTOM);
  948.     strcpy( HeaderItems[numItems].name,  strEditCustom);
  949.     HeaderItems[numItems].attrib = -1;  //identifies a command to launch the Edit headers dialog
  950.     HeaderItems[numItems].isEnabled = FALSE;
  951.  
  952.     CComboBox* comboScope;
  953.     int iScopeCurSel;
  954.  
  955.     comboScope = (CComboBox *) m_wnd->GetDlgItem( IDC_COMBO_SCOPE );
  956.     iScopeCurSel = comboScope->GetCurSel();
  957.     DWORD dwItemData = comboScope->GetItemData(iScopeCurSel);
  958.     MSG_ScopeAttribute scope = DetermineScope( dwItemData );
  959.     BOOL bUsesCustomHeaders = MSG_ScopeUsesCustomHeaders(WFE_MSGGetMaster(), scope, pInbox, FALSE);
  960.  
  961.     for (i = 0; i < 5; i++) {
  962.  
  963.         combo = (CComboBox *) m_wnd->GetDlgItem( ChoicesTable[i][COL_ATTRIB] );
  964.         if (!combo)
  965.         {
  966.             delete HeaderItems; //free the memory since it's now in the combo box
  967.             return;
  968.         }
  969.         combo->ResetContent();
  970.         for (j = 0; j < numItems; j++) {
  971.             combo->AddString(HeaderItems[j].name);
  972.             combo->SetItemData(j, HeaderItems[j].attrib);
  973.         }
  974.         if (j == numItems && bUsesCustomHeaders)
  975.         {   //place the edit text in the last position of the combo box
  976.             combo->AddString(HeaderItems[j].name);
  977.             combo->SetItemData(j, HeaderItems[j].attrib);
  978.         }
  979.  
  980.         combo->SetCurSel(0);
  981.         UpdateOpList(i, scope);
  982.     }
  983.  
  984.     delete HeaderItems; //free the memory since it's now in the combo box
  985. }
  986.  
  987.  
  988. MSG_ScopeAttribute CSearchObject::DetermineScope( DWORD dwItemData )
  989. {
  990.     MSG_Pane *pPane = NULL;
  991.     MSG_ScopeAttribute scope = scopeMailFolder;
  992.  
  993.     
  994.     MSG_FolderLine folderLine;
  995.     if (MSG_GetFolderLineById(WFE_MSGGetMaster(), (MSG_FolderInfo *) dwItemData, &folderLine)) 
  996.     {
  997.         if (folderLine.flags & MSG_FOLDER_FLAG_MAIL) 
  998.         {
  999.             scope = scopeMailFolder;    // Yeah, it's redundant
  1000.         }
  1001.         else if (folderLine.flags & (MSG_FOLDER_FLAG_NEWS_HOST|MSG_FOLDER_FLAG_NEWSGROUP)) 
  1002.         {
  1003.             scope = scopeNewsgroup;
  1004.         }
  1005.     }
  1006.     
  1007.     return scope;
  1008. }
  1009.  
  1010.