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.

522 lines
13 KiB

  1. /////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright (c) 1996 Microsoft Corporation
  4. //
  5. // Module Name:
  6. // ListItem.cpp
  7. //
  8. // Abstract:
  9. // Implementation of the CListItem class.
  10. //
  11. // Author:
  12. // David Potter (davidp) May 6, 1996
  13. //
  14. // Revision History:
  15. //
  16. // Notes:
  17. //
  18. /////////////////////////////////////////////////////////////////////////////
  19. #include "stdafx.h"
  20. #include "ListItem.h"
  21. #include "ClusItem.h"
  22. #include "ListItem.inl"
  23. #include "TraceTag.h"
  24. #ifdef _DEBUG
  25. #define new DEBUG_NEW
  26. #undef THIS_FILE
  27. static char THIS_FILE[] = __FILE__;
  28. #endif
  29. /////////////////////////////////////////////////////////////////////////////
  30. // Global Variables
  31. /////////////////////////////////////////////////////////////////////////////
  32. #ifdef _DEBUG
  33. CTraceTag g_tagListItem(_T("Document"), _T("LIST ITEM"), 0);
  34. CTraceTag g_tagListItemCreate(_T("Create"), _T("LIST ITEM CREATE"), 0);
  35. CTraceTag g_tagListItemDelete(_T("Delete"), _T("LIST ITEM DELETE"), 0);
  36. #endif
  37. /////////////////////////////////////////////////////////////////////////////
  38. // CListItem
  39. /////////////////////////////////////////////////////////////////////////////
  40. IMPLEMENT_DYNCREATE(CListItem, CCmdTarget)
  41. /////////////////////////////////////////////////////////////////////////////
  42. // Message Maps
  43. BEGIN_MESSAGE_MAP(CListItem, CCmdTarget)
  44. //{{AFX_MSG_MAP(CListItem)
  45. // NOTE - the ClassWizard will add and remove mapping macros here.
  46. //}}AFX_MSG_MAP
  47. END_MESSAGE_MAP()
  48. /////////////////////////////////////////////////////////////////////////////
  49. //++
  50. //
  51. // CListItem::CListItem
  52. //
  53. // Routine Description:
  54. // Default constructor.
  55. //
  56. // Arguments:
  57. // None.
  58. //
  59. // Return Value:
  60. // None.
  61. //
  62. //--
  63. /////////////////////////////////////////////////////////////////////////////
  64. CListItem::CListItem(void)
  65. {
  66. m_ptiParent = NULL;
  67. m_pci = NULL;
  68. } //*** CListItem::CListItem()
  69. /////////////////////////////////////////////////////////////////////////////
  70. //++
  71. //
  72. // CListItem::CListItem
  73. //
  74. // Routine Description:
  75. // Constructor.
  76. //
  77. // Arguments:
  78. // pci [IN OUT] Cluster item represented by this item.
  79. // ptiParent [IN OUT] Parent tree item to which this item belongs.
  80. //
  81. // Return Value:
  82. // None.
  83. //
  84. //--
  85. /////////////////////////////////////////////////////////////////////////////
  86. CListItem::CListItem(IN OUT CClusterItem * pci, IN OUT CTreeItem * ptiParent)
  87. {
  88. ASSERT_VALID(ptiParent);
  89. ASSERT_VALID(pci);
  90. m_ptiParent = ptiParent;
  91. m_pci = pci;
  92. Trace(g_tagListItemCreate, _T("CListItem() - Creating '%s', parent = '%s'"), pci->StrName(), (ptiParent ? ptiParent->Pci()->StrName() : _T("<None>")));
  93. } //*** CListItem::CListItem(pci)
  94. /////////////////////////////////////////////////////////////////////////////
  95. //++
  96. //
  97. // CListItem::~CListItem
  98. //
  99. // Routine Description:
  100. // Destructor.
  101. //
  102. // Arguments:
  103. // None.
  104. //
  105. // Return Value:
  106. // None.
  107. //
  108. //--
  109. /////////////////////////////////////////////////////////////////////////////
  110. CListItem::~CListItem(void)
  111. {
  112. Trace(g_tagListItemDelete, _T("~CListItem() - Deleting list item '%s', parent = '%s'"), (Pci() != NULL ? Pci()->StrName() : _T("<Unknown>")), (PtiParent()->Pci() != NULL ? PtiParent()->Pci()->StrName() : _T("<Unknown>")));
  113. // Remove ourselves from all views.
  114. RemoveFromAllLists();
  115. } //*** CListItem::~CListItem()
  116. /////////////////////////////////////////////////////////////////////////////
  117. //++
  118. //
  119. // CListItem::Ili
  120. //
  121. // Routine Description:
  122. // Returns the index of the item in the specified list view.
  123. //
  124. // Arguments:
  125. // pclv [IN OUT] List view in which to search for the item.
  126. //
  127. // Return Value:
  128. // ili Index of the item, or -1 if it was not found.
  129. //
  130. //--
  131. /////////////////////////////////////////////////////////////////////////////
  132. int CListItem::Ili(CClusterListView * pclv) const
  133. {
  134. LV_FINDINFO lvfi;
  135. int ili;
  136. lvfi.flags = LVFI_PARAM;
  137. lvfi.lParam = (LPARAM) this;
  138. ili = pclv->GetListCtrl().FindItem(&lvfi);
  139. Trace(g_tagListItem, _T("Item index = %d"), ili);
  140. return ili;
  141. } //*** CListItem::Ili()
  142. /////////////////////////////////////////////////////////////////////////////
  143. //++
  144. //
  145. // CListItem::IliInsertInList
  146. //
  147. // Routine Description:
  148. // Insert the item in a list.
  149. //
  150. // Arguments:
  151. // pclv [IN OUT] Cluster list view item is being added to.
  152. //
  153. // Return Value:
  154. // ili Index of the new item in the list, or -1 if unsuccessful.
  155. //
  156. //--
  157. /////////////////////////////////////////////////////////////////////////////
  158. int CListItem::IliInsertInList(IN OUT CClusterListView * pclv)
  159. {
  160. POSITION posColi;
  161. CColumnItem * pcoli;
  162. CString strColumnData;
  163. int ili;
  164. int iliReturn;
  165. ASSERT_VALID(Pci());
  166. ASSERT(Ili(pclv) == -1); // Make sure we aren't in that list yet.
  167. // Determine the index of this item.
  168. ili = Plc(pclv)->GetItemCount();
  169. // Save a pointer to the list view to which we are being added.
  170. if (LpclvViews().Find(pclv) == NULL)
  171. LpclvViews().AddTail(pclv);
  172. // Get the first column's data.
  173. VERIFY((posColi = Lpcoli().GetHeadPosition()) != NULL);
  174. VERIFY((pcoli = Lpcoli().GetNext(posColi)) != NULL);
  175. Pci()->BGetColumnData(pcoli->Colid(), strColumnData);
  176. // Insert the item into the list and add the first column.
  177. // The rest of the columns get added by the call to UpdateState().
  178. VERIFY((iliReturn
  179. = Plc(pclv)->InsertItem(
  180. LVIF_TEXT | LVIF_PARAM, // nMask
  181. ili, // nItem
  182. strColumnData, // lpszItem
  183. 0, // nState
  184. 0, // nStateMask
  185. 0, // nImage
  186. (LPARAM) this // lParam
  187. )) != -1);
  188. // Add ourselves to the cluster item's list.
  189. Pci()->AddListItem(this);
  190. UpdateState();
  191. return iliReturn;
  192. } //*** CListItem::IliInsertInList()
  193. /////////////////////////////////////////////////////////////////////////////
  194. //++
  195. //
  196. // CListItem::RemoveFromAllLists
  197. //
  198. // Routine Description:
  199. // Remove the item from all lists.
  200. //
  201. // Arguments:
  202. // None.
  203. //
  204. // Return Value:
  205. // None.
  206. //
  207. //--
  208. /////////////////////////////////////////////////////////////////////////////
  209. void CListItem::RemoveFromAllLists(void)
  210. {
  211. ASSERT_VALID(Pci());
  212. // Loop through each view and remove the item from the list.
  213. {
  214. int ili;
  215. POSITION posView;
  216. POSITION posViewPrev;
  217. CClusterListView * pclv;
  218. posView = LpclvViews().GetHeadPosition();
  219. while (posView != NULL)
  220. {
  221. // Get the next list view list entry.
  222. posViewPrev = posView;
  223. pclv = LpclvViews().GetNext(posView);
  224. ASSERT_VALID(pclv);
  225. ili = Ili(pclv);
  226. ASSERT(ili != -1);
  227. // Delete the item.
  228. VERIFY(pclv->GetListCtrl().DeleteItem(ili));
  229. LpclvViews().RemoveAt(posViewPrev);
  230. } // while: more lists
  231. } // Loop through each view and remove the item from the list
  232. // Remove ourselves from the cluster item's list.
  233. Pci()->RemoveListItem(this);
  234. // Remove ourselves from the tree's list.
  235. // PtiParent()->RemoveChild(Pci());
  236. } //*** CListItem::RemoveFromAllLists()
  237. /////////////////////////////////////////////////////////////////////////////
  238. //++
  239. //
  240. // CListItem::PreRemoveFromList
  241. //
  242. // Routine Description:
  243. // Prepare to remove the item from a list.
  244. //
  245. // Arguments:
  246. // pclv [IN OUT] Cluster list view item is being removed from.
  247. //
  248. // Return Value:
  249. // None.
  250. //
  251. //--
  252. /////////////////////////////////////////////////////////////////////////////
  253. void CListItem::PreRemoveFromList(IN OUT CClusterListView * pclv)
  254. {
  255. POSITION posView;
  256. ASSERT_VALID(pclv);
  257. ASSERT_VALID(Pci());
  258. // Find the view in our list.
  259. VERIFY((posView = LpclvViews().Find(pclv)) != NULL);
  260. // Remove ourselves from the cluster item's list if this is the last view.
  261. // if (LpclvViews().GetCount() == 1)
  262. // {
  263. // Pci()->RemoveListItem(this);
  264. // } // if: this is the last view
  265. // Remove the view from the list.
  266. LpclvViews().RemoveAt(posView);
  267. } //*** CListItem::PreRemoveFromList()
  268. /////////////////////////////////////////////////////////////////////////////
  269. //++
  270. //
  271. // CListItem::UpdateState
  272. //
  273. // Routine Description:
  274. // Update the current state of the item.
  275. //
  276. // Arguments:
  277. // None.
  278. //
  279. // Return Value:
  280. // None.
  281. //
  282. //--
  283. /////////////////////////////////////////////////////////////////////////////
  284. void CListItem::UpdateState(void)
  285. {
  286. ASSERT_VALID(Pci());
  287. // Ask the item to update its state.
  288. Pci()->UpdateState();
  289. } //*** CListItem::UpdateState()
  290. /////////////////////////////////////////////////////////////////////////////
  291. //++
  292. //
  293. // CListItem::UpdateUIState
  294. //
  295. // Routine Description:
  296. // Update the current UI state of the item.
  297. //
  298. // Arguments:
  299. // None.
  300. //
  301. // Return Value:
  302. // None.
  303. //
  304. //--
  305. /////////////////////////////////////////////////////////////////////////////
  306. void CListItem::UpdateUIState(void)
  307. {
  308. BOOL bSuccess;
  309. POSITION posView;
  310. POSITION posColi;
  311. CColumnItem * pcoli;
  312. int icoli;
  313. int ili;
  314. CString strColumnData;
  315. UINT nImage;
  316. UINT nMask;
  317. CClusterListView * pclv;
  318. CListCtrl * plc;
  319. ASSERT_VALID(Pci());
  320. // ASSERT(LpclvViews().GetCount() > 0);
  321. // Loop through the views and update the state on each one.
  322. posView = LpclvViews().GetHeadPosition();
  323. while (posView != NULL)
  324. {
  325. // Get the pointers to the view and the list control.
  326. VERIFY((pclv = LpclvViews().GetNext(posView)) != NULL);
  327. ASSERT_KINDOF(CClusterListView, pclv);
  328. plc = Plc(pclv);
  329. // Get the item index.
  330. VERIFY((ili = Ili(pclv)) != -1);
  331. // Set the column data.
  332. VERIFY((posColi = Lpcoli().GetHeadPosition()) != NULL);
  333. for (icoli = 0 ; posColi != NULL ; icoli++)
  334. {
  335. VERIFY((pcoli = Lpcoli().GetNext(posColi)) != NULL);
  336. ASSERT_KINDOF(CColumnItem, pcoli);
  337. bSuccess = Pci()->BGetColumnData(pcoli->Colid(), strColumnData);
  338. if (!bSuccess)
  339. {
  340. Trace(g_tagListItem, _T("IliInsertInList: Column #%d (ID %d) not available for %s '%s'"), icoli, pcoli->Colid(), Pci()->StrType(), Pci()->StrName());
  341. } // if: column data not available
  342. if (icoli == 0)
  343. {
  344. nMask = LVIF_TEXT | LVIF_IMAGE;
  345. nImage = Pci()->IimgState();
  346. } // if: first column
  347. else
  348. {
  349. nMask = LVIF_TEXT;
  350. nImage = (UINT) -1;
  351. } // else: not first column
  352. VERIFY(plc->SetItem(
  353. ili, // nItem
  354. icoli, // nSubItem
  355. nMask, // nMask
  356. strColumnData, // lpszItem
  357. nImage, // nImage
  358. 0, // nState
  359. 0, // nStateMask
  360. 0 // lParam
  361. ));
  362. } // for: each column item in the list
  363. } // while: more views
  364. } //*** CListItem::UpdateUIState()
  365. /////////////////////////////////////////////////////////////////////////////
  366. //++
  367. //
  368. // CListItem::OnCmdMsg
  369. //
  370. // Routine Description:
  371. // Processes command messages. Attempts to pass them on to a selected
  372. // item first.
  373. //
  374. // Arguments:
  375. // nID [IN] Command ID.
  376. // nCode [IN] Notification code.
  377. // pExtra [IN OUT] Used according to the value of nCode.
  378. // pHandlerInfo [OUT] ???
  379. //
  380. // Return Value:
  381. // None.
  382. //
  383. //--
  384. /////////////////////////////////////////////////////////////////////////////
  385. BOOL CListItem::OnCmdMsg(
  386. UINT nID,
  387. int nCode,
  388. void * pExtra,
  389. AFX_CMDHANDLERINFO * pHandlerInfo
  390. )
  391. {
  392. ASSERT_VALID(Pci());
  393. // Give the cluster item a chance to handle the message.
  394. if (Pci()->OnCmdMsg(nID, nCode, pExtra, pHandlerInfo))
  395. return TRUE;
  396. return CCmdTarget::OnCmdMsg(nID, nCode, pExtra, pHandlerInfo);
  397. } //*** CListItem::OnCmdMsg()
  398. /////////////////////////////////////////////////////////////////////////////
  399. //++
  400. //
  401. // CListItem::EditLabel
  402. //
  403. // Routine Description:
  404. // Processes the ID_FILE_RENAME menu command.
  405. //
  406. // Arguments:
  407. // pclv [IN OUT] Cluster list view item is being edited in.
  408. //
  409. // Return Value:
  410. // None.
  411. //
  412. //--
  413. /////////////////////////////////////////////////////////////////////////////
  414. void CListItem::EditLabel(IN OUT CClusterListView * pclv)
  415. {
  416. ASSERT_VALID(pclv);
  417. ASSERT_VALID(Pci());
  418. ASSERT(Pci()->BCanBeEdited());
  419. pclv->GetListCtrl().EditLabel(Ili(pclv));
  420. } //*** CListItem::EditLabel()
  421. //***************************************************************************
  422. /////////////////////////////////////////////////////////////////////////////
  423. // Global Functions
  424. /////////////////////////////////////////////////////////////////////////////
  425. /////////////////////////////////////////////////////////////////////////////
  426. //++
  427. //
  428. // DeleteAllItemData
  429. //
  430. // Routine Description:
  431. // Deletes all item data in a CList.
  432. //
  433. // Arguments:
  434. // rlp [IN OUT] List whose data is to be deleted.
  435. //
  436. // Return Value:
  437. // None.
  438. //
  439. //--
  440. /////////////////////////////////////////////////////////////////////////////
  441. void DeleteAllItemData(IN OUT CListItemList & rlp)
  442. {
  443. POSITION pos;
  444. CListItem * pli;
  445. // Delete all the items in the list.
  446. pos = rlp.GetHeadPosition();
  447. while (pos != NULL)
  448. {
  449. pli = rlp.GetNext(pos);
  450. ASSERT_VALID(pli);
  451. // Trace(g_tagListItemDelete, _T("DeleteAllItemData(rlpli) - Deleting list item '%s'"), pli->Pci()->StrName());
  452. delete pli;
  453. } // while: more items in the list
  454. } //*** DeleteAllItemData()