Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1543 lines
46 KiB

  1. ///////////////////////////////////////////////////////////////////////////////
  2. //
  3. // EditRule.cpp
  4. //
  5. ///////////////////////////////////////////////////////////////////////////////
  6. #include <pch.hxx>
  7. #include "editrule.h"
  8. #include "ruledesc.h"
  9. #include "ruleutil.h"
  10. #include "reutil.h"
  11. #include <rulesdlg.h>
  12. #include <imagelst.h>
  13. #include "shlwapip.h"
  14. #include <instance.h>
  15. #include <demand.h>
  16. // Constants
  17. static const int c_cCritItemGrow = 16;
  18. static const int c_cActItemGrow = 16;
  19. const static HELPMAP g_rgCtxMapEditRule[] = {
  20. {idlvCriteria, idhCriteriaRule},
  21. {idlvActions, idhActionsRule},
  22. {idredtDescription, idhDescriptionRule},
  23. {idedtRuleName, idhRuleName},
  24. {0, 0}};
  25. const static HELPMAP g_rgCtxMapEditView[] = {
  26. {idlvCriteria, idhCriteriaView},
  27. {idredtDescription, idhDescriptionView},
  28. {idedtRuleName, idhViewName},
  29. {0, 0}};
  30. // The methods for the Rules Editor UI
  31. CEditRuleUI::CEditRuleUI() : m_hwndOwner(NULL), m_dwFlags(0), m_dwState(STATE_UNINIT),
  32. m_typeRule(RULE_TYPE_MAIL), m_hwndCrit(NULL), m_hwndAct(NULL), m_hwndDescript(NULL),
  33. m_hwndName(NULL), m_pIRule(NULL), m_pDescriptUI(NULL)
  34. {
  35. ZeroMemory(m_rgfCritEnabled, sizeof(m_rgfCritEnabled));
  36. ZeroMemory(m_rgfActEnabled, sizeof(m_rgfActEnabled));
  37. }
  38. CEditRuleUI::~CEditRuleUI()
  39. {
  40. SafeRelease(m_pIRule);
  41. if (NULL != m_pDescriptUI)
  42. {
  43. delete m_pDescriptUI;
  44. }
  45. }
  46. ///////////////////////////////////////////////////////////////////////////////
  47. //
  48. // HrInit
  49. //
  50. // This initializes us with the owner window and any flags we might have
  51. //
  52. // hwndOwner - handle to the owner window
  53. // dwFlags - flags to use for this instance
  54. // typeRule - the type of rule editor to create
  55. // pIRule - the rule to edit
  56. // pmsginfo - the message to create the rule from
  57. //
  58. // Returns: S_OK
  59. //
  60. ///////////////////////////////////////////////////////////////////////////////
  61. HRESULT CEditRuleUI::HrInit(HWND hwndOwner, DWORD dwFlags, RULE_TYPE typeRule, IOERule * pIRule, MESSAGEINFO * pmsginfo)
  62. {
  63. HRESULT hr = S_OK;
  64. // If we're already initialized, then fail
  65. if ((0 != (m_dwState & STATE_INITIALIZED)) || (NULL == pIRule))
  66. {
  67. hr = E_FAIL;
  68. goto exit;
  69. }
  70. // Save off the owner window
  71. m_hwndOwner = hwndOwner;
  72. // Save off the flags
  73. m_dwFlags = dwFlags;
  74. // Save off the type of rule to edit
  75. m_typeRule = typeRule;
  76. Assert(NULL == m_pDescriptUI);
  77. m_pDescriptUI = new CRuleDescriptUI;
  78. if (NULL == m_pDescriptUI)
  79. {
  80. hr = E_OUTOFMEMORY;
  81. goto exit;
  82. }
  83. // Save off the rule
  84. Assert(NULL == m_pIRule);
  85. m_pIRule = pIRule;
  86. pIRule->AddRef();
  87. // We're done
  88. m_dwState |= STATE_INITIALIZED;
  89. hr = S_OK;
  90. exit:
  91. return hr;
  92. }
  93. ///////////////////////////////////////////////////////////////////////////////
  94. //
  95. // HrShow
  96. //
  97. // This brings up the rules editor UI
  98. //
  99. // Returns: S_OK, if IDOK was selected
  100. // otherwise, S_FALSE
  101. //
  102. ///////////////////////////////////////////////////////////////////////////////
  103. HRESULT CEditRuleUI::HrShow(void)
  104. {
  105. HRESULT hr = S_OK;
  106. int iRet = 0;
  107. // If we aren't initialized, then fail
  108. if (0 == (m_dwState & STATE_INITIALIZED))
  109. {
  110. hr = E_FAIL;
  111. goto exit;
  112. }
  113. // We need to load richedit
  114. if (FALSE == FInitRichEdit(TRUE))
  115. {
  116. hr = E_FAIL;
  117. goto exit;
  118. }
  119. iRet = (INT) DialogBoxParam(g_hLocRes, (RULE_TYPE_FILTER == m_typeRule) ?
  120. MAKEINTRESOURCE(iddEditView) : MAKEINTRESOURCE(iddEditRule),
  121. m_hwndOwner, CEditRuleUI::FEditRuleDlgProc, (LPARAM)this);
  122. if (-1 == iRet)
  123. {
  124. hr = E_FAIL;
  125. goto exit;
  126. }
  127. // Set the proper return code
  128. hr = (IDOK == iRet) ? S_OK : S_FALSE;
  129. exit:
  130. return hr;
  131. }
  132. ///////////////////////////////////////////////////////////////////////////////
  133. //
  134. // FEditRuleDlgProc
  135. //
  136. // This is the main dialog proc for the rules editor dialog
  137. //
  138. // hwndDlg - handle to the filter manager dialog
  139. // uMsg - the message to be acted upon
  140. // wParam - the 'word' parameter for the message
  141. // lParam - the 'long' parameter for the message
  142. //
  143. // Returns: TRUE, if the message was handled
  144. // FALSE, otherwise
  145. //
  146. ///////////////////////////////////////////////////////////////////////////////
  147. INT_PTR CALLBACK CEditRuleUI::FEditRuleDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
  148. {
  149. BOOL fRet = FALSE;
  150. CEditRuleUI * pEditRuleUI = NULL;
  151. LPNMHDR pnmhdr = NULL;
  152. LPNMLISTVIEW pnmlv = NULL;
  153. LVHITTESTINFO lvh;
  154. NMLVKEYDOWN * pnmlvkd = NULL;
  155. int nIndex = 0;
  156. HWND hwndRE = 0;
  157. pEditRuleUI = (CEditRuleUI *) GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
  158. switch (uMsg)
  159. {
  160. case WM_INITDIALOG:
  161. // Grab the UI object pointer
  162. pEditRuleUI = (CEditRuleUI *) lParam;
  163. // Set it into the dialog so we can get it back
  164. SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR) pEditRuleUI);
  165. hwndRE = CreateREInDialogA(hwndDlg, idredtDescription);
  166. if (!hwndRE || (FALSE == pEditRuleUI->FOnInitDialog(hwndDlg)))
  167. {
  168. EndDialog(hwndDlg, -1);
  169. fRet = TRUE;
  170. goto exit;
  171. }
  172. // We didn't set the focus so return TRUE
  173. fRet = TRUE;
  174. break;
  175. case WM_COMMAND:
  176. switch (LOWORD(wParam))
  177. {
  178. case idedtRuleName:
  179. if (EN_CHANGE == HIWORD(wParam))
  180. {
  181. pEditRuleUI->FOnNameChange((HWND) lParam);
  182. }
  183. break;
  184. case IDCANCEL:
  185. EndDialog(hwndDlg, IDCANCEL);
  186. fRet = TRUE;
  187. break;
  188. case IDOK:
  189. if (FALSE != pEditRuleUI->FOnOK())
  190. {
  191. EndDialog(hwndDlg, IDOK);
  192. fRet = TRUE;
  193. }
  194. break;
  195. }
  196. break;
  197. case WM_NOTIFY:
  198. pnmhdr = (LPNMHDR) lParam;
  199. switch (((LPNMHDR)lParam)->code)
  200. {
  201. case NM_CLICK:
  202. if ((idlvCriteria == GetDlgCtrlID(pnmhdr->hwndFrom)) ||
  203. (idlvActions == GetDlgCtrlID(pnmhdr->hwndFrom)))
  204. {
  205. pnmlv = (LPNMLISTVIEW) lParam;
  206. pEditRuleUI->FOnListClick(pnmhdr->hwndFrom, pnmlv);
  207. }
  208. break;
  209. case NM_DBLCLK:
  210. if ((idlvCriteria == GetDlgCtrlID(pnmhdr->hwndFrom)) ||
  211. (idlvActions == GetDlgCtrlID(pnmhdr->hwndFrom)))
  212. {
  213. pnmlv = (LPNMLISTVIEW) lParam;
  214. ZeroMemory(&lvh, sizeof(lvh));
  215. lvh.pt = pnmlv->ptAction;
  216. ListView_HitTest(pnmhdr->hwndFrom, &lvh);
  217. if ((-1 != pnmlv->iItem) && (0 != (lvh.flags & LVHT_ONITEMLABEL)))
  218. {
  219. pEditRuleUI->HandleEnabledState(pnmhdr->hwndFrom, pnmlv->iItem);
  220. }
  221. }
  222. break;
  223. case LVN_KEYDOWN:
  224. if ((idlvCriteria == GetDlgCtrlID(pnmhdr->hwndFrom)) ||
  225. (idlvActions == GetDlgCtrlID(pnmhdr->hwndFrom)))
  226. {
  227. pnmlvkd = (NMLVKEYDOWN *) lParam;
  228. if (VK_SPACE == pnmlvkd->wVKey)
  229. {
  230. nIndex = ListView_GetNextItem(pnmhdr->hwndFrom, -1, LVNI_SELECTED);
  231. if (0 <= nIndex)
  232. {
  233. pEditRuleUI->HandleEnabledState(pnmhdr->hwndFrom, nIndex);
  234. }
  235. }
  236. }
  237. break;
  238. }
  239. break;
  240. case WM_HELP:
  241. case WM_CONTEXTMENU:
  242. fRet = pEditRuleUI->FOnHelp(uMsg, wParam, lParam);
  243. break;
  244. }
  245. exit:
  246. return fRet;
  247. }
  248. ///////////////////////////////////////////////////////////////////////////////
  249. //
  250. // FOnInitDialog
  251. //
  252. // This is the initialization routine for the rules editor dialog
  253. //
  254. // hwndDlg - handle to the rules editor dialog
  255. //
  256. // Returns: TRUE, if the dialog was initialized successfully
  257. // FALSE, otherwise
  258. //
  259. ///////////////////////////////////////////////////////////////////////////////
  260. BOOL CEditRuleUI::FOnInitDialog(HWND hwndDlg)
  261. {
  262. BOOL fRet = FALSE;
  263. PROPVARIANT propvar = {0};
  264. INT iSelect = 0;
  265. // Check incoming params
  266. if (NULL == hwndDlg)
  267. {
  268. fRet = FALSE;
  269. goto exit;
  270. }
  271. // Save off the dialog window handle
  272. m_hwndDlg = hwndDlg;
  273. // Set the default font onto the dialog
  274. SetIntlFont(m_hwndDlg);
  275. // Save off some of the controls
  276. m_hwndCrit = GetDlgItem(m_hwndDlg, idlvCriteria);
  277. if (RULE_TYPE_FILTER != m_typeRule)
  278. {
  279. m_hwndAct = GetDlgItem(hwndDlg, idlvActions);
  280. }
  281. m_hwndDescript = GetDlgItem(hwndDlg, idredtDescription);
  282. m_hwndName = GetDlgItem(hwndDlg, idedtRuleName);
  283. if ((NULL == m_hwndCrit) || ((RULE_TYPE_FILTER != m_typeRule) && (NULL == m_hwndAct)) ||
  284. (NULL == m_hwndDescript) || (NULL == m_hwndName))
  285. {
  286. fRet = FALSE;
  287. goto exit;
  288. }
  289. // Initialize criteria listbox control
  290. if (FALSE == _FInitializeCritListCtrl())
  291. {
  292. fRet = FALSE;
  293. goto exit;
  294. }
  295. // Initialize criteria listbox control
  296. if (RULE_TYPE_FILTER != m_typeRule)
  297. {
  298. if (FALSE == _FInitializeActListCtrl())
  299. {
  300. fRet = FALSE;
  301. goto exit;
  302. }
  303. }
  304. // Load the criteria listbox control
  305. if (FALSE == _FLoadCritListCtrl(&iSelect))
  306. {
  307. fRet = FALSE;
  308. goto exit;
  309. }
  310. _SetTitleText();
  311. // Select the default item in the criteria list
  312. ListView_SetItemState(m_hwndCrit, iSelect, LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED);
  313. // Make sure the default item is visible
  314. ListView_EnsureVisible(m_hwndCrit, iSelect, FALSE);
  315. // Initialize the description field
  316. if (FAILED(m_pDescriptUI->HrInit(m_hwndDescript, 0)))
  317. {
  318. fRet = FALSE;
  319. goto exit;
  320. }
  321. if (FAILED(m_pDescriptUI->HrSetRule(m_typeRule, m_pIRule)))
  322. {
  323. fRet = FALSE;
  324. goto exit;
  325. }
  326. // If we are a filter and are new
  327. if ((RULE_TYPE_FILTER == m_typeRule) && (0 != (m_dwFlags & ERF_ADDDEFAULTACTION)))
  328. {
  329. // Set the default action
  330. if (FAILED(m_pDescriptUI->HrEnableActions(ACT_TYPE_SHOW, TRUE)))
  331. {
  332. goto exit;
  333. }
  334. }
  335. m_pDescriptUI->ShowDescriptionString();
  336. // Initialize the name field
  337. if (FAILED(m_pIRule->GetProp(RULE_PROP_NAME, 0, &propvar)))
  338. {
  339. fRet = FALSE;
  340. goto exit;
  341. }
  342. if ((VT_LPSTR != propvar.vt) || (NULL == propvar.pszVal) || ('\0' == propvar.pszVal[0]))
  343. {
  344. fRet = FALSE;
  345. goto exit;
  346. }
  347. Edit_SetText(m_hwndName, propvar.pszVal);
  348. // Everything's AOK
  349. fRet = TRUE;
  350. exit:
  351. PropVariantClear(&propvar);
  352. return fRet;
  353. }
  354. ///////////////////////////////////////////////////////////////////////////////
  355. //
  356. // FOnListClick
  357. //
  358. // This handles clicking on either of the lists
  359. //
  360. // Returns: TRUE, we handled the click message
  361. // FALSE, otherwise
  362. //
  363. ///////////////////////////////////////////////////////////////////////////////
  364. BOOL CEditRuleUI::FOnListClick(HWND hwndList, LPNMLISTVIEW pnmlv)
  365. {
  366. BOOL fRet = FALSE;
  367. int iIndex = 0;
  368. int iSelected = 0;
  369. LVHITTESTINFO lvh;
  370. Assert(NULL != m_hwndCrit);
  371. if ((NULL == hwndList) || (NULL == pnmlv))
  372. {
  373. fRet = FALSE;
  374. goto exit;
  375. }
  376. ZeroMemory(&lvh, sizeof(lvh));
  377. lvh.pt = pnmlv->ptAction;
  378. iIndex = ListView_HitTest(hwndList, &lvh);
  379. if (-1 == iIndex)
  380. {
  381. fRet = FALSE;
  382. goto exit;
  383. }
  384. // Let's make sure this item is already selected
  385. iSelected = ListView_GetNextItem(hwndList, -1, LVNI_SELECTED);
  386. if (iSelected != iIndex)
  387. {
  388. ListView_SetItemState(hwndList, iIndex, LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED);
  389. }
  390. if ((lvh.flags & LVHT_ONITEMSTATEICON) &&
  391. !(lvh.flags & LVHT_ONITEMLABEL))
  392. {
  393. HandleEnabledState(hwndList, iIndex);
  394. fRet = TRUE;
  395. }
  396. else
  397. {
  398. fRet = FALSE;
  399. }
  400. exit:
  401. return fRet;
  402. }
  403. ///////////////////////////////////////////////////////////////////////////////
  404. //
  405. // FOnOK
  406. //
  407. // This handles clicking on the links in the description field
  408. //
  409. // Returns: TRUE, we handled the click message
  410. // FALSE, otherwise
  411. //
  412. ///////////////////////////////////////////////////////////////////////////////
  413. BOOL CEditRuleUI::FOnOK(void)
  414. {
  415. BOOL fRet = FALSE;
  416. TCHAR szRes[CCHMAX_STRINGRES + 5];
  417. TCHAR szName[CCHMAX_STRINGRES + 5];
  418. ULONG cchRes = 0;
  419. ULONG ulIndex = 0;
  420. IOERule * pIRule = NULL;
  421. PROPVARIANT propvar;
  422. HRESULT hr = S_OK;
  423. CRIT_ITEM * pCritItem = NULL;
  424. ULONG cCritItem = 0;
  425. ACT_ITEM * pActItem = NULL;
  426. ULONG cActItem = 0;
  427. BOOL fNewRule = FALSE;
  428. LPSTR pszName = NULL;
  429. ULONG cchName = 0;
  430. ZeroMemory(&propvar, sizeof(propvar));
  431. if (NULL == m_pIRule)
  432. {
  433. fRet = FALSE;
  434. goto exit;
  435. }
  436. // First let's validate the name and all the criteria and actions
  437. // Get the name from the edit well
  438. cchName = Edit_GetTextLength(m_hwndName) + 1;
  439. if (FAILED(HrAlloc((void **) &pszName, cchName * sizeof(*pszName))))
  440. {
  441. fRet = FALSE;
  442. goto exit;
  443. }
  444. pszName[0] = '\0';
  445. cchName = Edit_GetText(m_hwndName, pszName, cchName);
  446. // Check to see if the name is valid
  447. if (0 == UlStripWhitespace(pszName, TRUE, TRUE, NULL))
  448. {
  449. // Put up a message saying something is busted
  450. AthMessageBoxW(m_hwndDlg, MAKEINTRESOURCEW(idsAthenaMail),
  451. (RULE_TYPE_FILTER != m_typeRule) ?
  452. MAKEINTRESOURCEW(idsRulesErrorNoName) : MAKEINTRESOURCEW(idsViewsErrorNoName),
  453. NULL, MB_OK | MB_ICONINFORMATION);
  454. fRet = FALSE;
  455. goto exit;
  456. }
  457. // Let's make sure they have the right parts
  458. // Get the criteria for the rule
  459. hr = m_pDescriptUI->HrGetCriteria(&pCritItem, &cCritItem);
  460. if (FAILED(hr))
  461. {
  462. fRet = FALSE;
  463. goto exit;
  464. }
  465. // Do we have any criteria
  466. if (0 == cCritItem)
  467. {
  468. // Put up a message saying something is busted
  469. AthMessageBoxW(m_hwndDlg, MAKEINTRESOURCEW(idsAthenaMail),
  470. (RULE_TYPE_FILTER != m_typeRule) ?
  471. MAKEINTRESOURCEW(idsRulesErrorNoCriteria) : MAKEINTRESOURCEW(idsViewsErrorNoCriteria),
  472. NULL, MB_OK | MB_ICONINFORMATION);
  473. fRet = FALSE;
  474. goto exit;
  475. }
  476. // Get the actions for the rule
  477. hr = m_pDescriptUI->HrGetActions(&pActItem, &cActItem);
  478. if (FAILED(hr))
  479. {
  480. fRet = FALSE;
  481. goto exit;
  482. }
  483. // Do we have any criteria
  484. if (0 == cActItem)
  485. {
  486. // Put up a message saying something is busted
  487. AthMessageBoxW(m_hwndDlg, MAKEINTRESOURCEW(idsAthenaMail),
  488. (RULE_TYPE_FILTER != m_typeRule) ?
  489. MAKEINTRESOURCEW(idsRulesErrorNoActions) : MAKEINTRESOURCEW(idsViewsErrorNoActions),
  490. NULL, MB_OK | MB_ICONINFORMATION);
  491. fRet = FALSE;
  492. goto exit;
  493. }
  494. // Let's check to see if we really need to do anything
  495. hr = m_pDescriptUI->HrIsDirty();
  496. if (FAILED(hr))
  497. {
  498. fRet = FALSE;
  499. goto exit;
  500. }
  501. if ((0 == (m_dwState & STATE_DIRTY)) && (S_FALSE == hr))
  502. {
  503. fRet = TRUE;
  504. goto exit;
  505. }
  506. hr = m_pDescriptUI->HrVerifyRule();
  507. if (S_OK != hr)
  508. {
  509. // Put up a message saying something is busted
  510. AthMessageBoxW(m_hwndDlg, MAKEINTRESOURCEW(idsAthenaMail),
  511. MAKEINTRESOURCEW(idsRulesErrorFix), NULL,
  512. MB_OK | MB_ICONINFORMATION);
  513. m_pDescriptUI->ShowDescriptionString();
  514. fRet = FALSE;
  515. goto exit;
  516. }
  517. // Set the criteria on the rule
  518. PropVariantClear(&propvar);
  519. propvar.vt = VT_BLOB;
  520. propvar.blob.cbSize = cCritItem * sizeof(CRIT_ITEM);
  521. propvar.blob.pBlobData = (BYTE *) pCritItem;
  522. hr = m_pIRule->SetProp(RULE_PROP_CRITERIA, 0, &propvar);
  523. ZeroMemory(&propvar, sizeof(propvar));
  524. if (FAILED(hr))
  525. {
  526. fRet = FALSE;
  527. goto exit;
  528. }
  529. // Set the actions on the rule
  530. PropVariantClear(&propvar);
  531. propvar.vt = VT_BLOB;
  532. propvar.blob.cbSize = cActItem * sizeof(ACT_ITEM);
  533. propvar.blob.pBlobData = (BYTE *) pActItem;
  534. hr = m_pIRule->SetProp(RULE_PROP_ACTIONS, 0, &propvar);
  535. ZeroMemory(&propvar, sizeof(propvar));
  536. if (FAILED(hr))
  537. {
  538. fRet = FALSE;
  539. goto exit;
  540. }
  541. // Set the rule name
  542. PropVariantClear(&propvar);
  543. propvar.vt = VT_LPSTR;
  544. propvar.pszVal = pszName;
  545. hr = m_pIRule->SetProp(RULE_PROP_NAME, 0, &propvar);
  546. ZeroMemory(&propvar, sizeof(propvar));
  547. if (FAILED(hr))
  548. {
  549. fRet = FALSE;
  550. goto exit;
  551. }
  552. // Make sure we clear out the fact that we saved the rule
  553. m_pDescriptUI->HrClearDirty();
  554. // Note that we saved
  555. m_dwState &= ~STATE_DIRTY;
  556. // Set the proper return value
  557. fRet = TRUE;
  558. exit:
  559. RuleUtil_HrFreeCriteriaItem(pCritItem, cCritItem);
  560. SafeMemFree(pCritItem);
  561. RuleUtil_HrFreeActionsItem(pActItem, cActItem);
  562. SafeMemFree(pActItem);
  563. PropVariantClear(&propvar);
  564. SafeMemFree(pszName);
  565. return fRet;
  566. }
  567. ///////////////////////////////////////////////////////////////////////////////
  568. //
  569. // FOnHelp
  570. //
  571. // This handles the WM_HELP message for the rules edit UI dialog
  572. //
  573. // Returns: TRUE, if it was successfully destroyed
  574. // FALSE, otherwise
  575. //
  576. ///////////////////////////////////////////////////////////////////////////////
  577. BOOL CEditRuleUI::FOnHelp(UINT uiMsg, WPARAM wParam, LPARAM lParam)
  578. {
  579. return(OnContextHelp(m_hwndDlg, uiMsg, wParam, lParam, (RULE_TYPE_FILTER == m_typeRule) ? g_rgCtxMapEditView : g_rgCtxMapEditRule));
  580. }
  581. ///////////////////////////////////////////////////////////////////////////////
  582. //
  583. // FOnNameChange
  584. //
  585. // This handles the user typing into the name field
  586. //
  587. // Returns: TRUE, we handled the edit message
  588. // FALSE, otherwise
  589. //
  590. ///////////////////////////////////////////////////////////////////////////////
  591. BOOL CEditRuleUI::FOnNameChange(HWND hwndName)
  592. {
  593. BOOL fRet = FALSE;
  594. Assert(NULL != m_hwndName);
  595. Assert(hwndName == m_hwndName);
  596. // Note that we're dirty
  597. m_dwState |= STATE_DIRTY;
  598. // Disable the OK button if the name is empty
  599. fRet = RuleUtil_FEnDisDialogItem(m_hwndDlg, IDOK, 0 != Edit_GetTextLength(m_hwndName));
  600. return fRet;
  601. }
  602. ///////////////////////////////////////////////////////////////////////////////
  603. //
  604. // HandleEnabledState
  605. //
  606. // This switches the current enabled state of the list view item
  607. // and updates the UI
  608. //
  609. // nIndex - index of the item in the listview to work on
  610. //
  611. // Returns: NONE
  612. //
  613. ///////////////////////////////////////////////////////////////////////////////
  614. void CEditRuleUI::HandleEnabledState(HWND hwndList, int nItem)
  615. {
  616. HRESULT hr = S_OK;
  617. LVITEM lvi;
  618. BOOL fEnabled = FALSE;
  619. INT iIndex = 0;
  620. LONG lItem = 0;
  621. INT cItems = 0;
  622. // Grab the list view item
  623. ZeroMemory(&lvi, sizeof(lvi));
  624. lvi.mask = LVIF_STATE | LVIF_PARAM;
  625. lvi.stateMask = LVIS_STATEIMAGEMASK;
  626. lvi.iItem = nItem;
  627. if (FALSE == ListView_GetItem(hwndList, &lvi))
  628. {
  629. goto exit;
  630. }
  631. lItem = (LONG) lvi.lParam;
  632. if (INDEXTOSTATEIMAGEMASK(iiconStateDisabled+1) == lvi.state)
  633. {
  634. goto exit;
  635. }
  636. // Get the new enabled value
  637. fEnabled = (lvi.state != INDEXTOSTATEIMAGEMASK(iiconStateChecked+1));
  638. // Build up the description string
  639. if (hwndList == m_hwndCrit)
  640. {
  641. if (FALSE == _FAddCritToList(nItem, fEnabled))
  642. {
  643. goto exit;
  644. }
  645. }
  646. else
  647. {
  648. // Set the UI to the opposite enabled state
  649. ZeroMemory(&lvi, sizeof(lvi));
  650. lvi.mask = LVIF_STATE;
  651. lvi.iItem = nItem;
  652. lvi.state = fEnabled ? INDEXTOSTATEIMAGEMASK(iiconStateChecked+1) :
  653. INDEXTOSTATEIMAGEMASK(iiconStateUnchecked+1);
  654. lvi.stateMask = LVIS_STATEIMAGEMASK;
  655. ListView_SetItem(hwndList, &lvi);
  656. // Figure out the number of items in the list
  657. cItems = ListView_GetItemCount(hwndList);
  658. Assert(hwndList == m_hwndAct);
  659. m_pDescriptUI->HrEnableActions(c_rgEditActList[lItem].typeAct, fEnabled);
  660. // Do we need to go through and update all the items?
  661. if (0 != (c_rgEditActList[lItem].dwFlags & STATE_EXCLUSIVE))
  662. {
  663. for (iIndex = 0; iIndex < cItems; iIndex++)
  664. {
  665. // We already handled this one
  666. if (iIndex == nItem)
  667. {
  668. continue;
  669. }
  670. // Change the state
  671. lvi.mask = LVIF_STATE;
  672. lvi.iItem = iIndex;
  673. lvi.state = fEnabled ? INDEXTOSTATEIMAGEMASK(iiconStateDisabled+1) :
  674. INDEXTOSTATEIMAGEMASK(iiconStateUnchecked+1);
  675. lvi.stateMask = LVIS_STATEIMAGEMASK;
  676. ListView_SetItem(hwndList, &lvi);
  677. if (FALSE != fEnabled)
  678. {
  679. // Figure out which action the item corresponds to
  680. lvi.mask = LVIF_PARAM;
  681. lvi.iItem = iIndex;
  682. if ((FALSE != ListView_GetItem(hwndList, &lvi)) &&
  683. (lvi.lParam >= 0) && (lvi.lParam < c_cEditActList))
  684. {
  685. m_pDescriptUI->HrEnableActions(c_rgEditActList[lvi.lParam].typeAct, FALSE);
  686. }
  687. }
  688. }
  689. }
  690. }
  691. // Note that we're dirty
  692. m_dwState |= STATE_DIRTY;
  693. exit:
  694. return;
  695. }
  696. ///////////////////////////////////////////////////////////////////////////////
  697. //
  698. // _FInitializeCritListCtrl
  699. //
  700. // This initializes the criteria list view with the list of criteria
  701. //
  702. // Returns: TRUE, if it was successfully loaded
  703. // FALSE, otherwise
  704. //
  705. ///////////////////////////////////////////////////////////////////////////////
  706. BOOL CEditRuleUI::_FInitializeCritListCtrl(void)
  707. {
  708. BOOL fRet = FALSE;
  709. LVCOLUMN lvc = {0};
  710. RECT rc = {0};
  711. HIMAGELIST himl = NULL;
  712. LVITEM lvi = {0};
  713. TCHAR szRes[CCHMAX_STRINGRES];
  714. UINT uiEditCritList = 0;
  715. const CRIT_LIST * pCritList = NULL;
  716. UINT cchRes = 0;
  717. LPTSTR pszMark = NULL;
  718. Assert(NULL != m_hwndCrit);
  719. // Initialize the list view column structure
  720. ZeroMemory(&lvc, sizeof(lvc));
  721. lvc.mask = LVCF_WIDTH;
  722. // Calculate the size of the list view
  723. GetClientRect(m_hwndCrit, &rc);
  724. lvc.cx = rc.right - GetSystemMetrics(SM_CXVSCROLL);
  725. ListView_InsertColumn(m_hwndCrit, 0, &lvc);
  726. // Set the state image list
  727. himl = ImageList_LoadBitmap(g_hLocRes, MAKEINTRESOURCE(idb16x16st), 16, 0, RGB(255, 0, 255));
  728. if (NULL != himl)
  729. {
  730. ListView_SetImageList(m_hwndCrit, himl, LVSIL_STATE);
  731. }
  732. // Full row selection on listview
  733. ListView_SetExtendedListViewStyle(m_hwndCrit, LVS_EX_FULLROWSELECT);
  734. // Initialize the list view item structure
  735. lvi.mask = LVIF_TEXT | LVIF_PARAM | LVIF_STATE;
  736. lvi.stateMask = LVIS_STATEIMAGEMASK;
  737. lvi.state = INDEXTOSTATEIMAGEMASK(iiconStateUnchecked+1);
  738. lvi.pszText = szRes;
  739. // Add each criteria to the list view
  740. for (uiEditCritList = 0; uiEditCritList < ARRAYSIZE(c_rgEditCritList); uiEditCritList++)
  741. {
  742. pCritList = &(c_rgEditCritList[uiEditCritList]);
  743. // Is this item editable
  744. if (0 != (pCritList->dwFlags & STATE_NOEDIT))
  745. {
  746. continue;
  747. }
  748. // Is this criteria valid for this type of rule?
  749. if (((RULE_TYPE_MAIL == m_typeRule) && (0 == (pCritList->dwFlags & STATE_MAIL))) ||
  750. ((RULE_TYPE_NEWS == m_typeRule) && (0 == (pCritList->dwFlags & STATE_NEWS))) ||
  751. ((RULE_TYPE_FILTER == m_typeRule) && (0 == (pCritList->dwFlags & STATE_FILTER))))
  752. {
  753. continue;
  754. }
  755. // Load up the string to use.
  756. cchRes = LoadString(g_hLocRes, pCritList->uiText, szRes, ARRAYSIZE(szRes));
  757. if (0 == cchRes)
  758. {
  759. continue;
  760. }
  761. // Parse out the string mark
  762. pszMark = StrStr(szRes, c_szRuleMarkStart);
  763. while (NULL != pszMark)
  764. {
  765. // Remove the mark start
  766. StrCpyN(pszMark, pszMark + lstrlen(c_szRuleMarkStart), (DWORD)(ARRAYSIZE(szRes) - (pszMark - szRes)));
  767. // Search for the mark end
  768. pszMark = StrStr(pszMark, c_szRuleMarkEnd);
  769. if (NULL == pszMark)
  770. {
  771. fRet = FALSE;
  772. goto exit;
  773. }
  774. // Remove the mark end
  775. StrCpyN(pszMark, pszMark + lstrlen(c_szRuleMarkEnd), (DWORD)(ARRAYSIZE(szRes) - (pszMark - szRes)));
  776. // Search for the mark start
  777. pszMark = StrStr(pszMark, c_szRuleMarkStart);
  778. }
  779. lvi.cchTextMax = lstrlen(szRes);
  780. lvi.lParam = (LONG) uiEditCritList;
  781. if (-1 != ListView_InsertItem(m_hwndCrit, &lvi))
  782. {
  783. lvi.iItem++;
  784. }
  785. }
  786. fRet = TRUE;
  787. exit:
  788. return fRet;
  789. }
  790. ///////////////////////////////////////////////////////////////////////////////
  791. //
  792. // _FLoadCritListCtrl
  793. //
  794. // This load the criteria list view with the list of criteria
  795. //
  796. // Returns: TRUE, if it was successfully loaded
  797. // FALSE, otherwise
  798. //
  799. ///////////////////////////////////////////////////////////////////////////////
  800. BOOL CEditRuleUI::_FLoadCritListCtrl(INT * piSelect)
  801. {
  802. BOOL fRet = FALSE;
  803. PROPVARIANT propvar = {0};
  804. CRIT_ITEM * pCritItem = NULL;
  805. ULONG cCritItem = 0;
  806. BOOL fExclusive = FALSE;
  807. INT cItems = 0;
  808. LVITEM lvi = {0};
  809. ULONG ulIndex = 0;
  810. INT iSelect = 0;
  811. DWORD dwState = 0;
  812. TCHAR szRes[CCHMAX_STRINGRES];
  813. INT iItem = 0;
  814. Assert(NULL != m_hwndCrit);
  815. Assert(NULL != piSelect);
  816. // Initialize the outgoing param
  817. *piSelect = 0;
  818. // Make sure we have something to do...
  819. if (NULL == m_pIRule)
  820. {
  821. fRet = TRUE;
  822. goto exit;
  823. }
  824. // Get the criteria from the rule
  825. if (FAILED(m_pIRule->GetProp(RULE_PROP_CRITERIA, 0, &propvar)))
  826. {
  827. fRet = FALSE;
  828. goto exit;
  829. }
  830. // Do we have anything to do?
  831. if (0 == propvar.blob.cbSize)
  832. {
  833. fRet = TRUE;
  834. goto exit;
  835. }
  836. Assert(NULL != propvar.blob.pBlobData);
  837. cCritItem = propvar.blob.cbSize / sizeof(CRIT_ITEM);
  838. pCritItem = (CRIT_ITEM *) (propvar.blob.pBlobData);
  839. // Do we have any exclusive criteria set?
  840. if (1 == cCritItem)
  841. {
  842. // Find the criteria item in the list
  843. for (ulIndex = 0; ulIndex < ARRAYSIZE(c_rgEditCritList); ulIndex++)
  844. {
  845. // Is this the criteria item?
  846. if ((pCritItem->type == c_rgEditCritList[ulIndex].typeCrit) &&
  847. (0 != (c_rgEditCritList[ulIndex].dwFlags & STATE_EXCLUSIVE)))
  848. {
  849. fExclusive = TRUE;
  850. break;
  851. }
  852. }
  853. }
  854. // Figure out how many items are in the list control
  855. cItems = ListView_GetItemCount(m_hwndCrit);
  856. iSelect = cItems;
  857. // Initialize the list view item structure
  858. lvi.mask = LVIF_PARAM | LVIF_STATE;
  859. lvi.stateMask = LVIS_STATEIMAGEMASK;
  860. // If we're exclusive
  861. if (FALSE != fExclusive)
  862. {
  863. // Disable each of the items
  864. // except for the exclusive one
  865. for (lvi.iItem = 0; lvi.iItem < cItems; lvi.iItem++)
  866. {
  867. if (FALSE == ListView_GetItem(m_hwndCrit, &lvi))
  868. {
  869. continue;
  870. }
  871. // Is this the criteria item?
  872. if (pCritItem->type == c_rgEditCritList[lvi.lParam].typeCrit)
  873. {
  874. dwState = INDEXTOSTATEIMAGEMASK(iiconStateChecked+1);
  875. // Is this the first item we found in the list
  876. if (iSelect > lvi.iItem)
  877. {
  878. iSelect = lvi.iItem;
  879. }
  880. }
  881. else
  882. {
  883. dwState = INDEXTOSTATEIMAGEMASK(iiconStateDisabled+1);
  884. }
  885. // Set the state
  886. ListView_SetItemState(m_hwndCrit, lvi.iItem, dwState, LVIS_STATEIMAGEMASK);
  887. }
  888. }
  889. else
  890. {
  891. // Add each criteria to the list view
  892. for (ulIndex = 0; ulIndex < cCritItem; ulIndex++)
  893. {
  894. // Find the criteria item in the list
  895. for (lvi.iItem = 0; lvi.iItem < cItems; lvi.iItem++)
  896. {
  897. if (FALSE == ListView_GetItem(m_hwndCrit, &lvi))
  898. {
  899. continue;
  900. }
  901. // Is this the criteria item?
  902. if ((pCritItem[ulIndex].type == c_rgEditCritList[lvi.lParam].typeCrit) &&
  903. (INDEXTOSTATEIMAGEMASK(iiconStateUnchecked+1) == lvi.state))
  904. {
  905. break;
  906. }
  907. }
  908. // Did we find anything?
  909. if (lvi.iItem >= cItems)
  910. {
  911. fRet = FALSE;
  912. goto exit;
  913. }
  914. // Save off the item
  915. iItem = lvi.iItem;
  916. // Is this the first item we found in the list
  917. if (iSelect > iItem)
  918. {
  919. iSelect = iItem;
  920. }
  921. #ifdef NEVER
  922. // Can we add multiple items?
  923. if (0 == (c_rgEditCritList[lvi.lParam].dwFlags & STATE_NODUPS))
  924. {
  925. // Regrab the item
  926. lvi.mask = LVIF_TEXT | LVIF_PARAM | LVIF_STATE;
  927. lvi.stateMask = LVIS_STATEIMAGEMASK;
  928. lvi.pszText = szRes;
  929. lvi.cchTextMax = sizeof(szRes);
  930. if (FALSE == ListView_GetItem(m_hwndCrit, &lvi))
  931. {
  932. continue;
  933. }
  934. // Add the item to the list
  935. // Fix up the item to insert into the list
  936. lvi.state = INDEXTOSTATEIMAGEMASK(iiconStateUnchecked+1);
  937. // Insert the item into the list
  938. lvi.iItem++;
  939. if (-1 == ListView_InsertItem(m_hwndCrit, &lvi))
  940. {
  941. fRet = FALSE;
  942. goto exit;
  943. }
  944. // Add one since we just added an item
  945. cItems++;
  946. }
  947. #endif // NEVER
  948. // Set the state
  949. ListView_SetItemState(m_hwndCrit, iItem, INDEXTOSTATEIMAGEMASK(iiconStateChecked+1), LVIS_STATEIMAGEMASK);
  950. }
  951. }
  952. // Set the outgoing param
  953. *piSelect = iSelect;
  954. // Set the return value
  955. fRet = TRUE;
  956. exit:
  957. RuleUtil_HrFreeCriteriaItem(pCritItem, cCritItem);
  958. SafeMemFree(pCritItem);
  959. return fRet;
  960. }
  961. ///////////////////////////////////////////////////////////////////////////////
  962. //
  963. // _FAddRuleToList
  964. //
  965. // This adds the view passed in to the list view
  966. //
  967. // dwIndex - the index on where to add the view to into the list
  968. // pIRule - the actual view
  969. //
  970. // Returns: TRUE, if it was successfully added
  971. // FALSE, otherwise
  972. //
  973. ///////////////////////////////////////////////////////////////////////////////
  974. BOOL CEditRuleUI::_FAddCritToList(INT iItem, BOOL fEnable)
  975. {
  976. BOOL fRet = FALSE;
  977. LVITEM lvitem = {0};
  978. TCHAR szRes[CCHMAX_STRINGRES];
  979. INT cItems = 0;
  980. LVITEM lvi = {0};
  981. DWORD dwState = 0;
  982. Assert(NULL != m_hwndCrit);
  983. // If there's nothing to do...
  984. if (-1 == iItem)
  985. {
  986. fRet = FALSE;
  987. goto exit;
  988. }
  989. // Initialize the list view item structure
  990. lvitem.mask = LVIF_TEXT | LVIF_PARAM | LVIF_STATE;
  991. lvitem.iItem = iItem;
  992. lvitem.stateMask = LVIS_STATEIMAGEMASK;
  993. lvitem.pszText = szRes;
  994. lvitem.cchTextMax = sizeof(szRes);
  995. // Get the item from the list
  996. if (FALSE == ListView_GetItem(m_hwndCrit, &lvitem))
  997. {
  998. fRet = FALSE;
  999. goto exit;
  1000. }
  1001. if (INDEXTOSTATEIMAGEMASK(iiconStateDisabled+1) == lvitem.state)
  1002. {
  1003. fRet = TRUE;
  1004. goto exit;
  1005. }
  1006. // Do we need to go through and update all the items?
  1007. if (0 != (c_rgEditCritList[lvitem.lParam].dwFlags & STATE_EXCLUSIVE))
  1008. {
  1009. // Figure out how many items are in the list control
  1010. cItems = ListView_GetItemCount(m_hwndCrit);
  1011. // Initialize the list view item structure
  1012. lvi.mask = LVIF_PARAM | LVIF_STATE;
  1013. lvi.stateMask = LVIS_STATEIMAGEMASK;
  1014. // For each item in the list
  1015. for (lvi.iItem = 0; lvi.iItem < cItems; lvi.iItem++)
  1016. {
  1017. // Get the item from the list
  1018. if (FALSE == ListView_GetItem(m_hwndCrit, &lvi))
  1019. {
  1020. fRet = FALSE;
  1021. goto exit;
  1022. }
  1023. // We'll handle this item later
  1024. if (lvitem.lParam == lvi.lParam)
  1025. {
  1026. iItem = lvi.iItem;
  1027. continue;
  1028. }
  1029. // If it's enabled
  1030. if (INDEXTOSTATEIMAGEMASK(iiconStateChecked + 1) == lvi.state)
  1031. {
  1032. // Remove it from the criteria
  1033. if (FAILED(m_pDescriptUI->HrEnableCriteria(c_rgEditCritList[lvi.lParam].typeCrit, FALSE)))
  1034. {
  1035. fRet = FALSE;
  1036. goto exit;
  1037. }
  1038. #ifdef NEVER
  1039. // if it allows dups
  1040. if (0 == (c_rgEditCritList[lvi.lParam].dwFlags & STATE_NODUPS))
  1041. {
  1042. // remove it
  1043. if (FALSE == ListView_DeleteItem(m_hwndCrit, lvi.iItem))
  1044. {
  1045. fRet = FALSE;
  1046. goto exit;
  1047. }
  1048. // Subtract the item
  1049. cItems--;
  1050. lvi.iItem--;
  1051. }
  1052. else
  1053. #endif // NEVER
  1054. {
  1055. // disable
  1056. ListView_SetItemState(m_hwndCrit, lvi.iItem, INDEXTOSTATEIMAGEMASK(iiconStateDisabled + 1), LVIS_STATEIMAGEMASK);
  1057. }
  1058. }
  1059. else
  1060. {
  1061. if (FALSE == fEnable)
  1062. {
  1063. dwState = INDEXTOSTATEIMAGEMASK(iiconStateUnchecked + 1);
  1064. }
  1065. else
  1066. {
  1067. dwState = INDEXTOSTATEIMAGEMASK(iiconStateDisabled + 1);
  1068. }
  1069. // uncheck/disable it
  1070. ListView_SetItemState(m_hwndCrit, lvi.iItem, dwState, LVIS_STATEIMAGEMASK);
  1071. }
  1072. }
  1073. }
  1074. // Add/Remove the item from the description
  1075. if (FAILED(m_pDescriptUI->HrEnableCriteria(c_rgEditCritList[lvitem.lParam].typeCrit, fEnable)))
  1076. {
  1077. fRet = FALSE;
  1078. goto exit;
  1079. }
  1080. if (FALSE != fEnable)
  1081. {
  1082. #ifdef NEVER
  1083. // Can we add another one?
  1084. if (0 == (c_rgEditCritList[lvitem.lParam].dwFlags & STATE_NODUPS))
  1085. {
  1086. // Fix up the item to insert into the list
  1087. lvitem.state = INDEXTOSTATEIMAGEMASK(iiconStateUnchecked+1);
  1088. // Insert the item into the list
  1089. lvitem.iItem++;
  1090. if (-1 == ListView_InsertItem(m_hwndCrit, &lvitem))
  1091. {
  1092. fRet = FALSE;
  1093. goto exit;
  1094. }
  1095. }
  1096. #endif // NEVER
  1097. // Set the item to enabled
  1098. ListView_SetItemState(m_hwndCrit, iItem, INDEXTOSTATEIMAGEMASK(iiconStateChecked+1), LVIS_STATEIMAGEMASK);
  1099. }
  1100. else
  1101. {
  1102. #ifdef NEVER
  1103. // Can we remove this one?
  1104. if (0 == (c_rgEditCritList[lvitem.lParam].dwFlags & STATE_NODUPS))
  1105. {
  1106. // Remove the inserted item
  1107. if (FALSE == ListView_DeleteItem(m_hwndCrit, iItem))
  1108. {
  1109. fRet = FALSE;
  1110. goto exit;
  1111. }
  1112. }
  1113. else
  1114. #endif // NEVER
  1115. {
  1116. // Set the item to enabled
  1117. ListView_SetItemState(m_hwndCrit, iItem, INDEXTOSTATEIMAGEMASK(iiconStateUnchecked + 1), LVIS_STATEIMAGEMASK);
  1118. }
  1119. }
  1120. fRet = TRUE;
  1121. exit:
  1122. return fRet;
  1123. }
  1124. ///////////////////////////////////////////////////////////////////////////////
  1125. //
  1126. // _FInitializeActListCtrl
  1127. //
  1128. // This initializes the actions list view with the list of actions
  1129. //
  1130. // Returns: TRUE, if it was successfully loaded
  1131. // FALSE, otherwise
  1132. //
  1133. ///////////////////////////////////////////////////////////////////////////////
  1134. BOOL CEditRuleUI::_FInitializeActListCtrl(void)
  1135. {
  1136. BOOL fRet = FALSE;
  1137. LVCOLUMN lvc;
  1138. RECT rc;
  1139. HIMAGELIST himl = NULL;
  1140. HRESULT hr = S_OK;
  1141. ACT_ITEM * pActItem = NULL;
  1142. ULONG cActItem = 0;
  1143. ULONG ulIndex = 0;
  1144. UINT uiEditActList = 0;
  1145. DWORD dwIndex = 0;
  1146. const ACT_LIST * pActList = NULL;
  1147. LVITEM lvi;
  1148. TCHAR szRes[CCHMAX_STRINGRES];
  1149. UINT cchRes = 0;
  1150. LPTSTR pszMark = NULL;
  1151. BOOL fEnabled = FALSE;
  1152. BOOL fExclusive = FALSE;
  1153. PROPVARIANT propvar;
  1154. Assert(NULL != m_hwndAct);
  1155. ZeroMemory(&propvar, sizeof(propvar));
  1156. // Initialize the list view structure
  1157. ZeroMemory(&lvc, sizeof(lvc));
  1158. lvc.mask = LVCF_WIDTH;
  1159. // Calculate the size of the list view
  1160. GetClientRect(m_hwndAct, &rc);
  1161. lvc.cx = rc.right - GetSystemMetrics(SM_CXVSCROLL);
  1162. ListView_InsertColumn(m_hwndAct, 0, &lvc);
  1163. // Set the state image list
  1164. himl = ImageList_LoadBitmap(g_hLocRes, MAKEINTRESOURCE(idb16x16st), 16, 0, RGB(255, 0, 255));
  1165. if (NULL != himl)
  1166. {
  1167. ListView_SetImageList(m_hwndAct, himl, LVSIL_STATE);
  1168. }
  1169. // Full row selection on listview
  1170. ListView_SetExtendedListViewStyle(m_hwndAct, LVS_EX_FULLROWSELECT);
  1171. // Get the list of actions from the rule
  1172. hr = m_pIRule->GetProp(RULE_PROP_ACTIONS, 0, &propvar);
  1173. if (SUCCEEDED(hr) && (0 != propvar.blob.cbSize))
  1174. {
  1175. cActItem = propvar.blob.cbSize / sizeof(ACT_ITEM);
  1176. pActItem = (ACT_ITEM *) (propvar.blob.pBlobData);
  1177. propvar.blob.pBlobData = NULL;
  1178. propvar.blob.cbSize = 0;
  1179. }
  1180. // Do we have any exclusive actions
  1181. for (ulIndex = 0; ulIndex < cActItem; ulIndex++)
  1182. {
  1183. for (uiEditActList = 0; uiEditActList < ARRAYSIZE(c_rgEditActList); uiEditActList++)
  1184. {
  1185. pActList = &(c_rgEditActList[uiEditActList]);
  1186. if ((pActItem[ulIndex].type == pActList->typeAct) &&
  1187. (0 != (pActList->dwFlags & STATE_EXCLUSIVE)))
  1188. {
  1189. fExclusive = TRUE;
  1190. break;
  1191. }
  1192. }
  1193. }
  1194. // Add the actions to the list view
  1195. for (uiEditActList = 0; uiEditActList < ARRAYSIZE(c_rgEditActList); uiEditActList++)
  1196. {
  1197. pActList = &(c_rgEditActList[uiEditActList]);
  1198. // Is this item editable
  1199. if (0 != (pActList->dwFlags & STATE_NOEDIT))
  1200. {
  1201. continue;
  1202. }
  1203. // Is this action valid for this type of rule?
  1204. if (((RULE_TYPE_MAIL == m_typeRule) && (0 == (pActList->dwFlags & STATE_MAIL))) ||
  1205. ((RULE_TYPE_NEWS == m_typeRule) && (0 == (pActList->dwFlags & STATE_NEWS))) ||
  1206. ((RULE_TYPE_FILTER == m_typeRule) && (0 == (pActList->dwFlags & STATE_FILTER))) ||
  1207. ((RULE_TYPE_MAIL == m_typeRule) && (0 != (pActList->dwFlags & STATE_JUNK))
  1208. && (0 == (g_dwAthenaMode & MODE_JUNKMAIL))
  1209. ))
  1210. {
  1211. continue;
  1212. }
  1213. // Is this action enabled?
  1214. fEnabled = FALSE;
  1215. for (ulIndex = 0; ulIndex < cActItem; ulIndex++)
  1216. {
  1217. if (pActItem[ulIndex].type == pActList->typeAct)
  1218. {
  1219. fEnabled = TRUE;
  1220. break;
  1221. }
  1222. }
  1223. ZeroMemory(&lvi, sizeof(lvi));
  1224. lvi.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM | LVIF_STATE;
  1225. lvi.iItem = dwIndex;
  1226. lvi.iSubItem = 0;
  1227. lvi.stateMask = LVIS_STATEIMAGEMASK;
  1228. if (FALSE != fEnabled)
  1229. {
  1230. lvi.state = INDEXTOSTATEIMAGEMASK(iiconStateChecked+1);
  1231. }
  1232. else
  1233. {
  1234. lvi.state = fExclusive ? INDEXTOSTATEIMAGEMASK(iiconStateDisabled+1)
  1235. : INDEXTOSTATEIMAGEMASK(iiconStateUnchecked+1);
  1236. }
  1237. // Load up the string to use.
  1238. cchRes = LoadString(g_hLocRes, pActList->uiText, szRes, ARRAYSIZE(szRes));
  1239. if (0 == cchRes)
  1240. {
  1241. continue;
  1242. }
  1243. // Parse out the string mark
  1244. pszMark = StrStr(szRes, c_szRuleMarkStart);
  1245. while (NULL != pszMark)
  1246. {
  1247. // Remove the mark start
  1248. StrCpyN(pszMark, pszMark + lstrlen(c_szRuleMarkStart), (DWORD)(ARRAYSIZE(szRes) - (pszMark - szRes)));
  1249. // Search for the mark end
  1250. pszMark = StrStr(pszMark, c_szRuleMarkEnd);
  1251. if (NULL == pszMark)
  1252. {
  1253. fRet = FALSE;
  1254. goto exit;
  1255. }
  1256. // Remove the mark end
  1257. StrCpyN(pszMark, pszMark + lstrlen(c_szRuleMarkEnd), (DWORD)(ARRAYSIZE(szRes) - (pszMark - szRes)));
  1258. // Search for the mark start
  1259. pszMark = StrStr(pszMark, c_szRuleMarkStart);
  1260. }
  1261. lvi.pszText = szRes;
  1262. lvi.cchTextMax = lstrlen(szRes);
  1263. lvi.lParam = (LONG) uiEditActList;
  1264. if (-1 != ListView_InsertItem(m_hwndAct, &lvi))
  1265. {
  1266. dwIndex++;
  1267. }
  1268. }
  1269. ListView_SetItemState(m_hwndAct, 0, LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED);
  1270. fRet = TRUE;
  1271. exit:
  1272. RuleUtil_HrFreeActionsItem(pActItem, cActItem);
  1273. SafeMemFree(pActItem);
  1274. return fRet;
  1275. }
  1276. VOID CEditRuleUI::_SetTitleText(VOID)
  1277. {
  1278. CHAR rgchTitle[CCHMAX_STRINGRES];
  1279. UINT uiID = 0;
  1280. // Figure out which string to load
  1281. switch (m_typeRule)
  1282. {
  1283. case RULE_TYPE_MAIL:
  1284. if (0 != (m_dwFlags & ERF_NEWRULE))
  1285. {
  1286. uiID = idsNewMailRuleTitle;
  1287. }
  1288. else
  1289. {
  1290. uiID = idsEditMailRuleTitle;
  1291. }
  1292. break;
  1293. case RULE_TYPE_NEWS:
  1294. if (0 != (m_dwFlags & ERF_NEWRULE))
  1295. {
  1296. uiID = idsNewNewsRuleTitle;
  1297. }
  1298. else
  1299. {
  1300. uiID = idsEditNewsRuleTitle;
  1301. }
  1302. break;
  1303. case RULE_TYPE_FILTER:
  1304. if (0 != (m_dwFlags & ERF_CUSTOMIZEVIEW))
  1305. {
  1306. uiID = idsCustomizeViewTitle;
  1307. }
  1308. else if (0 != (m_dwFlags & ERF_NEWRULE))
  1309. {
  1310. uiID = idsNewViewTitle;
  1311. }
  1312. else
  1313. {
  1314. uiID = idsEditViewTitle;
  1315. }
  1316. break;
  1317. }
  1318. // Is there anything to do?
  1319. if (0 == uiID)
  1320. {
  1321. goto exit;
  1322. }
  1323. // Load the string
  1324. AthLoadString(uiID, rgchTitle, sizeof(rgchTitle));
  1325. // Set the title
  1326. SetWindowText(m_hwndDlg, rgchTitle);
  1327. exit:
  1328. return;
  1329. }