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.

243 lines
7.1 KiB

  1. // UndoDialog.h : Declaration of the CUndoDialog
  2. #ifndef __UNDODIALOG_H_
  3. #define __UNDODIALOG_H_
  4. #include "resource.h" // main symbols
  5. #include <atlhost.h>
  6. #include "undolog.h"
  7. #ifndef ListView_SetCheckState
  8. #define ListView_SetCheckState(hwndLV, i, fCheck) \
  9. ListView_SetItemState(hwndLV, i, \
  10. INDEXTOSTATEIMAGEMASK((fCheck)+1), LVIS_STATEIMAGEMASK)
  11. #endif
  12. /////////////////////////////////////////////////////////////////////////////
  13. // CUndoDialog
  14. class CUndoDialog :
  15. public CAxDialogImpl<CUndoDialog>
  16. {
  17. public:
  18. CUndoDialog(CUndoLog * pUndoLog, BOOL fFromUserClick = TRUE)
  19. {
  20. ASSERT(pUndoLog);
  21. m_pUndoLog = pUndoLog;
  22. m_fFromUserClick = fFromUserClick;
  23. }
  24. ~CUndoDialog()
  25. {
  26. }
  27. enum { IDD = IDD_UNDODIALOG };
  28. BEGIN_MSG_MAP(CUndoDialog)
  29. MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog)
  30. COMMAND_HANDLER(IDC_CLOSE, BN_CLICKED, OnClickedClose)
  31. NOTIFY_HANDLER(IDC_LISTCHANGES, LVN_ITEMCHANGED, OnItemChangedListChanges)
  32. COMMAND_HANDLER(IDC_BUTTONUNDOALL, BN_CLICKED, OnClickedButtonUndoAll)
  33. COMMAND_HANDLER(IDC_BUTTONUNDOSELECTED, BN_CLICKED, OnClickedButtonUndoSelected)
  34. COMMAND_HANDLER(IDC_RUNMSCONFIG, BN_CLICKED, OnClickedRunMSConfig)
  35. END_MSG_MAP()
  36. // Handler prototypes:
  37. // LRESULT MessageHandler(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
  38. // LRESULT CommandHandler(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled);
  39. // LRESULT NotifyHandler(int idCtrl, LPNMHDR pnmh, BOOL& bHandled);
  40. LRESULT OnInitDialog(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  41. {
  42. m_list.Attach(GetDlgItem(IDC_LISTCHANGES));
  43. ListView_SetExtendedListViewStyle(m_list.m_hWnd, LVS_EX_CHECKBOXES | LVS_EX_FULLROWSELECT);
  44. // If this is launched by the user clicking on the button, hide the "Run MSConfig"
  45. // button and resize the dialog.
  46. if (m_fFromUserClick)
  47. {
  48. CWindow wndRun;
  49. RECT rectRun, rectWindow;
  50. wndRun.Attach(GetDlgItem(IDC_RUNMSCONFIG));
  51. wndRun.ShowWindow(SW_HIDE);
  52. wndRun.GetWindowRect(&rectRun);
  53. GetWindowRect(&rectWindow);
  54. rectWindow.bottom -= (rectWindow.bottom - rectRun.top);
  55. MoveWindow(&rectWindow);
  56. }
  57. // Insert the columns.
  58. CRect rect;
  59. m_list.GetClientRect(&rect);
  60. int cxWidth = rect.Width();
  61. LVCOLUMN lvc;
  62. lvc.mask = LVCF_TEXT | LVCF_WIDTH;
  63. ::AfxSetResourceHandle(_Module.GetResourceInstance());
  64. CString strColumn;
  65. strColumn.LoadString(IDS_DATECAPTION);
  66. lvc.pszText = (LPTSTR)(LPCTSTR)strColumn;
  67. lvc.cx = 4 * cxWidth / 10;
  68. ListView_InsertColumn(m_list.m_hWnd, 0, &lvc);
  69. strColumn.LoadString(IDS_CHANGECAPTION);
  70. lvc.pszText = (LPTSTR)(LPCTSTR)strColumn;
  71. lvc.cx = 6 * cxWidth / 10;
  72. ListView_InsertColumn(m_list.m_hWnd, 1, &lvc);
  73. FillChangeList();
  74. CenterWindow();
  75. return 1; // Let the system set the focus
  76. }
  77. //-------------------------------------------------------------------------
  78. // When one of the items in the list view changes, we need to check the
  79. // state of the check boxes. In particular, if there are any boxes checked,
  80. // we need to enable to Undo Selected button. Also, we can't allow any
  81. // boxes items to be checked unless all of the more recent items for the
  82. // tab are also checked.
  83. //-------------------------------------------------------------------------
  84. LRESULT OnItemChangedListChanges(int idCtrl, LPNMHDR pnmh, BOOL& bHandled)
  85. {
  86. LPNMLISTVIEW pnmv = (LPNMLISTVIEW) pnmh;
  87. if (!pnmv)
  88. return 0;
  89. CString strTab, strCheckTab;
  90. m_pUndoLog->GetUndoEntry(pnmv->iItem, &strTab, NULL);
  91. BOOL fChecked = ListView_GetCheckState(m_list.m_hWnd, pnmv->iItem);
  92. if (fChecked)
  93. {
  94. // Make sure all previous entries in the list with the same
  95. // tab name are also checked.
  96. for (int i = pnmv->iItem - 1; i >= 0; i--)
  97. if (m_pUndoLog->GetUndoEntry(i, &strCheckTab, NULL) && strTab.Compare(strCheckTab) == 0)
  98. ListView_SetCheckState(m_list.m_hWnd, i, TRUE);
  99. }
  100. else
  101. {
  102. // Make sure all later entries in the list with the same tab
  103. // name are unchecked.
  104. int iCount = ListView_GetItemCount(m_list.m_hWnd);
  105. for (int i = pnmv->iItem + 1; i < iCount; i++)
  106. if (m_pUndoLog->GetUndoEntry(i, &strCheckTab, NULL) && strTab.Compare(strCheckTab) == 0)
  107. ListView_SetCheckState(m_list.m_hWnd, i, FALSE);
  108. }
  109. for (int i = ListView_GetItemCount(m_list.m_hWnd) - 1; i >= 0; i--)
  110. if (ListView_GetCheckState(m_list.m_hWnd, i))
  111. {
  112. ::EnableWindow(GetDlgItem(IDC_BUTTONUNDOSELECTED), TRUE);
  113. return 0;
  114. }
  115. ::EnableWindow(GetDlgItem(IDC_BUTTONUNDOSELECTED), FALSE);
  116. return 0;
  117. }
  118. LRESULT OnClickedClose(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
  119. {
  120. EndDialog(wID);
  121. return 0;
  122. }
  123. void FillChangeList()
  124. {
  125. ListView_DeleteAllItems(m_list.m_hWnd);
  126. ASSERT(m_pUndoLog);
  127. if (!m_pUndoLog)
  128. return;
  129. LVITEM lvi;
  130. lvi.mask = LVIF_TEXT;
  131. int nEntries = m_pUndoLog->GetUndoEntryCount();
  132. for (int i = 0; i < nEntries; i++)
  133. {
  134. COleDateTime timestamp;
  135. CString strDescription, strTimestamp;
  136. if (m_pUndoLog->GetUndoEntryInfo(i, strDescription, timestamp))
  137. {
  138. strTimestamp = timestamp.Format();
  139. lvi.pszText = (LPTSTR)(LPCTSTR)strTimestamp;
  140. lvi.iSubItem = 0;
  141. lvi.iItem = i;
  142. ListView_InsertItem(m_list.m_hWnd, &lvi);
  143. lvi.pszText = (LPTSTR)(LPCTSTR)strDescription;
  144. lvi.iSubItem = 1;
  145. ListView_SetItem(m_list.m_hWnd, &lvi);
  146. }
  147. }
  148. ::EnableWindow(GetDlgItem(IDC_BUTTONUNDOALL), (nEntries != 0));
  149. if (nEntries == 0)
  150. ::EnableWindow(GetDlgItem(IDC_BUTTONUNDOSELECTED), FALSE);
  151. }
  152. //-------------------------------------------------------------------------
  153. // When the user chooses to undo selected items or all items, we need
  154. // to locate the tab page for each change and call its undo function.
  155. //-------------------------------------------------------------------------
  156. LRESULT OnClickedButtonUndoAll(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
  157. {
  158. DoUndo(TRUE);
  159. return 0;
  160. }
  161. LRESULT OnClickedButtonUndoSelected(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
  162. {
  163. DoUndo(FALSE);
  164. return 0;
  165. }
  166. void DoUndo(BOOL fAll)
  167. {
  168. CString strTab, strEntry;
  169. int iUndoIndex = 0, iCount = ListView_GetItemCount(m_list.m_hWnd);
  170. // Have to do something a little screwy here. Since the index into the
  171. // undo log is based on the number of changes into the log (not counting
  172. // undone entries), we need to keep track of the index into the undo log.
  173. // This undo index will not be incremented when we undo an entry (undoing
  174. // it makes it invisible, so the same index will then point to the next
  175. // undo entry).
  176. for (int i = 0; i < iCount; i++)
  177. if (fAll || ListView_GetCheckState(m_list.m_hWnd, i))
  178. m_pUndoLog->UndoEntry(iUndoIndex);
  179. else
  180. iUndoIndex += 1;
  181. FillChangeList();
  182. }
  183. HRESULT ShowDialog()
  184. {
  185. return ((DoModal() == IDC_RUNMSCONFIG) ? S_FALSE : S_OK);
  186. }
  187. LRESULT OnClickedRunMSConfig(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
  188. {
  189. EndDialog(IDC_RUNMSCONFIG);
  190. return 0;
  191. }
  192. private:
  193. CWindow m_list;
  194. CUndoLog * m_pUndoLog;
  195. BOOL m_fFromUserClick;
  196. };
  197. #endif //__UNDODIALOG_H_