|
|
///////////////////////////////////////////////////////////////////////////////
//
// EditRule.cpp
//
///////////////////////////////////////////////////////////////////////////////
#include <pch.hxx>
#include "editrule.h"
#include "ruledesc.h"
#include "ruleutil.h"
#include "reutil.h"
#include <rulesdlg.h>
#include <imagelst.h>
#include "shlwapip.h"
#include <instance.h>
#include <demand.h>
// Constants
static const int c_cCritItemGrow = 16; static const int c_cActItemGrow = 16; const static HELPMAP g_rgCtxMapEditRule[] = { {idlvCriteria, idhCriteriaRule}, {idlvActions, idhActionsRule}, {idredtDescription, idhDescriptionRule}, {idedtRuleName, idhRuleName}, {0, 0}}; const static HELPMAP g_rgCtxMapEditView[] = { {idlvCriteria, idhCriteriaView}, {idredtDescription, idhDescriptionView}, {idedtRuleName, idhViewName}, {0, 0}}; // The methods for the Rules Editor UI
CEditRuleUI::CEditRuleUI() : m_hwndOwner(NULL), m_dwFlags(0), m_dwState(STATE_UNINIT), m_typeRule(RULE_TYPE_MAIL), m_hwndCrit(NULL), m_hwndAct(NULL), m_hwndDescript(NULL), m_hwndName(NULL), m_pIRule(NULL), m_pDescriptUI(NULL) { ZeroMemory(m_rgfCritEnabled, sizeof(m_rgfCritEnabled)); ZeroMemory(m_rgfActEnabled, sizeof(m_rgfActEnabled)); }
CEditRuleUI::~CEditRuleUI() { SafeRelease(m_pIRule); if (NULL != m_pDescriptUI) { delete m_pDescriptUI; } }
///////////////////////////////////////////////////////////////////////////////
//
// HrInit
//
// This initializes us with the owner window and any flags we might have
//
// hwndOwner - handle to the owner window
// dwFlags - flags to use for this instance
// typeRule - the type of rule editor to create
// pIRule - the rule to edit
// pmsginfo - the message to create the rule from
//
// Returns: S_OK
//
///////////////////////////////////////////////////////////////////////////////
HRESULT CEditRuleUI::HrInit(HWND hwndOwner, DWORD dwFlags, RULE_TYPE typeRule, IOERule * pIRule, MESSAGEINFO * pmsginfo) { HRESULT hr = S_OK; // If we're already initialized, then fail
if ((0 != (m_dwState & STATE_INITIALIZED)) || (NULL == pIRule)) { hr = E_FAIL; goto exit; }
// Save off the owner window
m_hwndOwner = hwndOwner; // Save off the flags
m_dwFlags = dwFlags;
// Save off the type of rule to edit
m_typeRule = typeRule;
Assert(NULL == m_pDescriptUI); m_pDescriptUI = new CRuleDescriptUI; if (NULL == m_pDescriptUI) { hr = E_OUTOFMEMORY; goto exit; }
// Save off the rule
Assert(NULL == m_pIRule); m_pIRule = pIRule; pIRule->AddRef(); // We're done
m_dwState |= STATE_INITIALIZED;
hr = S_OK; exit: return hr; }
///////////////////////////////////////////////////////////////////////////////
//
// HrShow
//
// This brings up the rules editor UI
//
// Returns: S_OK, if IDOK was selected
// otherwise, S_FALSE
//
///////////////////////////////////////////////////////////////////////////////
HRESULT CEditRuleUI::HrShow(void) { HRESULT hr = S_OK; int iRet = 0;
// If we aren't initialized, then fail
if (0 == (m_dwState & STATE_INITIALIZED)) { hr = E_FAIL; goto exit; }
// We need to load richedit
if (FALSE == FInitRichEdit(TRUE)) { hr = E_FAIL; goto exit; }
iRet = (INT) DialogBoxParam(g_hLocRes, (RULE_TYPE_FILTER == m_typeRule) ? MAKEINTRESOURCE(iddEditView) : MAKEINTRESOURCE(iddEditRule), m_hwndOwner, CEditRuleUI::FEditRuleDlgProc, (LPARAM)this); if (-1 == iRet) { hr = E_FAIL; goto exit; }
// Set the proper return code
hr = (IDOK == iRet) ? S_OK : S_FALSE; exit: return hr; }
///////////////////////////////////////////////////////////////////////////////
//
// FEditRuleDlgProc
//
// This is the main dialog proc for the rules editor dialog
//
// hwndDlg - handle to the filter manager dialog
// uMsg - the message to be acted upon
// wParam - the 'word' parameter for the message
// lParam - the 'long' parameter for the message
//
// Returns: TRUE, if the message was handled
// FALSE, otherwise
//
///////////////////////////////////////////////////////////////////////////////
INT_PTR CALLBACK CEditRuleUI::FEditRuleDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { BOOL fRet = FALSE; CEditRuleUI * pEditRuleUI = NULL; LPNMHDR pnmhdr = NULL; LPNMLISTVIEW pnmlv = NULL; LVHITTESTINFO lvh; NMLVKEYDOWN * pnmlvkd = NULL; int nIndex = 0; HWND hwndRE = 0;
pEditRuleUI = (CEditRuleUI *) GetWindowLongPtr(hwndDlg, GWLP_USERDATA); switch (uMsg) { case WM_INITDIALOG: // Grab the UI object pointer
pEditRuleUI = (CEditRuleUI *) lParam;
// Set it into the dialog so we can get it back
SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR) pEditRuleUI);
hwndRE = CreateREInDialogA(hwndDlg, idredtDescription);
if (!hwndRE || (FALSE == pEditRuleUI->FOnInitDialog(hwndDlg))) { EndDialog(hwndDlg, -1); fRet = TRUE; goto exit; } // We didn't set the focus so return TRUE
fRet = TRUE; break; case WM_COMMAND: switch (LOWORD(wParam)) { case idedtRuleName: if (EN_CHANGE == HIWORD(wParam)) { pEditRuleUI->FOnNameChange((HWND) lParam); } break; case IDCANCEL: EndDialog(hwndDlg, IDCANCEL); fRet = TRUE; break; case IDOK: if (FALSE != pEditRuleUI->FOnOK()) { EndDialog(hwndDlg, IDOK); fRet = TRUE; } break; } break;
case WM_NOTIFY: pnmhdr = (LPNMHDR) lParam; switch (((LPNMHDR)lParam)->code) { case NM_CLICK: if ((idlvCriteria == GetDlgCtrlID(pnmhdr->hwndFrom)) || (idlvActions == GetDlgCtrlID(pnmhdr->hwndFrom))) { pnmlv = (LPNMLISTVIEW) lParam; pEditRuleUI->FOnListClick(pnmhdr->hwndFrom, pnmlv); } break;
case NM_DBLCLK: if ((idlvCriteria == GetDlgCtrlID(pnmhdr->hwndFrom)) || (idlvActions == GetDlgCtrlID(pnmhdr->hwndFrom))) { pnmlv = (LPNMLISTVIEW) lParam; ZeroMemory(&lvh, sizeof(lvh)); lvh.pt = pnmlv->ptAction; ListView_HitTest(pnmhdr->hwndFrom, &lvh); if ((-1 != pnmlv->iItem) && (0 != (lvh.flags & LVHT_ONITEMLABEL))) { pEditRuleUI->HandleEnabledState(pnmhdr->hwndFrom, pnmlv->iItem); } } break; case LVN_KEYDOWN: if ((idlvCriteria == GetDlgCtrlID(pnmhdr->hwndFrom)) || (idlvActions == GetDlgCtrlID(pnmhdr->hwndFrom))) { pnmlvkd = (NMLVKEYDOWN *) lParam; if (VK_SPACE == pnmlvkd->wVKey) { nIndex = ListView_GetNextItem(pnmhdr->hwndFrom, -1, LVNI_SELECTED); if (0 <= nIndex) { pEditRuleUI->HandleEnabledState(pnmhdr->hwndFrom, nIndex); } } } break; } break; case WM_HELP: case WM_CONTEXTMENU: fRet = pEditRuleUI->FOnHelp(uMsg, wParam, lParam); break; } exit: return fRet; }
///////////////////////////////////////////////////////////////////////////////
//
// FOnInitDialog
//
// This is the initialization routine for the rules editor dialog
//
// hwndDlg - handle to the rules editor dialog
//
// Returns: TRUE, if the dialog was initialized successfully
// FALSE, otherwise
//
///////////////////////////////////////////////////////////////////////////////
BOOL CEditRuleUI::FOnInitDialog(HWND hwndDlg) { BOOL fRet = FALSE; PROPVARIANT propvar = {0}; INT iSelect = 0;
// Check incoming params
if (NULL == hwndDlg) { fRet = FALSE; goto exit; } // Save off the dialog window handle
m_hwndDlg = hwndDlg; // Set the default font onto the dialog
SetIntlFont(m_hwndDlg);
// Save off some of the controls
m_hwndCrit = GetDlgItem(m_hwndDlg, idlvCriteria); if (RULE_TYPE_FILTER != m_typeRule) { m_hwndAct = GetDlgItem(hwndDlg, idlvActions); } m_hwndDescript = GetDlgItem(hwndDlg, idredtDescription); m_hwndName = GetDlgItem(hwndDlg, idedtRuleName); if ((NULL == m_hwndCrit) || ((RULE_TYPE_FILTER != m_typeRule) && (NULL == m_hwndAct)) || (NULL == m_hwndDescript) || (NULL == m_hwndName)) { fRet = FALSE; goto exit; } // Initialize criteria listbox control
if (FALSE == _FInitializeCritListCtrl()) { fRet = FALSE; goto exit; } // Initialize criteria listbox control
if (RULE_TYPE_FILTER != m_typeRule) { if (FALSE == _FInitializeActListCtrl()) { fRet = FALSE; goto exit; } }
// Load the criteria listbox control
if (FALSE == _FLoadCritListCtrl(&iSelect)) { fRet = FALSE; goto exit; }
_SetTitleText(); // Select the default item in the criteria list
ListView_SetItemState(m_hwndCrit, iSelect, LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED); // Make sure the default item is visible
ListView_EnsureVisible(m_hwndCrit, iSelect, FALSE); // Initialize the description field
if (FAILED(m_pDescriptUI->HrInit(m_hwndDescript, 0))) { fRet = FALSE; goto exit; } if (FAILED(m_pDescriptUI->HrSetRule(m_typeRule, m_pIRule))) { fRet = FALSE; goto exit; }
// If we are a filter and are new
if ((RULE_TYPE_FILTER == m_typeRule) && (0 != (m_dwFlags & ERF_ADDDEFAULTACTION))) { // Set the default action
if (FAILED(m_pDescriptUI->HrEnableActions(ACT_TYPE_SHOW, TRUE))) { goto exit; } }
m_pDescriptUI->ShowDescriptionString();
// Initialize the name field
if (FAILED(m_pIRule->GetProp(RULE_PROP_NAME, 0, &propvar))) { fRet = FALSE; goto exit; }
if ((VT_LPSTR != propvar.vt) || (NULL == propvar.pszVal) || ('\0' == propvar.pszVal[0])) { fRet = FALSE; goto exit; }
Edit_SetText(m_hwndName, propvar.pszVal); // Everything's AOK
fRet = TRUE; exit: PropVariantClear(&propvar); return fRet; }
///////////////////////////////////////////////////////////////////////////////
//
// FOnListClick
//
// This handles clicking on either of the lists
//
// Returns: TRUE, we handled the click message
// FALSE, otherwise
//
///////////////////////////////////////////////////////////////////////////////
BOOL CEditRuleUI::FOnListClick(HWND hwndList, LPNMLISTVIEW pnmlv) { BOOL fRet = FALSE; int iIndex = 0; int iSelected = 0; LVHITTESTINFO lvh;
Assert(NULL != m_hwndCrit); if ((NULL == hwndList) || (NULL == pnmlv)) { fRet = FALSE; goto exit; } ZeroMemory(&lvh, sizeof(lvh)); lvh.pt = pnmlv->ptAction; iIndex = ListView_HitTest(hwndList, &lvh); if (-1 == iIndex) { fRet = FALSE; goto exit; } // Let's make sure this item is already selected
iSelected = ListView_GetNextItem(hwndList, -1, LVNI_SELECTED); if (iSelected != iIndex) { ListView_SetItemState(hwndList, iIndex, LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED); }
if ((lvh.flags & LVHT_ONITEMSTATEICON) && !(lvh.flags & LVHT_ONITEMLABEL)) { HandleEnabledState(hwndList, iIndex); fRet = TRUE; } else { fRet = FALSE; }
exit: return fRet; }
///////////////////////////////////////////////////////////////////////////////
//
// FOnOK
//
// This handles clicking on the links in the description field
//
// Returns: TRUE, we handled the click message
// FALSE, otherwise
//
///////////////////////////////////////////////////////////////////////////////
BOOL CEditRuleUI::FOnOK(void) { BOOL fRet = FALSE; TCHAR szRes[CCHMAX_STRINGRES + 5]; TCHAR szName[CCHMAX_STRINGRES + 5]; ULONG cchRes = 0; ULONG ulIndex = 0; IOERule * pIRule = NULL; PROPVARIANT propvar; HRESULT hr = S_OK; CRIT_ITEM * pCritItem = NULL; ULONG cCritItem = 0; ACT_ITEM * pActItem = NULL; ULONG cActItem = 0; BOOL fNewRule = FALSE; LPSTR pszName = NULL; ULONG cchName = 0; ZeroMemory(&propvar, sizeof(propvar)); if (NULL == m_pIRule) { fRet = FALSE; goto exit; }
// First let's validate the name and all the criteria and actions
// Get the name from the edit well
cchName = Edit_GetTextLength(m_hwndName) + 1; if (FAILED(HrAlloc((void **) &pszName, cchName * sizeof(*pszName)))) { fRet = FALSE; goto exit; } pszName[0] = '\0'; cchName = Edit_GetText(m_hwndName, pszName, cchName); // Check to see if the name is valid
if (0 == UlStripWhitespace(pszName, TRUE, TRUE, NULL)) { // Put up a message saying something is busted
AthMessageBoxW(m_hwndDlg, MAKEINTRESOURCEW(idsAthenaMail), (RULE_TYPE_FILTER != m_typeRule) ? MAKEINTRESOURCEW(idsRulesErrorNoName) : MAKEINTRESOURCEW(idsViewsErrorNoName), NULL, MB_OK | MB_ICONINFORMATION); fRet = FALSE; goto exit; }
// Let's make sure they have the right parts
// Get the criteria for the rule
hr = m_pDescriptUI->HrGetCriteria(&pCritItem, &cCritItem); if (FAILED(hr)) { fRet = FALSE; goto exit; }
// Do we have any criteria
if (0 == cCritItem) { // Put up a message saying something is busted
AthMessageBoxW(m_hwndDlg, MAKEINTRESOURCEW(idsAthenaMail), (RULE_TYPE_FILTER != m_typeRule) ? MAKEINTRESOURCEW(idsRulesErrorNoCriteria) : MAKEINTRESOURCEW(idsViewsErrorNoCriteria), NULL, MB_OK | MB_ICONINFORMATION); fRet = FALSE; goto exit; } // Get the actions for the rule
hr = m_pDescriptUI->HrGetActions(&pActItem, &cActItem); if (FAILED(hr)) { fRet = FALSE; goto exit; } // Do we have any criteria
if (0 == cActItem) { // Put up a message saying something is busted
AthMessageBoxW(m_hwndDlg, MAKEINTRESOURCEW(idsAthenaMail), (RULE_TYPE_FILTER != m_typeRule) ? MAKEINTRESOURCEW(idsRulesErrorNoActions) : MAKEINTRESOURCEW(idsViewsErrorNoActions), NULL, MB_OK | MB_ICONINFORMATION); fRet = FALSE; goto exit; }
// Let's check to see if we really need to do anything
hr = m_pDescriptUI->HrIsDirty(); if (FAILED(hr)) { fRet = FALSE; goto exit; } if ((0 == (m_dwState & STATE_DIRTY)) && (S_FALSE == hr)) { fRet = TRUE; goto exit; } hr = m_pDescriptUI->HrVerifyRule(); if (S_OK != hr) { // Put up a message saying something is busted
AthMessageBoxW(m_hwndDlg, MAKEINTRESOURCEW(idsAthenaMail), MAKEINTRESOURCEW(idsRulesErrorFix), NULL, MB_OK | MB_ICONINFORMATION); m_pDescriptUI->ShowDescriptionString(); fRet = FALSE; goto exit; }
// Set the criteria on the rule
PropVariantClear(&propvar); propvar.vt = VT_BLOB; propvar.blob.cbSize = cCritItem * sizeof(CRIT_ITEM); propvar.blob.pBlobData = (BYTE *) pCritItem; hr = m_pIRule->SetProp(RULE_PROP_CRITERIA, 0, &propvar); ZeroMemory(&propvar, sizeof(propvar)); if (FAILED(hr)) { fRet = FALSE; goto exit; }
// Set the actions on the rule
PropVariantClear(&propvar); propvar.vt = VT_BLOB; propvar.blob.cbSize = cActItem * sizeof(ACT_ITEM); propvar.blob.pBlobData = (BYTE *) pActItem; hr = m_pIRule->SetProp(RULE_PROP_ACTIONS, 0, &propvar); ZeroMemory(&propvar, sizeof(propvar)); if (FAILED(hr)) { fRet = FALSE; goto exit; } // Set the rule name
PropVariantClear(&propvar); propvar.vt = VT_LPSTR; propvar.pszVal = pszName; hr = m_pIRule->SetProp(RULE_PROP_NAME, 0, &propvar); ZeroMemory(&propvar, sizeof(propvar)); if (FAILED(hr)) { fRet = FALSE; goto exit; } // Make sure we clear out the fact that we saved the rule
m_pDescriptUI->HrClearDirty();
// Note that we saved
m_dwState &= ~STATE_DIRTY; // Set the proper return value
fRet = TRUE;
exit: RuleUtil_HrFreeCriteriaItem(pCritItem, cCritItem); SafeMemFree(pCritItem); RuleUtil_HrFreeActionsItem(pActItem, cActItem); SafeMemFree(pActItem); PropVariantClear(&propvar); SafeMemFree(pszName); return fRet; }
///////////////////////////////////////////////////////////////////////////////
//
// FOnHelp
//
// This handles the WM_HELP message for the rules edit UI dialog
//
// Returns: TRUE, if it was successfully destroyed
// FALSE, otherwise
//
///////////////////////////////////////////////////////////////////////////////
BOOL CEditRuleUI::FOnHelp(UINT uiMsg, WPARAM wParam, LPARAM lParam) { return(OnContextHelp(m_hwndDlg, uiMsg, wParam, lParam, (RULE_TYPE_FILTER == m_typeRule) ? g_rgCtxMapEditView : g_rgCtxMapEditRule)); }
///////////////////////////////////////////////////////////////////////////////
//
// FOnNameChange
//
// This handles the user typing into the name field
//
// Returns: TRUE, we handled the edit message
// FALSE, otherwise
//
///////////////////////////////////////////////////////////////////////////////
BOOL CEditRuleUI::FOnNameChange(HWND hwndName) { BOOL fRet = FALSE;
Assert(NULL != m_hwndName); Assert(hwndName == m_hwndName);
// Note that we're dirty
m_dwState |= STATE_DIRTY; // Disable the OK button if the name is empty
fRet = RuleUtil_FEnDisDialogItem(m_hwndDlg, IDOK, 0 != Edit_GetTextLength(m_hwndName));
return fRet; }
///////////////////////////////////////////////////////////////////////////////
//
// HandleEnabledState
//
// This switches the current enabled state of the list view item
// and updates the UI
//
// nIndex - index of the item in the listview to work on
//
// Returns: NONE
//
///////////////////////////////////////////////////////////////////////////////
void CEditRuleUI::HandleEnabledState(HWND hwndList, int nItem) { HRESULT hr = S_OK; LVITEM lvi; BOOL fEnabled = FALSE; INT iIndex = 0; LONG lItem = 0; INT cItems = 0;
// Grab the list view item
ZeroMemory(&lvi, sizeof(lvi)); lvi.mask = LVIF_STATE | LVIF_PARAM; lvi.stateMask = LVIS_STATEIMAGEMASK; lvi.iItem = nItem; if (FALSE == ListView_GetItem(hwndList, &lvi)) { goto exit; }
lItem = (LONG) lvi.lParam; if (INDEXTOSTATEIMAGEMASK(iiconStateDisabled+1) == lvi.state) { goto exit; } // Get the new enabled value
fEnabled = (lvi.state != INDEXTOSTATEIMAGEMASK(iiconStateChecked+1));
// Build up the description string
if (hwndList == m_hwndCrit) { if (FALSE == _FAddCritToList(nItem, fEnabled)) { goto exit; } } else { // Set the UI to the opposite enabled state
ZeroMemory(&lvi, sizeof(lvi)); lvi.mask = LVIF_STATE; lvi.iItem = nItem; lvi.state = fEnabled ? INDEXTOSTATEIMAGEMASK(iiconStateChecked+1) : INDEXTOSTATEIMAGEMASK(iiconStateUnchecked+1); lvi.stateMask = LVIS_STATEIMAGEMASK; ListView_SetItem(hwndList, &lvi);
// Figure out the number of items in the list
cItems = ListView_GetItemCount(hwndList);
Assert(hwndList == m_hwndAct); m_pDescriptUI->HrEnableActions(c_rgEditActList[lItem].typeAct, fEnabled); // Do we need to go through and update all the items?
if (0 != (c_rgEditActList[lItem].dwFlags & STATE_EXCLUSIVE)) { for (iIndex = 0; iIndex < cItems; iIndex++) { // We already handled this one
if (iIndex == nItem) { continue; } // Change the state
lvi.mask = LVIF_STATE; lvi.iItem = iIndex; lvi.state = fEnabled ? INDEXTOSTATEIMAGEMASK(iiconStateDisabled+1) : INDEXTOSTATEIMAGEMASK(iiconStateUnchecked+1); lvi.stateMask = LVIS_STATEIMAGEMASK; ListView_SetItem(hwndList, &lvi);
if (FALSE != fEnabled) { // Figure out which action the item corresponds to
lvi.mask = LVIF_PARAM; lvi.iItem = iIndex; if ((FALSE != ListView_GetItem(hwndList, &lvi)) && (lvi.lParam >= 0) && (lvi.lParam < c_cEditActList)) { m_pDescriptUI->HrEnableActions(c_rgEditActList[lvi.lParam].typeAct, FALSE); } } } } }
// Note that we're dirty
m_dwState |= STATE_DIRTY; exit: return; }
///////////////////////////////////////////////////////////////////////////////
//
// _FInitializeCritListCtrl
//
// This initializes the criteria list view with the list of criteria
//
// Returns: TRUE, if it was successfully loaded
// FALSE, otherwise
//
///////////////////////////////////////////////////////////////////////////////
BOOL CEditRuleUI::_FInitializeCritListCtrl(void) { BOOL fRet = FALSE; LVCOLUMN lvc = {0}; RECT rc = {0}; HIMAGELIST himl = NULL; LVITEM lvi = {0}; TCHAR szRes[CCHMAX_STRINGRES]; UINT uiEditCritList = 0; const CRIT_LIST * pCritList = NULL; UINT cchRes = 0; LPTSTR pszMark = NULL;
Assert(NULL != m_hwndCrit);
// Initialize the list view column structure
ZeroMemory(&lvc, sizeof(lvc)); lvc.mask = LVCF_WIDTH;
// Calculate the size of the list view
GetClientRect(m_hwndCrit, &rc); lvc.cx = rc.right - GetSystemMetrics(SM_CXVSCROLL);
ListView_InsertColumn(m_hwndCrit, 0, &lvc);
// Set the state image list
himl = ImageList_LoadBitmap(g_hLocRes, MAKEINTRESOURCE(idb16x16st), 16, 0, RGB(255, 0, 255)); if (NULL != himl) { ListView_SetImageList(m_hwndCrit, himl, LVSIL_STATE); }
// Full row selection on listview
ListView_SetExtendedListViewStyle(m_hwndCrit, LVS_EX_FULLROWSELECT);
// Initialize the list view item structure
lvi.mask = LVIF_TEXT | LVIF_PARAM | LVIF_STATE; lvi.stateMask = LVIS_STATEIMAGEMASK; lvi.state = INDEXTOSTATEIMAGEMASK(iiconStateUnchecked+1); lvi.pszText = szRes; // Add each criteria to the list view
for (uiEditCritList = 0; uiEditCritList < ARRAYSIZE(c_rgEditCritList); uiEditCritList++) { pCritList = &(c_rgEditCritList[uiEditCritList]);
// Is this item editable
if (0 != (pCritList->dwFlags & STATE_NOEDIT)) { continue; } // Is this criteria valid for this type of rule?
if (((RULE_TYPE_MAIL == m_typeRule) && (0 == (pCritList->dwFlags & STATE_MAIL))) || ((RULE_TYPE_NEWS == m_typeRule) && (0 == (pCritList->dwFlags & STATE_NEWS))) || ((RULE_TYPE_FILTER == m_typeRule) && (0 == (pCritList->dwFlags & STATE_FILTER)))) { continue; } // Load up the string to use.
cchRes = LoadString(g_hLocRes, pCritList->uiText, szRes, ARRAYSIZE(szRes)); if (0 == cchRes) { continue; }
// Parse out the string mark
pszMark = StrStr(szRes, c_szRuleMarkStart); while (NULL != pszMark) { // Remove the mark start
StrCpyN(pszMark, pszMark + lstrlen(c_szRuleMarkStart), (DWORD)(ARRAYSIZE(szRes) - (pszMark - szRes)));
// Search for the mark end
pszMark = StrStr(pszMark, c_szRuleMarkEnd); if (NULL == pszMark) { fRet = FALSE; goto exit; } // Remove the mark end
StrCpyN(pszMark, pszMark + lstrlen(c_szRuleMarkEnd), (DWORD)(ARRAYSIZE(szRes) - (pszMark - szRes))); // Search for the mark start
pszMark = StrStr(pszMark, c_szRuleMarkStart); } lvi.cchTextMax = lstrlen(szRes); lvi.lParam = (LONG) uiEditCritList;
if (-1 != ListView_InsertItem(m_hwndCrit, &lvi)) { lvi.iItem++; } }
fRet = TRUE; exit: return fRet; }
///////////////////////////////////////////////////////////////////////////////
//
// _FLoadCritListCtrl
//
// This load the criteria list view with the list of criteria
//
// Returns: TRUE, if it was successfully loaded
// FALSE, otherwise
//
///////////////////////////////////////////////////////////////////////////////
BOOL CEditRuleUI::_FLoadCritListCtrl(INT * piSelect) { BOOL fRet = FALSE; PROPVARIANT propvar = {0}; CRIT_ITEM * pCritItem = NULL; ULONG cCritItem = 0; BOOL fExclusive = FALSE; INT cItems = 0; LVITEM lvi = {0}; ULONG ulIndex = 0; INT iSelect = 0; DWORD dwState = 0; TCHAR szRes[CCHMAX_STRINGRES]; INT iItem = 0; Assert(NULL != m_hwndCrit); Assert(NULL != piSelect);
// Initialize the outgoing param
*piSelect = 0;
// Make sure we have something to do...
if (NULL == m_pIRule) { fRet = TRUE; goto exit; } // Get the criteria from the rule
if (FAILED(m_pIRule->GetProp(RULE_PROP_CRITERIA, 0, &propvar))) { fRet = FALSE; goto exit; }
// Do we have anything to do?
if (0 == propvar.blob.cbSize) { fRet = TRUE; goto exit; }
Assert(NULL != propvar.blob.pBlobData); cCritItem = propvar.blob.cbSize / sizeof(CRIT_ITEM); pCritItem = (CRIT_ITEM *) (propvar.blob.pBlobData); // Do we have any exclusive criteria set?
if (1 == cCritItem) { // Find the criteria item in the list
for (ulIndex = 0; ulIndex < ARRAYSIZE(c_rgEditCritList); ulIndex++) { // Is this the criteria item?
if ((pCritItem->type == c_rgEditCritList[ulIndex].typeCrit) && (0 != (c_rgEditCritList[ulIndex].dwFlags & STATE_EXCLUSIVE))) { fExclusive = TRUE; break; } } } // Figure out how many items are in the list control
cItems = ListView_GetItemCount(m_hwndCrit); iSelect = cItems; // Initialize the list view item structure
lvi.mask = LVIF_PARAM | LVIF_STATE; lvi.stateMask = LVIS_STATEIMAGEMASK; // If we're exclusive
if (FALSE != fExclusive) { // Disable each of the items
// except for the exclusive one
for (lvi.iItem = 0; lvi.iItem < cItems; lvi.iItem++) { if (FALSE == ListView_GetItem(m_hwndCrit, &lvi)) { continue; }
// Is this the criteria item?
if (pCritItem->type == c_rgEditCritList[lvi.lParam].typeCrit) { dwState = INDEXTOSTATEIMAGEMASK(iiconStateChecked+1); // Is this the first item we found in the list
if (iSelect > lvi.iItem) { iSelect = lvi.iItem; } } else { dwState = INDEXTOSTATEIMAGEMASK(iiconStateDisabled+1); }
// Set the state
ListView_SetItemState(m_hwndCrit, lvi.iItem, dwState, LVIS_STATEIMAGEMASK); } } else { // Add each criteria to the list view
for (ulIndex = 0; ulIndex < cCritItem; ulIndex++) { // Find the criteria item in the list
for (lvi.iItem = 0; lvi.iItem < cItems; lvi.iItem++) { if (FALSE == ListView_GetItem(m_hwndCrit, &lvi)) { continue; }
// Is this the criteria item?
if ((pCritItem[ulIndex].type == c_rgEditCritList[lvi.lParam].typeCrit) && (INDEXTOSTATEIMAGEMASK(iiconStateUnchecked+1) == lvi.state)) { break; } }
// Did we find anything?
if (lvi.iItem >= cItems) { fRet = FALSE; goto exit; }
// Save off the item
iItem = lvi.iItem; // Is this the first item we found in the list
if (iSelect > iItem) { iSelect = iItem; }
#ifdef NEVER
// Can we add multiple items?
if (0 == (c_rgEditCritList[lvi.lParam].dwFlags & STATE_NODUPS)) { // Regrab the item
lvi.mask = LVIF_TEXT | LVIF_PARAM | LVIF_STATE; lvi.stateMask = LVIS_STATEIMAGEMASK; lvi.pszText = szRes; lvi.cchTextMax = sizeof(szRes);
if (FALSE == ListView_GetItem(m_hwndCrit, &lvi)) { continue; }
// Add the item to the list
// Fix up the item to insert into the list
lvi.state = INDEXTOSTATEIMAGEMASK(iiconStateUnchecked+1);
// Insert the item into the list
lvi.iItem++; if (-1 == ListView_InsertItem(m_hwndCrit, &lvi)) { fRet = FALSE; goto exit; }
// Add one since we just added an item
cItems++; } #endif // NEVER
// Set the state
ListView_SetItemState(m_hwndCrit, iItem, INDEXTOSTATEIMAGEMASK(iiconStateChecked+1), LVIS_STATEIMAGEMASK); } }
// Set the outgoing param
*piSelect = iSelect; // Set the return value
fRet = TRUE; exit: RuleUtil_HrFreeCriteriaItem(pCritItem, cCritItem); SafeMemFree(pCritItem); return fRet; }
///////////////////////////////////////////////////////////////////////////////
//
// _FAddRuleToList
//
// This adds the view passed in to the list view
//
// dwIndex - the index on where to add the view to into the list
// pIRule - the actual view
//
// Returns: TRUE, if it was successfully added
// FALSE, otherwise
//
///////////////////////////////////////////////////////////////////////////////
BOOL CEditRuleUI::_FAddCritToList(INT iItem, BOOL fEnable) { BOOL fRet = FALSE; LVITEM lvitem = {0}; TCHAR szRes[CCHMAX_STRINGRES]; INT cItems = 0; LVITEM lvi = {0}; DWORD dwState = 0;
Assert(NULL != m_hwndCrit);
// If there's nothing to do...
if (-1 == iItem) { fRet = FALSE; goto exit; } // Initialize the list view item structure
lvitem.mask = LVIF_TEXT | LVIF_PARAM | LVIF_STATE; lvitem.iItem = iItem; lvitem.stateMask = LVIS_STATEIMAGEMASK; lvitem.pszText = szRes; lvitem.cchTextMax = sizeof(szRes); // Get the item from the list
if (FALSE == ListView_GetItem(m_hwndCrit, &lvitem)) { fRet = FALSE; goto exit; }
if (INDEXTOSTATEIMAGEMASK(iiconStateDisabled+1) == lvitem.state) { fRet = TRUE; goto exit; } // Do we need to go through and update all the items?
if (0 != (c_rgEditCritList[lvitem.lParam].dwFlags & STATE_EXCLUSIVE)) { // Figure out how many items are in the list control
cItems = ListView_GetItemCount(m_hwndCrit); // Initialize the list view item structure
lvi.mask = LVIF_PARAM | LVIF_STATE; lvi.stateMask = LVIS_STATEIMAGEMASK; // For each item in the list
for (lvi.iItem = 0; lvi.iItem < cItems; lvi.iItem++) { // Get the item from the list
if (FALSE == ListView_GetItem(m_hwndCrit, &lvi)) { fRet = FALSE; goto exit; }
// We'll handle this item later
if (lvitem.lParam == lvi.lParam) { iItem = lvi.iItem; continue; } // If it's enabled
if (INDEXTOSTATEIMAGEMASK(iiconStateChecked + 1) == lvi.state) { // Remove it from the criteria
if (FAILED(m_pDescriptUI->HrEnableCriteria(c_rgEditCritList[lvi.lParam].typeCrit, FALSE))) { fRet = FALSE; goto exit; } #ifdef NEVER
// if it allows dups
if (0 == (c_rgEditCritList[lvi.lParam].dwFlags & STATE_NODUPS)) { // remove it
if (FALSE == ListView_DeleteItem(m_hwndCrit, lvi.iItem)) { fRet = FALSE; goto exit; }
// Subtract the item
cItems--; lvi.iItem--; } else #endif // NEVER
{ // disable
ListView_SetItemState(m_hwndCrit, lvi.iItem, INDEXTOSTATEIMAGEMASK(iiconStateDisabled + 1), LVIS_STATEIMAGEMASK); } } else { if (FALSE == fEnable) { dwState = INDEXTOSTATEIMAGEMASK(iiconStateUnchecked + 1); } else { dwState = INDEXTOSTATEIMAGEMASK(iiconStateDisabled + 1); } // uncheck/disable it
ListView_SetItemState(m_hwndCrit, lvi.iItem, dwState, LVIS_STATEIMAGEMASK); } } }
// Add/Remove the item from the description
if (FAILED(m_pDescriptUI->HrEnableCriteria(c_rgEditCritList[lvitem.lParam].typeCrit, fEnable))) { fRet = FALSE; goto exit; } if (FALSE != fEnable) { #ifdef NEVER
// Can we add another one?
if (0 == (c_rgEditCritList[lvitem.lParam].dwFlags & STATE_NODUPS)) { // Fix up the item to insert into the list
lvitem.state = INDEXTOSTATEIMAGEMASK(iiconStateUnchecked+1);
// Insert the item into the list
lvitem.iItem++; if (-1 == ListView_InsertItem(m_hwndCrit, &lvitem)) { fRet = FALSE; goto exit; } } #endif // NEVER
// Set the item to enabled
ListView_SetItemState(m_hwndCrit, iItem, INDEXTOSTATEIMAGEMASK(iiconStateChecked+1), LVIS_STATEIMAGEMASK); } else { #ifdef NEVER
// Can we remove this one?
if (0 == (c_rgEditCritList[lvitem.lParam].dwFlags & STATE_NODUPS)) { // Remove the inserted item
if (FALSE == ListView_DeleteItem(m_hwndCrit, iItem)) { fRet = FALSE; goto exit; } } else #endif // NEVER
{ // Set the item to enabled
ListView_SetItemState(m_hwndCrit, iItem, INDEXTOSTATEIMAGEMASK(iiconStateUnchecked + 1), LVIS_STATEIMAGEMASK); } }
fRet = TRUE; exit: return fRet; }
///////////////////////////////////////////////////////////////////////////////
//
// _FInitializeActListCtrl
//
// This initializes the actions list view with the list of actions
//
// Returns: TRUE, if it was successfully loaded
// FALSE, otherwise
//
///////////////////////////////////////////////////////////////////////////////
BOOL CEditRuleUI::_FInitializeActListCtrl(void) { BOOL fRet = FALSE; LVCOLUMN lvc; RECT rc; HIMAGELIST himl = NULL; HRESULT hr = S_OK; ACT_ITEM * pActItem = NULL; ULONG cActItem = 0; ULONG ulIndex = 0; UINT uiEditActList = 0; DWORD dwIndex = 0; const ACT_LIST * pActList = NULL; LVITEM lvi; TCHAR szRes[CCHMAX_STRINGRES]; UINT cchRes = 0; LPTSTR pszMark = NULL; BOOL fEnabled = FALSE; BOOL fExclusive = FALSE; PROPVARIANT propvar;
Assert(NULL != m_hwndAct);
ZeroMemory(&propvar, sizeof(propvar)); // Initialize the list view structure
ZeroMemory(&lvc, sizeof(lvc)); lvc.mask = LVCF_WIDTH;
// Calculate the size of the list view
GetClientRect(m_hwndAct, &rc); lvc.cx = rc.right - GetSystemMetrics(SM_CXVSCROLL);
ListView_InsertColumn(m_hwndAct, 0, &lvc);
// Set the state image list
himl = ImageList_LoadBitmap(g_hLocRes, MAKEINTRESOURCE(idb16x16st), 16, 0, RGB(255, 0, 255)); if (NULL != himl) { ListView_SetImageList(m_hwndAct, himl, LVSIL_STATE); }
// Full row selection on listview
ListView_SetExtendedListViewStyle(m_hwndAct, LVS_EX_FULLROWSELECT);
// Get the list of actions from the rule
hr = m_pIRule->GetProp(RULE_PROP_ACTIONS, 0, &propvar); if (SUCCEEDED(hr) && (0 != propvar.blob.cbSize)) { cActItem = propvar.blob.cbSize / sizeof(ACT_ITEM); pActItem = (ACT_ITEM *) (propvar.blob.pBlobData); propvar.blob.pBlobData = NULL; propvar.blob.cbSize = 0;
} // Do we have any exclusive actions
for (ulIndex = 0; ulIndex < cActItem; ulIndex++) { for (uiEditActList = 0; uiEditActList < ARRAYSIZE(c_rgEditActList); uiEditActList++) { pActList = &(c_rgEditActList[uiEditActList]); if ((pActItem[ulIndex].type == pActList->typeAct) && (0 != (pActList->dwFlags & STATE_EXCLUSIVE))) { fExclusive = TRUE; break; } } } // Add the actions to the list view
for (uiEditActList = 0; uiEditActList < ARRAYSIZE(c_rgEditActList); uiEditActList++) { pActList = &(c_rgEditActList[uiEditActList]); // Is this item editable
if (0 != (pActList->dwFlags & STATE_NOEDIT)) { continue; } // Is this action valid for this type of rule?
if (((RULE_TYPE_MAIL == m_typeRule) && (0 == (pActList->dwFlags & STATE_MAIL))) || ((RULE_TYPE_NEWS == m_typeRule) && (0 == (pActList->dwFlags & STATE_NEWS))) || ((RULE_TYPE_FILTER == m_typeRule) && (0 == (pActList->dwFlags & STATE_FILTER))) || ((RULE_TYPE_MAIL == m_typeRule) && (0 != (pActList->dwFlags & STATE_JUNK)) && (0 == (g_dwAthenaMode & MODE_JUNKMAIL)) )) { continue; } // Is this action enabled?
fEnabled = FALSE; for (ulIndex = 0; ulIndex < cActItem; ulIndex++) { if (pActItem[ulIndex].type == pActList->typeAct) { fEnabled = TRUE; break; } } ZeroMemory(&lvi, sizeof(lvi)); lvi.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM | LVIF_STATE; lvi.iItem = dwIndex; lvi.iSubItem = 0; lvi.stateMask = LVIS_STATEIMAGEMASK; if (FALSE != fEnabled) { lvi.state = INDEXTOSTATEIMAGEMASK(iiconStateChecked+1); } else { lvi.state = fExclusive ? INDEXTOSTATEIMAGEMASK(iiconStateDisabled+1) : INDEXTOSTATEIMAGEMASK(iiconStateUnchecked+1); }
// Load up the string to use.
cchRes = LoadString(g_hLocRes, pActList->uiText, szRes, ARRAYSIZE(szRes)); if (0 == cchRes) { continue; }
// Parse out the string mark
pszMark = StrStr(szRes, c_szRuleMarkStart); while (NULL != pszMark) { // Remove the mark start
StrCpyN(pszMark, pszMark + lstrlen(c_szRuleMarkStart), (DWORD)(ARRAYSIZE(szRes) - (pszMark - szRes)));
// Search for the mark end
pszMark = StrStr(pszMark, c_szRuleMarkEnd); if (NULL == pszMark) { fRet = FALSE; goto exit; } // Remove the mark end
StrCpyN(pszMark, pszMark + lstrlen(c_szRuleMarkEnd), (DWORD)(ARRAYSIZE(szRes) - (pszMark - szRes))); // Search for the mark start
pszMark = StrStr(pszMark, c_szRuleMarkStart); } lvi.pszText = szRes; lvi.cchTextMax = lstrlen(szRes); lvi.lParam = (LONG) uiEditActList;
if (-1 != ListView_InsertItem(m_hwndAct, &lvi)) { dwIndex++; } } ListView_SetItemState(m_hwndAct, 0, LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED); fRet = TRUE; exit: RuleUtil_HrFreeActionsItem(pActItem, cActItem); SafeMemFree(pActItem); return fRet; }
VOID CEditRuleUI::_SetTitleText(VOID) { CHAR rgchTitle[CCHMAX_STRINGRES]; UINT uiID = 0; // Figure out which string to load
switch (m_typeRule) { case RULE_TYPE_MAIL: if (0 != (m_dwFlags & ERF_NEWRULE)) { uiID = idsNewMailRuleTitle; } else { uiID = idsEditMailRuleTitle; } break;
case RULE_TYPE_NEWS: if (0 != (m_dwFlags & ERF_NEWRULE)) { uiID = idsNewNewsRuleTitle; } else { uiID = idsEditNewsRuleTitle; } break;
case RULE_TYPE_FILTER: if (0 != (m_dwFlags & ERF_CUSTOMIZEVIEW)) { uiID = idsCustomizeViewTitle; } else if (0 != (m_dwFlags & ERF_NEWRULE)) { uiID = idsNewViewTitle; } else { uiID = idsEditViewTitle; } break; }
// Is there anything to do?
if (0 == uiID) { goto exit; } // Load the string
AthLoadString(uiID, rgchTitle, sizeof(rgchTitle)); // Set the title
SetWindowText(m_hwndDlg, rgchTitle);
exit: return; }
|