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.

1962 lines
54 KiB

  1. ///////////////////////////////////////////////////////////////////////////////
  2. //
  3. // ViewsUI.cpp
  4. //
  5. ///////////////////////////////////////////////////////////////////////////////
  6. #include <pch.hxx>
  7. #include "viewsui.h"
  8. #include "editrule.h"
  9. #include "ruledesc.h"
  10. #include "ruleutil.h"
  11. #include "rulesmgr.h"
  12. #include "rule.h"
  13. #include "reutil.h"
  14. #include "shlwapip.h"
  15. #include <rulesdlg.h>
  16. #include <imagelst.h>
  17. #include <demand.h>
  18. INT_PTR CALLBACK FSelectApplyViewDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
  19. // Global data
  20. const static HELPMAP g_rgCtxMapViewsMgr[] = {
  21. {idbNewView, idhNewView},
  22. {idbModifyView, idhModifyView},
  23. {idbCopyView, idhCopyView},
  24. {idbDeleteView, idhRemoveView},
  25. {idbDefaultView, idhApplyView},
  26. {idredtViewDescription, idhViewDescription},
  27. {0, 0}};
  28. COEViewsMgrUI::COEViewsMgrUI() : m_hwndOwner(NULL), m_dwFlags(0), m_dwState(STATE_UNINIT),
  29. m_hwndDlg(NULL), m_hwndList(NULL), m_hwndDescript(NULL),
  30. m_pDescriptUI(NULL), m_pridRule(NULL), m_pIRuleDownloaded(NULL),
  31. m_fApplyAll(FALSE)
  32. {
  33. }
  34. COEViewsMgrUI::~COEViewsMgrUI()
  35. {
  36. if (NULL != m_pDescriptUI)
  37. {
  38. delete m_pDescriptUI;
  39. }
  40. SafeRelease(m_pIRuleDownloaded);
  41. }
  42. HRESULT COEViewsMgrUI::HrInit(HWND hwndOwner, DWORD dwFlags, RULEID * pridRule)
  43. {
  44. HRESULT hr = S_OK;
  45. // Check incoming params
  46. if (NULL == hwndOwner)
  47. {
  48. hr = E_INVALIDARG;
  49. goto exit;
  50. }
  51. if (0 != (m_dwState & STATE_INITIALIZED))
  52. {
  53. hr = E_UNEXPECTED;
  54. goto exit;
  55. }
  56. m_hwndOwner = hwndOwner;
  57. m_dwFlags = dwFlags;
  58. m_pridRule = pridRule;
  59. // Setup the description field
  60. m_pDescriptUI = new CRuleDescriptUI;
  61. if (NULL == m_pDescriptUI)
  62. {
  63. hr = E_OUTOFMEMORY;
  64. goto exit;
  65. }
  66. m_dwState |= STATE_INITIALIZED;
  67. hr = S_OK;
  68. exit:
  69. return hr;
  70. }
  71. HRESULT COEViewsMgrUI::HrShow(BOOL * pfApplyAll)
  72. {
  73. HRESULT hr = S_OK;
  74. int iRet = 0;
  75. if (NULL == pfApplyAll)
  76. {
  77. hr = E_INVALIDARG;
  78. goto exit;
  79. }
  80. if (0 == (m_dwState & STATE_INITIALIZED))
  81. {
  82. hr = E_UNEXPECTED;
  83. goto exit;
  84. }
  85. *pfApplyAll = FALSE;
  86. // We need to load richedit
  87. if (FALSE == FInitRichEdit(TRUE))
  88. {
  89. hr = E_FAIL;
  90. goto exit;
  91. }
  92. iRet = (INT) DialogBoxParam(g_hLocRes, MAKEINTRESOURCE(iddViewsManager),
  93. m_hwndOwner, COEViewsMgrUI::FOEViewMgrDlgProc,
  94. (LPARAM) this);
  95. if (-1 == iRet)
  96. {
  97. hr = E_FAIL;
  98. goto exit;
  99. }
  100. *pfApplyAll = m_fApplyAll;
  101. // Set the proper return code
  102. hr = (IDOK == iRet) ? S_OK : S_FALSE;
  103. exit:
  104. return hr;
  105. }
  106. INT_PTR CALLBACK COEViewsMgrUI::FOEViewMgrDlgProc(HWND hwndDlg, UINT uiMsg, WPARAM wParam, LPARAM lParam)
  107. {
  108. BOOL fRet = FALSE;
  109. COEViewsMgrUI * pViewsUI = NULL;
  110. HWND hwndRE = 0;
  111. pViewsUI = (COEViewsMgrUI *) GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
  112. switch (uiMsg)
  113. {
  114. case WM_INITDIALOG:
  115. // Grab the UI object pointer
  116. pViewsUI = (COEViewsMgrUI *) lParam;
  117. // Set it into the dialog so we can get it back
  118. SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR) pViewsUI);
  119. hwndRE = CreateREInDialogA(hwndDlg, idredtViewDescription);
  120. if (!hwndRE || (FALSE == pViewsUI->FOnInitDialog(hwndDlg)))
  121. {
  122. EndDialog(hwndDlg, -1);
  123. fRet = TRUE;
  124. goto exit;
  125. }
  126. // We set the focus
  127. fRet = TRUE;
  128. break;
  129. case WM_COMMAND:
  130. fRet = pViewsUI->FOnCommand((UINT) HIWORD(wParam), (INT) LOWORD(wParam), (HWND) lParam);
  131. break;
  132. case WM_NOTIFY:
  133. fRet = pViewsUI->FOnNotify((INT) LOWORD(wParam), (NMHDR *) lParam);
  134. break;
  135. case WM_DESTROY:
  136. fRet = pViewsUI->FOnDestroy();
  137. break;
  138. case WM_HELP:
  139. case WM_CONTEXTMENU:
  140. fRet = OnContextHelp(hwndDlg, uiMsg, wParam, lParam, g_rgCtxMapViewsMgr);
  141. break;
  142. }
  143. exit:
  144. return fRet;
  145. }
  146. ///////////////////////////////////////////////////////////////////////////////
  147. //
  148. // FOnInitDialog
  149. //
  150. // This handles the WM_INITDIALOG message for the view manager UI dialog
  151. //
  152. // hwndDlg - the handle to the dialog window
  153. //
  154. // Returns: TRUE, if it was successfully initialized
  155. // FALSE, otherwise
  156. //
  157. ///////////////////////////////////////////////////////////////////////////////
  158. BOOL COEViewsMgrUI::FOnInitDialog(HWND hwndDlg)
  159. {
  160. BOOL fRet = FALSE;
  161. HRESULT hr = S_OK;
  162. // Check incoming params
  163. if (NULL == hwndDlg)
  164. {
  165. fRet = FALSE;
  166. goto exit;
  167. }
  168. // Save off the dialog window handle
  169. m_hwndDlg = hwndDlg;
  170. // Set the default font onto the dialog
  171. SetIntlFont(m_hwndDlg);
  172. // Save off some of the controls
  173. m_hwndList = GetDlgItem(hwndDlg, idlvViewsList);
  174. m_hwndDescript = GetDlgItem(hwndDlg, idredtViewDescription);
  175. if ((NULL == m_hwndList) || (NULL == m_hwndDescript))
  176. {
  177. fRet = FALSE;
  178. goto exit;
  179. }
  180. if (FAILED(m_pDescriptUI->HrInit(m_hwndDescript, 0)))
  181. {
  182. fRet = FALSE;
  183. goto exit;
  184. }
  185. // Initialize the list view
  186. fRet = _FInitListCtrl();
  187. if (FALSE == fRet)
  188. {
  189. goto exit;
  190. }
  191. // Load the list view
  192. fRet = _FLoadListCtrl();
  193. if (FALSE == fRet)
  194. {
  195. goto exit;
  196. }
  197. // Everything's AOK
  198. fRet = TRUE;
  199. exit:
  200. return fRet;
  201. }
  202. ///////////////////////////////////////////////////////////////////////////////
  203. //
  204. // FOnCommand
  205. //
  206. // This handles the WM_COMMAND message for the view manager UI dialog
  207. //
  208. // Returns: TRUE, if it was successfully handled
  209. // FALSE, otherwise
  210. //
  211. ///////////////////////////////////////////////////////////////////////////////
  212. BOOL COEViewsMgrUI::FOnCommand(UINT uiNotify, INT iCtl, HWND hwndCtl)
  213. {
  214. BOOL fRet = FALSE;
  215. INT iSelected = 0;
  216. // We only handle menu and accelerator commands
  217. if ((0 != uiNotify) && (1 != uiNotify))
  218. {
  219. fRet = FALSE;
  220. goto exit;
  221. }
  222. switch (iCtl)
  223. {
  224. case IDOK:
  225. if (FALSE != _FOnOK())
  226. {
  227. EndDialog(m_hwndDlg, IDOK);
  228. fRet = TRUE;
  229. }
  230. break;
  231. case IDCANCEL:
  232. EndDialog(m_hwndDlg, IDCANCEL);
  233. fRet = TRUE;
  234. break;
  235. case idbNewView:
  236. _NewView();
  237. fRet = TRUE;
  238. break;
  239. case idbModifyView:
  240. // Get the selected item from the view list
  241. iSelected = ListView_GetNextItem(m_hwndList, -1, LVNI_SELECTED);
  242. if (-1 != iSelected)
  243. {
  244. // Bring up the view editor for that item
  245. _EditView(iSelected);
  246. fRet = TRUE;
  247. }
  248. break;
  249. case idbDeleteView:
  250. // Get the selected item from the view list
  251. iSelected = ListView_GetNextItem(m_hwndList, -1, LVNI_SELECTED);
  252. if (-1 != iSelected)
  253. {
  254. // Remove the rule from the list
  255. _RemoveView(iSelected);
  256. fRet = TRUE;
  257. }
  258. break;
  259. case idbDefaultView:
  260. // Get the selected item from the view list
  261. iSelected = ListView_GetNextItem(m_hwndList, -1, LVNI_SELECTED);
  262. if (-1 != iSelected)
  263. {
  264. // Remove the rule from the list
  265. _DefaultView(iSelected);
  266. fRet = TRUE;
  267. }
  268. break;
  269. case idbCopyView:
  270. // Get the selected item from the view list
  271. iSelected = ListView_GetNextItem(m_hwndList, -1, LVNI_SELECTED);
  272. if (-1 != iSelected)
  273. {
  274. // Remove the rule from the list
  275. _CopyView(iSelected);
  276. fRet = TRUE;
  277. }
  278. break;
  279. case idbRenameView:
  280. // Get the selected item from the view list
  281. iSelected = ListView_GetNextItem(m_hwndList, -1, LVNI_SELECTED);
  282. if (-1 != iSelected)
  283. {
  284. // Set the focus in the list view
  285. SetFocus(m_hwndList);
  286. // Edit the view label in the list
  287. fRet = (NULL != ListView_EditLabel(m_hwndList, iSelected));
  288. }
  289. break;
  290. }
  291. exit:
  292. return fRet;
  293. }
  294. ///////////////////////////////////////////////////////////////////////////////
  295. //
  296. // FOnNotify
  297. //
  298. // This handles the WM_NOTIFY message for the view manager UI dialog
  299. //
  300. // Returns: TRUE, if it was successfully destroyed
  301. // FALSE, otherwise
  302. //
  303. ///////////////////////////////////////////////////////////////////////////////
  304. BOOL COEViewsMgrUI::FOnNotify(INT iCtl, NMHDR * pnmhdr)
  305. {
  306. BOOL fRet = FALSE;
  307. NMLISTVIEW * pnmlv = NULL;
  308. NMLVKEYDOWN * pnmlvkd = NULL;
  309. INT iSelected = 0;
  310. LVHITTESTINFO lvh = {0};
  311. // We only handle notifications for the list control
  312. // or the desscription field
  313. if ((idlvViewsList != pnmhdr->idFrom) && (idredtViewDescription != pnmhdr->idFrom))
  314. {
  315. fRet = FALSE;
  316. goto exit;
  317. }
  318. pnmlv = (LPNMLISTVIEW) pnmhdr;
  319. switch (pnmlv->hdr.code)
  320. {
  321. case NM_CLICK:
  322. // Did we click on an item?
  323. if (-1 == pnmlv->iItem)
  324. {
  325. // We clicked outside the list
  326. // Disable the buttons
  327. _EnableButtons(pnmlv->iItem);
  328. }
  329. else
  330. {
  331. lvh.pt = pnmlv->ptAction;
  332. iSelected = ListView_HitTest(m_hwndList, &lvh);
  333. if (-1 != iSelected)
  334. {
  335. // Did we click on the enable field?
  336. if ((0 != (lvh.flags & LVHT_ONITEMSTATEICON)) &&
  337. (0 == (lvh.flags & LVHT_ONITEMLABEL)))
  338. {
  339. // Make sure this item is selected
  340. ListView_SetItemState(m_hwndList, iSelected,
  341. LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED);
  342. // Set the proper enable state
  343. _EnableView(iSelected);
  344. }
  345. }
  346. }
  347. break;
  348. case NM_DBLCLK:
  349. // Did we click on an item?
  350. if (-1 != pnmlv->iItem)
  351. {
  352. lvh.pt = pnmlv->ptAction;
  353. iSelected = ListView_HitTest(pnmlv->hdr.hwndFrom, &lvh);
  354. if (-1 != iSelected)
  355. {
  356. // Did we click on the rule name?
  357. if (0 != (lvh.flags & LVHT_ONITEMLABEL))
  358. {
  359. // Edit the rule
  360. _EditView(iSelected);
  361. }
  362. }
  363. }
  364. else
  365. {
  366. // We clicked outside the list
  367. // Disable the buttons
  368. _EnableButtons(pnmlv->iItem);
  369. }
  370. break;
  371. case LVN_ITEMCHANGED:
  372. // If an item's state changed to selected..
  373. if ((-1 != pnmlv->iItem) &&
  374. (0 != (pnmlv->uChanged & LVIF_STATE)) &&
  375. (0 == (pnmlv->uOldState & LVIS_SELECTED)) &&
  376. (0 != (pnmlv->uNewState & LVIS_SELECTED)))
  377. {
  378. // Enable the buttons
  379. _EnableButtons(pnmlv->iItem);
  380. }
  381. break;
  382. case LVN_ITEMCHANGING:
  383. // If an item's state changed to unselected..
  384. if ((-1 != pnmlv->iItem) &&
  385. (0 != (pnmlv->uChanged & LVIF_STATE)) &&
  386. (0 != (pnmlv->uOldState & LVIS_SELECTED)) &&
  387. (0 == (pnmlv->uNewState & LVIS_SELECTED)))
  388. {
  389. // Save off the rule changes
  390. _FSaveView(pnmlv->iItem);
  391. }
  392. break;
  393. case LVN_KEYDOWN:
  394. pnmlvkd = (NMLVKEYDOWN *) pnmhdr;
  395. // The space key changes the enable state of a rule
  396. if (VK_SPACE == pnmlvkd->wVKey)
  397. {
  398. // Are we on a rule?
  399. iSelected = ListView_GetNextItem(m_hwndList, -1, LVNI_SELECTED);
  400. if (-1 != iSelected)
  401. {
  402. // Change the enable state of the rule
  403. _EnableView(iSelected);
  404. }
  405. }
  406. // The delete key removes the rule from the list view
  407. else if (VK_DELETE == pnmlvkd->wVKey)
  408. {
  409. // Are we on a rule?
  410. iSelected = ListView_GetNextItem(m_hwndList, -1, LVNI_SELECTED);
  411. if (-1 != iSelected)
  412. {
  413. // Remove the rule from the list
  414. _RemoveView(iSelected);
  415. }
  416. }
  417. break;
  418. case LVN_BEGINLABELEDIT:
  419. case LVN_ENDLABELEDIT:
  420. fRet = _FOnLabelEdit((LVN_BEGINLABELEDIT == pnmlv->hdr.code), (NMLVDISPINFO *) pnmhdr);
  421. break;
  422. }
  423. exit:
  424. return fRet;
  425. }
  426. ///////////////////////////////////////////////////////////////////////////////
  427. //
  428. // FOnDestroy
  429. //
  430. // This handles the WM_DESTROY message for the view manager UI dialog
  431. //
  432. // Returns: TRUE, if it was successfully destroyed
  433. // FALSE, otherwise
  434. //
  435. ///////////////////////////////////////////////////////////////////////////////
  436. BOOL COEViewsMgrUI::FOnDestroy(VOID)
  437. {
  438. BOOL fRet = FALSE;
  439. UINT cRules = 0;
  440. UINT uiIndex = 0;
  441. LVITEM lvitem = {0};
  442. RULEINFO * pIRuleInfo = NULL;
  443. Assert(m_hwndList);
  444. // Get the number of views in the list view
  445. cRules = ListView_GetItemCount(m_hwndList);
  446. // Initialize to get the rule interface from the list view
  447. lvitem.mask = LVIF_PARAM;
  448. // Release each of the views from the list view
  449. for (uiIndex = 0; uiIndex < cRules; uiIndex++)
  450. {
  451. lvitem.iItem = uiIndex;
  452. // Get the rule interface
  453. if (FALSE != ListView_GetItem(m_hwndList, &lvitem))
  454. {
  455. pIRuleInfo = (RULEINFO *) (lvitem.lParam);
  456. if (NULL != pIRuleInfo)
  457. {
  458. // Release the view
  459. if (NULL != pIRuleInfo->pIRule)
  460. {
  461. pIRuleInfo->pIRule->Release();
  462. }
  463. delete pIRuleInfo; // MemFree(pIRuleInfo);
  464. }
  465. }
  466. }
  467. fRet = TRUE;
  468. return fRet;
  469. }
  470. ///////////////////////////////////////////////////////////////////////////////
  471. //
  472. // _FOnOK
  473. //
  474. // This commits the changes to the rules
  475. //
  476. // dwFlags - modifiers on how we should commit the changes
  477. // fClearDirty - should we clear the dirty state
  478. //
  479. // Returns: S_OK, if it was successfully committed
  480. //
  481. ///////////////////////////////////////////////////////////////////////////////
  482. BOOL COEViewsMgrUI::_FOnOK(VOID)
  483. {
  484. BOOL fRet = FALSE;
  485. HRESULT hr = S_OK;
  486. LONG cViews = 0;
  487. INT iSelected = 0;
  488. RULEINFO * pinfoRule = NULL;
  489. ULONG cpinfoRule = 0;
  490. LVITEM lvitem = {0};
  491. IOERule * pIRuleDefault = NULL;
  492. ULONG ulIndex = 0;
  493. ULONG cViewsTotal = 0;
  494. Assert(NULL != m_hwndList);
  495. // Fail if we weren't initialized
  496. if (0 == (m_dwState & STATE_INITIALIZED))
  497. {
  498. fRet = FALSE;
  499. goto exit;
  500. }
  501. // If we aren't dirty, then there's
  502. // nothing to do
  503. if ((0 == (m_dwState & STATE_DIRTY)) && (S_OK != m_pDescriptUI->HrIsDirty()))
  504. {
  505. fRet = TRUE;
  506. goto exit;
  507. }
  508. // Let's make sure the selected rule is saved...
  509. iSelected = ListView_GetNextItem(m_hwndList, -1, LVNI_SELECTED);
  510. if (-1 != iSelected)
  511. {
  512. _FSaveView(iSelected);
  513. }
  514. // Get the number of rules in the list view
  515. cViews = ListView_GetItemCount(m_hwndList);
  516. cViewsTotal = cViews;
  517. if (NULL != m_pIRuleDownloaded)
  518. {
  519. cViewsTotal++;
  520. }
  521. if (0 != cViewsTotal)
  522. {
  523. // Allocate space to hold the rules
  524. hr = HrAlloc( (void **) &pinfoRule, cViewsTotal * sizeof(*pinfoRule));
  525. if (FAILED(hr))
  526. {
  527. fRet = FALSE;
  528. goto exit;
  529. }
  530. ZeroMemory(pinfoRule, cViewsTotal * sizeof(*pinfoRule));
  531. if (0 != cViews)
  532. {
  533. lvitem.mask = LVIF_PARAM;
  534. cpinfoRule = 0;
  535. for (lvitem.iItem = 0; lvitem.iItem < cViews; lvitem.iItem++)
  536. {
  537. // Grab the rule from the list view
  538. if (FALSE != ListView_GetItem(m_hwndList, &lvitem))
  539. {
  540. pinfoRule[cpinfoRule] = *((RULEINFO *) (lvitem.lParam));
  541. cpinfoRule++;
  542. }
  543. }
  544. }
  545. if (NULL != m_pIRuleDownloaded)
  546. {
  547. pinfoRule[cpinfoRule].ridRule = RULEID_VIEW_DOWNLOADED;
  548. pinfoRule[cpinfoRule].pIRule = m_pIRuleDownloaded;
  549. cpinfoRule++;
  550. }
  551. }
  552. // Set the rules into the rules manager
  553. hr = g_pRulesMan->SetRules(SETF_CLEAR, RULE_TYPE_FILTER, pinfoRule, cpinfoRule);
  554. if (FAILED(hr))
  555. {
  556. fRet = FALSE;
  557. goto exit;
  558. }
  559. // Get the default item
  560. if (0 != cViews)
  561. {
  562. // Get the current default item
  563. if (FALSE != _FGetDefaultItem(&pIRuleDefault, NULL))
  564. {
  565. // Search for it in the list of rules
  566. for (ulIndex = 0; ulIndex < cpinfoRule; ulIndex++)
  567. {
  568. if (pIRuleDefault == pinfoRule[ulIndex].pIRule)
  569. {
  570. *m_pridRule = pinfoRule[ulIndex].ridRule;
  571. break;
  572. }
  573. }
  574. }
  575. }
  576. // Clear the dirty state
  577. m_dwState &= ~STATE_DIRTY;
  578. fRet = TRUE;
  579. exit:
  580. delete pinfoRule; //SafeMemFree(pinfoRule);
  581. return fRet;
  582. }
  583. BOOL COEViewsMgrUI::_FOnCancel(VOID)
  584. {
  585. return TRUE;
  586. }
  587. ///////////////////////////////////////////////////////////////////////////////
  588. //
  589. // _FInitListCtrl
  590. //
  591. // This initializes the list view control in the view manager UI dialog
  592. //
  593. // Returns: TRUE, on successful initialization
  594. // FALSE, otherwise.
  595. //
  596. ///////////////////////////////////////////////////////////////////////////////
  597. BOOL COEViewsMgrUI::_FInitListCtrl(VOID)
  598. {
  599. BOOL fRet = FALSE;
  600. LVCOLUMN lvc = {0};
  601. RECT rc = {0};
  602. HIMAGELIST himl = NULL;
  603. TCHAR szRes[CCHMAX_STRINGRES + 5];
  604. Assert(NULL != m_hwndList);
  605. // Initialize the list view structure
  606. lvc.mask = LVCF_WIDTH | LVCF_TEXT;
  607. // Calculate the size of the list view
  608. GetClientRect(m_hwndList, &rc);
  609. lvc.cx = rc.right - GetSystemMetrics(SM_CXVSCROLL);
  610. // Load the string for the column
  611. lvc.pszText = szRes;
  612. lvc.cchTextMax = ARRAYSIZE(szRes);
  613. if (0 == LoadString(g_hLocRes, idsNameCol, szRes, ARRAYSIZE(szRes)))
  614. {
  615. szRes[0] = '\0';
  616. }
  617. ListView_InsertColumn(m_hwndList, 0, &lvc);
  618. // Set the state image list
  619. himl = ImageList_LoadBitmap(g_hLocRes, MAKEINTRESOURCE(idb16x16st), 16, 0, RGB(255, 0, 255));
  620. if (NULL != himl)
  621. {
  622. ListView_SetImageList(m_hwndList, himl, LVSIL_STATE);
  623. }
  624. // Full row selection on listview
  625. ListView_SetExtendedListViewStyle(m_hwndList, LVS_EX_FULLROWSELECT);
  626. // We worked
  627. fRet = TRUE;
  628. return fRet;
  629. }
  630. ///////////////////////////////////////////////////////////////////////////////
  631. //
  632. // _FLoadListCtrl
  633. //
  634. // This loads the list view with the current views
  635. //
  636. // Returns: TRUE, if it was successfully loaded
  637. // FALSE, otherwise
  638. //
  639. ///////////////////////////////////////////////////////////////////////////////
  640. BOOL COEViewsMgrUI::_FLoadListCtrl(VOID)
  641. {
  642. BOOL fRet = FALSE;
  643. HRESULT hr = S_OK;
  644. DWORD dwListIndex = 0;
  645. RULEINFO * pinfoRules = NULL;
  646. ULONG cpinfoRules = 0;
  647. ULONG ulIndex = 0;
  648. IOERule * pIRule = NULL;
  649. BOOL fSelect = FALSE;
  650. BOOL fFoundDefault = FALSE;
  651. Assert(NULL != m_hwndList);
  652. // Get the Rules enumerator
  653. Assert(NULL != g_pRulesMan);
  654. hr = g_pRulesMan->GetRules(GETF_EDIT, RULE_TYPE_FILTER, &pinfoRules, &cpinfoRules);
  655. if (FAILED(hr))
  656. {
  657. fRet = FALSE;
  658. goto exit;
  659. }
  660. // Remove all the items from the list control
  661. ListView_DeleteAllItems(m_hwndList);
  662. // Add each filter to the list
  663. dwListIndex = 0;
  664. for (ulIndex = 0; ulIndex < cpinfoRules; ulIndex++)
  665. {
  666. // Make a copy of the view
  667. hr = pinfoRules[ulIndex].pIRule->Clone(&pIRule);
  668. if (FAILED(hr))
  669. {
  670. continue;
  671. }
  672. // Check to see if this is a default view we aren't supposed to show
  673. if ((0 != (m_dwFlags & VRDF_POP3)) && (RULEID_VIEW_DOWNLOADED == pinfoRules[ulIndex].ridRule))
  674. {
  675. m_pIRuleDownloaded = pIRule;
  676. pIRule = NULL;
  677. }
  678. else
  679. {
  680. // Is this the default view?
  681. if ((NULL != m_pridRule) && (*m_pridRule == pinfoRules[ulIndex].ridRule))
  682. {
  683. fSelect = TRUE;
  684. fFoundDefault = TRUE;
  685. }
  686. else
  687. {
  688. fSelect = FALSE;
  689. }
  690. // Add view to the list
  691. if (FALSE != _FAddViewToList(dwListIndex, pinfoRules[ulIndex].ridRule, pIRule, fSelect))
  692. {
  693. dwListIndex++;
  694. }
  695. SafeRelease(pIRule);
  696. }
  697. }
  698. // Select the first item in the list
  699. if (0 != dwListIndex)
  700. {
  701. if (FALSE == fFoundDefault)
  702. {
  703. ListView_SetItemState(m_hwndList, 0, LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED);
  704. }
  705. }
  706. else
  707. {
  708. // Enable the dialog buttons.
  709. _EnableButtons(-1);
  710. }
  711. fRet = TRUE;
  712. exit:
  713. SafeRelease(pIRule);
  714. if (NULL != pinfoRules)
  715. {
  716. for (ulIndex = 0; ulIndex < cpinfoRules; ulIndex++)
  717. {
  718. pinfoRules[ulIndex].pIRule->Release();
  719. }
  720. SafeMemFree(pinfoRules); //delete pinfoRules;
  721. }
  722. return fRet;
  723. }
  724. ///////////////////////////////////////////////////////////////////////////////
  725. //
  726. // _FAddRuleToList
  727. //
  728. // This adds the view passed in to the list view
  729. //
  730. // dwIndex - the index on where to add the view to into the list
  731. // pIRule - the actual view
  732. //
  733. // Returns: TRUE, if it was successfully added
  734. // FALSE, otherwise
  735. //
  736. ///////////////////////////////////////////////////////////////////////////////
  737. BOOL COEViewsMgrUI::_FAddViewToList(DWORD dwIndex, RULEID ridRule, IOERule * pIRule, BOOL fSelect)
  738. {
  739. BOOL fRet = FALSE;
  740. HRESULT hr = S_OK;
  741. PROPVARIANT propvar = {0};
  742. LVITEM lvitem = {0};
  743. RULEINFO * pinfoRule = NULL;
  744. INT iItem = 0;
  745. Assert(NULL != m_hwndList);
  746. // If there's nothing to do...
  747. if (NULL == pIRule)
  748. {
  749. fRet = FALSE;
  750. goto exit;
  751. }
  752. // Find out the name of the filter
  753. hr = pIRule->GetProp(RULE_PROP_NAME, 0, &propvar);
  754. if (FAILED(hr))
  755. {
  756. fRet = FALSE;
  757. goto exit;
  758. }
  759. // Allocate space for the rule
  760. pinfoRule = new RULEINFO;
  761. if (NULL == pinfoRule)
  762. {
  763. fRet = FALSE;
  764. goto exit;
  765. }
  766. // Set up the value
  767. pinfoRule->ridRule = ridRule;
  768. pinfoRule->pIRule = pIRule;
  769. pinfoRule->pIRule->AddRef();
  770. // Add in the image and rule interface
  771. lvitem.mask = LVIF_PARAM | LVIF_STATE | LVIF_TEXT;
  772. lvitem.stateMask = LVIS_STATEIMAGEMASK;
  773. lvitem.iItem = dwIndex;
  774. if ((NULL != m_pridRule) && (*m_pridRule == pinfoRule->ridRule))
  775. {
  776. lvitem.state = INDEXTOSTATEIMAGEMASK(iiconStateDefault + 1);
  777. }
  778. lvitem.pszText = propvar.pszVal;
  779. lvitem.cchTextMax = lstrlen(propvar.pszVal) + 1;
  780. lvitem.lParam = (LONG_PTR) pinfoRule;
  781. iItem = ListView_InsertItem(m_hwndList, &lvitem);
  782. if (-1 == iItem)
  783. {
  784. fRet = FALSE;
  785. goto exit;
  786. }
  787. if (FALSE != fSelect)
  788. {
  789. // Make sure the new item is selected
  790. ListView_SetItemState(m_hwndList, iItem, LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED);
  791. // Make sure the new item is visible
  792. ListView_EnsureVisible(m_hwndList, iItem, FALSE);
  793. }
  794. fRet = TRUE;
  795. exit:
  796. PropVariantClear(&propvar);
  797. return fRet;
  798. }
  799. ///////////////////////////////////////////////////////////////////////////////
  800. //
  801. // _EnableButtons
  802. //
  803. // This enables or disables the buttons in the view manager UI dialog
  804. // depending on what is selected.
  805. //
  806. // iSelected - the item that was selected,
  807. // -1 means that nothing was selected
  808. //
  809. // Returns: NONE
  810. //
  811. ///////////////////////////////////////////////////////////////////////////////
  812. void COEViewsMgrUI::_EnableButtons(INT iSelected)
  813. {
  814. int cRules = 0;
  815. BOOL fSelected = FALSE;
  816. BOOL fEditable = FALSE;
  817. LVITEM lvi = {0};
  818. RULEID ridFilter = RULEID_INVALID;
  819. Assert(NULL != m_hwndList);
  820. // Load the description field
  821. _LoadView(iSelected);
  822. // Grab the rule from the list view
  823. if (-1 != iSelected)
  824. {
  825. lvi.iItem = iSelected;
  826. lvi.mask = LVIF_PARAM;
  827. if (FALSE != ListView_GetItem(m_hwndList, &lvi))
  828. {
  829. ridFilter = ((RULEINFO *) (lvi.lParam))->ridRule;
  830. }
  831. }
  832. // Check the count of items in the list view
  833. cRules = ListView_GetItemCount(m_hwndList);
  834. fSelected = (-1 != iSelected);
  835. fEditable = !FIsFilterReadOnly(ridFilter);
  836. // Enable the rule action buttons
  837. RuleUtil_FEnDisDialogItem(m_hwndDlg, idbDefaultView, fSelected);
  838. RuleUtil_FEnDisDialogItem(m_hwndDlg, idbDeleteView, fSelected && fEditable);
  839. RuleUtil_FEnDisDialogItem(m_hwndDlg, idbCopyView, fSelected);
  840. RuleUtil_FEnDisDialogItem(m_hwndDlg, idbRenameView, fSelected && fEditable);
  841. RuleUtil_FEnDisDialogItem(m_hwndDlg, idbModifyView, fSelected && fEditable);
  842. return;
  843. }
  844. ///////////////////////////////////////////////////////////////////////////////
  845. //
  846. // _EnableView
  847. //
  848. // This switches the current default state of the list view item
  849. // and updates the UI
  850. //
  851. // iSelected - index of the item in the listview to work on
  852. //
  853. // Returns: NONE
  854. //
  855. ///////////////////////////////////////////////////////////////////////////////
  856. VOID COEViewsMgrUI::_EnableView(int iSelected)
  857. {
  858. HRESULT hr = S_OK;
  859. LVITEM lvitem = {0};
  860. int iRet = 0;
  861. INT cViews = 0;
  862. Assert(-1 != iSelected);
  863. iRet = (INT) DialogBoxParam(g_hLocRes, MAKEINTRESOURCE(iddApplyView),
  864. m_hwndDlg, FSelectApplyViewDlgProc, (LPARAM) &m_fApplyAll);
  865. if (IDOK != iRet)
  866. {
  867. goto exit;
  868. }
  869. // Get the current count of item
  870. cViews = ListView_GetItemCount(m_hwndList);
  871. // Set up the list view item
  872. lvitem.mask = LVIF_PARAM | LVIF_STATE;
  873. lvitem.stateMask = LVIS_STATEIMAGEMASK;
  874. // Walk each item in the list
  875. for (lvitem.iItem = 0; lvitem.iItem < cViews; lvitem.iItem++)
  876. {
  877. ListView_GetItem(m_hwndList, &lvitem);
  878. // Set the selected item to the default
  879. if (iSelected == lvitem.iItem)
  880. {
  881. if (INDEXTOSTATEIMAGEMASK(iiconStateDefault + 1) != lvitem.state)
  882. {
  883. // Save off the default item
  884. if (NULL != m_pridRule)
  885. {
  886. *m_pridRule = ((RULEINFO *) (lvitem.lParam))->ridRule;
  887. }
  888. // Set the state
  889. ListView_SetItemState(m_hwndList, lvitem.iItem,
  890. INDEXTOSTATEIMAGEMASK(iiconStateDefault + 1),
  891. LVIS_STATEIMAGEMASK);
  892. }
  893. }
  894. else
  895. {
  896. if (0 != lvitem.state)
  897. {
  898. // Clear out the state
  899. ListView_SetItemState(m_hwndList, lvitem.iItem, 0, LVIS_STATEIMAGEMASK);
  900. // Need to update the item
  901. ListView_Update(m_hwndList, lvitem.iItem);
  902. }
  903. }
  904. }
  905. // Mark the rule list as dirty
  906. m_dwState |= STATE_DIRTY;
  907. exit:
  908. return;
  909. }
  910. ///////////////////////////////////////////////////////////////////////////////
  911. //
  912. // _LoadView
  913. //
  914. // This loads the selected view into the description field.
  915. // If there isn't a selected view, then the description field is cleared.
  916. //
  917. // iSelected - the item that was selected,
  918. // -1 means that nothing was selected
  919. //
  920. // Returns: NONE
  921. //
  922. ///////////////////////////////////////////////////////////////////////////////
  923. void COEViewsMgrUI::_LoadView(INT iSelected)
  924. {
  925. LVITEM lvi = {0};
  926. IOERule * pIRule = NULL;
  927. RULEID ridFilter = RULEID_INVALID;
  928. Assert(NULL != m_hwndList);
  929. Assert(NULL != m_pDescriptUI);
  930. // Grab the rule from the list view
  931. if (-1 != iSelected)
  932. {
  933. lvi.iItem = iSelected;
  934. lvi.mask = LVIF_PARAM;
  935. if (FALSE != ListView_GetItem(m_hwndList, &lvi))
  936. {
  937. pIRule = ((RULEINFO *) (lvi.lParam))->pIRule;
  938. ridFilter = ((RULEINFO *) (lvi.lParam))->ridRule;
  939. }
  940. }
  941. // Have the description field load this rule
  942. m_pDescriptUI->HrSetRule(RULE_TYPE_FILTER, pIRule);
  943. // Set the proper read only state of the description field
  944. m_pDescriptUI->HrSetReadOnly(FIsFilterReadOnly(ridFilter));
  945. // Display the new rule
  946. m_pDescriptUI->ShowDescriptionString();
  947. return;
  948. }
  949. ///////////////////////////////////////////////////////////////////////////////
  950. //
  951. // _FSaveView
  952. //
  953. // This checks to see if the view has been changed in the description
  954. // area and if it has, then it warns the user and changes the text
  955. //
  956. // iSelected - index of the item in the listview to work on
  957. //
  958. // Returns: TRUE, if the rule either didn't change or did change without problems
  959. //
  960. ///////////////////////////////////////////////////////////////////////////////
  961. BOOL COEViewsMgrUI::_FSaveView(int iSelected)
  962. {
  963. BOOL fRet = FALSE;
  964. HRESULT hr = S_OK;
  965. LVITEM lvi = {0};
  966. IOERule * pIRule = NULL;
  967. PROPVARIANT propvar = {0};
  968. CRIT_ITEM * pCritItem = NULL;
  969. ULONG cCritItem = 0;
  970. ACT_ITEM * pActItem = NULL;
  971. ULONG cActItem = 0;
  972. // If the rule didn't change, then we're done
  973. hr = m_pDescriptUI->HrIsDirty();
  974. if (S_OK != hr)
  975. {
  976. fRet = (S_FALSE == hr);
  977. goto exit;
  978. }
  979. // Grab the list view item
  980. lvi.mask = LVIF_PARAM;
  981. lvi.iItem = iSelected;
  982. if (FALSE == ListView_GetItem(m_hwndList, &lvi))
  983. {
  984. fRet = FALSE;
  985. goto exit;
  986. }
  987. pIRule = ((RULEINFO *) (lvi.lParam))->pIRule;
  988. // Get the criteria from the rule
  989. hr = m_pDescriptUI->HrGetCriteria(&pCritItem, &cCritItem);
  990. if (FAILED(hr))
  991. {
  992. fRet = FALSE;
  993. goto exit;
  994. }
  995. // Get the actions for the rule
  996. hr = m_pDescriptUI->HrGetActions(&pActItem, &cActItem);
  997. if (FAILED(hr))
  998. {
  999. fRet = FALSE;
  1000. goto exit;
  1001. }
  1002. // Set the criteria from the rule
  1003. propvar.vt = VT_BLOB;
  1004. propvar.blob.cbSize = cCritItem * sizeof(CRIT_ITEM);
  1005. propvar.blob.pBlobData = (BYTE *) pCritItem;
  1006. hr = pIRule->SetProp(RULE_PROP_CRITERIA, 0, &propvar);
  1007. ZeroMemory(&propvar, sizeof(propvar));
  1008. if (FAILED(hr))
  1009. {
  1010. fRet = FALSE;
  1011. goto exit;
  1012. }
  1013. // Set the actions for the rule
  1014. PropVariantClear(&propvar);
  1015. propvar.vt = VT_BLOB;
  1016. propvar.blob.cbSize = cActItem * sizeof(ACT_ITEM);
  1017. propvar.blob.pBlobData = (BYTE *) pActItem;
  1018. hr = pIRule->SetProp(RULE_PROP_ACTIONS, 0, &propvar);
  1019. ZeroMemory(&propvar, sizeof(propvar));
  1020. if (FAILED(hr))
  1021. {
  1022. fRet = FALSE;
  1023. goto exit;
  1024. }
  1025. // Make sure we clear out the fact that we saved the rule
  1026. m_pDescriptUI->HrClearDirty();
  1027. // Mark the rule list as dirty
  1028. m_dwState |= STATE_DIRTY;
  1029. // Set the proper return value
  1030. fRet = TRUE;
  1031. exit:
  1032. RuleUtil_HrFreeCriteriaItem(pCritItem, cCritItem);
  1033. SafeMemFree(pCritItem);
  1034. RuleUtil_HrFreeActionsItem(pActItem, cActItem);
  1035. SafeMemFree(pActItem);
  1036. return fRet;
  1037. }
  1038. ///////////////////////////////////////////////////////////////////////////////
  1039. //
  1040. // _NewView
  1041. //
  1042. // This brings up a fresh rules editor
  1043. //
  1044. // Returns: NONE
  1045. //
  1046. ///////////////////////////////////////////////////////////////////////////////
  1047. void COEViewsMgrUI::_NewView(VOID)
  1048. {
  1049. HRESULT hr = S_OK;
  1050. IOERule * pIRule = NULL;
  1051. TCHAR szRes[CCHMAX_STRINGRES + 5];
  1052. ULONG cchRes = 0;
  1053. ULONG ulIndex = 0;
  1054. TCHAR szName[CCHMAX_STRINGRES + 5];
  1055. LVFINDINFO lvfinfo = {0};
  1056. PROPVARIANT propvar = {0};
  1057. ACT_ITEM aitem;
  1058. CEditRuleUI * pEditRuleUI = NULL;
  1059. LONG cRules = 0;
  1060. // Create a new rule object
  1061. if (FAILED(HrCreateRule(&pIRule)))
  1062. {
  1063. goto exit;
  1064. }
  1065. // Figure out the name of the new rule ...
  1066. cchRes = LoadString(g_hLocRes, idsViewDefaultName, szRes, ARRAYSIZE(szRes));
  1067. if (0 == cchRes)
  1068. {
  1069. goto exit;
  1070. }
  1071. ulIndex = 1;
  1072. wnsprintf(szName, ARRAYSIZE(szName), szRes, ulIndex);
  1073. lvfinfo.flags = LVFI_STRING;
  1074. lvfinfo.psz = szName;
  1075. while (-1 != ListView_FindItem(m_hwndList, -1, &lvfinfo))
  1076. {
  1077. ulIndex++;
  1078. wnsprintf(szName, ARRAYSIZE(szName), szRes, ulIndex);
  1079. }
  1080. propvar.vt = VT_LPSTR;
  1081. propvar.pszVal = szName;
  1082. hr = pIRule->SetProp(RULE_PROP_NAME, 0, &propvar);
  1083. if (FAILED(hr))
  1084. {
  1085. goto exit;
  1086. }
  1087. #ifdef NEVER
  1088. // Set the default action
  1089. // Set the normal action
  1090. ZeroMemory(&aitem, sizeof(aitem));
  1091. aitem.type = ACT_TYPE_SHOW;
  1092. aitem.dwFlags = ACT_FLAG_DEFAULT;
  1093. aitem.propvar.vt = VT_UI4;
  1094. aitem.propvar.ulVal = ACT_DATA_NULL;
  1095. ZeroMemory(&propvar, sizeof(propvar));
  1096. propvar.vt = VT_BLOB;
  1097. propvar.blob.cbSize = sizeof(ACT_ITEM);
  1098. propvar.blob.pBlobData = (BYTE *) &aitem;
  1099. hr = pIRule->SetProp(RULE_PROP_ACTIONS, 0, &propvar);
  1100. if (FAILED(hr))
  1101. {
  1102. goto exit;
  1103. }
  1104. #endif // NEVER
  1105. // Create a rules editor object
  1106. pEditRuleUI = new CEditRuleUI;
  1107. if (NULL == pEditRuleUI)
  1108. {
  1109. goto exit;
  1110. }
  1111. // Initialize the editor object
  1112. if (FAILED(pEditRuleUI->HrInit(m_hwndDlg, ERF_NEWRULE | ERF_ADDDEFAULTACTION, RULE_TYPE_FILTER, pIRule, NULL)))
  1113. {
  1114. goto exit;
  1115. }
  1116. // Bring up the rules editor UI
  1117. hr = pEditRuleUI->HrShow();
  1118. if (FAILED(hr))
  1119. {
  1120. goto exit;
  1121. }
  1122. if (S_OK == hr)
  1123. {
  1124. // Mark the rule list as dirty
  1125. m_dwState |= STATE_DIRTY;
  1126. // Add the rule to the manager UI
  1127. cRules = ListView_GetItemCount(m_hwndList);
  1128. _FAddViewToList(cRules, RULEID_INVALID, pIRule, TRUE);
  1129. }
  1130. exit:
  1131. SafeRelease(pIRule);
  1132. if (NULL != pEditRuleUI)
  1133. {
  1134. delete pEditRuleUI;
  1135. }
  1136. return;
  1137. }
  1138. ///////////////////////////////////////////////////////////////////////////////
  1139. //
  1140. // _EditView
  1141. //
  1142. // This brings up the edit UI for the selected view from the view list
  1143. //
  1144. // iSelected - index of the item in the listview to work on
  1145. //
  1146. // Returns: NONE
  1147. //
  1148. ///////////////////////////////////////////////////////////////////////////////
  1149. VOID COEViewsMgrUI::_EditView(int iSelected)
  1150. {
  1151. HRESULT hr = S_OK;
  1152. LVITEM lvitem = {0};
  1153. IOERule * pIRule = NULL;
  1154. CEditRuleUI * pEditRuleUI = NULL;
  1155. PROPVARIANT propvar = {0};
  1156. Assert(NULL != m_hwndList);
  1157. // Make sure we don't loose any changes
  1158. _FSaveView(iSelected);
  1159. // Grab the rule from the list view
  1160. lvitem.iItem = iSelected;
  1161. lvitem.mask = LVIF_PARAM;
  1162. if (FALSE == ListView_GetItem(m_hwndList, &lvitem))
  1163. {
  1164. goto exit;
  1165. }
  1166. pIRule = ((RULEINFO *) (lvitem.lParam))->pIRule;
  1167. if (NULL == pIRule)
  1168. {
  1169. goto exit;
  1170. }
  1171. // If the rule is read-only then we're done
  1172. if (FALSE != FIsFilterReadOnly(((RULEINFO *) (lvitem.lParam))->ridRule))
  1173. {
  1174. goto exit;
  1175. }
  1176. // Create the rules editor
  1177. pEditRuleUI = new CEditRuleUI;
  1178. if (NULL == pEditRuleUI)
  1179. {
  1180. goto exit;
  1181. }
  1182. // Initialize the editor object
  1183. if (FAILED(pEditRuleUI->HrInit(m_hwndDlg, 0, RULE_TYPE_FILTER, pIRule, NULL)))
  1184. {
  1185. goto exit;
  1186. }
  1187. // Bring up the rules editor UI
  1188. hr = pEditRuleUI->HrShow();
  1189. if (FAILED(hr))
  1190. {
  1191. goto exit;
  1192. }
  1193. // If the rule changed, make sure we reload the description field
  1194. if (S_OK == hr)
  1195. {
  1196. // Mark the rule list as dirty
  1197. m_dwState |= STATE_DIRTY;
  1198. // Grab the rule name
  1199. PropVariantClear(&propvar);
  1200. hr = pIRule->GetProp(RULE_PROP_NAME, 0, &propvar);
  1201. if (FAILED(hr))
  1202. {
  1203. goto exit;
  1204. }
  1205. if ((VT_LPSTR == propvar.vt) && (NULL != propvar.pszVal) && ('\0' != propvar.pszVal[0]))
  1206. {
  1207. ZeroMemory(&lvitem, sizeof(lvitem));
  1208. lvitem.iItem = iSelected;
  1209. lvitem.mask = LVIF_TEXT;
  1210. lvitem.pszText = propvar.pszVal;
  1211. lvitem.cchTextMax = lstrlen(propvar.pszVal) + 1;
  1212. if (-1 == ListView_SetItem(m_hwndList, &lvitem))
  1213. {
  1214. goto exit;
  1215. }
  1216. }
  1217. _EnableButtons(iSelected);
  1218. }
  1219. exit:
  1220. PropVariantClear(&propvar);
  1221. if (NULL != pEditRuleUI)
  1222. {
  1223. delete pEditRuleUI;
  1224. }
  1225. return;
  1226. }
  1227. ///////////////////////////////////////////////////////////////////////////////
  1228. //
  1229. // _RemoveView
  1230. //
  1231. // This removes the selected rule from the mail rules list
  1232. //
  1233. // iSelected - index of the item in the listview to work on
  1234. //
  1235. // Returns: NONE
  1236. //
  1237. ///////////////////////////////////////////////////////////////////////////////
  1238. VOID COEViewsMgrUI::_RemoveView(int iSelected)
  1239. {
  1240. LVITEM lvitem = {0};
  1241. RULEINFO * pinfoRule = NULL;
  1242. BOOL fDefault = FALSE;
  1243. PROPVARIANT propvar = {0};
  1244. int cViews = 0;
  1245. TCHAR szRes[CCHMAX_STRINGRES];
  1246. UINT cchRes = 0;
  1247. LPTSTR pszMessage = NULL;
  1248. Assert(NULL != m_hwndList);
  1249. // Grab the rule from the list view
  1250. lvitem.iItem = iSelected;
  1251. lvitem.mask = LVIF_PARAM | LVIF_STATE;
  1252. lvitem.stateMask = LVIS_STATEIMAGEMASK;
  1253. if (FALSE == ListView_GetItem(m_hwndList, &lvitem))
  1254. {
  1255. goto exit;
  1256. }
  1257. pinfoRule = (RULEINFO *) (lvitem.lParam);
  1258. fDefault = (INDEXTOSTATEIMAGEMASK(iiconStateDefault + 1) == lvitem.state);
  1259. if ((NULL == pinfoRule) || (NULL == pinfoRule->pIRule))
  1260. {
  1261. goto exit;
  1262. }
  1263. // If the rule is read-only then we're done
  1264. if (FALSE != FIsFilterReadOnly(pinfoRule->ridRule))
  1265. {
  1266. goto exit;
  1267. }
  1268. // Warn the user to make sure they know we are going to remove the rule
  1269. if (FAILED(pinfoRule->pIRule->GetProp(RULE_PROP_NAME, 0, &propvar)))
  1270. {
  1271. goto exit;
  1272. }
  1273. // Get the string template to display
  1274. cchRes = LoadString(g_hLocRes, idsRulesWarnDelete, szRes, ARRAYSIZE(szRes));
  1275. if (0 == cchRes)
  1276. {
  1277. goto exit;
  1278. }
  1279. // Allocate space to hold the final display string
  1280. DWORD cchSize = (cchRes + lstrlen(propvar.pszVal) + 1);
  1281. if (FAILED(HrAlloc((void ** ) &pszMessage, cchSize)))
  1282. {
  1283. goto exit;
  1284. }
  1285. // Build up the string and display it
  1286. wnsprintf(pszMessage, cchSize, szRes, propvar.pszVal);
  1287. if (IDNO == AthMessageBox(m_hwndDlg, MAKEINTRESOURCE(idsAthenaMail), pszMessage,
  1288. NULL, MB_YESNO | MB_ICONINFORMATION))
  1289. {
  1290. goto exit;
  1291. }
  1292. // Remove the item from the list
  1293. ListView_DeleteItem(m_hwndList, iSelected);
  1294. // Let's make sure we have a selection in the list
  1295. cViews = ListView_GetItemCount(m_hwndList);
  1296. if (cViews > 0)
  1297. {
  1298. // Did we delete the last item in the list
  1299. if (iSelected >= cViews)
  1300. {
  1301. // Move the selection to the new last item in the list
  1302. iSelected = cViews - 1;
  1303. }
  1304. // Do we need to reset the default
  1305. if (FALSE != fDefault)
  1306. {
  1307. // Set the state
  1308. ListView_SetItemState(m_hwndList, iSelected, INDEXTOSTATEIMAGEMASK(iiconStateDefault + 1),
  1309. LVIS_STATEIMAGEMASK);
  1310. }
  1311. // Set the new selection
  1312. ListView_SetItemState(m_hwndList, iSelected, LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED);
  1313. // Let's make sure we can see this new item
  1314. ListView_EnsureVisible(m_hwndList, iSelected, FALSE);
  1315. }
  1316. else
  1317. {
  1318. // Make sure we clear out all of the buttons
  1319. _EnableButtons(-1);
  1320. }
  1321. // Release the rule
  1322. SafeRelease(pinfoRule->pIRule);
  1323. // Free up the memory
  1324. delete pinfoRule; //SafeMemFree(pinfoRule);
  1325. // Mark the rule list as dirty
  1326. m_dwState |= STATE_DIRTY;
  1327. exit:
  1328. PropVariantClear(&propvar);
  1329. SafeMemFree(pszMessage);
  1330. return;
  1331. }
  1332. ///////////////////////////////////////////////////////////////////////////////
  1333. //
  1334. // _CopyView
  1335. //
  1336. // This copies the selected view from the view manager UI
  1337. //
  1338. // iSelected - index of the item in the listview to work on
  1339. //
  1340. // Returns: NONE
  1341. //
  1342. ///////////////////////////////////////////////////////////////////////////////
  1343. VOID COEViewsMgrUI::_CopyView(INT iSelected)
  1344. {
  1345. LVITEM lvitem = {0};
  1346. IOERule * pIRule = NULL;
  1347. HRESULT hr = S_OK;
  1348. IOERule * pIRuleNew = NULL;
  1349. PROPVARIANT propvar = {0};
  1350. UINT cRules = 0;
  1351. TCHAR szRes[CCHMAX_STRINGRES];
  1352. UINT cchRes = 0;
  1353. LPTSTR pszName = NULL;
  1354. Assert(NULL != m_hwndList);
  1355. // Make sure we don't loose any changes
  1356. _FSaveView(iSelected);
  1357. // Grab the rule from the list view
  1358. lvitem.iItem = iSelected;
  1359. lvitem.mask = LVIF_PARAM;
  1360. if (FALSE == ListView_GetItem(m_hwndList, &lvitem))
  1361. {
  1362. goto exit;
  1363. }
  1364. pIRule = ((RULEINFO *) (lvitem.lParam))->pIRule;
  1365. if (NULL == pIRule)
  1366. {
  1367. goto exit;
  1368. }
  1369. // Create a new rule object
  1370. hr = pIRule->Clone(&pIRuleNew);
  1371. if (FAILED(hr))
  1372. {
  1373. goto exit;
  1374. }
  1375. // Let's set the name
  1376. // Get the name from the source rule
  1377. hr = pIRule->GetProp(RULE_PROP_NAME, 0, &propvar);
  1378. if (FAILED(hr))
  1379. {
  1380. goto exit;
  1381. }
  1382. // Get the string template to display
  1383. cchRes = LoadString(g_hLocRes, idsRulesCopyName, szRes, ARRAYSIZE(szRes));
  1384. if (0 == cchRes)
  1385. {
  1386. goto exit;
  1387. }
  1388. // Allocate space to hold the final display string
  1389. DWORD cchSize = (cchRes + lstrlen(propvar.pszVal) + 1);
  1390. if (FAILED(HrAlloc((void ** ) &pszName, cchSize)))
  1391. {
  1392. goto exit;
  1393. }
  1394. // Build up the string and set it
  1395. wnsprintf(pszName, cchSize, szRes, propvar.pszVal);
  1396. PropVariantClear(&propvar);
  1397. propvar.vt = VT_LPSTR;
  1398. propvar.pszVal = pszName;
  1399. pszName = NULL;
  1400. // Set the name into the new rule
  1401. Assert(VT_LPSTR == propvar.vt);
  1402. Assert(NULL != propvar.pszVal);
  1403. hr = pIRuleNew->SetProp(RULE_PROP_NAME, 0, &propvar);
  1404. if (FAILED(hr))
  1405. {
  1406. goto exit;
  1407. }
  1408. // Clear the version of the new rule
  1409. PropVariantClear(&propvar);
  1410. propvar.vt = VT_UI4;
  1411. propvar.ulVal = 0;
  1412. hr = pIRuleNew->SetProp(RULE_PROP_VERSION, 0, &propvar);
  1413. if (FAILED(hr))
  1414. {
  1415. goto exit;
  1416. }
  1417. // Add the rule to the rules list right below
  1418. // the original rule
  1419. iSelected++;
  1420. _FAddViewToList(iSelected, RULEID_INVALID, pIRuleNew, TRUE);
  1421. // Mark the rule list as dirty
  1422. m_dwState |= STATE_DIRTY;
  1423. exit:
  1424. SafeMemFree(pszName);
  1425. SafeRelease(pIRuleNew);
  1426. PropVariantClear(&propvar);
  1427. return;
  1428. }
  1429. ///////////////////////////////////////////////////////////////////////////////
  1430. //
  1431. // _DefaultView
  1432. //
  1433. // This sets the selected view as the default view
  1434. //
  1435. // iSelected - index of the item in the listview to work on
  1436. //
  1437. // Returns: NONE
  1438. //
  1439. ///////////////////////////////////////////////////////////////////////////////
  1440. VOID COEViewsMgrUI::_DefaultView(int iSelected)
  1441. {
  1442. Assert(NULL != m_hwndList);
  1443. _EnableView(iSelected);
  1444. return;
  1445. }
  1446. ///////////////////////////////////////////////////////////////////////////////
  1447. //
  1448. // _DefaultView
  1449. //
  1450. // This sets the selected view as the default view
  1451. //
  1452. // iSelected - index of the item in the listview to work on
  1453. //
  1454. // Returns: NONE
  1455. //
  1456. ///////////////////////////////////////////////////////////////////////////////
  1457. BOOL COEViewsMgrUI::_FGetDefaultItem(IOERule ** ppIRuleDefault, RULEID * pridDefault)
  1458. {
  1459. BOOL fRet = FALSE;
  1460. LVITEM lvitem = {0};
  1461. INT cViews = 0;
  1462. Assert(NULL != m_hwndList);
  1463. // Get the current count of item
  1464. cViews = ListView_GetItemCount(m_hwndList);
  1465. // Set up the list view item
  1466. lvitem.mask = LVIF_PARAM | LVIF_STATE;
  1467. lvitem.stateMask = LVIS_STATEIMAGEMASK;
  1468. // Walk each item in the list
  1469. for (lvitem.iItem = 0; lvitem.iItem < cViews; lvitem.iItem++)
  1470. {
  1471. ListView_GetItem(m_hwndList, &lvitem);
  1472. // Set the selected item to the default
  1473. if (INDEXTOSTATEIMAGEMASK(iiconStateDefault + 1) == lvitem.state)
  1474. {
  1475. // We found it
  1476. fRet = TRUE;
  1477. // Save off the default item
  1478. if (NULL != pridDefault)
  1479. {
  1480. *pridDefault = ((RULEINFO *) (lvitem.lParam))->ridRule;
  1481. }
  1482. if (NULL != ppIRuleDefault)
  1483. {
  1484. *ppIRuleDefault = ((RULEINFO *) (lvitem.lParam))->pIRule;
  1485. }
  1486. break;
  1487. }
  1488. }
  1489. return fRet;
  1490. }
  1491. ///////////////////////////////////////////////////////////////////////////////
  1492. //
  1493. // _FOnLabelEdit
  1494. //
  1495. // This brings up the edit UI for the selected view from the view list
  1496. //
  1497. // fBegin - is this for the LVN_BEGINLABELEDIT notification
  1498. // pdi - the display info for the message
  1499. //
  1500. // Returns: TRUE, if the message was handled
  1501. // FALSE, otherwise
  1502. //
  1503. ///////////////////////////////////////////////////////////////////////////////
  1504. BOOL COEViewsMgrUI::_FOnLabelEdit(BOOL fBegin, NMLVDISPINFO * pdi)
  1505. {
  1506. BOOL fRet = FALSE;
  1507. HWND hwndEdit = NULL;
  1508. ULONG cchName = 0;
  1509. IOERule * pIRule = NULL;
  1510. LVITEM lvitem = {0};
  1511. PROPVARIANT propvar = {0};
  1512. Assert(NULL != m_hwndList);
  1513. if (NULL == pdi)
  1514. {
  1515. fRet = FALSE;
  1516. goto exit;
  1517. }
  1518. Assert(m_hwndList == pdi->hdr.hwndFrom);
  1519. if (FALSE != fBegin)
  1520. {
  1521. // Get the rule for the item
  1522. lvitem.iItem = pdi->item.iItem;
  1523. lvitem.mask = LVIF_PARAM;
  1524. if (FALSE == ListView_GetItem(m_hwndList, &lvitem))
  1525. {
  1526. SetDlgMsgResult(m_hwndDlg, WM_NOTIFY, TRUE);
  1527. fRet = TRUE;
  1528. goto exit;
  1529. }
  1530. // Should we allow the use to end the item?
  1531. if (FALSE != FIsFilterReadOnly(((RULEINFO *) (lvitem.lParam))->ridRule))
  1532. {
  1533. SetDlgMsgResult(m_hwndDlg, WM_NOTIFY, TRUE);
  1534. fRet = TRUE;
  1535. goto exit;
  1536. }
  1537. // Get the edit control
  1538. hwndEdit = ListView_GetEditControl(m_hwndList);
  1539. if (NULL == hwndEdit)
  1540. {
  1541. fRet = FALSE;
  1542. goto exit;
  1543. }
  1544. // Limit the amount of text for the name
  1545. SendMessage(hwndEdit, EM_LIMITTEXT, c_cchNameMax - 1, 0);
  1546. // Tell the dialog it's aok to proceed
  1547. SetDlgMsgResult(m_hwndDlg, WM_NOTIFY, FALSE);
  1548. }
  1549. else
  1550. {
  1551. // Did something change?
  1552. if ((-1 != pdi->item.iItem) && (NULL != pdi->item.pszText))
  1553. {
  1554. cchName = lstrlen(pdi->item.pszText);
  1555. // Check to see if the rule name is valid
  1556. if ((0 == cchName) || (0 == UlStripWhitespace(pdi->item.pszText, TRUE, TRUE, &cchName)))
  1557. {
  1558. // Put up a message saying something is busted
  1559. AthMessageBoxW(m_hwndDlg, MAKEINTRESOURCEW(idsAthenaMail),
  1560. MAKEINTRESOURCEW(idsRulesErrorNoName), NULL,
  1561. MB_OK | MB_ICONINFORMATION);
  1562. SetDlgMsgResult(m_hwndDlg, WM_NOTIFY, FALSE);
  1563. fRet = TRUE;
  1564. goto exit;
  1565. }
  1566. // Get the rule for the item
  1567. lvitem.iItem = pdi->item.iItem;
  1568. lvitem.mask = LVIF_PARAM;
  1569. if (FALSE == ListView_GetItem(m_hwndList, &lvitem))
  1570. {
  1571. SetDlgMsgResult(m_hwndDlg, WM_NOTIFY, FALSE);
  1572. fRet = TRUE;
  1573. goto exit;
  1574. }
  1575. pIRule = ((RULEINFO *) (lvitem.lParam))->pIRule;
  1576. if (NULL == pIRule)
  1577. {
  1578. SetDlgMsgResult(m_hwndDlg, WM_NOTIFY, FALSE);
  1579. fRet = TRUE;
  1580. goto exit;
  1581. }
  1582. // Set the new name into the rule
  1583. propvar.vt = VT_LPSTR;
  1584. propvar.pszVal = pdi->item.pszText;
  1585. SideAssert(S_OK == pIRule->SetProp(RULE_PROP_NAME, 0, &propvar));
  1586. // Mark the rule list as dirty
  1587. m_dwState |= STATE_DIRTY;
  1588. SetDlgMsgResult(m_hwndDlg, WM_NOTIFY, TRUE);
  1589. }
  1590. }
  1591. fRet = TRUE;
  1592. exit:
  1593. return fRet;
  1594. }
  1595. BOOL FIsFilterReadOnly(RULEID ridFilter)
  1596. {
  1597. BOOL fRet = FALSE;
  1598. // Check the incoming params
  1599. if (RULEID_INVALID == ridFilter)
  1600. {
  1601. goto exit;
  1602. }
  1603. if ((RULEID_VIEW_ALL == ridFilter) ||
  1604. (RULEID_VIEW_UNREAD == ridFilter) ||
  1605. (RULEID_VIEW_DOWNLOADED == ridFilter) ||
  1606. (RULEID_VIEW_IGNORED == ridFilter))
  1607. {
  1608. fRet = TRUE;
  1609. }
  1610. exit:
  1611. return fRet;
  1612. }
  1613. ///////////////////////////////////////////////////////////////////////////////
  1614. //
  1615. // FSelectApplyViewDlgProc
  1616. //
  1617. // This is the main dialog proc for selecting the thread state dialog
  1618. //
  1619. // hwndDlg - handle to the filter manager dialog
  1620. // uMsg - the message to be acted upon
  1621. // wParam - the 'word' parameter for the message
  1622. // lParam - the 'long' parameter for the message
  1623. //
  1624. // Returns: TRUE, if the message was handled
  1625. // FALSE, otherwise
  1626. //
  1627. ///////////////////////////////////////////////////////////////////////////////
  1628. INT_PTR CALLBACK FSelectApplyViewDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
  1629. {
  1630. BOOL fRet = FALSE;
  1631. BOOL * pfApplyAll = NULL;
  1632. UINT uiId = 0;
  1633. pfApplyAll = (BOOL *) GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
  1634. switch (uMsg)
  1635. {
  1636. case WM_INITDIALOG:
  1637. // Grab the propvariant pointer
  1638. pfApplyAll = (BOOL *) lParam;
  1639. if (NULL == pfApplyAll)
  1640. {
  1641. fRet = FALSE;
  1642. EndDialog(hwndDlg, -1);
  1643. }
  1644. // Set it into the dialog so we can get it back
  1645. SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR) pfApplyAll);
  1646. // Set the default item
  1647. if (FALSE != *pfApplyAll)
  1648. {
  1649. uiId = idcViewAll;
  1650. }
  1651. else
  1652. {
  1653. uiId = idcViewCurrent;
  1654. }
  1655. CheckDlgButton(hwndDlg, uiId, BST_CHECKED);
  1656. // We didn't set the focus so return TRUE
  1657. fRet = TRUE;
  1658. break;
  1659. case WM_COMMAND:
  1660. switch (LOWORD(wParam))
  1661. {
  1662. case IDCANCEL:
  1663. EndDialog(hwndDlg, IDCANCEL);
  1664. fRet = TRUE;
  1665. break;
  1666. case IDOK:
  1667. *pfApplyAll = (BST_CHECKED == IsDlgButtonChecked(hwndDlg, idcViewAll));
  1668. EndDialog(hwndDlg, IDOK);
  1669. fRet = TRUE;
  1670. break;
  1671. }
  1672. break;
  1673. }
  1674. return fRet;
  1675. }