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.

1026 lines
28 KiB

  1. ///////////////////////////////////////////////////////////////////////////////
  2. //
  3. // AplyRule.cpp
  4. //
  5. ///////////////////////////////////////////////////////////////////////////////
  6. #include <pch.hxx>
  7. #include "aplyrule.h"
  8. #include "ruledesc.h"
  9. #include "rulesui.h"
  10. #include "ruleutil.h"
  11. #include "rulesmgr.h"
  12. #include "rule.h"
  13. #include "reutil.h"
  14. #include <rulesdlg.h>
  15. #include <imagelst.h>
  16. #include <newfldr.h>
  17. #include <storutil.h>
  18. #include "shlwapip.h"
  19. #include <xpcomm.h>
  20. #include <demand.h>
  21. // Global data
  22. const static HELPMAP g_rgCtxMapApplyMail[] = {
  23. {idlvRulesApplyList, idhRulesList},
  24. {idcApplyRulesAll, idhApplyRulesAll},
  25. {idcApplyRulesNone, idhApplyRulesNone},
  26. {idredtApplyDescription, idhApplyDescription},
  27. {idcApplyFolder, idhApplyFolder},
  28. {idcBrowseApplyFolder, idhBrowseApplyFolder},
  29. {idcRulesApplySubfolder, idhApplySubfolder},
  30. {idcRulesApply, idhApplyNow},
  31. {0, 0}};
  32. COEApplyRulesUI::~COEApplyRulesUI()
  33. {
  34. RULENODE * prnodeWalk = NULL;
  35. if (NULL != m_pDescriptUI)
  36. {
  37. delete m_pDescriptUI;
  38. }
  39. // Free up any rules
  40. while (NULL != m_prnodeList)
  41. {
  42. prnodeWalk = m_prnodeList;
  43. if (NULL != prnodeWalk->pIRule)
  44. {
  45. prnodeWalk->pIRule->Release();
  46. }
  47. m_prnodeList = m_prnodeList->pNext;
  48. delete prnodeWalk; // MemFree(prnodeWalk);
  49. }
  50. }
  51. HRESULT COEApplyRulesUI::HrInit(HWND hwndOwner, DWORD dwFlags, RULE_TYPE typeRule, RULENODE * prnode, IOERule * pIRuleDef)
  52. {
  53. HRESULT hr = S_OK;
  54. // Check incoming params
  55. if (NULL == hwndOwner)
  56. {
  57. hr = E_INVALIDARG;
  58. goto exit;
  59. }
  60. if (0 != (m_dwState & STATE_INITIALIZED))
  61. {
  62. hr = E_UNEXPECTED;
  63. goto exit;
  64. }
  65. m_hwndOwner = hwndOwner;
  66. m_dwFlags = dwFlags;
  67. m_typeRule = typeRule;
  68. m_pIRuleDef = pIRuleDef;
  69. // Setup the description field
  70. m_pDescriptUI = new CRuleDescriptUI;
  71. if (NULL == m_pDescriptUI)
  72. {
  73. hr = E_OUTOFMEMORY;
  74. goto exit;
  75. }
  76. // We own the list now...
  77. m_prnodeList = prnode;
  78. m_dwState |= STATE_INITIALIZED;
  79. hr = S_OK;
  80. exit:
  81. return hr;
  82. }
  83. HRESULT COEApplyRulesUI::HrShow(VOID)
  84. {
  85. HRESULT hr = S_OK;
  86. int iRet = 0;
  87. if (0 == (m_dwState & STATE_INITIALIZED))
  88. {
  89. hr = E_UNEXPECTED;
  90. goto exit;
  91. }
  92. // We need to load richedit
  93. if (FALSE == FInitRichEdit(TRUE))
  94. {
  95. hr = E_FAIL;
  96. goto exit;
  97. }
  98. iRet = (INT) DialogBoxParam(g_hLocRes, MAKEINTRESOURCE(iddRuleApplyTo),
  99. m_hwndOwner, COEApplyRulesUI::FOEApplyRulesDlgProc,
  100. (LPARAM) this);
  101. if (-1 == iRet)
  102. {
  103. hr = E_FAIL;
  104. goto exit;
  105. }
  106. // Set the proper return code
  107. hr = (IDOK == iRet) ? S_OK : S_FALSE;
  108. exit:
  109. return hr;
  110. }
  111. INT_PTR CALLBACK COEApplyRulesUI::FOEApplyRulesDlgProc(HWND hwndDlg, UINT uiMsg, WPARAM wParam, LPARAM lParam)
  112. {
  113. BOOL fRet = FALSE;
  114. COEApplyRulesUI * pApplyRulesUI = NULL;
  115. HWND hwndRE = 0;
  116. pApplyRulesUI = (COEApplyRulesUI *) GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
  117. switch (uiMsg)
  118. {
  119. case WM_INITDIALOG:
  120. // Grab the UI object pointer
  121. pApplyRulesUI = (COEApplyRulesUI *) lParam;
  122. // Set it into the dialog so we can get it back
  123. SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LPARAM) pApplyRulesUI);
  124. hwndRE = CreateREInDialogA(hwndDlg, idredtApplyDescription);
  125. if (!hwndRE || (FALSE == pApplyRulesUI->FOnInitDialog(hwndDlg)))
  126. {
  127. EndDialog(hwndDlg, -1);
  128. fRet = TRUE;
  129. goto exit;
  130. }
  131. // We set the focus
  132. fRet = FALSE;
  133. break;
  134. case WM_COMMAND:
  135. fRet = pApplyRulesUI->FOnCommand((UINT) HIWORD(wParam), (INT) LOWORD(wParam), (HWND) lParam);
  136. break;
  137. case WM_DESTROY:
  138. fRet = pApplyRulesUI->FOnDestroy();
  139. break;
  140. case WM_HELP:
  141. case WM_CONTEXTMENU:
  142. fRet = OnContextHelp(hwndDlg, uiMsg, wParam, lParam, g_rgCtxMapApplyMail);
  143. break;
  144. }
  145. exit:
  146. return fRet;
  147. }
  148. ///////////////////////////////////////////////////////////////////////////////
  149. //
  150. // FOnInitDialog
  151. //
  152. // This handles the WM_INITDIALOG message for the mail rules UI dialog
  153. //
  154. // hwndDlg - the handle to the dialog window
  155. //
  156. // Returns: TRUE, if it was successfully initialized
  157. // FALSE, otherwise
  158. //
  159. ///////////////////////////////////////////////////////////////////////////////
  160. BOOL COEApplyRulesUI::FOnInitDialog(HWND hwndDlg)
  161. {
  162. BOOL fRet = FALSE;
  163. HRESULT hr = S_OK;
  164. TCHAR szRes[CCHMAX_STRINGRES];
  165. FOLDERID idDefault;
  166. FOLDERINFO fldinfo = {0};
  167. BOOL fEnable = FALSE;
  168. IEnumerateFolders * pChildren=NULL;
  169. // Check incoming params
  170. if (NULL == hwndDlg)
  171. {
  172. fRet = FALSE;
  173. goto exit;
  174. }
  175. // If we haven't been initialized yet...
  176. if (0 == (m_dwState & STATE_INITIALIZED))
  177. {
  178. fRet = FALSE;
  179. goto exit;
  180. }
  181. // Save off the dialog window handle
  182. m_hwndDlg = hwndDlg;
  183. // Set the default font onto the dialog
  184. SetIntlFont(m_hwndDlg);
  185. // Save off some of the controls
  186. m_hwndList = GetDlgItem(hwndDlg, idlvRulesApplyList);
  187. m_hwndDescript = GetDlgItem(hwndDlg, idredtApplyDescription);
  188. if ((NULL == m_hwndList) || (NULL == m_hwndDescript))
  189. {
  190. fRet = FALSE;
  191. goto exit;
  192. }
  193. if (FAILED(m_pDescriptUI->HrInit(m_hwndDescript, RDF_READONLY | RDF_APPLYDLG)))
  194. {
  195. fRet = FALSE;
  196. goto exit;
  197. }
  198. // Figure out the default folder to select
  199. if (RULE_TYPE_MAIL == m_typeRule)
  200. {
  201. if (SUCCEEDED(g_pStore->GetSpecialFolderInfo(FOLDERID_LOCAL_STORE, FOLDER_INBOX, &fldinfo)))
  202. {
  203. idDefault = fldinfo.idFolder;
  204. }
  205. else
  206. {
  207. idDefault = FOLDERID_LOCAL_STORE;
  208. }
  209. }
  210. else
  211. {
  212. // Get default news server from accoutn manager
  213. if (FAILED(GetDefaultServerId(ACCT_NEWS, &idDefault)))
  214. {
  215. idDefault = FOLDERID_ROOT;
  216. m_dwState |= STATE_NONEWSACCT;
  217. }
  218. else
  219. {
  220. if ((SUCCEEDED(g_pStore->EnumChildren(idDefault, TRUE, &pChildren))) &&
  221. (S_OK == pChildren->Next(1, &fldinfo, NULL)))
  222. {
  223. idDefault = fldinfo.idFolder;
  224. }
  225. }
  226. }
  227. if (FAILED(InitFolderPickerEdit(GetDlgItem(m_hwndDlg, idcApplyFolder), idDefault)))
  228. {
  229. fRet = FALSE;
  230. goto exit;
  231. }
  232. // What should the default subfolder state be?
  233. fEnable = TRUE;
  234. if ((FOLDERID_ROOT == idDefault) || (FOLDERID_LOCAL_STORE == idDefault) || (0 != (fldinfo.dwFlags & FOLDER_SERVER)))
  235. {
  236. CheckDlgButton(m_hwndDlg, idcRulesApplySubfolder, BST_CHECKED);
  237. fEnable = FALSE;
  238. }
  239. else if (0 == (fldinfo.dwFlags & FOLDER_HASCHILDREN))
  240. {
  241. CheckDlgButton(m_hwndDlg, idcRulesApplySubfolder, BST_UNCHECKED);
  242. fEnable = FALSE;
  243. }
  244. // Should the subfolder button be enabled?
  245. RuleUtil_FEnDisDialogItem(m_hwndDlg, idcRulesApplySubfolder, fEnable);
  246. // Load the list view
  247. fRet = _FLoadListCtrl();
  248. if (FALSE == fRet)
  249. {
  250. goto exit;
  251. }
  252. // Get the proper title string
  253. AthLoadString((RULE_TYPE_MAIL == m_typeRule) ? idsRulesApplyMail : idsRulesApplyNews, szRes, ARRAYSIZE(szRes));
  254. // Set the proper window text
  255. SetWindowText(m_hwndDlg, szRes);
  256. // Note that we've been loaded
  257. m_dwState |= STATE_LOADED;
  258. // Everything's AOK
  259. fRet = TRUE;
  260. exit:
  261. g_pStore->FreeRecord(&fldinfo);
  262. SafeRelease(pChildren);
  263. return fRet;
  264. }
  265. ///////////////////////////////////////////////////////////////////////////////
  266. //
  267. // FOnCommand
  268. //
  269. // This handles the WM_COMMAND message for the mail rules UI dialog
  270. //
  271. // Returns: TRUE, if it was successfully handled
  272. // FALSE, otherwise
  273. //
  274. ///////////////////////////////////////////////////////////////////////////////
  275. BOOL COEApplyRulesUI::FOnCommand(UINT uiNotify, INT iCtl, HWND hwndCtl)
  276. {
  277. BOOL fRet = FALSE;
  278. FOLDERINFO fldinfo;
  279. HWND hwndFolder = NULL;
  280. FOLDERID idFolder;
  281. BOOL fEnable;
  282. FOLDERDIALOGFLAGS dwFlags = 0;
  283. INT cItems = 0;
  284. INT iSelected = 0;
  285. CHAR rgchTitle[CCHMAX_STRINGRES];
  286. switch (iCtl)
  287. {
  288. case IDCANCEL:
  289. if (FALSE != _FOnClose())
  290. {
  291. EndDialog(m_hwndDlg, IDOK);
  292. fRet = TRUE;
  293. }
  294. break;
  295. case idcBrowseApplyFolder:
  296. if (BN_CLICKED == uiNotify )
  297. {
  298. dwFlags = TREEVIEW_NOIMAP | TREEVIEW_NOHTTP | FD_NONEWFOLDERS;
  299. if (RULE_TYPE_MAIL == m_typeRule)
  300. {
  301. dwFlags |= TREEVIEW_NONEWS;
  302. }
  303. else
  304. {
  305. dwFlags |= TREEVIEW_NOLOCAL;
  306. }
  307. AthLoadString(idsApplyRuleTitle, rgchTitle, sizeof(rgchTitle));
  308. if (SUCCEEDED(PickFolderInEdit(m_hwndDlg, GetDlgItem(m_hwndDlg, idcApplyFolder), dwFlags, rgchTitle, NULL, &idFolder)))
  309. {
  310. if (SUCCEEDED(g_pStore->GetFolderInfo(idFolder, &fldinfo)))
  311. {
  312. if ((0 != (fldinfo.dwFlags & FOLDER_SERVER)) || (FOLDERID_ROOT == fldinfo.idFolder))
  313. {
  314. SendDlgItemMessage(m_hwndDlg, idcRulesApplySubfolder,
  315. BM_SETCHECK, (WPARAM) BST_CHECKED, (LPARAM) 0);
  316. }
  317. else if (0 == (fldinfo.dwFlags & FOLDER_HASCHILDREN))
  318. {
  319. SendDlgItemMessage(m_hwndDlg, idcRulesApplySubfolder,
  320. BM_SETCHECK, (WPARAM) BST_UNCHECKED, (LPARAM) 0);
  321. }
  322. fEnable = (0 != (fldinfo.dwFlags & FOLDER_HASCHILDREN)) &&
  323. (0 == (fldinfo.dwFlags & FOLDER_SERVER)) && (FOLDERID_ROOT != fldinfo.idFolder);
  324. RuleUtil_FEnDisDialogItem(m_hwndDlg, idcRulesApplySubfolder, fEnable);
  325. g_pStore->FreeRecord(&fldinfo);
  326. fRet = TRUE;
  327. }
  328. }
  329. }
  330. break;
  331. case idcRulesApply:
  332. // Check to see if we should handle this
  333. if (0 != (m_dwState & STATE_NONEWSACCT))
  334. {
  335. AthMessageBoxW(m_hwndDlg, MAKEINTRESOURCEW(idsAthena),
  336. MAKEINTRESOURCEW(idsApplyRulesNoNewsFolders), NULL, MB_OK | MB_ICONERROR);
  337. fRet = FALSE;
  338. }
  339. else
  340. {
  341. fRet = _FOnApplyRules();
  342. }
  343. break;
  344. case idcApplyRulesAll:
  345. case idcApplyRulesNone:
  346. if (NULL != m_hwndList)
  347. {
  348. cItems = (INT) SendMessage(m_hwndList, LB_GETCOUNT, (WPARAM) 0, (LPARAM) 0);
  349. if (LB_ERR != cItems)
  350. {
  351. fEnable = (idcApplyRulesAll == iCtl);
  352. SendMessage(m_hwndList, LB_SELITEMRANGE, (WPARAM) fEnable, (LPARAM) MAKELPARAM(0, cItems));
  353. // Set the focus on the first item
  354. SendMessage(m_hwndList, LB_SETCARETINDEX, (WPARAM) 0, (LPARAM) MAKELPARAM(FALSE, 0));
  355. // Enable the buttons
  356. _EnableButtons(0);
  357. }
  358. }
  359. break;
  360. case idlvRulesApplyList:
  361. if (LBN_SELCHANGE == uiNotify)
  362. {
  363. iSelected = (INT) SendMessage(hwndCtl, LB_GETCARETINDEX, (WPARAM) 0, (LPARAM) 0);
  364. // Enable the buttons
  365. _EnableButtons(iSelected);
  366. }
  367. break;
  368. }
  369. return fRet;
  370. }
  371. ///////////////////////////////////////////////////////////////////////////////
  372. //
  373. // FOnDestroy
  374. //
  375. // This handles the WM_DESTROY message for the mail rules UI dialog
  376. //
  377. // Returns: TRUE, if it was successfully destroyed
  378. // FALSE, otherwise
  379. //
  380. ///////////////////////////////////////////////////////////////////////////////
  381. BOOL COEApplyRulesUI::FOnDestroy(VOID)
  382. {
  383. BOOL fRet = FALSE;
  384. INT cRules = 0;
  385. INT iIndex = 0;
  386. DWORD_PTR dwData = 0;
  387. Assert(m_hwndList);
  388. // Get the number of rules in the list view
  389. cRules = (INT) SendMessage(m_hwndList, LB_GETCOUNT, (WPARAM) 0, (LPARAM) 0);
  390. if (LB_ERR == cRules)
  391. {
  392. fRet = FALSE;
  393. goto exit;
  394. }
  395. // Release each of the rules from the list view
  396. for (iIndex = 0; iIndex < cRules; iIndex++)
  397. {
  398. // Get the rule interface
  399. dwData = SendMessage(m_hwndList, LB_GETITEMDATA, (WPARAM) iIndex, (LPARAM) 0);
  400. if ((LB_ERR == dwData) || (NULL == dwData))
  401. {
  402. continue;
  403. }
  404. // Release the rule
  405. ((IOERule *) (dwData))->Release();
  406. }
  407. exit:
  408. return fRet;
  409. }
  410. BOOL COEApplyRulesUI::_FOnClose(VOID)
  411. {
  412. return TRUE;
  413. }
  414. ///////////////////////////////////////////////////////////////////////////////
  415. //
  416. // _FLoadListCtrl
  417. //
  418. // This loads the list view with the current Mail rules
  419. //
  420. // Returns: TRUE, if it was successfully loaded
  421. // FALSE, otherwise
  422. //
  423. ///////////////////////////////////////////////////////////////////////////////
  424. BOOL COEApplyRulesUI::_FLoadListCtrl(VOID)
  425. {
  426. BOOL fRet = FALSE;
  427. HRESULT hr = S_OK;
  428. DWORD dwListIndex = 0;
  429. RULENODE * prnodeWalk = NULL;
  430. INT iDefault = 0;
  431. Assert(NULL != m_hwndList);
  432. // Remove all the items from the list control
  433. SendMessage(m_hwndList, LB_RESETCONTENT, (WPARAM) 0, (LPARAM) 0);
  434. // Add each filter to the list
  435. dwListIndex = 0;
  436. while (NULL != m_prnodeList)
  437. {
  438. // Add rule to the list
  439. if (NULL != m_prnodeList->pIRule)
  440. {
  441. if (FALSE != _FAddRuleToList(dwListIndex, m_prnodeList->pIRule))
  442. {
  443. if (m_pIRuleDef == m_prnodeList->pIRule)
  444. {
  445. iDefault = dwListIndex;
  446. }
  447. dwListIndex++;
  448. }
  449. m_prnodeList->pIRule->Release();
  450. }
  451. prnodeWalk = m_prnodeList;
  452. m_prnodeList = m_prnodeList->pNext;
  453. delete prnodeWalk; // MemFree(prnodeWalk);
  454. }
  455. if (0 != dwListIndex)
  456. {
  457. // Select the default
  458. SendMessage(m_hwndList, LB_SETSEL, (WPARAM) TRUE, (LPARAM) iDefault);
  459. // Set the focus on the item also
  460. SendMessage(m_hwndList, LB_SETCARETINDEX, (WPARAM) iDefault, (LPARAM) MAKELPARAM(FALSE, 0));
  461. }
  462. // Enable the dialog buttons.
  463. _EnableButtons((0 != dwListIndex) ? iDefault : -1);
  464. fRet = TRUE;
  465. return fRet;
  466. }
  467. ///////////////////////////////////////////////////////////////////////////////
  468. //
  469. // _FAddRuleToList
  470. //
  471. // This adds the filter passed in to the list view
  472. //
  473. // dwIndex - the index on where to add the filter to into the list
  474. // pIRule - the actual rule
  475. //
  476. // Returns: TRUE, if it was successfully added
  477. // FALSE, otherwise
  478. //
  479. ///////////////////////////////////////////////////////////////////////////////
  480. BOOL COEApplyRulesUI::_FAddRuleToList(DWORD dwIndex, IOERule * pIRule)
  481. {
  482. BOOL fRet = FALSE;
  483. HRESULT hr = S_OK;
  484. PROPVARIANT propvar = {0};
  485. Assert(NULL != m_hwndList);
  486. // If there's nothing to do...
  487. if (NULL == pIRule)
  488. {
  489. fRet = FALSE;
  490. goto exit;
  491. }
  492. // Find out the name of the filter
  493. hr = pIRule->GetProp(RULE_PROP_NAME , 0, &propvar);
  494. if (FAILED(hr))
  495. {
  496. fRet = FALSE;
  497. goto exit;
  498. }
  499. // Insert the rule name
  500. dwIndex = (DWORD) SendMessage(m_hwndList, LB_INSERTSTRING, (WPARAM) dwIndex, (LPARAM) propvar.pszVal);
  501. if (LB_ERR == dwIndex)
  502. {
  503. fRet = FALSE;
  504. goto exit;
  505. }
  506. // Set the rule into the item
  507. if (LB_ERR == SendMessage(m_hwndList, LB_SETITEMDATA, (WPARAM) dwIndex, (LPARAM) pIRule))
  508. {
  509. fRet = FALSE;
  510. goto exit;
  511. }
  512. // Hold a reference to the rule object
  513. pIRule->AddRef();
  514. fRet = TRUE;
  515. exit:
  516. PropVariantClear(&propvar);
  517. return fRet;
  518. }
  519. ///////////////////////////////////////////////////////////////////////////////
  520. //
  521. // _EnableButtons
  522. //
  523. // This enables or disables the buttons in the Mail rules UI dialog
  524. // depending on what is selected.
  525. //
  526. // iSelected - the item that was selected,
  527. // -1 means that nothing was selected
  528. //
  529. // Returns: NONE
  530. //
  531. ///////////////////////////////////////////////////////////////////////////////
  532. VOID COEApplyRulesUI::_EnableButtons(INT iSelected)
  533. {
  534. BOOL fRet = FALSE;
  535. INT cRules = 0;
  536. INT cRulesSel = 0;
  537. // How many rules do we have?
  538. cRules = (INT) SendMessage(m_hwndList, LB_GETCOUNT, (WPARAM) 0, (LPARAM) 0);
  539. if (LB_ERR == cRules)
  540. {
  541. fRet = TRUE;
  542. goto exit;
  543. }
  544. if (0 != cRules)
  545. {
  546. // How many rules are selected?
  547. cRulesSel = (INT) SendMessage(m_hwndList, LB_GETSELCOUNT, (WPARAM) 0, (LPARAM) 0);
  548. if (LB_ERR == cRulesSel)
  549. {
  550. fRet = TRUE;
  551. goto exit;
  552. }
  553. }
  554. // Load the description field
  555. _LoadRule(iSelected);
  556. // Enable the rule action buttons
  557. RuleUtil_FEnDisDialogItem(m_hwndDlg, idcRulesApply, cRulesSel != 0);
  558. // Enable the selection buttons
  559. RuleUtil_FEnDisDialogItem(m_hwndDlg, idcApplyRulesNone, cRules != 0);
  560. RuleUtil_FEnDisDialogItem(m_hwndDlg, idcApplyRulesAll, cRules != 0);
  561. // Set the return value
  562. fRet = TRUE;
  563. exit:
  564. return;
  565. }
  566. ///////////////////////////////////////////////////////////////////////////////
  567. //
  568. // _LoadRule
  569. //
  570. // This loads the selected rule into the description field.
  571. // If there isn't a selected rule, then the description field is cleared.
  572. //
  573. // iSelected - the item that was selected,
  574. // -1 means that nothing was selected
  575. //
  576. // Returns: NONE
  577. //
  578. ///////////////////////////////////////////////////////////////////////////////
  579. void COEApplyRulesUI::_LoadRule(INT iSelected)
  580. {
  581. DWORD_PTR dwData = 0;
  582. IOERule * pIRule = NULL;
  583. Assert(NULL != m_hwndList);
  584. Assert(NULL != m_pDescriptUI);
  585. // Grab the rule from the list view
  586. if (-1 != iSelected)
  587. {
  588. dwData = SendMessage(m_hwndList, LB_GETITEMDATA, (WPARAM) iSelected, (LPARAM) 0);
  589. if (LB_ERR != dwData)
  590. {
  591. pIRule = (IOERule *) (dwData);
  592. }
  593. }
  594. // Have the description field load this rule
  595. m_pDescriptUI->HrSetRule(m_typeRule, pIRule);
  596. // Display the new rule
  597. m_pDescriptUI->ShowDescriptionString();
  598. return;
  599. }
  600. ///////////////////////////////////////////////////////////////////////////////
  601. //
  602. // FOnApplyTo
  603. //
  604. // This applies the rules into a folder
  605. //
  606. // Returns: NONE
  607. //
  608. ///////////////////////////////////////////////////////////////////////////////
  609. BOOL COEApplyRulesUI::_FOnApplyRules(VOID)
  610. {
  611. BOOL fRet = FALSE;
  612. FOLDERID idFolder = 0;
  613. INT cRulesAlloc = 0;
  614. INT * piItems = NULL;
  615. INT cRules = 0;
  616. INT iIndex = 0;
  617. DWORD_PTR dwData = 0;
  618. RULENODE * prnodeList = NULL;
  619. RULENODE * prnodeWalk = NULL;
  620. RULENODE * prnodeNew = NULL;
  621. CExecRules * pExecRules = NULL;
  622. IOEExecRules * pIExecRules = NULL;
  623. RECURSEAPPLY rapply;
  624. DWORD dwFlags;
  625. CProgress * pProgress = NULL;
  626. ULONG cMsgs = 0;
  627. FOLDERINFO infoFolder = {0};
  628. CHAR rgchTmpl[CCHMAX_STRINGRES];
  629. LPSTR pszText = NULL;
  630. HRESULT hr = S_OK;
  631. #ifdef DEBUG
  632. DWORD dwTime = 0;
  633. #endif // DEBUG
  634. Assert(NULL != m_hwndList);
  635. idFolder = _FldIdGetFolderSel();
  636. // Get the count of rules
  637. cRulesAlloc = (INT) SendMessage(m_hwndList, LB_GETSELCOUNT, (WPARAM) 0, (LPARAM) 0);
  638. if (LB_ERR == cRulesAlloc)
  639. {
  640. fRet = FALSE;
  641. goto exit;
  642. }
  643. // Is there anything to do?
  644. if (0 == cRulesAlloc)
  645. {
  646. fRet = TRUE;
  647. goto exit;
  648. }
  649. // Allocate space tp hold the list of items
  650. if (FAILED(HrAlloc((VOID **) &piItems, sizeof(*piItems) * cRulesAlloc)))
  651. {
  652. fRet = FALSE;
  653. goto exit;
  654. }
  655. // Grab the list of items
  656. cRules = (INT) SendMessage(m_hwndList, LB_GETSELITEMS, (WPARAM) cRulesAlloc, (LPARAM) piItems);
  657. if (LB_ERR == cRules)
  658. {
  659. fRet = FALSE;
  660. goto exit;
  661. }
  662. // Grab each of the enabled rules
  663. for (iIndex = 0; iIndex < cRules; iIndex++)
  664. {
  665. // Get the rule from the list
  666. dwData = SendMessage(m_hwndList, LB_GETITEMDATA, (WPARAM) piItems[iIndex], (LPARAM) 0);
  667. if ((LB_ERR == dwData) || (NULL == dwData))
  668. {
  669. continue;
  670. }
  671. // Save the rule
  672. prnodeNew = new RULENODE;
  673. if (NULL == prnodeNew)
  674. {
  675. continue;
  676. }
  677. prnodeNew->pIRule = (IOERule *) dwData;
  678. prnodeNew->pIRule->AddRef();
  679. if (NULL == prnodeWalk)
  680. {
  681. prnodeList = prnodeNew;
  682. prnodeWalk = prnodeList;
  683. }
  684. else
  685. {
  686. prnodeWalk->pNext = prnodeNew;
  687. prnodeWalk = prnodeWalk->pNext;
  688. }
  689. prnodeNew = NULL;
  690. prnodeWalk->pNext = NULL;
  691. }
  692. // If we don't have any rules then just return
  693. if (NULL == prnodeList)
  694. {
  695. fRet = TRUE;
  696. goto exit;
  697. }
  698. // Create the executor object
  699. pExecRules = new CExecRules;
  700. if (NULL == pExecRules)
  701. {
  702. fRet = FALSE;
  703. goto exit;
  704. }
  705. // Initialize it with the list of rules
  706. if (FAILED(pExecRules->_HrInitialize(0, prnodeList)))
  707. {
  708. fRet = FALSE;
  709. goto exit;
  710. }
  711. // Grab the executor interface
  712. if (FAILED(pExecRules->QueryInterface(IID_IOEExecRules, (void **) &pIExecRules)))
  713. {
  714. fRet = FALSE;
  715. goto exit;
  716. }
  717. pExecRules = NULL;
  718. // Apply to rule to the folder
  719. rapply.pIExecRules = pIExecRules;
  720. dwFlags = RECURSE_INCLUDECURRENT;
  721. if (RULE_TYPE_MAIL == m_typeRule)
  722. {
  723. dwFlags |= RECURSE_ONLYLOCAL;
  724. }
  725. else
  726. {
  727. dwFlags |= RECURSE_ONLYNEWS;
  728. }
  729. if (BST_CHECKED == SendDlgItemMessage(m_hwndDlg, idcRulesApplySubfolder, BM_GETCHECK, (WPARAM) 0, (LPARAM) 0))
  730. {
  731. dwFlags |= RECURSE_SUBFOLDERS;
  732. }
  733. if (FAILED(RecurseFolderHierarchy(idFolder, dwFlags, 0, (DWORD_PTR)&cMsgs, (PFNRECURSECALLBACK)RecurseFolderCounts)))
  734. {
  735. fRet = FALSE;
  736. goto exit;
  737. }
  738. pProgress = new CProgress;
  739. if (NULL == pProgress)
  740. {
  741. fRet = FALSE;
  742. goto exit;
  743. }
  744. pProgress->Init(m_hwndDlg, MAKEINTRESOURCE(idsAthena),
  745. MAKEINTRESOURCE(idsApplyingRules), cMsgs, 0, TRUE, FALSE);
  746. // Show the progress dialog
  747. pProgress->Show(0);
  748. rapply.pProgress = pProgress;
  749. rapply.hwndOwner = pProgress->GetHwnd();
  750. #ifdef DEBUG
  751. dwTime = GetTickCount();
  752. #endif // DEBUG
  753. // Set up the timer
  754. hr = RecurseFolderHierarchy(idFolder, dwFlags, 0, (DWORD_PTR) &rapply, (PFNRECURSECALLBACK)_HrRecurseApplyFolder);
  755. #ifdef DEBUG
  756. // Time to Apply Rules
  757. TraceInfo(_MSG("Applying Rules Time: %d Milli-Seconds", GetTickCount() - dwTime));
  758. #endif // DEBUG
  759. // Close the progress window
  760. pProgress->Close();
  761. if (FAILED(hr))
  762. {
  763. fRet = FALSE;
  764. goto exit;
  765. }
  766. // Get the template string
  767. AthLoadString(idsApplyRulesFinished, rgchTmpl, sizeof(rgchTmpl));
  768. // Get the name of the folder
  769. if (SUCCEEDED(g_pStore->GetFolderInfo(idFolder, &infoFolder)))
  770. {
  771. // Allocate space to hold the final string
  772. DWORD cchSize = (sizeof(rgchTmpl) * lstrlen(infoFolder.pszName));
  773. if (SUCCEEDED(HrAlloc((VOID **) &pszText, cchSize * sizeof(*pszText))))
  774. {
  775. // Build up the final string
  776. wnsprintf(pszText, cchSize, rgchTmpl, infoFolder.pszName);
  777. // Show confirmation dialog
  778. AthMessageBox(m_hwndDlg, MAKEINTRESOURCE(idsAthena), pszText, NULL, MB_OK | MB_ICONINFORMATION);
  779. }
  780. }
  781. fRet = TRUE;
  782. exit:
  783. SafeMemFree(pszText);
  784. g_pStore->FreeRecord(&infoFolder);
  785. SafeRelease(pProgress);
  786. SafeRelease(pIExecRules);
  787. if (NULL != pExecRules)
  788. {
  789. delete pExecRules;
  790. }
  791. while (NULL != prnodeList)
  792. {
  793. prnodeWalk = prnodeList;
  794. if (NULL != prnodeWalk->pIRule)
  795. {
  796. prnodeWalk->pIRule->Release();
  797. }
  798. prnodeList = prnodeList->pNext;
  799. delete prnodeWalk; // MemFree(prnodeWalk);
  800. }
  801. if (NULL != prnodeNew)
  802. {
  803. if (NULL != prnodeNew->pIRule)
  804. {
  805. prnodeNew->pIRule->Release();
  806. }
  807. delete prnodeNew; //MemFree(prnodeNew);
  808. }
  809. SafeMemFree(piItems);
  810. if (FALSE == fRet)
  811. {
  812. AthMessageBoxW(m_hwndDlg, MAKEINTRESOURCEW(idsAthena),
  813. MAKEINTRESOURCEW(idsRulesApplyFail), NULL, MB_OK | MB_ICONERROR);
  814. }
  815. return fRet;
  816. }
  817. FOLDERID COEApplyRulesUI::_FldIdGetFolderSel(VOID)
  818. {
  819. return(GetFolderIdFromEdit(GetDlgItem(m_hwndDlg, idcApplyFolder)));
  820. }
  821. // --------------------------------------------------------------------------------
  822. HRESULT COEApplyRulesUI::_HrRecurseApplyFolder(FOLDERINFO * pfldinfo, BOOL fSubFolders,
  823. DWORD cIndent, DWORD_PTR dwpCookie)
  824. {
  825. HRESULT hr = S_OK;
  826. RECURSEAPPLY * prapply = NULL;
  827. IMessageFolder * pFolder = NULL;
  828. prapply = (RECURSEAPPLY *) dwpCookie;
  829. if (NULL == prapply)
  830. {
  831. goto exit;
  832. }
  833. // If not hidden
  834. if ((0 != (pfldinfo->dwFlags & FOLDER_HIDDEN)) || (FOLDERID_ROOT == pfldinfo->idFolder))
  835. {
  836. goto exit;
  837. }
  838. // Not Subscribed
  839. if (0 == (pfldinfo->dwFlags & FOLDER_SUBSCRIBED))
  840. {
  841. goto exit;
  842. }
  843. // Server node
  844. if (0 != (pfldinfo->dwFlags & FOLDER_SERVER))
  845. {
  846. goto exit;
  847. }
  848. hr = g_pStore->OpenFolder(pfldinfo->idFolder, NULL, NOFLAGS, &pFolder);
  849. if (FAILED(hr))
  850. {
  851. goto exit;
  852. }
  853. // Create the struct to insert
  854. hr = RuleUtil_HrApplyRulesToFolder(RULE_APPLY_SHOWUI, (FOLDER_LOCAL != pfldinfo->tyFolder) ? DELETE_MESSAGE_NOTRASHCAN : 0,
  855. prapply->pIExecRules, pFolder, prapply->hwndOwner, prapply->pProgress);
  856. if (FAILED(hr))
  857. {
  858. goto exit;
  859. }
  860. // If the user hit cancel then we're done
  861. if (S_FALSE == hr)
  862. {
  863. hr = E_FAIL;
  864. }
  865. exit:
  866. SafeRelease(pFolder);
  867. return(hr);
  868. }