/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- * * The contents of this file are subject to the Netscape Public License * Version 1.0 (the "NPL"); you may not use this file except in * compliance with the NPL. You may obtain a copy of the NPL at * http://www.mozilla.org/NPL/ * * Software distributed under the NPL is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL * for the specific language governing rights and limitations under the * NPL. * * The Initial Developer of this code under the NPL is Netscape * Communications Corporation. Portions created by Netscape are * Copyright (C) 1998 Netscape Communications Corporation. All Rights * Reserved. */ // // filter.cpp : implementation file // #include "stdafx.h" #include "filter.h" // // filter.cpp : implementation file // #include "mailmisc.h" #include "xp_time.h" #include "xplocale.h" #include "wfemsg.h" #include "dateedit.h" #include "nethelp.h" #include "xp_help.h" #include "prefapi.h" #include "numedit.h" #include "mailpriv.h" #include "mailfrm.h" #include "advprosh.h" #ifdef _DEBUG #undef THIS_FILE static char BASED_CODE THIS_FILE[] = __FILE__; #endif extern MSG_SearchError MSG_GetValuesForAttribute( MSG_ScopeAttribute scope, MSG_SearchAttribute attrib, MSG_SearchMenuItem *items, uint16 *maxItems); extern "C" void HelperInitFonts( HDC hdc , HFONT *phFont, HFONT *phBoldFont); #define NAV_BUTTONWIDTH 24 #define NAV_BUTTONHEIGHT 16 #define BITMAP_MARGIN 5 CFilterScopeCombo::CFilterScopeCombo() : CMiscFolderCombo() { m_bFirst = TRUE; m_hFont = NULL; m_hBigFont = NULL; } CFilterScopeCombo::~CFilterScopeCombo() { } void CFilterScopeCombo::SetFont( CFont *pFont, CFont *pBigFont ) { m_hFont = (HFONT) pFont->m_hObject; m_hBigFont = (HFONT) pBigFont->m_hObject; CMailFolderCombo::SetFont(pFont); } void CFilterScopeCombo::DrawItem( LPDRAWITEMSTRUCT lpDrawItemStruct ) { HDC hDC = lpDrawItemStruct->hDC; RECT rcItem = lpDrawItemStruct->rcItem; RECT rcTemp = rcItem; RECT rcText; DWORD dwItemData = lpDrawItemStruct->itemData; HBRUSH hBrushWindow = ::CreateSolidBrush( GetSysColor( COLOR_WINDOW ) ); HBRUSH hBrushHigh = ::CreateSolidBrush( GetSysColor( COLOR_HIGHLIGHT ) ); HBRUSH hBrushFill = NULL; if ( !m_hFont ) { HelperInitFonts( hDC, &m_hFont, &m_hBoldFont); } HFONT hOldFont = NULL; if ( m_hFont ) { hOldFont = (HFONT) ::SelectObject( hDC,(HFONT)&m_hFont ); } if ( lpDrawItemStruct->itemState & ODS_SELECTED ) { hBrushFill = hBrushHigh; ::SetBkColor( hDC, GetSysColor( COLOR_HIGHLIGHT ) ); ::SetTextColor( hDC, GetSysColor( COLOR_HIGHLIGHTTEXT ) ); } else { hBrushFill = hBrushWindow; ::SetBkColor( hDC, GetSysColor( COLOR_WINDOW ) ); ::SetTextColor( hDC, GetSysColor( COLOR_WINDOWTEXT ) ); } if ( lpDrawItemStruct->itemID != -1 && dwItemData) { MSG_FolderInfo *itemData = (MSG_FolderInfo *) lpDrawItemStruct->itemData; MSG_FolderLine folderLine; MSG_GetFolderLineById( m_pMaster, itemData , &folderLine); int idxImage = WFE_MSGTranslateFolderIcon( folderLine.level, folderLine.flags, folderLine.numChildren ); if ( m_hBoldFont && folderLine.unseen > 0 ) { ::SelectObject( hDC, (HFONT)&m_hBoldFont ); } int iIndent = 0; BOOL bStatic = FALSE; #ifdef _WIN32 if ( sysInfo.m_bWin4 ) bStatic = ( lpDrawItemStruct->itemState & ODS_COMBOBOXEDIT ) ? TRUE : FALSE; else #endif bStatic = m_bStaticCtl; if (!bStatic) iIndent += (folderLine.level - m_iInitialDepth) * 8; //Draw the news bitmap m_pIImageMap->DrawImage( idxImage, iIndent + BITMAP_MARGIN , rcItem.top, hDC, FALSE ); LPCTSTR name = (LPCTSTR) folderLine.prettyName; if ( !name || !name[0] ) name = folderLine.name; //Draw the text ::DrawText( hDC, name, -1, &rcTemp, DT_SINGLELINE|DT_CALCRECT|DT_NOPREFIX ); int iWidth = rcTemp.right - rcTemp.left; rcTemp = rcItem; rcText = rcItem; rcTemp.left = iIndent + BITMAP_MARGIN + 20; rcTemp.right = rcTemp.left + iWidth + 4; VERIFY(::FillRect( hDC, &rcTemp, hBrushFill )); rcText.left = rcTemp.left + 2; rcText.right = rcTemp.right - 2; ::DrawText( hDC, name, -1, &rcText, DT_SINGLELINE|DT_VCENTER|DT_NOPREFIX ); } if ( hBrushHigh ) VERIFY( ::DeleteObject( hBrushHigh )); if ( hBrushWindow ) VERIFY( ::DeleteObject( hBrushWindow )); if ( hOldFont ) ::SelectObject( hDC, hOldFont ); } BEGIN_MESSAGE_MAP( CFilterScopeCombo, CMiscFolderCombo ) ON_WM_CTLCOLOR() ON_WM_PAINT() END_MESSAGE_MAP() void CFilterScopeCombo::OnPaint() { m_bStaticCtl = TRUE; CMailFolderCombo::OnPaint(); m_bFirst = TRUE; } HBRUSH CFilterScopeCombo::OnCtlColor( CDC* pDC, CWnd* pWnd, UINT nCtlColor ) { if (nCtlColor == CTLCOLOR_LISTBOX) { if (m_bFirst) { RECT rcParent; GetWindowRect( &rcParent ); pWnd->GetWindowRect(&m_rcList); m_bFirst = FALSE; int height = m_rcList.bottom - m_rcList.top; if ( (rcParent.bottom + height) > GetSystemMetrics( SM_CYFULLSCREEN ) ) { height = GetSystemMetrics( SM_CYFULLSCREEN ) - rcParent.bottom; } pWnd->MoveWindow( m_rcList.left, rcParent.bottom, m_rcList.right - m_rcList.left, height ); } } m_bStaticCtl = (nCtlColor == CTLCOLOR_EDIT); return CMailFolderCombo::OnCtlColor( pDC, pWnd, nCtlColor ); } int CFilterScopeCombo::PopulateNews(MSG_Master *pMaster, BOOL bRoots) { m_pMaster = pMaster; int index = 0; int nCount=0; m_iInitialDepth = 1; ::SendMessage( m_hWnd, m_nResetContent, (WPARAM) 0, (LPARAM) 0 ); int32 iLines = MSG_GetFolderChildren (m_pMaster, NULL, NULL, 0); MSG_FolderInfo **ppFolderInfo = new MSG_FolderInfo *[iLines]; ASSERT(ppFolderInfo); if (ppFolderInfo) { MSG_GetFolderChildren (m_pMaster, NULL, ppFolderInfo, iLines); for (int i = 0; i < iLines; i++) { MSG_FolderLine folderLine; if (MSG_GetFolderLineById (m_pMaster, ppFolderInfo[i], &folderLine)) { if ( folderLine.flags & MSG_FOLDER_FLAG_NEWSGROUP || folderLine.flags & MSG_FOLDER_FLAG_NEWS_HOST || folderLine.flags & MSG_FOLDER_FLAG_IMAP_PUBLIC || folderLine.flags & MSG_FOLDER_FLAG_INBOX || folderLine.flags & MSG_FOLDER_FLAG_MAIL || folderLine.flags & MSG_FOLDER_FLAG_IMAP_SERVER || folderLine.flags & MSG_FOLDER_FLAG_CAT_CONTAINER) { if ( bRoots ) { if ( folderLine.flags & MSG_FOLDER_FLAG_IMAP_PUBLIC || folderLine.flags & MSG_FOLDER_FLAG_INBOX) { ::SendMessage( m_hWnd, m_nAddString, (WPARAM) 0, (LPARAM) folderLine.name ); ::SendMessage( m_hWnd, m_nSetItemData, (WPARAM) index,(DWORD)(folderLine.id) ); index++; } if ( folderLine.numChildren > 0 ) { SubPopulate(index, folderLine.id ); } } } } } delete [] ppFolderInfo; } return 1; } void CFilterScopeCombo::SubPopulate(int &index, MSG_FolderInfo *folder ) { int32 iLines = MSG_GetFolderChildren (m_pMaster, folder, NULL, 0); MSG_FolderInfo **ppFolderInfo = new MSG_FolderInfo *[iLines]; ASSERT(ppFolderInfo); if (ppFolderInfo) { MSG_GetFolderChildren (m_pMaster, folder, ppFolderInfo, iLines); for (int i = 0; i < iLines; i++) { MSG_FolderLine folderLine; if (MSG_GetFolderLineById (m_pMaster, ppFolderInfo[i], &folderLine)) { if ( folderLine.flags & MSG_FOLDER_FLAG_NEWSGROUP || folderLine.flags & MSG_FOLDER_FLAG_NEWS_HOST || folderLine.flags & MSG_FOLDER_FLAG_IMAP_PUBLIC || folderLine.flags & MSG_FOLDER_FLAG_INBOX) { ::SendMessage( m_hWnd, m_nAddString, (WPARAM) 0, (LPARAM) folderLine.name ); ::SendMessage( m_hWnd, m_nSetItemData, (WPARAM) index,(DWORD)(folderLine.id) ); index++; } if ( folderLine.numChildren > 0 ) { SubPopulate(index, folderLine.id); } } } delete [] ppFolderInfo; } } ///////////////////////////////////////////////////////////////////////////// // CFilterList CFilterList::CFilterList(): CListBox() { m_iPosIndex = 0; m_iPosName = 50; m_iPosStatus = 100; ApiApiPtr(api); m_pIImageUnk = api->CreateClassInstance(APICLASS_IMAGEMAP); ASSERT(m_pIImageUnk); if (m_pIImageUnk) { m_pIImageUnk->QueryInterface(IID_IImageMap,(LPVOID*)&m_pIImageMap); ASSERT(m_pIImageMap); m_pIImageMap->Initialize(IDB_MAILNEWS,16,16); } } CFilterList::~CFilterList() { if (m_pIImageUnk && m_pIImageMap ) { m_pIImageUnk->Release(); } } void CFilterList::SetColumnPositions(int iPosIndex, int iPosName, int iPosStatus) { m_iPosIndex = iPosIndex; m_iPosName = iPosName; m_iPosStatus = iPosStatus; } BEGIN_MESSAGE_MAP( CFilterList, CListBox ) ON_WM_LBUTTONDOWN() ON_WM_LBUTTONDBLCLK() END_MESSAGE_MAP( ) void CFilterList::DrawItem( LPDRAWITEMSTRUCT lpDrawItemStruct ) { HDC hDC = lpDrawItemStruct->hDC; RECT rcItem = lpDrawItemStruct->rcItem; MSG_Filter *itemData = (MSG_Filter *) lpDrawItemStruct->itemData; HBRUSH hBrushFill = NULL; COLORREF oldBk, oldText; if ( lpDrawItemStruct->itemState & ODS_SELECTED ) { hBrushFill = ::CreateSolidBrush( GetSysColor( COLOR_HIGHLIGHT ) ); oldBk = ::SetBkColor( hDC, GetSysColor( COLOR_HIGHLIGHT ) ); oldText = ::SetTextColor( hDC, GetSysColor( COLOR_HIGHLIGHTTEXT ) ); } else { hBrushFill = ::CreateSolidBrush( GetSysColor( COLOR_WINDOW ) ); oldBk = ::SetBkColor( hDC, GetSysColor( COLOR_WINDOW ) ); oldText = ::SetTextColor( hDC, GetSysColor( COLOR_WINDOWTEXT ) ); } if ( itemData ) { RECT rcTemp = rcItem; _TCHAR lpszIndex[8]; // Temp string for index LPSTR lpszName; XP_Bool bEnabled; ::FillRect( hDC, &rcItem, hBrushFill ); _stprintf( lpszIndex, _T("%3d"), lpDrawItemStruct->itemID + 1); MSG_GetFilterName( itemData, (char **) &lpszName ); MSG_IsFilterEnabled( itemData, &bEnabled ); rcTemp.left = m_iPosIndex; rcTemp.right = m_iPosName; ::DrawText( hDC, lpszIndex, -1, &rcTemp, DT_VCENTER|DT_LEFT|DT_NOPREFIX ); rcTemp.left = rcTemp.right; rcTemp.right = m_iPosStatus; ::DrawText( hDC, lpszName, -1, &rcTemp, DT_VCENTER|DT_LEFT ); m_pIImageMap->DrawTransImage( bEnabled ? IDX_CHECKMARK : IDX_CHECKBOX, m_iPosStatus, rcItem.top, hDC ); } if ( lpDrawItemStruct->itemAction & ODA_FOCUS ) { ::DrawFocusRect( hDC, &lpDrawItemStruct->rcItem ); } if (hBrushFill) VERIFY( ::DeleteObject( hBrushFill ) ); ::SetBkColor( hDC, oldBk ); ::SetTextColor( hDC, oldText ); } UINT CFilterList::ItemFromPoint(CPoint pt, BOOL& bOutside) const { RECT rect; GetClientRect(&rect); int iHeight = GetItemHeight(0); int iCount = GetCount(); int iTopIndex = GetTopIndex(); int iListHeight = iHeight * ( iCount - iTopIndex ); rect.bottom = rect.bottom < iListHeight ? rect.bottom : iListHeight; bOutside = !::PtInRect(&rect, pt); if ( bOutside ) { return 0; } return (pt.y / iHeight) + iTopIndex; } void CFilterList::OnLButtonDown( UINT nFlags, CPoint point ) { if ( point.x > m_iPosStatus ) { BOOL bOutside; UINT item = ItemFromPoint( point, bOutside ); RECT rcItem; GetItemRect( item, &rcItem ); if ( (point.y < rcItem.bottom) && (point.y >= rcItem.top) ) { MSG_Filter *pFilter = (MSG_Filter *) GetItemData( item ); if ( pFilter ) { XP_Bool bEnabled; MSG_IsFilterEnabled( pFilter, &bEnabled ); MSG_EnableFilter( pFilter, !bEnabled ); InvalidateRect( &rcItem ); } } } else { CListBox::OnLButtonDown( nFlags, point ); } } void CFilterList::OnLButtonDblClk( UINT nFlags, CPoint point ) { if ( point.x > m_iPosStatus ) { BOOL bOutside; UINT item = ItemFromPoint( point, bOutside ); RECT rcItem; GetItemRect( item, &rcItem ); if ( (point.y < rcItem.bottom) && (point.y >= rcItem.top) ) { MSG_Filter *pFilter = (MSG_Filter *) GetItemData( item ); if ( pFilter ) { XP_Bool bEnabled; MSG_IsFilterEnabled( pFilter, &bEnabled ); MSG_EnableFilter( pFilter, !bEnabled ); InvalidateRect( &rcItem ); } } } else { CListBox::OnLButtonDblClk( nFlags, point ); } } ///////////////////////////////////////////////////////////////////////////// // CFilterPickerDialog dialog #define COL_COUNT 5 #define COL_ATTRIB 0 #define COL_OP 1 #define COL_VALUE 2 static int RuleMatrix[5][COL_COUNT] = { { IDC_COMBO_ATTRIB1, IDC_COMBO_OP1, IDC_EDIT_VALUE1, IDC_STATIC_THE1, IDC_STATIC_OF1 }, { IDC_COMBO_ATTRIB2, IDC_COMBO_OP2, IDC_EDIT_VALUE2, IDC_STATIC_THE2, IDC_STATIC_OF2 }, { IDC_COMBO_ATTRIB3, IDC_COMBO_OP3, IDC_EDIT_VALUE3, IDC_STATIC_THE3, IDC_STATIC_OF3 }, { IDC_COMBO_ATTRIB4, IDC_COMBO_OP4, IDC_EDIT_VALUE4, IDC_STATIC_THE4, IDC_STATIC_OF4 }, { IDC_COMBO_ATTRIB5, IDC_COMBO_OP5, IDC_EDIT_VALUE5, IDC_STATIC_THE5, IDC_STATIC_OF5 } }; static MSG_SearchValueWidget WidgetWas[] = { widgetText, widgetText, widgetText, widgetText, widgetText }; static MSG_SearchAttribute AttribWas[] = { attribSender, attribSender, attribSender, attribSender, attribSender }; CFilterPickerDialog::CFilterPickerDialog(MSG_Pane *pPane, CWnd* pParent /*=NULL*/) : CDialog(CFilterPickerDialog::IDD, pParent) { m_pPane = pPane; m_pParent = pParent; m_FolderInfoScope = NULL; m_pDWordArray = new CDWordArray; //list of Filter Lists //each each filter list represents a change in scope } CFilterPickerDialog::~CFilterPickerDialog() { MSG_FilterList *pListData = NULL; while (-1 != m_pDWordArray->GetUpperBound()) { m_pDWordArray->RemoveAt(m_pDWordArray->GetUpperBound()); m_pDWordArray->FreeExtra(); //we don't need to free what was in the array because the backend ownes the memory. } if (m_pDWordArray) delete m_pDWordArray; } void CFilterPickerDialog::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); } int CFilterPickerDialog::OnInitDialog() { CDialog::OnInitDialog(); m_FilterList.SubclassDlgItem( IDC_LIST_FILTERS, this ); m_ScopeCombo.SubclassDlgItem(IDC_COMBO_SERVER_SCOPE, this); m_ScopeCombo.PopulateNews(WFE_MSGGetMaster(),TRUE); m_ScopeCombo.SetCurSel(0); CRect comboRect; m_ScopeCombo.GetWindowRect(comboRect); m_ScopeCombo.SetWindowPos(NULL, 0, 0, comboRect.Width(), comboRect.Height() * 5, SWP_NOMOVE | SWP_NOZORDER); DWORD dwData = m_ScopeCombo.GetItemData(0); if(dwData != -1) m_FolderInfoScope = (MSG_FolderInfo*)dwData; else m_FolderInfoScope = NULL; ASSERT(m_FolderInfoScope != NULL); m_UpButton.AutoLoad( IDC_UP, this ); m_DownButton.AutoLoad( IDC_DOWN, this ); if(m_FolderInfoScope != NULL) { MSG_OpenFolderFilterList(m_pPane, m_FolderInfoScope, GetFilterType(m_FolderInfoScope), &m_pFilterList); m_pDWordArray->Add((DWORD)m_pFilterList); //put the list on the array MSG_GetFilterCount(m_pFilterList, &m_iFilterCount); m_bLoggingEnabled = MSG_IsLoggingEnabled(m_pFilterList); m_iIndex = 0; } else { m_pFilterList = NULL; } CWnd *widget; widget = GetDlgItem(IDC_CHECK_LOG); ((CButton *) widget)->SetCheck(m_bLoggingEnabled); #ifdef _WIN32 if ( sysInfo.m_bWin4 ) { widget = GetDlgItem( IDC_STATIC_DESCRIPTION ); widget->ModifyStyle( WS_BORDER, 0, SWP_FRAMECHANGED ); widget->ModifyStyleEx( 0, WS_EX_CLIENTEDGE, SWP_FRAMECHANGED ); } #endif int iPosIndex, iPosName, iPosStatus; RECT rect, rcText; widget = GetDlgItem(IDC_LIST_FILTERS); widget->GetWindowRect(&rect); int iListLeft = 4; CDC *pDC = GetDC(); ::SetRect( &rcText, 0, 0, 64, 64 ); pDC->DrawText(_T("0"), 1, &rcText, DT_CALCRECT ); ReleaseDC( pDC ); iPosIndex = iListLeft + 4; iPosName = iPosIndex + rcText.right * 3; iPosStatus = rect.right - rect.left - 20 - GetSystemMetrics(SM_CXVSCROLL); m_FilterList.SetColumnPositions( iPosIndex, iPosName, iPosStatus ); UpdateList(); return TRUE; } void CFilterPickerDialog::UpdateList() { if(m_pFilterList != NULL) { MSG_GetFilterCount(m_pFilterList, &m_iFilterCount); const char *lpszName; CListBox *pListBox = (CListBox *) GetDlgItem( IDC_LIST_FILTERS ); pListBox->ResetContent(); for ( int i = 0; i < m_iFilterCount; i++ ) { if (FilterError_Success == MSG_GetFilterAt(m_pFilterList, (MSG_FilterIndex) i, &m_pFilter) && m_pFilter) { MSG_GetFilterName( m_pFilter, (char **) &lpszName ); pListBox->AddString( lpszName ); pListBox->SetItemData( i, (ULONG) m_pFilter ); } } pListBox->SetCurSel(m_iIndex); OnSelchangeListFilter(); } } BEGIN_MESSAGE_MAP(CFilterPickerDialog, CDialog) ON_BN_CLICKED( IDOK, OnOK) ON_BN_CLICKED( IDCANCEL, OnCancel) ON_BN_CLICKED( IDC_NEW, OnNew) ON_BN_CLICKED( IDC_EDIT, OnEdit) ON_BN_CLICKED( IDC_BUTTON_SERVER_FILTERS, OnServerFilters) ON_UPDATE_COMMAND_UI( IDC_EDIT, OnUpdateEdit ) ON_UPDATE_COMMAND_UI(IDC_BUTTON_SERVER_FILTERS, OnUpdateServerFilters) ON_BN_CLICKED( IDC_DELETE, OnDelete) ON_UPDATE_COMMAND_UI( IDC_DELETE, OnUpdateEdit ) ON_BN_CLICKED( IDC_UP, OnUp) ON_BN_DOUBLECLICKED( IDC_UP, OnUp) ON_UPDATE_COMMAND_UI( IDC_UP, OnUpdateUp ) ON_BN_CLICKED( IDC_DOWN, OnDown) ON_BN_DOUBLECLICKED( IDC_DOWN, OnDown) ON_UPDATE_COMMAND_UI( IDC_DOWN, OnUpdateDown ) ON_LBN_DBLCLK( IDC_LIST_FILTERS, OnDblclkListFilter ) ON_LBN_SELCHANGE( IDC_LIST_FILTERS, OnSelchangeListFilter ) ON_CBN_SELCHANGE(IDC_COMBO_SERVER_SCOPE, OnScope) ON_BN_CLICKED( IDC_FILTER_HELP, OnHelp) ON_BN_CLICKED( IDC_VIEW, OnView) END_MESSAGE_MAP() void CFilterPickerDialog::OnServerFilters() { if(m_FolderInfoScope != NULL) { CMailNewsFrame *pFrame = (CMailNewsFrame *)m_pParent; MWContext *context = pFrame->GetContext()->GetContext(); MSG_GetAdminUrlForFolder(context, m_FolderInfoScope,MSG_AdminServerSideFilters); } } void CFilterPickerDialog::OnUpdateServerFilters(CCmdUI *pCmdUI) { if(m_FolderInfoScope != NULL) { BOOL bOKToEnable = MSG_HaveAdminUrlForFolder(m_FolderInfoScope,MSG_AdminServerSideFilters); pCmdUI->Enable(bOKToEnable); } else { pCmdUI->Enable(FALSE); } } void CFilterPickerDialog::OnScope() { int iCurSel = m_ScopeCombo.GetCurSel(); MSG_FolderInfo *pfolderInfo = NULL; DWORD dwData = m_ScopeCombo.GetItemData(iCurSel); if(dwData != -1) { pfolderInfo = (MSG_FolderInfo*)dwData; } else { pfolderInfo = NULL; } if ( m_FolderInfoScope != pfolderInfo) { //set the new scope m_FolderInfoScope = pfolderInfo; if(m_FolderInfoScope != NULL) { //Check the filter arrary to see if we already opened this scope's filter list if ( !FilterListAlreadyOpen(m_FolderInfoScope,m_pFilterList) ) { //Get a new list of filters for this scope MSG_OpenFolderFilterList(m_pPane, m_FolderInfoScope, GetFilterType(m_FolderInfoScope), &m_pFilterList); //put the list on the array m_pDWordArray->Add((DWORD)m_pFilterList); } MSG_GetFilterCount(m_pFilterList, &m_iFilterCount); m_bLoggingEnabled = MSG_IsLoggingEnabled(m_pFilterList); m_iIndex = 0; } else { m_pFilterList = NULL; } CWnd *widget; widget = GetDlgItem(IDC_CHECK_LOG); ((CButton *) widget)->SetCheck(m_bLoggingEnabled); UpdateList(); } //nothing change so don't do anything } MSG_FilterType CFilterPickerDialog::GetFilterType(MSG_FolderInfo *pFolderInfo) { if (!(MSG_GetFolderFlags(pFolderInfo) & MSG_FOLDER_FLAG_NEWSGROUP) && !(MSG_GetFolderFlags(pFolderInfo) & MSG_FOLDER_FLAG_NEWS_HOST)) { return filterInbox; } else { return filterNews; } } //Searches the filter list array to see if we arleady have an open filter list for this folder scope BOOL CFilterPickerDialog::FilterListAlreadyOpen(MSG_FolderInfo *pFolder, MSG_FilterList *&pReturnList) { for (int i=0; i <= m_pDWordArray->GetUpperBound(); i++) { MSG_FilterList *pFilterList = NULL; pFilterList = (MSG_FilterList*)m_pDWordArray->GetAt(i); if (pFilterList) { if (MSG_GetFolderInfoForFilterList(pFilterList) == pFolder) { pReturnList = pFilterList; return TRUE; } } } return FALSE; } void CFilterPickerDialog::OnDblclkListFilter() { if (m_iIndex < m_iFilterCount) { OnEdit(); } else { OnNew(); } } void CFilterPickerDialog::OnSelchangeListFilter() { CListBox *pListBox = (CListBox *) GetDlgItem( IDC_LIST_FILTERS ); m_iIndex = pListBox->GetCurSel(); CWnd *widget; m_pFilter = NULL; MSG_GetFilterAt( m_pFilterList, (MSG_FilterIndex) m_iIndex, &m_pFilter ); const char *lpszDesc = ""; widget = GetDlgItem(IDC_STATIC_DESCRIPTION); if ( m_pFilter ) { MSG_GetFilterDesc( m_pFilter, (char **) &lpszDesc ); } widget->SetWindowText( lpszDesc ); UpdateDialogControls( this, TRUE ); } void CFilterPickerDialog::OnSelcancelListFilter() { } void CFilterPickerDialog::OnNew() { if(m_FolderInfoScope != NULL ) { m_pFilter = NULL; CFilterDialog dialog( m_pPane, m_FolderInfoScope, &m_pFilter, this ); if (dialog.DoModal() == IDOK ) { m_iIndex += 1; MSG_InsertFilterAt( m_pFilterList, (MSG_FilterIndex) m_iIndex, m_pFilter ); } UpdateList(); } } void CFilterPickerDialog::OnEdit() { if(m_FolderInfoScope != NULL) { MSG_GetFilterAt(m_pFilterList, (MSG_FilterIndex) m_iIndex, &m_pFilter); CFilterDialog dialog( m_pPane, m_FolderInfoScope, &m_pFilter, this ); if ( dialog.DoModal() == IDOK ) MSG_SetFilterAt( m_pFilterList, (MSG_FilterIndex) m_iIndex, m_pFilter ); UpdateList(); } } void CFilterPickerDialog::OnUpdateEdit( CCmdUI *pCmdUI ) { BOOL bEnable = (m_iIndex < m_iFilterCount) && (m_iIndex >= 0); MSG_FilterType filterType = filterInboxJavaScript; MSG_GetFilterType( m_pFilter, &filterType ); if ( filterType == filterInboxJavaScript || filterType == filterNewsJavaScript ) { bEnable = FALSE; } pCmdUI->Enable(bEnable); } void CFilterPickerDialog::OnDelete() { if(m_FolderInfoScope != NULL) { if (m_iIndex < m_iFilterCount && m_iIndex >= 0) { MSG_GetFilterAt( m_pFilterList, (MSG_FilterIndex) m_iIndex, &m_pFilter ); MSG_RemoveFilterAt( m_pFilterList, (MSG_FilterIndex) m_iIndex ); MSG_DestroyFilter( m_pFilter ); if (m_iIndex) { m_iIndex--; } UpdateList(); } } } void CFilterPickerDialog::OnUp() { MSG_MoveFilterAt(m_pFilterList, (MSG_FilterIndex) m_iIndex, filterUp); m_iIndex--; UpdateList(); } void CFilterPickerDialog::OnUpdateUp( CCmdUI *pCmdUI ) { pCmdUI->Enable( m_iIndex > 0 ); } void CFilterPickerDialog::OnDown() { MSG_MoveFilterAt(m_pFilterList, (MSG_FilterIndex) m_iIndex, filterDown); m_iIndex++; UpdateList(); } void CFilterPickerDialog::OnUpdateDown( CCmdUI *pCmdUI ) { pCmdUI->Enable( m_iFilterCount > 0 && m_iIndex < m_iFilterCount - 1 ); } void CFilterPickerDialog::OnOK() { CDialog::OnOK(); //Set logging for the currently displayed filter scope MSG_EnableLogging(m_pFilterList, IsDlgButtonChecked(IDC_CHECK_LOG)); for (int i=0; i <= m_pDWordArray->GetUpperBound(); i++) { MSG_FilterList *pFilterList = (MSG_FilterList*)m_pDWordArray->GetAt(i); if (pFilterList) { MSG_CloseFilterList(pFilterList); } } } void CFilterPickerDialog::OnCancel() { CDialog::OnCancel(); for (int i=0; i <= m_pDWordArray->GetUpperBound(); i++) { MSG_FilterList *pFilterList = (MSG_FilterList*)m_pDWordArray->GetAt(i); if (pFilterList) { MSG_CancelFilterList( pFilterList ); } } } void CFilterPickerDialog::OnHelp() { NetHelp(HELP_MAIL_FILTERS); } void CFilterPickerDialog::OnView() { MSG_ViewFilterLog(m_pPane); } ///////////////////////////////////////////////////////////////////////////// // CFilterDialog dialog CFilterDialog::CFilterDialog(MSG_Pane *pPane, MSG_FolderInfo *pFolderInfoScope, MSG_Filter **filter, CWnd* pParent /*=NULL*/) : CDialog(CFilterDialog::IDD, pParent) { m_pPane = pPane; m_pFolderInfoScope = pFolderInfoScope; m_hFilter = filter; m_bLogicType = 0; m_iRowIndex = 0; //{{AFX_DATA_INIT(CFilterDialog) m_iActive = 1; m_lpszFilterName = szLoadString(IDS_UNTITLED); m_lpszFilterDesc = _T(""); //}}AFX_DATA_INIT for (int i = 0; i < 5; i++ ) { WidgetWas[i] = widgetText; AttribWas[i] = attribSender; } } void CFilterDialog::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CFilterDialog) DDX_Text(pDX, IDC_EDIT_NAME, m_lpszFilterName); DDX_Text(pDX, IDC_EDIT_DESC, m_lpszFilterDesc); //}}AFX_DATA_MAP } MSG_ScopeAttribute CFilterDialog::GetFolderScopeAttribute() { uint32 flags = MSG_GetFolderFlags(m_pFolderInfoScope); MSG_ScopeAttribute scopeAttrib; if (flags & MSG_FOLDER_FLAG_NEWSGROUP || flags & MSG_FOLDER_FLAG_NEWS_HOST) { scopeAttrib = scopeNewsgroup; } else { scopeAttrib = scopeMailFolder; } return scopeAttrib; } MSG_FilterType CFilterDialog::GetFolderFilterType() { MSG_FilterType filterType; uint32 flags = MSG_GetFolderFlags(m_pFolderInfoScope); if(flags & MSG_FOLDER_FLAG_NEWSGROUP || flags & MSG_FOLDER_FLAG_NEWS_HOST) { filterType = filterNewsRule; } else { filterType = filterInboxRule; } return filterType; } int CFilterDialog::OnInitDialog() { CDialog::OnInitDialog(); uint16 i, j; int dy; CWnd *widget; CRect rect, rect2; CComboBox *combo; MSG_FolderInfo *pInbox = NULL; MSG_GetFoldersWithFlag (WFE_MSGGetMaster(), MSG_FOLDER_FLAG_INBOX, &pInbox, 1); uint16 numItems; MSG_ScopeAttribute scopeAttrib = GetFolderScopeAttribute(); MSG_GetNumAttributesForFilterScopes (WFE_MSGGetMaster(), scopeAttrib, (void**)&m_pFolderInfoScope, 1, &numItems); MSG_SearchMenuItem * HeaderItems = new MSG_SearchMenuItem [numItems]; if (!HeaderItems) return FALSE; //something bad happened here!! MSG_GetAttributesForFilterScopes (WFE_MSGGetMaster(), scopeAttrib, (void**)&m_pFolderInfoScope, 1, HeaderItems, &numItems); for (i = 0; i < 5; i++) { combo = (CComboBox *) GetDlgItem( RuleMatrix[i][COL_ATTRIB] ); combo->ResetContent(); for (j = 0; j < numItems; j++) { combo->AddString(HeaderItems[j].name); combo->SetItemData(j, HeaderItems[j].attrib); } if (i > 0) { for (j = 0; j < COL_COUNT; j++) { widget = GetDlgItem(RuleMatrix[i][j]); if(widget != NULL) widget->ShowWindow(SW_HIDE); } } combo->SetCurSel(0); UpdateOpList(i); } if (HeaderItems) delete HeaderItems; //free the memory since it's now in the combo box //Above we are getting the list of Headers and updating controls in column 1 CheckRadioButton(IDC_RADIO_ANY, IDC_RADIO_ALL, IDC_RADIO_ANY); MSG_RuleActionType type; combo = (CComboBox *) GetDlgItem( IDC_COMBO_ACTION ); combo->ResetContent(); MSG_RuleMenuItem items[16]; uint16 maxItems = 16; MSG_FilterType filterType = GetFolderFilterType(); MSG_GetRuleActionMenuItems(filterType, items, &maxItems); for (j = 0; j < maxItems; j++) { combo->AddString(items[j].name); combo->SetItemData(j, items[j].attrib); } combo->SetCurSel( 0 ); UpdateDestList(); widget = GetDlgItem(IDC_FEWER); widget->EnableWindow(FALSE); widget->GetWindowRect(&rect); widget = GetDlgItem(RuleMatrix[0][0]); widget->GetWindowRect(&rect2); dy = rect2.bottom - rect.top; widget = GetDlgItem(RuleMatrix[4][0]); widget->GetWindowRect(&rect2); dy += rect.top - rect2.bottom; SlideBottomControls(dy); if ( *m_hFilter ) { const char *lpszTemp; CWnd *widget; // Name MSG_GetFilterName( *m_hFilter, (char **) &lpszTemp); m_lpszFilterName = lpszTemp; widget = GetDlgItem( IDC_EDIT_NAME ); widget->SetWindowText(lpszTemp); // Description MSG_GetFilterDesc( *m_hFilter, (char **) &lpszTemp); m_lpszFilterDesc = lpszTemp; widget = GetDlgItem( IDC_EDIT_DESC ); widget->SetWindowText(lpszTemp); // Enabled XP_Bool bEnabled; MSG_IsFilterEnabled( *m_hFilter, &bEnabled ); m_iActive = bEnabled ? 1 : 0; // Terms long iNumTerms; MSG_SearchAttribute attrib; MSG_SearchOperator op; MSG_SearchValue value; MSG_Rule *rule; const char *arbitraryHeaders; MSG_GetFilterRule( *m_hFilter, &rule ); MSG_RuleGetNumTerms( rule, &iNumTerms ); ASSERT(iNumTerms > 0 && iNumTerms < 6); for ( i = 0; i < (uint16)iNumTerms; i++) { if (i > 0) OnMore(); #ifndef FE_IMPLEMENTS_BOOLEAN_OR MSG_RuleGetTerm(rule, i, &attrib, &op, &value); SetTerm(i, attrib, op, value); #else MSG_RuleGetTerm(rule, i, &attrib, &op, &value, &m_bLogicType, (char **)&arbitraryHeaders); SetTerm(i, attrib, op, value, (char*)arbitraryHeaders); #endif } CheckRadioButton(IDC_RADIO_ANY, IDC_RADIO_ALL, m_bLogicType ? IDC_RADIO_ALL : IDC_RADIO_ANY); ChangeLogicText(); void *value2; MSG_RuleGetAction( rule, &type, &value2); SetAction( type, value2 ); if(iNumTerms > 1) { GetDlgItem(IDC_RADIO_ANY)->EnableWindow(TRUE); GetDlgItem(IDC_RADIO_ALL)->EnableWindow(TRUE); } else { GetDlgItem(IDC_RADIO_ANY)->EnableWindow(FALSE); GetDlgItem(IDC_RADIO_ALL)->EnableWindow(FALSE); } } return TRUE; // return TRUE unless you set the focus to a control // EXCEPTION: OCX Property Pages should return FALSE } void CFilterDialog::UpdateColumn1Attributes() { uint16 i, j; CWnd *widget = NULL; uint16 numItems; CComboBox *combo = NULL; MSG_ScopeAttribute scopeAttrib = GetFolderScopeAttribute(); MSG_GetNumAttributesForFilterScopes (WFE_MSGGetMaster(), scopeAttrib, (void**)&m_pFolderInfoScope, 1, &numItems); MSG_SearchMenuItem * HeaderItems = new MSG_SearchMenuItem [numItems]; if (!HeaderItems) return; //something bad happened here!! //we are getting the list of Headers and updating controls in column 1 MSG_GetAttributesForFilterScopes (WFE_MSGGetMaster(), scopeAttrib, (void**)&m_pFolderInfoScope, 1, HeaderItems, &numItems); for (i = 0; i < 5; i++) { combo = (CComboBox *) GetDlgItem( RuleMatrix[i][COL_ATTRIB] ); if (!combo) { delete HeaderItems; //free the memory since it's now in the combo box return; } combo->ResetContent(); for (j = 0; j < numItems; j++) { combo->AddString(HeaderItems[j].name); combo->SetItemData(j, HeaderItems[j].attrib); } combo->SetCurSel(0); UpdateOpList(i); } delete HeaderItems; //free the memory since it's now in the combo box } LONG CFilterDialog::OnFinishedHeaders(WPARAM wParam, LPARAM lParam ) { MSG_Master *master = WFE_MSGGetMaster(); if (lParam == IDOK ) UpdateColumn1Attributes(); MSG_ReleaseEditHeadersSemaphore(master, this); return 0; } void CFilterDialog::OnNewFolder() { int iCurSel = m_FolderCombo.GetCurSel(); MSG_FolderInfo *pFolderInfo = (MSG_FolderInfo*)m_FolderCombo.GetItemData(iCurSel); CNewFolderDialog nfd(this, m_pPane, pFolderInfo); nfd.DoModal(); OnUpdateDest(); } void CFilterDialog::UpdateOpList(int iRow) { CComboBox *combo; CNSDateEdit *date; CWnd *widget, *widgetPrior; CEdit *edit; uint16 j, iCurSel; MSG_SearchAttribute attrib; combo = (CComboBox *) GetDlgItem( RuleMatrix[iRow][COL_ATTRIB] ); iCurSel = combo->GetCurSel(); attrib = (MSG_SearchAttribute) combo->GetItemData(iCurSel); MSG_SearchMenuItem items[16]; uint16 maxItems = 16; combo = (CComboBox *) GetDlgItem( RuleMatrix[iRow][COL_OP] ); combo->ResetContent(); MSG_ScopeAttribute scopeAttrib = GetFolderScopeAttribute(); MSG_GetOperatorsForFilterScopes (WFE_MSGGetMaster(), scopeAttrib, (void**) &m_pFolderInfoScope, 1, attrib, items, &maxItems); for (j = 0; j < maxItems; j++) { combo->AddString(items[j].name); combo->SetItemData(j, items[j].attrib); } combo->SetCurSel(0); // Calculate a dialog unit RECT rect = {0, 0, 1, 1}; ::MapDialogRect(this->m_hWnd, &rect); int iDialogUnit = rect.right; POINT ptUs = {0,0}; ClientToScreen(&ptUs); // // Substitute a happy new widget based on the search attribute // if ( attrib == AttribWas [iRow] ) { return; } AttribWas[iRow] = attrib; MSG_SearchValueWidget valueWidget; MSG_GetSearchWidgetForAttribute ( attrib, &valueWidget ); if (( WidgetWas[iRow] == valueWidget ) && ( valueWidget != widgetMenu) ) { return; } WidgetWas[iRow] = valueWidget; widget = GetDlgItem( RuleMatrix[iRow][COL_VALUE] ); widgetPrior = GetDlgItem( RuleMatrix[iRow][COL_OP] ); RECT rectWidget; widget->GetWindowRect(&rectWidget); ::OffsetRect( &rectWidget, -ptUs.x, -ptUs.y ); DWORD dwStyle = widget->GetStyle() & (WS_CHILD|WS_VISIBLE|WS_DISABLED|WS_GROUP|WS_TABSTOP); DWORD dwExStyle = 0; widget->DestroyWindow(); switch( valueWidget ) { case widgetMenu: rectWidget.bottom = rectWidget.top + 60 * iDialogUnit; dwStyle |= WS_VSCROLL|CBS_DROPDOWNLIST; combo = new CComboBox; maxItems = 16; combo->Create( dwStyle, rectWidget, this, RuleMatrix[iRow][COL_VALUE] ); combo->SetFont(GetFont()); MSG_GetValuesForAttribute( scopeMailFolder, attrib, items, &maxItems ); for (j = 0; j < maxItems; j++) { combo->AddString( items[j].name ); combo->SetItemData( j, items[j].attrib ); } combo->SetCurSel(0); // Fix Tab Order combo->SetWindowPos( widgetPrior, 0, 0, 0, 0, SWP_NOSIZE|SWP_NOMOVE); break; case widgetDate: #ifdef XP_WIN32 dwExStyle |= WS_EX_CLIENTEDGE; if ( !sysInfo.m_bWin4 ) #endif { dwStyle |= WS_BORDER; } dwStyle |= WS_CLIPCHILDREN; date = new CNSDateEdit; #ifdef XP_WIN32 date->CreateEx( dwExStyle, _T("STATIC"), "", dwStyle, rectWidget.left, rectWidget.top, rectWidget.right - rectWidget.left, rectWidget.bottom - rectWidget.top, this->m_hWnd, (HMENU) RuleMatrix[iRow][COL_VALUE]); #else date->Create( "", dwStyle|SS_SIMPLE, rectWidget, this, RuleMatrix[iRow][COL_VALUE]); #endif date->SetFont( GetFont() ); date->SetDate( CTime( time( NULL ) ) ); date->SetWindowPos( widgetPrior, 0, 0, 0, 0, SWP_NOSIZE|SWP_NOMOVE); break; case widgetText: default: dwStyle |= ES_AUTOHSCROLL; #ifdef XP_WIN32 dwExStyle |= WS_EX_CLIENTEDGE; ::InflateRect(&rectWidget, GetSystemMetrics(SM_CXEDGE), GetSystemMetrics(SM_CYEDGE)); if ( !sysInfo.m_bWin4 ) #endif { dwStyle |= WS_BORDER; } edit = new CEdit; #ifdef _WIN32 edit->CreateEx( dwExStyle, _T("EDIT"), "", dwStyle, rectWidget.left, rectWidget.top, rectWidget.right - rectWidget.left, rectWidget.bottom - rectWidget.top, this->m_hWnd, (HMENU) RuleMatrix[iRow][COL_VALUE]); #else edit->Create( dwStyle, rectWidget, this, RuleMatrix[iRow][COL_VALUE]); #endif edit->SetFont(GetFont()); edit->SetWindowText(""); // Fix Tab Order edit->SetWindowPos( widgetPrior, 0, 0, 0, 0, SWP_NOSIZE|SWP_NOMOVE); break; } } void CFilterDialog::UpdateDestList() { CComboBox *combo; CWnd *widgetPrior; uint16 j, iCurSel; MSG_RuleActionType action; MSG_SearchMenuItem items[16]; uint16 maxItems = 16; combo = (CComboBox *) GetDlgItem( IDC_COMBO_ACTION ); widgetPrior = combo; iCurSel = combo->GetCurSel(); action = (MSG_RuleActionType) combo->GetItemData( iCurSel ); MSG_SearchValueWidget destWidget; MSG_GetFilterWidgetForAction( action, &destWidget ); combo = (CComboBox *) GetDlgItem( IDC_COMBO_DEST ); switch (destWidget) { case widgetMenu: { RECT rect = {0, 0, 1, 1}; ::MapDialogRect(this->m_hWnd, &rect); int iDialogUnit = rect.right; POINT ptUs = {0,0}; ClientToScreen(&ptUs); RECT rectWidget; combo->GetWindowRect( &rectWidget ); ::OffsetRect( &rectWidget, -ptUs.x, -ptUs.y ); rectWidget.bottom = rectWidget.top + 60 * iDialogUnit; DWORD dwStyle = combo->GetStyle() & (WS_CHILD|WS_VISIBLE|WS_DISABLED|WS_GROUP|WS_TABSTOP); switch (action) { case acChangePriority: if (m_FolderCombo.m_hWnd != NULL) { m_FolderCombo.DestroyWindow(); dwStyle |= WS_VSCROLL|CBS_DROPDOWNLIST; combo = new CComboBox; combo->Create( dwStyle, rectWidget, this, IDC_COMBO_DEST ); combo->SetFont(GetFont()); combo->SetWindowPos( widgetPrior, 0, 0, 0, 0, SWP_NOSIZE|SWP_NOMOVE); combo->ResetContent(); MSG_GetValuesForAction( action, items, &maxItems ); for (j = 0; j < maxItems; j++) { combo->AddString( items[j].name ); combo->SetItemData( j, items[j].attrib ); } combo->SetCurSel(0); } combo->ShowWindow(SW_SHOW); break; case acMoveToFolder: if (m_FolderCombo.m_hWnd == NULL) { combo->DestroyWindow(); dwStyle |= WS_VSCROLL|CBS_DROPDOWNLIST|CBS_OWNERDRAWFIXED; m_FolderCombo.Create( dwStyle, rectWidget, this, IDC_COMBO_DEST ); m_FolderCombo.SetFont(GetFont()); m_FolderCombo.SetWindowPos( widgetPrior, 0, 0, 0, 0, SWP_NOSIZE|SWP_NOMOVE); m_FolderCombo.PopulateMail(WFE_MSGGetMaster(), FALSE); m_FolderCombo.SetCurSel(0); } m_FolderCombo.ShowWindow(SW_SHOW); break; default: ASSERT(0); // Not handled } } break; case widgetNone: combo->ShowWindow(SW_HIDE); break; default: case widgetInt: case widgetText: case widgetDate: ASSERT(0); // Not handled } } int CFilterDialog::ChangeLogicText() { CWnd *widget; if (m_iRowIndex <= 4) { CString strLogicText; for (int Row = 1; Row <= m_iRowIndex; Row++) { widget = GetDlgItem(RuleMatrix[Row][3]); if (!widget) return 0; if (m_bLogicType) { //Display AND logic text strLogicText.LoadString(IDS_ANDTHE); widget->SetWindowText(strLogicText); } else { //Display OR logic text strLogicText.LoadString(IDS_ORTHE); widget->SetWindowText(strLogicText); } widget->ShowWindow(SW_SHOW); } } return 1; } int CFilterDialog::GetNumTerms() { return m_iRowIndex + 1; } static char szResultText[64]; #ifdef FE_IMPLEMENTS_BOOLEAN_OR void CFilterDialog::GetTerm( int iRow, MSG_SearchAttribute *attrib, MSG_SearchOperator *op, MSG_SearchValue *value, char *pszArbitraryHeader) { CComboBox *combo; CNSDateEdit *date; CWnd *widget; int iCurSel; combo = (CComboBox *) GetDlgItem(RuleMatrix[iRow][COL_ATTRIB]); iCurSel = combo->GetCurSel(); *attrib = (MSG_SearchAttribute) combo->GetItemData(iCurSel); CString strHeader; combo->GetWindowText(strHeader); strcpy(pszArbitraryHeader,strHeader); combo = (CComboBox *) GetDlgItem(RuleMatrix[iRow][COL_OP]); iCurSel = combo->GetCurSel(); *op = (MSG_SearchOperator) combo->GetItemData(iCurSel); widget = GetDlgItem(RuleMatrix[iRow][COL_VALUE]); widget->GetWindowText(szResultText, sizeof(szResultText)); value->attribute = *attrib; switch (*attrib) { case attribDate: { CTime ctime; date = (CNSDateEdit *) GetDlgItem(RuleMatrix[iRow][COL_VALUE]); date->GetDate(ctime); value->u.date = ctime.GetTime(); } break; case attribPriority: combo = (CComboBox *) GetDlgItem(RuleMatrix[iRow][COL_VALUE]); iCurSel = combo->GetCurSel(); value->u.priority = (MSG_PRIORITY) combo->GetItemData(iCurSel); break; case attribMsgStatus: combo = (CComboBox *) GetDlgItem(RuleMatrix[iRow][COL_VALUE]); iCurSel = combo->GetCurSel(); value->u.msgStatus = combo->GetItemData(iCurSel); break; default: value->u.string = XP_STRDUP( szResultText ); } } #else void CFilterDialog::GetTerm( int iRow, MSG_SearchAttribute *attrib, MSG_SearchOperator *op, MSG_SearchValue *value) { CComboBox *combo; CNSDateEdit *date; CWnd *widget; int iCurSel; combo = (CComboBox *) GetDlgItem(RuleMatrix[iRow][COL_ATTRIB]); iCurSel = combo->GetCurSel(); *attrib = (MSG_SearchAttribute) combo->GetItemData(iCurSel); combo = (CComboBox *) GetDlgItem(RuleMatrix[iRow][COL_OP]); iCurSel = combo->GetCurSel(); *op = (MSG_SearchOperator) combo->GetItemData(iCurSel); widget = GetDlgItem(RuleMatrix[iRow][COL_VALUE]); widget->GetWindowText(szResultText, sizeof(szResultText)); value->attribute = *attrib; switch (*attrib) { case attribDate: { CTime ctime; date = (CNSDateEdit *) GetDlgItem(RuleMatrix[iRow][COL_VALUE]); date->GetDate(ctime); value->u.date = ctime.GetTime(); } break; case attribPriority: combo = (CComboBox *) GetDlgItem(RuleMatrix[iRow][COL_VALUE]); iCurSel = combo->GetCurSel(); value->u.priority = (MSG_PRIORITY) combo->GetItemData(iCurSel); break; case attribMsgStatus: combo = (CComboBox *) GetDlgItem(RuleMatrix[iRow][COL_VALUE]); iCurSel = combo->GetCurSel(); value->u.msgStatus = combo->GetItemData(iCurSel); break; default: value->u.string = XP_STRDUP( szResultText ); } } #endif #ifdef FE_IMPLEMENTS_BOOLEAN_OR void CFilterDialog::SetTerm( int iRow, MSG_SearchAttribute attrib, MSG_SearchOperator op, MSG_SearchValue value, char *pszArbitraryHeader) { CComboBox *combo; CNSDateEdit *date; CWnd *widget; CString strHeader; int i; BOOL bFound = FALSE; combo = (CComboBox *) GetDlgItem( RuleMatrix[iRow][COL_ATTRIB] ); combo->SetCurSel(0); CString strCheckHeader = pszArbitraryHeader; MSG_ScopeAttribute scopeAttrib = GetFolderScopeAttribute(); BOOL bUsesCustomHeaders = MSG_ScopeUsesCustomHeaders(WFE_MSGGetMaster(),scopeAttrib, m_pFolderInfoScope, TRUE); //if it uses custom headers then don't compare last item which is the "Custom" item int headerCount = bUsesCustomHeaders ? combo->GetCount() - 1 : combo->GetCount(); if (!strCheckHeader.IsEmpty() ) { for ( i = 0; i < headerCount ; i++ ) { combo->GetLBText(i,strHeader); if ( (MSG_SearchAttribute) combo->GetItemData(i) == attrib && !strHeader.Compare(strCheckHeader) ) { combo->SetCurSel(i); bFound=TRUE; break; } } } else { // get count has to be based on whether or not there is a custom header in this. for ( i = 0; i < headerCount ; i++ ) { if ( (MSG_SearchAttribute) combo->GetItemData(i) == attrib ) { combo->SetCurSel(i); bFound=TRUE; break; } } } //The saved header may not be on the globally stored list of headers. prompt so they can retain settings if (!bFound && (attrib == attribOtherHeader) && !strCheckHeader.IsEmpty()) { CString strMessage; AfxFormatString1(strMessage,IDS_HEADER_DELETED_WARN,pszArbitraryHeader); if (AfxMessageBox(strMessage,MB_OKCANCEL) == IDOK) { //Update Arbitrary header list CString strArbitraryHeaders; char *pHeaderList=NULL; PREF_CopyCharPref("mailnews.customHeaders",&pHeaderList); strArbitraryHeaders = pHeaderList; if (!strArbitraryHeaders.IsEmpty()) { strArbitraryHeaders += ": " + (CString)pszArbitraryHeader; } else if (!strHeader.IsEmpty()) { strArbitraryHeaders = pszArbitraryHeader; } PREF_SetCharPref("mailnews.customHeaders",strArbitraryHeaders); UpdateColumn1Attributes(); for ( i = 0; i < (combo->GetCount()-1); i++ ) { combo->GetLBText(i,strHeader); if ( (MSG_SearchAttribute) combo->GetItemData(i) == attrib && !strHeader.Compare(pszArbitraryHeader) ) { combo->SetCurSel(i); bFound=TRUE; break; } } } } UpdateOpList( iRow ); combo = (CComboBox *) GetDlgItem( RuleMatrix[iRow][COL_OP] ); combo->SetCurSel(0); for ( i = 0; i < combo->GetCount(); i++ ) { if ( (MSG_SearchOperator) combo->GetItemData(i) == op) { combo->SetCurSel(i); break; } } switch ( value.attribute ) { case attribDate: { CTime ctime( value.u.date ); date = (CNSDateEdit *) GetDlgItem( RuleMatrix[iRow][COL_VALUE] ); date->SetDate( ctime ); } break; case attribPriority: combo = (CComboBox *) GetDlgItem( RuleMatrix[iRow][COL_VALUE] ); combo->SetCurSel(0); for ( i = 0; i < combo->GetCount(); i++ ) { if ( (MSG_PRIORITY) combo->GetItemData(i) == value.u.priority ) { combo->SetCurSel(i); break; } } break; case attribMsgStatus: combo = (CComboBox *) GetDlgItem( RuleMatrix[iRow][COL_VALUE] ); for ( i = 0; i < combo->GetCount(); i++ ) { if ( combo->GetItemData(i) == value.u.msgStatus ) { combo->SetCurSel(i); break; } } break; default: widget = GetDlgItem( RuleMatrix[iRow][COL_VALUE] ); widget->SetWindowText( (const char *) value.u.string ); } } #else void CFilterDialog::SetTerm( int iRow, MSG_SearchAttribute attrib, MSG_SearchOperator op, MSG_SearchValue value) { CComboBox *combo; CNSDateEdit *date; CWnd *widget; int i; combo = (CComboBox *) GetDlgItem( RuleMatrix[iRow][COL_ATTRIB] ); combo->SetCurSel(0); for ( i = 0; i < (combo->GetCount() -1) ; i++ ) { if ( (MSG_SearchAttribute) combo->GetItemData(i) == attrib ) { combo->SetCurSel(i); break; } } UpdateOpList( iRow ); combo = (CComboBox *) GetDlgItem( RuleMatrix[iRow][COL_OP] ); combo->SetCurSel(0); for ( i = 0; i < combo->GetCount(); i++ ) { if ( (MSG_SearchOperator) combo->GetItemData(i) == op) { combo->SetCurSel(i); break; } } switch ( value.attribute ) { case attribDate: { CTime ctime( value.u.date ); date = (CNSDateEdit *) GetDlgItem( RuleMatrix[iRow][COL_VALUE] ); date->SetDate( ctime ); } break; case attribPriority: combo = (CComboBox *) GetDlgItem( RuleMatrix[iRow][COL_VALUE] ); combo->SetCurSel(0); for ( i = 0; i < combo->GetCount(); i++ ) { if ( (MSG_PRIORITY) combo->GetItemData(i) == value.u.priority ) { combo->SetCurSel(i); break; } } break; case attribMsgStatus: combo = (CComboBox *) GetDlgItem( RuleMatrix[iRow][COL_VALUE] ); for ( i = 0; i < combo->GetCount(); i++ ) { if ( combo->GetItemData(i) == value.u.msgStatus ) { combo->SetCurSel(i); break; } } break; default: widget = GetDlgItem( RuleMatrix[iRow][COL_VALUE] ); widget->SetWindowText( (const char *) value.u.string ); } } #endif void CFilterDialog::GetAction(MSG_RuleActionType *action, void **value) { CComboBox *combo; int iCurSel; MSG_FolderInfo *folderID; combo = (CComboBox *) GetDlgItem( IDC_COMBO_ACTION ); iCurSel = combo->GetCurSel(); *action = (MSG_RuleActionType) combo->GetItemData( iCurSel); switch (*action) { case acMoveToFolder: combo = (CComboBox *) GetDlgItem( IDC_COMBO_DEST ); iCurSel = combo->GetCurSel(); folderID = (MSG_FolderInfo *) combo->GetItemData( iCurSel); * (const char **) value = MSG_GetFolderNameFromID(folderID); break; case acChangePriority: combo = (CComboBox *) GetDlgItem( IDC_COMBO_DEST ); iCurSel = combo->GetCurSel(); *value = (void *) combo->GetItemData(iCurSel); break; default: *value = NULL; } } void CFilterDialog::SetAction(MSG_RuleActionType action, void *value) { CComboBox *combo; int i; BOOL bSet; combo = (CComboBox *) GetDlgItem( IDC_COMBO_ACTION ); combo->SetCurSel(0); for ( i = 0; i < combo->GetCount(); i++ ) { if ( (MSG_RuleActionType) combo->GetItemData(i) == action) { combo->SetCurSel(i); break; } } UpdateDestList(); switch ( action ) { case acMoveToFolder: combo = (CComboBox *) GetDlgItem( IDC_COMBO_DEST ); combo->SetCurSel(0); for ( i = 0; i < combo->GetCount(); i++ ) { char *folderName = (char *) value; DWORD dwItemData = combo->GetItemData(i); if (!XP_FILENAMECMP(MSG_GetFolderNameFromID((MSG_FolderInfo *) dwItemData), folderName)) { combo->SetCurSel(i); break; } } break; case acChangePriority: combo = (CComboBox *) GetDlgItem( IDC_COMBO_DEST ); combo->SetCurSel(0); bSet = FALSE; for ( i = 0; i < combo->GetCount(); i++ ) { MSG_PRIORITY priority = (MSG_PRIORITY) (int) value; if ( ((MSG_PRIORITY) combo->GetItemData(i)) == priority ) { combo->SetCurSel(i); break; } } break; default: // Do nothing break; } } BEGIN_MESSAGE_MAP(CFilterDialog, CDialog) //{{AFX_MSG_MAP(CFilterDialog) ON_BN_CLICKED(IDC_MORE, OnMore) ON_BN_CLICKED(IDC_FEWER, OnFewer) ON_BN_CLICKED(IDC_NETHELP, OnHelp) ON_BN_CLICKED(IDC_BUTTON_NEW_FOLDER, OnNewFolder) ON_CBN_DROPDOWN(IDC_COMBO_DEST, OnUpdateDest ) ON_CBN_SELCHANGE( IDC_COMBO_ACTION, OnAction ) ON_CBN_SELCHANGE( IDC_COMBO_ATTRIB1, OnAttrib1 ) ON_CBN_SELCHANGE( IDC_COMBO_ATTRIB2, OnAttrib2 ) ON_CBN_SELCHANGE( IDC_COMBO_ATTRIB3, OnAttrib3 ) ON_CBN_SELCHANGE( IDC_COMBO_ATTRIB4, OnAttrib4 ) ON_CBN_SELCHANGE( IDC_COMBO_ATTRIB5, OnAttrib5 ) ON_BN_CLICKED(IDC_RADIO_ALL, OnAndOr) ON_BN_CLICKED(IDC_RADIO_ANY, OnAndOr) ON_BN_CLICKED(IDC_ADVANCED_OPTIONS, OnAdvanced) ON_MESSAGE(WM_EDIT_CUSTOM_DONE, OnFinishedHeaders ) //}}AFX_MSG_MAP #ifndef _WIN32 ON_MESSAGE(WM_DLGSUBCLASS, OnDlgSubclass) #endif END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CFilterDialog message handlers static void GrowDialog(CWnd *pWnd, int dx, int dy) { CRect rect; pWnd->GetWindowRect(&rect); rect.bottom += dy; rect.right += dx; pWnd->MoveWindow(&rect, TRUE); pWnd->Invalidate(); } static void SlideWindow(CWnd *pWnd, int dx, int dy) { if(pWnd == NULL) return; CRect rect; CWnd *parent; pWnd->GetWindowRect(&rect); if (parent = pWnd->GetParent()) parent->ScreenToClient(&rect); rect.top += dy; rect.left += dx; rect.bottom += dy; rect.right += dx; pWnd->MoveWindow(&rect, TRUE); pWnd->Invalidate(); } void CFilterDialog::SlideBottomControls(int dy) { CWnd *widget; // Move bottom controls widget = GetDlgItem(IDC_STATIC1); SlideWindow(widget, 0, dy); widget = GetDlgItem(IDC_STATIC2); SlideWindow(widget, 0, dy); widget = GetDlgItem(IDCANCEL); SlideWindow(widget, 0, dy); widget = GetDlgItem(IDOK); SlideWindow(widget, 0, dy); widget = GetDlgItem(IDC_NETHELP); SlideWindow(widget, 0, dy); widget = GetDlgItem(IDC_EDIT_DESC); SlideWindow(widget, 0, dy); widget = GetDlgItem(IDC_COMBO_ACTION); SlideWindow(widget, 0, dy); widget = GetDlgItem(IDC_COMBO_DEST); SlideWindow(widget, 0, dy); widget = GetDlgItem(IDC_BUTTON_NEW_FOLDER); SlideWindow(widget,0,dy); widget = GetDlgItem(IDC_FEWER); SlideWindow(widget, 0, dy); widget = GetDlgItem(IDC_MORE); SlideWindow(widget, 0, dy); // Grow the dialog GrowDialog(this, 0, dy); } void CFilterDialog::OnUpdateDest() { if (m_FolderCombo.m_hWnd) { int idx = m_FolderCombo.GetCurSel(); DWORD dwData = idx >= 0 ? m_FolderCombo.GetItemData(idx) : 0; m_FolderCombo.PopulateMail( WFE_MSGGetMaster(), FALSE ); m_FolderCombo.SetCurSel(0); for ( int i = 0; i < m_FolderCombo.GetCount(); i++ ) { DWORD dwItemData = m_FolderCombo.GetItemData(i); if (dwItemData == dwData) { m_FolderCombo.SetCurSel(i); break; } } } } void CFilterDialog::OnAction() { UpdateDestList(); } void CFilterDialog::OnAttrib1() { UpdateOpList(0); } void CFilterDialog::OnAttrib2() { UpdateOpList(1); } void CFilterDialog::OnAttrib3() { UpdateOpList(2); } void CFilterDialog::OnAttrib4() { UpdateOpList(3); } void CFilterDialog::OnAttrib5() { UpdateOpList(4); } void CFilterDialog::OnAndOr() { m_bLogicType = IsDlgButtonChecked(IDC_RADIO_ALL); ChangeLogicText(); } void CFilterDialog::updateAndOr() { BOOL bEnable = GetDlgItem(IDC_COMBO_ATTRIB2)->IsWindowVisible(); GetDlgItem(IDC_RADIO_ANY)->EnableWindow(bEnable); GetDlgItem(IDC_RADIO_ALL)->EnableWindow(bEnable); } void CFilterDialog::OnMore() { // TODO: Add your control notification handler code here CWnd *widget; CRect rect, rect2; int j, dy; CString strLogicText; // Calculate how much we need to expand for a new rule widget = GetDlgItem(RuleMatrix[m_iRowIndex][0]); widget->GetWindowRect(&rect); m_iRowIndex++; for (j = 0; j < COL_COUNT; j++) { widget = GetDlgItem(RuleMatrix[m_iRowIndex][j]); if(widget == NULL) continue; if (j == 3 && m_bLogicType) { strLogicText.LoadString(IDS_ANDTHE); widget->SetWindowText(strLogicText); } else if ( j==3 && !m_bLogicType) { //change the logic text for this new rule line to OR strLogicText.LoadString(IDS_ORTHE); widget->SetWindowText(strLogicText); } widget->ShowWindow(SW_SHOW); } widget = GetDlgItem(RuleMatrix[m_iRowIndex][0]); widget->GetWindowRect(&rect2); dy = rect2.top - rect.top; SlideBottomControls(dy); if (m_iRowIndex > 3) { widget = GetDlgItem(IDC_MORE); widget->EnableWindow(FALSE); } widget = GetDlgItem(IDC_FEWER); widget->EnableWindow(TRUE); updateAndOr(); Invalidate(); } void CFilterDialog::OnFewer() { // TODO: Add your control notification handler code here CWnd *widget; CRect rect, rect2; int j, dy; // Calculate how much we need to expand for a new rule widget = GetDlgItem(RuleMatrix[m_iRowIndex][0]); widget->GetWindowRect(&rect); for (j = 0; j < COL_COUNT; j++) { widget = GetDlgItem(RuleMatrix[m_iRowIndex][j]); if(widget == NULL) continue; widget->ShowWindow(SW_HIDE); } m_iRowIndex--; widget = GetDlgItem(RuleMatrix[m_iRowIndex][0]); widget->GetWindowRect(&rect2); dy = rect2.top - rect.top; SlideBottomControls(dy); if (m_iRowIndex < 1) { widget = GetDlgItem(IDC_FEWER); widget->EnableWindow(FALSE); } widget = GetDlgItem(IDC_MORE); widget->EnableWindow(TRUE); updateAndOr(); Invalidate(); } void CFilterDialog::OnAdvanced() { MSG_Master *master = WFE_MSGGetMaster(); //find out if we are the only ones trying to edit headers. if (master) { if (!MSG_AcquireEditHeadersSemaphore(master, this)) { ::MessageBox(FEU_GetLastActiveFrame()->GetSafeHwnd(), szLoadString(IDS_EDIT_HEADER_IN_USE), szLoadString(IDS_CUSTOM_HEADER_ERROR), MB_OK|MB_ICONSTOP); return; //We can't edit anything since another window already has the semaphore. } } else { //Something is hosed! return; } CString title; title.LoadString(IDS_ADVFILTER_PROPERTY_SHEET); // it will delete itself in OnNcDestroy. This is a way to have two "modal" dialogs CAdvancedOptionsPropertySheet * paops = new CAdvancedOptionsPropertySheet(this, title, AOP_CUSTOM_HEADERS); assert(paops != NULL); if(paops != NULL) paops->Create(this); } void CFilterDialog::OnHelp() { NetHelp(HELP_FILTER_RULES); } void CFilterDialog::OnOK() { CDialog::OnOK(); // TODO: Add extra validation here if (*m_hFilter != NULL) { MSG_DestroyFilter( *m_hFilter ); } MSG_FilterType filterType = GetFolderFilterType(); MSG_CreateFilter(filterType, (char *) (const char *) m_lpszFilterName, m_hFilter); int i; MSG_Rule *rule; MSG_SetFilterDesc( *m_hFilter, (char *) (const char *) m_lpszFilterDesc ); MSG_EnableFilter( *m_hFilter, m_iActive ? TRUE : FALSE ); MSG_GetFilterRule( *m_hFilter, &rule ); MSG_SearchAttribute attrib; MSG_SearchOperator op; MSG_SearchValue value; char szHeader[67]; for (i = 0; i < GetNumTerms(); i++) { //TODO add support for arbitrary headers #ifdef FE_IMPLEMENTS_BOOLEAN_OR GetTerm(i, &attrib, &op, &value, szHeader); MSG_RuleAddTerm( rule, attrib, op, &value, m_bLogicType, szHeader); //~~ #else GetTerm(i, &attrib, &op, &value); MSG_RuleAddTerm( rule, attrib, op, &value); #endif } MSG_RuleActionType action; void *value2; GetAction( &action, &value2 ), MSG_RuleSetAction( rule, action, value2 ); } #ifndef _WIN32 LRESULT CFilterDialog::OnDlgSubclass(WPARAM wParam, LPARAM lParam) { *(int FAR*) lParam = 0; return 0; } #endif