Source code of Windows XP (NT5)
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.

1936 lines
57 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 1999
  5. //
  6. // File: colwidth.cpp
  7. //
  8. // Contents: Column Persistence data structures and property pages
  9. // implementation.
  10. //
  11. // History: 16-Oct-98 AnandhaG Created
  12. //
  13. //--------------------------------------------------------------------------
  14. #include "stdafx.h"
  15. #include "colwidth.h"
  16. #include "macros.h"
  17. #include "comdbg.h"
  18. #include "columninfo.h"
  19. #define MAX_COLUMNS_PERSISTED 50
  20. //+-------------------------------------------------------------------
  21. //
  22. // Class: ViewToColSetDataMapPersistor (wrapper, helper)
  23. //
  24. // Purpose: wraps ViewToColSetDataMap implementing XML persistence
  25. // map is persisted as linear list
  26. //
  27. // see "Data structures used to persist column information" comment
  28. // int file colwidth.h for more information
  29. //--------------------------------------------------------------------
  30. class ViewToColSetDataMapPersistor : public XMLListCollectionBase
  31. {
  32. public:
  33. ViewToColSetDataMapPersistor(ViewToColSetDataMap &map, ColSetDataList &list)
  34. : m_map(map), m_list(list) {}
  35. DEFINE_XML_TYPE(XML_TAG_COLUMN_SET);
  36. virtual void Persist(CPersistor &persistor);
  37. virtual void OnNewElement(CPersistor& persistor);
  38. private:
  39. ViewToColSetDataMap &m_map; // wrapped map
  40. ColSetDataList &m_list; // value list to persist actual information
  41. };
  42. //+-------------------------------------------------------------------
  43. //
  44. // Class: ColSetIDToViewTableMapPersistor (wrapper, helper)
  45. //
  46. // Purpose: wraps ColSetIDToViewTableMap implementing XML persistence
  47. // map is persisted as linear list
  48. //
  49. // see "Data structures used to persist column information" comment
  50. // int file colwidth.h for more information
  51. //--------------------------------------------------------------------
  52. class ColSetIDToViewTableMapPersistor : public XMLListCollectionBase
  53. {
  54. public:
  55. ColSetIDToViewTableMapPersistor(ColSetIDToViewTableMap &map, ColSetDataList &list)
  56. : m_map(map), m_list(list) {}
  57. DEFINE_XML_TYPE(XML_TAG_COLUMN_PERIST_ENTRY);
  58. virtual void Persist(CPersistor &persistor);
  59. virtual void OnNewElement(CPersistor& persistor);
  60. private:
  61. ColSetIDToViewTableMap &m_map; // wrapped map
  62. ColSetDataList &m_list; // value list to persist actual information
  63. };
  64. //+-------------------------------------------------------------------
  65. //
  66. // Class: SnapinToColSetIDMapPersistor (wrapper, helper)
  67. //
  68. // Purpose: wraps SnapinToColSetIDMap implementing XML persistence
  69. // map is persisted as linear list
  70. //
  71. // see "Data structures used to persist column information" comment
  72. // int file colwidth.h for more information
  73. //--------------------------------------------------------------------
  74. class SnapinToColSetIDMapPersistor : public XMLListCollectionBase
  75. {
  76. public:
  77. SnapinToColSetIDMapPersistor(SnapinToColSetIDMap &map, ColSetDataList &list)
  78. : m_map(map), m_list(list) {}
  79. DEFINE_XML_TYPE(XML_TAG_COLUMN_PERIST_ENTRY);
  80. virtual void Persist(CPersistor &persistor);
  81. virtual void OnNewElement(CPersistor& persistor);
  82. // prior-to-save cleanup
  83. SC ScPurgeUnusedColumnData();
  84. private:
  85. SnapinToColSetIDMap &m_map; // wrapped map
  86. ColSetDataList &m_list; // value list to persist actual information
  87. };
  88. //+-------------------------------------------------------------------
  89. //
  90. // Member: ReadSerialObject
  91. //
  92. // Synopsis: Read the given version of CColumnSortInfo object from
  93. // the given stream.
  94. //
  95. // Arguments: [stm] - The input stream.
  96. // [nVersion] - version of CColumnSortInfo to be read.
  97. //
  98. // The format is :
  99. // INT column index
  100. // DWORD Sort options
  101. // ULONG_PTR Any user (snapin) param
  102. //
  103. //--------------------------------------------------------------------
  104. HRESULT CColumnSortInfo::ReadSerialObject(IStream &stm, UINT nVersion /*,LARGE_INTEGER nBytes*/)
  105. {
  106. HRESULT hr = S_FALSE; // assume bad version
  107. if (GetVersion() >= nVersion)
  108. {
  109. try
  110. {
  111. stm >> m_nCol;
  112. // In version we stored just ascending or descending flag
  113. if (1 == nVersion)
  114. {
  115. BYTE bAscend;
  116. stm >> bAscend;
  117. m_dwSortOptions |= (bAscend ? 0 : RSI_DESCENDING);
  118. }
  119. else if (nVersion > 1)
  120. {
  121. // Versions greater than 1 has these sort data which
  122. // includes ascend/descend flags and a user param.
  123. stm >> m_dwSortOptions;
  124. stm >> m_lpUserParam;
  125. }
  126. hr = S_OK;
  127. }
  128. catch (_com_error& err)
  129. {
  130. hr = err.Error();
  131. ASSERT (false && "Caught _com_error");
  132. }
  133. }
  134. return (hr);
  135. }
  136. //+-------------------------------------------------------------------
  137. //
  138. // Member: CColumnSortInfo::Persist
  139. //
  140. // Synopsis: Persists object data
  141. //
  142. // Arguments:
  143. //
  144. // History: 10-10-1999 AudriusZ Created
  145. //
  146. //--------------------------------------------------------------------
  147. void CColumnSortInfo::Persist(CPersistor &persistor)
  148. {
  149. persistor.PersistAttribute(XML_ATTR_COLUMN_SORT_INFO_COLMN, m_nCol) ;
  150. static const EnumLiteral sortOptions[] =
  151. {
  152. { RSI_DESCENDING, XML_BITFLAG_COL_SORT_DESCENDING },
  153. { RSI_NOSORTICON, XML_BITFLAG_COL_SORT_NOSORTICON },
  154. };
  155. CXMLBitFlags optionPersistor(m_dwSortOptions, sortOptions, countof(sortOptions));
  156. persistor.PersistAttribute(XML_ATTR_COLUMN_SORT_INFO_OPTNS, optionPersistor) ;
  157. }
  158. //+-------------------------------------------------------------------
  159. //
  160. // Member: ReadSerialObject
  161. //
  162. // Synopsis: Reads CColumnSortList data from stream.
  163. //
  164. // Format: number of columns : each CColumnSortInfo entry.
  165. //
  166. // Arguments: [stm] - The input stream.
  167. // [nVersion] - Version of CColumnSortList to be read.
  168. //
  169. //
  170. //--------------------------------------------------------------------
  171. HRESULT CColumnSortList::ReadSerialObject (IStream &stm, UINT nVersion /*,LARGE_INTEGER nBytes*/)
  172. {
  173. HRESULT hr = S_FALSE; // assume bad version
  174. if (GetVersion() == nVersion)
  175. {
  176. try
  177. {
  178. // Number of columns.
  179. DWORD dwCols;
  180. stm >> dwCols;
  181. clear();
  182. for (int i = 0; i < dwCols; i++)
  183. {
  184. CColumnSortInfo colSortEntry;
  185. // Read data into colSortEntry structure.
  186. if (colSortEntry.Read(stm) != S_OK)
  187. continue;
  188. push_back(colSortEntry);
  189. }
  190. hr = S_OK;
  191. }
  192. catch (_com_error& err)
  193. {
  194. hr = err.Error();
  195. ASSERT (false && "Caught _com_error");
  196. }
  197. }
  198. return (hr);
  199. }
  200. /***************************************************************************\
  201. *
  202. * METHOD: CColumnSortList::Persist
  203. *
  204. * PURPOSE: persists object to XML
  205. *
  206. * PARAMETERS:
  207. * CPersistor& persistor [in/out] persistor to persist under
  208. *
  209. * RETURNS:
  210. * void
  211. *
  212. \***************************************************************************/
  213. void CColumnSortList::PersistSortList(CPersistor& persistor)
  214. {
  215. DECLARE_SC(sc, TEXT("CColumnSortList::PersistSortList"));
  216. if (persistor.IsLoading())
  217. {
  218. clear();
  219. CColumnSortInfo sortInfo;
  220. if (persistor.HasElement(sortInfo.GetXMLType(), NULL))
  221. {
  222. persistor.Persist(sortInfo);
  223. insert(end(), sortInfo);
  224. }
  225. }
  226. else
  227. {
  228. if (size() > 1)
  229. sc.Throw(E_UNEXPECTED);
  230. else if (size())
  231. persistor.Persist(*begin());
  232. }
  233. }
  234. //+-------------------------------------------------------------------
  235. //
  236. // Member: ReadSerialObject
  237. //
  238. // Synopsis: Read CColumnSetData data from the stream.
  239. //
  240. // Arguments: [stm] - The input stream.
  241. // [nVersion] - Version of CColumnSetData structure.
  242. //
  243. // Format : CColumnInfoList : CColumnSortList
  244. //
  245. //
  246. //--------------------------------------------------------------------
  247. HRESULT CColumnSetData::ReadSerialObject (IStream &stm, UINT nVersion /*,LARGE_INTEGER nBytes*/)
  248. {
  249. HRESULT hr = S_FALSE; // assume bad version
  250. if (GetVersion() == nVersion)
  251. {
  252. try
  253. {
  254. do // not a loop
  255. {
  256. // Read the rank
  257. stm >> m_dwRank;
  258. // Read the CColumnInfoList
  259. hr = get_ColumnInfoList()->Read(stm);
  260. if (hr != S_OK)
  261. break;
  262. // Read the CColumnSortList
  263. hr = get_ColumnSortList()->Read(stm);
  264. if (hr != S_OK)
  265. break;
  266. ASSERT (hr == S_OK);
  267. } while (false);
  268. }
  269. catch (_com_error& err)
  270. {
  271. hr = err.Error();
  272. ASSERT (false && "Caught _com_error");
  273. }
  274. }
  275. return (hr);
  276. }
  277. //+-------------------------------------------------------------------
  278. //
  279. // Member: CColumnSetData::Persist
  280. //
  281. // Synopsis: Persists object data
  282. //
  283. // Arguments:
  284. //
  285. // History: 10-10-1999 AudriusZ Created
  286. //
  287. //--------------------------------------------------------------------
  288. void CColumnSetData::Persist(CPersistor &persistor)
  289. {
  290. DECLARE_SC(sc, TEXT("CColumnSetData::Persist"));
  291. sc = ScCheckPointers(get_ColumnInfoList(), get_ColumnSortList());
  292. if (sc)
  293. sc.Throw();
  294. persistor.PersistAttribute(XML_ATTR_COLUMN_SET_RANK, m_dwRank);
  295. // Write CColumnInfoList
  296. persistor.Persist(*get_ColumnInfoList());
  297. // Write CColumnSortList
  298. get_ColumnSortList()->PersistSortList(persistor);
  299. }
  300. //------------------------------------------------------------------
  301. // class CColumnPersistInfo
  302. //------------------------------------------------------------------
  303. CColumnPersistInfo::CColumnPersistInfo() :
  304. m_bInitialized(FALSE), m_dwMaxItems(MAX_COLUMNS_PERSISTED),
  305. m_bDirty(FALSE)
  306. {
  307. }
  308. CColumnPersistInfo::~CColumnPersistInfo()
  309. {
  310. }
  311. //+-------------------------------------------------------------------
  312. //
  313. // Member: RetrieveColumnData
  314. //
  315. // Synopsis: Copy and return the persisted column information
  316. // for given column id and view id.
  317. //
  318. // Arguments: [refSnapinCLSID] - Snapin Guid
  319. // [SColumnSetID] - Column Set Identifier.
  320. // [nViewID] - View ID.
  321. // [columnSetData] - CColumnSetData, used to return the
  322. // persisted column information.
  323. //
  324. // Returns: TRUE - Loaded successfully.
  325. //
  326. // History: 10-16-1998 AnandhaG Created
  327. //
  328. //--------------------------------------------------------------------
  329. BOOL CColumnPersistInfo::RetrieveColumnData( const CLSID& refSnapinCLSID,
  330. const SColumnSetID& colID,
  331. INT nViewID,
  332. CColumnSetData& columnSetData)
  333. {
  334. BOOL bFound = FALSE;
  335. // Make sure we are initialized.
  336. if (!m_bInitialized && !Init())
  337. {
  338. ASSERT(FALSE);
  339. return bFound;
  340. }
  341. // Construct CColumnSetID.
  342. CColumnSetID colSetID(colID);
  343. // Use the snapin clsid to get the ColSetIDToViewTableMap.
  344. SnapinToColSetIDMap::iterator itSnapins;
  345. itSnapins = m_spSnapinsMap->find(refSnapinCLSID);
  346. if (itSnapins == m_spSnapinsMap->end())
  347. return bFound;
  348. // The ColSetIDToViewTableMap is a simple map.
  349. ColSetIDToViewTableMap::iterator itColSetIDMap;
  350. ColSetIDToViewTableMap& colSetIDMap = itSnapins->second;
  351. // Get the data for colSetID.
  352. itColSetIDMap = colSetIDMap.find(colSetID);
  353. if (colSetIDMap.end() == itColSetIDMap)
  354. return bFound;
  355. ViewToColSetDataMap& viewData = itColSetIDMap->second;
  356. ViewToColSetDataMap::iterator itViews;
  357. // See if our view is present.
  358. itViews = viewData.find(nViewID);
  359. if (viewData.end() != itViews)
  360. {
  361. // Found the item.
  362. bFound = TRUE;
  363. ItColSetDataList itColSetData = itViews->second;
  364. // Copy the data.
  365. columnSetData = *itColSetData;
  366. // So move this item to the top of the queue.
  367. m_spColSetList->erase(itColSetData);
  368. itColSetData = m_spColSetList->insert(m_spColSetList->begin(), columnSetData);
  369. itViews->second = itColSetData;
  370. }
  371. return bFound;
  372. }
  373. //+-------------------------------------------------------------------
  374. //
  375. // Member: SaveColumnData
  376. //
  377. // Synopsis: Save/Modify the column information for persistence into
  378. // CColumnPersistInfo.
  379. //
  380. // Arguments:
  381. // [refSnapinCLSID] - Snapin Guid.
  382. // [SColumnSetID] - Column Set Identifier.
  383. // [nViewID] - View ID.
  384. // [columnSetData] - CColumnSetData, Column data.
  385. //
  386. // Returns: TRUE - Saved successfully.
  387. //
  388. // History: 10-16-1998 AnandhaG Created
  389. //
  390. //--------------------------------------------------------------------
  391. BOOL CColumnPersistInfo::SaveColumnData( const CLSID& refSnapinCLSID,
  392. const SColumnSetID& colID,
  393. INT nViewID,
  394. CColumnSetData& columnSetData)
  395. {
  396. // Make sure we are init
  397. if (!m_bInitialized && !Init())
  398. {
  399. ASSERT(FALSE);
  400. return FALSE;
  401. }
  402. // Construct the CColumnSetID.
  403. CColumnSetID colSetID(colID);
  404. // Garbage collect if the number of items in the list is 40% more then pre-set limit.
  405. if (m_spColSetList->size() >= (m_dwMaxItems * (1 + COLUMNS_MAXLIMIT)) )
  406. GarbageCollectItems();
  407. // Insert this item to the top of the queue.
  408. ItColSetDataList itColData;
  409. itColData = m_spColSetList->insert(m_spColSetList->begin(), columnSetData);
  410. SnapinToColSetIDMap::iterator itSnapins;
  411. itSnapins = m_spSnapinsMap->find(refSnapinCLSID);
  412. if (itSnapins != m_spSnapinsMap->end())
  413. {
  414. // Snapin is already in the map.
  415. // Look if the col-id is already inserted.
  416. ColSetIDToViewTableMap::iterator itColSetIDMap;
  417. ColSetIDToViewTableMap& colSetIDMap = itSnapins->second;
  418. // Get the data for the colSetID.
  419. itColSetIDMap = colSetIDMap.find(colSetID);
  420. if (colSetIDMap.end() == itColSetIDMap)
  421. {
  422. // The column-id not found.
  423. // So insert new one.
  424. // Construct the view-id to column-data map
  425. ViewToColSetDataMap viewIDMap;
  426. viewIDMap.insert( ViewToColSetDataVal(nViewID, itColData) );
  427. colSetIDMap.insert(ColSetIDToViewTableVal(colSetID, viewIDMap) );
  428. }
  429. else
  430. {
  431. // The data for Col-ID exists.
  432. // find if the given view exists in the map.
  433. ViewToColSetDataMap::iterator itViewIDMap;
  434. ViewToColSetDataMap& viewIDMap = itColSetIDMap->second;
  435. itViewIDMap = viewIDMap.find(nViewID);
  436. if (viewIDMap.end() != itViewIDMap)
  437. {
  438. // The map from ViewID to column list exists.
  439. // So delete the old data and insert new data
  440. // at the top of the queue.
  441. m_spColSetList->erase(itViewIDMap->second);
  442. itViewIDMap->second = itColData;
  443. }
  444. else
  445. {
  446. // This view is not found.
  447. // So insert new one.
  448. viewIDMap.insert( ViewToColSetDataVal(nViewID, itColData) );
  449. }
  450. }
  451. }
  452. else
  453. {
  454. // Insert the snapin into the map.
  455. // Construct the ViewID to column-data map.
  456. ViewToColSetDataMap viewIDMap;
  457. viewIDMap.insert( ViewToColSetDataVal(nViewID, itColData) );
  458. // Insert the above into the col-id map.
  459. ColSetIDToViewTableMap colIDMap;
  460. colIDMap.insert( ColSetIDToViewTableVal(colSetID, viewIDMap) );
  461. // Insert into the snapins map.
  462. m_spSnapinsMap->insert( SnapinToColSetIDVal(refSnapinCLSID, colIDMap) );
  463. }
  464. // Set dirty after modifying the column-data.
  465. m_bDirty = TRUE;
  466. return TRUE;
  467. }
  468. //+-------------------------------------------------------------------
  469. //
  470. // Member: DeleteColumnData
  471. //
  472. // Synopsis: Delete the persisted column information for the given
  473. // snapin, col-id and view id.
  474. //
  475. // Arguments:
  476. // [refSnapinCLSID] - Snapin Guid.
  477. // [SColumnSetID] - Column Set Identifier.
  478. // [nViewID] - View ID.
  479. //
  480. // Returns: None.
  481. //
  482. // History: 02-13-1999 AnandhaG Created
  483. //
  484. //--------------------------------------------------------------------
  485. VOID CColumnPersistInfo::DeleteColumnData( const CLSID& refSnapinCLSID,
  486. const SColumnSetID& colID,
  487. INT nViewID)
  488. {
  489. // Make sure we are initialized.
  490. if (!m_bInitialized && !Init())
  491. {
  492. ASSERT(FALSE);
  493. return;
  494. }
  495. // Construct CColumnSetID.
  496. CColumnSetID colSetID(colID);
  497. // Use the snapin clsid to get the ColSetIDToViewTableMap.
  498. SnapinToColSetIDMap::iterator itSnapins;
  499. itSnapins = m_spSnapinsMap->find(refSnapinCLSID);
  500. if (itSnapins == m_spSnapinsMap->end())
  501. return;
  502. // The ColSetIDToViewTableMap is a simple map.
  503. ColSetIDToViewTableMap::iterator itColSetIDMap;
  504. ColSetIDToViewTableMap& colSetIDMap = itSnapins->second;
  505. // Get the data for colSetID.
  506. itColSetIDMap = colSetIDMap.find(colSetID);
  507. if (colSetIDMap.end() == itColSetIDMap)
  508. return;
  509. ViewToColSetDataMap& viewData = itColSetIDMap->second;
  510. ViewToColSetDataMap::iterator itViews;
  511. // See if our view is present.
  512. itViews = viewData.find(nViewID);
  513. if (viewData.end() == itViews)
  514. return;
  515. ItColSetDataList itColSetData = itViews->second;
  516. itColSetData->m_bInvalid = TRUE;
  517. // Delete the invalid items.
  518. DeleteMarkedItems();
  519. return;
  520. }
  521. //+-------------------------------------------------------------------
  522. //
  523. // Member: DeleteColumnDataOfSnapin
  524. //
  525. // Synopsis: Delete the column data of given snapin.
  526. //
  527. // Arguments: [refSnapinCLSID] - Snapin Guid.
  528. //
  529. // Returns: TRUE - Data removed successfully.
  530. //
  531. // History: 02-11-1999 AnandhaG Created
  532. //
  533. //--------------------------------------------------------------------
  534. BOOL CColumnPersistInfo::DeleteColumnDataOfSnapin( const CLSID& refSnapinCLSID)
  535. {
  536. // Make sure we are init
  537. if (!m_bInitialized)
  538. {
  539. return FALSE;
  540. }
  541. SnapinToColSetIDMap::iterator itSnapinsMap;
  542. itSnapinsMap = m_spSnapinsMap->find(refSnapinCLSID);
  543. // Find the given snapin.
  544. // Iterate thro all the col-ids of this snapin and
  545. // all the views of those col-id and set the data
  546. // to be invalid.
  547. if (m_spSnapinsMap->end() != itSnapinsMap)
  548. {
  549. ColSetIDToViewTableMap& colSets = itSnapinsMap->second;
  550. // Iterate thro' all colset ids of this snapin.
  551. ColSetIDToViewTableMap::iterator itColumnSetIDMap;
  552. for (itColumnSetIDMap = colSets.begin();
  553. itColumnSetIDMap != colSets.end();
  554. ++itColumnSetIDMap)
  555. {
  556. // Get the view map
  557. ViewToColSetDataMap& viewIDMap = itColumnSetIDMap->second;
  558. ViewToColSetDataMap::iterator itViewIDMap;
  559. // Iterate thro' all views and set the data invalid.
  560. for (itViewIDMap = viewIDMap.begin();
  561. itViewIDMap != viewIDMap.end();
  562. ++itViewIDMap)
  563. {
  564. ItColSetDataList itColSetData = itViewIDMap->second;
  565. itColSetData->m_bInvalid = TRUE;
  566. }
  567. }
  568. }
  569. // Delete the invalid items.
  570. DeleteMarkedItems();
  571. return TRUE;
  572. }
  573. //+-------------------------------------------------------------------
  574. //
  575. // Member: DeleteColumnDataOfView
  576. //
  577. // Synopsis: Delete the column data of given view.
  578. //
  579. // Arguments: [nViewID] - View ID.
  580. //
  581. // Returns: TRUE - Data removed successfully.
  582. //
  583. // History: 02-11-1999 AnandhaG Created
  584. //
  585. //--------------------------------------------------------------------
  586. BOOL CColumnPersistInfo::DeleteColumnDataOfView( int nViewID)
  587. {
  588. // Make sure we are init
  589. if (!m_bInitialized)
  590. {
  591. return FALSE;
  592. }
  593. // Iterate thro all snapins, col-ids and find the matching
  594. // view and set data to be invalid.
  595. SnapinToColSetIDMap::iterator itSnapinsMap;
  596. // Iterate thro all snapins.
  597. for (itSnapinsMap = m_spSnapinsMap->begin();
  598. m_spSnapinsMap->end() != itSnapinsMap;
  599. ++itSnapinsMap)
  600. {
  601. ColSetIDToViewTableMap& colSets = itSnapinsMap->second;
  602. ColSetIDToViewTableMap::iterator itColumnSetIDMap;
  603. // Iterate thro' all colset ids of this snapin.
  604. for (itColumnSetIDMap = colSets.begin();
  605. itColumnSetIDMap != colSets.end();
  606. ++itColumnSetIDMap)
  607. {
  608. // Get the view map
  609. ViewToColSetDataMap& viewIDMap = itColumnSetIDMap->second;
  610. ViewToColSetDataMap::iterator itViewIDMap;
  611. // Find the matching views and mark them to be deleted.
  612. for (itViewIDMap = viewIDMap.begin();
  613. itViewIDMap != viewIDMap.end();
  614. ++itViewIDMap)
  615. {
  616. if (nViewID == itViewIDMap->first)
  617. {
  618. ItColSetDataList itColSetData = itViewIDMap->second;
  619. itColSetData->m_bInvalid = TRUE;
  620. }
  621. }
  622. }
  623. }
  624. // Delete the invalid items.
  625. DeleteMarkedItems();
  626. return TRUE;
  627. }
  628. //+-------------------------------------------------------------------
  629. //
  630. // Member: Init
  631. //
  632. // Synopsis: Create the Map and the list for CColumnSetData.
  633. //
  634. // Returns: TRUE - for success.
  635. //
  636. // History: 10-16-1998 AnandhaG Created
  637. //
  638. //--------------------------------------------------------------------
  639. BOOL CColumnPersistInfo::Init()
  640. {
  641. // Create the data structures to store column data.
  642. m_spSnapinsMap = auto_ptr<SnapinToColSetIDMap>(new SnapinToColSetIDMap);
  643. m_spColSetList = auto_ptr<ColSetDataList> (new ColSetDataList);
  644. // Now the objects are created, so now set initialized to true.
  645. m_bInitialized = TRUE;
  646. // Now read the registry to see if m_dwMaxItems is specified.
  647. // Check if the settings key exists.
  648. CRegKeyEx rSettingsKey;
  649. if (rSettingsKey.ScOpen (HKEY_LOCAL_MACHINE, SETTINGS_KEY, KEY_READ).IsError())
  650. return m_bInitialized;
  651. // Read the values for MaxColDataPersisted.
  652. if (rSettingsKey.IsValuePresent(g_szMaxColumnDataPersisted))
  653. {
  654. DWORD dwType = REG_DWORD;
  655. DWORD dwSize = sizeof(DWORD);
  656. SC sc = rSettingsKey.ScQueryValue (g_szMaxColumnDataPersisted, &dwType,
  657. &m_dwMaxItems, &dwSize);
  658. if (sc)
  659. sc.TraceAndClear();
  660. }
  661. return m_bInitialized;
  662. }
  663. //+-------------------------------------------------------------------
  664. //
  665. // Member: GarbageCollectItems
  666. //
  667. // Synopsis: Free least used column data.
  668. //
  669. // Arguments: None.
  670. //
  671. // History: 02-11-1999 AnandhaG Created
  672. //
  673. //--------------------------------------------------------------------
  674. VOID CColumnPersistInfo::GarbageCollectItems()
  675. {
  676. INT nItemsToBeRemoved = COLUMNS_MAXLIMIT * m_dwMaxItems;
  677. // Go thro' the list and set the nItemsToBeRemoved that was least recently
  678. // accessed to be invalid.
  679. INT nIndex = 0;
  680. ItColSetDataList itColList;
  681. // Skip first m_dwMaxItems.
  682. for (itColList = m_spColSetList->begin();
  683. ( (itColList != m_spColSetList->end()) && (nIndex <= m_dwMaxItems) );
  684. ++itColList, nIndex++)
  685. {
  686. nIndex++;
  687. }
  688. // Mark rest of the items to be garbage.
  689. while (itColList != m_spColSetList->end())
  690. {
  691. itColList->m_bInvalid = TRUE;
  692. ++itColList;
  693. }
  694. // Delete the invalid items.
  695. DeleteMarkedItems();
  696. return;
  697. }
  698. //+-------------------------------------------------------------------
  699. //
  700. // Member: DeleteMarkedItems
  701. //
  702. // Synopsis: Delete invalidated items. This involves iterating thro
  703. // the maps to find the invalid items. Then deleting the
  704. // items. If the map becomes empty then delete the map.
  705. //
  706. // History: 02-11-1999 AnandhaG Created
  707. //
  708. //--------------------------------------------------------------------
  709. VOID CColumnPersistInfo::DeleteMarkedItems()
  710. {
  711. SnapinToColSetIDMap::iterator itSnapinsMap, itSnapinsMapNew;
  712. // Now iterate thro the map and remove those elements.
  713. itSnapinsMap = m_spSnapinsMap->begin();
  714. while (itSnapinsMap != m_spSnapinsMap->end())
  715. {
  716. ColSetIDToViewTableMap& colSets = itSnapinsMap->second;
  717. ColSetIDToViewTableMap::iterator itColumnSetIDMap;
  718. // Iterate thro this snapins col-ids.
  719. itColumnSetIDMap = colSets.begin();
  720. while (itColumnSetIDMap != colSets.end())
  721. {
  722. // Get the view map
  723. ViewToColSetDataMap& viewIDMap = itColumnSetIDMap->second;
  724. ViewToColSetDataMap::iterator itViewIDMap;
  725. // Iterate thro all the views.
  726. itViewIDMap = viewIDMap.begin();
  727. while (itViewIDMap != viewIDMap.end())
  728. {
  729. ItColSetDataList itColSetData = itViewIDMap->second;
  730. if (itColSetData->m_bInvalid)
  731. {
  732. // Delete the item ref from the map.
  733. // Erase returns iterator to next item.
  734. itViewIDMap = viewIDMap.erase(itViewIDMap);
  735. // Delete the item from the list.
  736. m_spColSetList->erase(itColSetData);
  737. }
  738. else
  739. // Item is valid item.
  740. ++itViewIDMap;
  741. }
  742. // If the view has zero items we need to remove this
  743. // view map. (ColID to ViewMap).
  744. if (0 == viewIDMap.size())
  745. {
  746. // Delete the col-id map.
  747. // Erase returns iterator to next item.
  748. itColumnSetIDMap = colSets.erase(itColumnSetIDMap);
  749. }
  750. else
  751. ++itColumnSetIDMap;
  752. }
  753. // If there are no col-id's remove the
  754. // Snapin to this col-id map.
  755. if (0 == colSets.size())
  756. {
  757. // Delete this snapin map.
  758. // Erase returns iterator to next item.
  759. itSnapinsMap = m_spSnapinsMap->erase(itSnapinsMap);
  760. }
  761. else
  762. ++itSnapinsMap;
  763. }
  764. return;
  765. }
  766. //+-------------------------------------------------------------------
  767. //
  768. // Member: Load
  769. //
  770. // Synopsis: Load the persisted column information.
  771. //
  772. // Arguments: [pStream]- ISteam from which column widths to be loaded.
  773. //
  774. // Returns: S_OK - Loaded successfully.
  775. //
  776. // History: 10-16-1998 AnandhaG Created
  777. //
  778. //--------------------------------------------------------------------
  779. STDMETHODIMP CColumnPersistInfo::Load (IStream* pStream)
  780. {
  781. HRESULT hr = E_FAIL;
  782. if (!m_bInitialized && !Init())
  783. {
  784. ASSERT(FALSE);
  785. return hr;
  786. }
  787. // read the column width information.
  788. try
  789. {
  790. do
  791. {
  792. // Read the version. If it did not match return
  793. INT nVersion = 0;
  794. *pStream >> nVersion;
  795. if (COLPersistenceVersion != nVersion)
  796. return S_FALSE;
  797. // Read the # of Snapins
  798. DWORD dwSnapins = 0;
  799. *pStream >> dwSnapins;
  800. m_spColSetList->clear();
  801. m_spSnapinsMap->clear();
  802. // For each snapin...
  803. for (int nSnapIdx = 0; nSnapIdx < dwSnapins; nSnapIdx++)
  804. {
  805. // Read snapin CLSID.
  806. CLSID clsidSnapin;
  807. *pStream >> clsidSnapin;
  808. // Read the number of col-ids for this snapin.
  809. DWORD dwColIDs = 0;
  810. *pStream >> dwColIDs;
  811. ColSetIDToViewTableMap colSetsMap;
  812. // For each col-id...
  813. for (int nColIDIdx = 0; nColIDIdx < dwColIDs; nColIDIdx++)
  814. {
  815. // Read the col-id
  816. CColumnSetID colSetID;
  817. *pStream >> colSetID;
  818. // Read the number of views.
  819. DWORD dwNumViews = 0;
  820. *pStream >> dwNumViews;
  821. ViewToColSetDataMap ViewIDMap;
  822. // For each view...
  823. for (int nViewIdx = 0; nViewIdx < dwNumViews; nViewIdx++)
  824. {
  825. // Read view id.
  826. DWORD dwViewID;
  827. *pStream >> dwViewID;
  828. // Read the CColumnSetData.
  829. CColumnSetData ColData;
  830. ColData.Read(*pStream);
  831. // Insert the data into the global linked list.
  832. ItColSetDataList itColSetData;
  833. itColSetData = m_spColSetList->insert(m_spColSetList->begin(), ColData);
  834. // Insert the pointer to the data in to view map.
  835. ViewIDMap.insert(ViewToColSetDataVal(dwViewID, itColSetData));
  836. }
  837. // Insert the view map into the col-id map.
  838. colSetsMap.insert(ColSetIDToViewTableVal(colSetID, ViewIDMap));
  839. }
  840. // Insert the col-id map into the snapin map.
  841. m_spSnapinsMap->insert(SnapinToColSetIDVal(clsidSnapin, colSetsMap));
  842. }
  843. // Now sort the list.
  844. m_spColSetList->sort();
  845. } while (FALSE);
  846. }
  847. catch (_com_error& err)
  848. {
  849. hr = err.Error();
  850. }
  851. catch (...)
  852. {
  853. ASSERT (0 && "Unexpected exception");
  854. throw;
  855. }
  856. return S_OK;
  857. }
  858. //+-------------------------------------------------------------------
  859. //
  860. // Member: Save
  861. //
  862. // Synopsis: Persist the column information.
  863. //
  864. // Arguments: [pStream]- IStream in which column widths are to be saved.
  865. //
  866. // Returns: S_OK - Saved successfully.
  867. //
  868. // History: 10-16-1998 AnandhaG Created
  869. //
  870. //--------------------------------------------------------------------
  871. STDMETHODIMP CColumnPersistInfo::Save (IStream* pStream, BOOL bClearDirty)
  872. {
  873. // absolete method.
  874. // this method is left here since we use IPersistStream to export
  875. // persistence to CONUI side and need to implement it.
  876. // But this interface will never be called to save data
  877. // [we will use CPersistor-based XML saving instead]
  878. // so the method will always fail.
  879. ASSERT(FALSE && "Should never come here");
  880. return E_NOTIMPL;
  881. }
  882. //+-------------------------------------------------------------------
  883. //
  884. // Member: Persist
  885. //
  886. // Synopsis: Persists the column information.
  887. //
  888. // Arguments: [persistor]- CPersistor in/from which column widths are persisted.
  889. //
  890. // Returns: void.
  891. //
  892. // History: 10-08-1999 AudriusZ Created
  893. //
  894. //--------------------------------------------------------------------
  895. void CColumnPersistInfo::Persist(CPersistor &persistor)
  896. {
  897. DECLARE_SC(sc, TEXT("CColumnPersistInfo::Persist"));
  898. if (!m_bInitialized && !Init())
  899. sc.Throw(E_FAIL);
  900. sc = ScCheckPointers(m_spColSetList.get(), m_spSnapinsMap.get(), E_UNEXPECTED);
  901. if (sc)
  902. sc.Throw();
  903. if (persistor.IsStoring())
  904. {
  905. // Give ranking to each column data.
  906. ItColSetDataList itColList;
  907. DWORD dwRank = 0;
  908. for (itColList = m_spColSetList->begin();
  909. itColList != m_spColSetList->end();
  910. ++itColList)
  911. {
  912. itColList->m_dwRank = dwRank++;
  913. }
  914. }
  915. else // if (persistor.IsLoading())
  916. {
  917. m_spColSetList->clear();
  918. m_spSnapinsMap->clear();
  919. }
  920. SnapinToColSetIDMapPersistor childPersisot(*m_spSnapinsMap, *m_spColSetList);
  921. childPersisot.Persist(persistor);
  922. if (persistor.IsStoring())
  923. m_bDirty = FALSE;
  924. }
  925. //+-------------------------------------------------------------------
  926. //
  927. // Member: OnInitDialog
  928. //
  929. // Synopsis: Initialize the Columns dialog.
  930. //
  931. // Arguments:
  932. //
  933. // History: 11-16-1998 AnandhaG Created
  934. //
  935. //--------------------------------------------------------------------
  936. LRESULT CColumnsDlg::OnInitDialog (UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  937. {
  938. m_btnAdd = ::GetDlgItem(m_hWnd, IDC_ADD_COLUMNS);
  939. m_btnRemove = ::GetDlgItem(m_hWnd, IDC_REMOVE_COLUMNS);
  940. m_btnRestoreDefaultColumns = ::GetDlgItem(m_hWnd, IDC_RESTORE_DEFAULT_COLUMNS);
  941. m_btnMoveUp = ::GetDlgItem(m_hWnd, IDC_MOVEUP_COLUMN);
  942. m_btnMoveDown = ::GetDlgItem(m_hWnd, IDC_MOVEDOWN_COLUMN);
  943. m_HiddenColList.Attach(::GetDlgItem(m_hWnd, IDC_HIDDEN_COLUMNS));
  944. m_DisplayedColList.Attach(::GetDlgItem(m_hWnd, IDC_DISPLAYED_COLUMNS));
  945. m_bUsingDefaultColumnSettings = (*m_pColumnInfoList == m_DefaultColumnInfoList);
  946. InitializeLists();
  947. EnableUIObjects();
  948. return 0;
  949. }
  950. //+-------------------------------------------------------------------
  951. //
  952. // Member: OnOK
  953. //
  954. // Synopsis: Get the hidden and visible columns.
  955. //
  956. // Arguments:
  957. //
  958. // History: 11-16-1998 AnandhaG Created
  959. //
  960. //--------------------------------------------------------------------
  961. LRESULT CColumnsDlg::OnOK (WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
  962. {
  963. if (! m_bDirty) // column settings are not modified
  964. {
  965. EndDialog (IDCANCEL);
  966. return 1;
  967. }
  968. if (m_bUsingDefaultColumnSettings)
  969. {
  970. EndDialog(IDC_RESTORE_DEFAULT_COLUMNS);
  971. return 1;
  972. }
  973. ASSERT(NULL != m_pColumnInfoList);
  974. if (NULL == m_pColumnInfoList)
  975. return 0;
  976. WTL::CString strColumnName;
  977. CColumnInfoList::iterator it;
  978. CColumnInfo colinfo;
  979. // Get the strings from Hidden_List_Box.
  980. // These cols are to be hidden. So put them first in the list.
  981. int cItems = m_HiddenColList.GetCount();
  982. for (int i = 0; i < cItems; i++)
  983. {
  984. // Get the text from list box
  985. int nRet = m_HiddenColList.GetText(i, strColumnName);
  986. if (LB_ERR == nRet)
  987. {
  988. ASSERT(FALSE);
  989. break;
  990. }
  991. // Use the string to get the actual index of the column.
  992. int nIndex = GetColIndex(strColumnName);
  993. if (0 > nIndex )
  994. {
  995. ASSERT(FALSE);
  996. break;
  997. }
  998. // With the index get the column and insert it at beginning.
  999. it = find_if(m_pColumnInfoList->begin(), m_pColumnInfoList->end(),
  1000. bind2nd(ColPosCompare(), nIndex));
  1001. if (it == m_pColumnInfoList->end())
  1002. {
  1003. ASSERT(FALSE);
  1004. break;
  1005. }
  1006. // Set the *it flag to be hidden. Insert it at beginning.
  1007. colinfo = *it;
  1008. colinfo.SetColHidden();
  1009. // Move the item to the head of the list
  1010. m_pColumnInfoList->erase(it);
  1011. m_pColumnInfoList->push_front(colinfo);
  1012. }
  1013. // Then get the strings from DisplayedColumns_List_Box.
  1014. cItems = m_DisplayedColList.GetCount();
  1015. for (i = 0; i < cItems; i++)
  1016. {
  1017. // Get the text from list box
  1018. int nRet = m_DisplayedColList.GetText(i, strColumnName);
  1019. if (LB_ERR == nRet)
  1020. {
  1021. ASSERT(FALSE);
  1022. break;
  1023. }
  1024. // Use the column name to get the column index.
  1025. int nIndex = GetColIndex(strColumnName);
  1026. if (0 > nIndex )
  1027. {
  1028. ASSERT(FALSE);
  1029. break;
  1030. }
  1031. // Get the CColumnInfo and insert at end.
  1032. it = find_if(m_pColumnInfoList->begin(), m_pColumnInfoList->end(),
  1033. bind2nd(ColPosCompare(), nIndex));
  1034. if (it == m_pColumnInfoList->end())
  1035. break;
  1036. colinfo = *it;
  1037. if (colinfo.IsColHidden())
  1038. {
  1039. // If hidden column is made visible
  1040. // reset the hidden flag and set the width
  1041. // to auto_width.
  1042. colinfo.SetColHidden(false);
  1043. if (colinfo.GetColWidth() <= 0)
  1044. colinfo.SetColWidth(AUTO_WIDTH);
  1045. }
  1046. // Move it to the end of the list.
  1047. m_pColumnInfoList->erase(it);
  1048. m_pColumnInfoList->push_back(colinfo);
  1049. }
  1050. EndDialog (IDOK);
  1051. return 1;
  1052. }
  1053. LRESULT CColumnsDlg::OnCancel (WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
  1054. {
  1055. EndDialog (IDCANCEL);
  1056. return 0;
  1057. }
  1058. LRESULT CColumnsDlg::OnMoveUp (WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
  1059. {
  1060. MoveItem(TRUE);
  1061. return 0;
  1062. }
  1063. LRESULT CColumnsDlg::OnMoveDown (WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
  1064. {
  1065. MoveItem(FALSE);
  1066. return 0;
  1067. }
  1068. //+-------------------------------------------------------------------
  1069. //
  1070. // Member: OnAdd
  1071. //
  1072. // Synopsis: Adds a column to displayed columns list by removing
  1073. // the currently selected column from hidden column list.
  1074. //
  1075. // Arguments:
  1076. //
  1077. //--------------------------------------------------------------------
  1078. LRESULT CColumnsDlg::OnAdd (WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
  1079. {
  1080. // First remove from hidden column list.
  1081. int nCurSel = m_HiddenColList.GetCurSel();
  1082. WTL::CString strColumnName;
  1083. int nRet = m_HiddenColList.GetText(nCurSel, strColumnName);
  1084. if (LB_ERR == nRet)
  1085. {
  1086. ASSERT(FALSE);
  1087. return 0;
  1088. }
  1089. m_HiddenColList.DeleteString(nCurSel);
  1090. // now add it to Displayed column list.
  1091. m_DisplayedColList.AddString(strColumnName);
  1092. SetDirty();
  1093. if (nCurSel > m_HiddenColList.GetCount()-1)
  1094. nCurSel = m_HiddenColList.GetCount()-1;
  1095. m_HiddenColList.SetCurSel(nCurSel);
  1096. m_DisplayedColList.SelectString(0, strColumnName);
  1097. SetListBoxHScrollSize();
  1098. EnableUIObjects();
  1099. return 0;
  1100. }
  1101. //+-------------------------------------------------------------------
  1102. //
  1103. // Member: OnRemove
  1104. //
  1105. // Synopsis: Removes the currently selected column from displayed
  1106. // columns list by removing and adds it to hidden column list.
  1107. //
  1108. // Arguments:
  1109. //
  1110. //--------------------------------------------------------------------
  1111. LRESULT CColumnsDlg::OnRemove (WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
  1112. {
  1113. // Get the currently selected item in Displayed Columns list.
  1114. int nCurSel = m_DisplayedColList.GetCurSel();
  1115. WTL::CString strColumnName;
  1116. int nRet = m_DisplayedColList.GetText(nCurSel, strColumnName);
  1117. if (LB_ERR == nRet)
  1118. {
  1119. ASSERT(FALSE);
  1120. return 0;
  1121. }
  1122. // If column zero do not hide it.
  1123. if (0 == GetColIndex(strColumnName))
  1124. return 0;
  1125. m_DisplayedColList.DeleteString(nCurSel);
  1126. // Add it to hidden column list.
  1127. m_HiddenColList.AddString(strColumnName);
  1128. SetDirty();
  1129. if (nCurSel > m_DisplayedColList.GetCount()-1)
  1130. nCurSel = m_DisplayedColList.GetCount()-1;
  1131. m_DisplayedColList.SetCurSel(nCurSel);
  1132. m_HiddenColList.SelectString(0, strColumnName);
  1133. EnableUIObjects();
  1134. SetListBoxHScrollSize();
  1135. return 0;
  1136. }
  1137. LRESULT CColumnsDlg::OnRestoreDefaultColumns (WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
  1138. {
  1139. DECLARE_SC(sc, TEXT("CColumnsDlg::OnRestoreDefaultColumns"));
  1140. // Get the default data and populate the columns dialog.
  1141. *m_pColumnInfoList = m_DefaultColumnInfoList;
  1142. SetUsingDefaultColumnSettings();
  1143. InitializeLists();
  1144. EnableUIObjects();
  1145. // Button is disabled so put the focus on the dialog.
  1146. SetFocus();
  1147. return 0;
  1148. }
  1149. LRESULT CColumnsDlg::OnSelChange (WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
  1150. {
  1151. EnableUIObjects();
  1152. return 0;
  1153. }
  1154. //+-------------------------------------------------------------------
  1155. //
  1156. // Member: MoveItem
  1157. //
  1158. // Synopsis: Moves an item in the displayed columns list up or down.
  1159. // The up down order is same as column visible order from
  1160. // left to right.
  1161. //
  1162. // Arguments: [BOOL] - up or down.
  1163. //
  1164. //--------------------------------------------------------------------
  1165. void CColumnsDlg::MoveItem (BOOL bMoveUp)
  1166. {
  1167. int nCurSel = m_DisplayedColList.GetCurSel();
  1168. WTL::CString strColumnName;
  1169. int nRet = m_DisplayedColList.GetText(nCurSel, strColumnName);
  1170. if (LB_ERR == nRet)
  1171. {
  1172. ASSERT(FALSE);
  1173. return;
  1174. }
  1175. m_DisplayedColList.DeleteString(nCurSel);
  1176. if (bMoveUp)
  1177. m_DisplayedColList.InsertString(nCurSel-1, strColumnName);
  1178. else
  1179. m_DisplayedColList.InsertString(nCurSel+1, strColumnName);
  1180. m_DisplayedColList.SelectString(0, strColumnName);
  1181. SetDirty();
  1182. EnableUIObjects();
  1183. return;
  1184. }
  1185. //+-------------------------------------------------------------------
  1186. //
  1187. // Member: EnableUIObjects
  1188. //
  1189. // Synopsis: Enable/Disable the UI objects in the dialog.
  1190. //
  1191. // Arguments:
  1192. //
  1193. //--------------------------------------------------------------------
  1194. void CColumnsDlg::EnableUIObjects()
  1195. {
  1196. int curselAvailable = m_HiddenColList.GetCurSel();
  1197. int curselShow = m_DisplayedColList.GetCurSel();
  1198. int cItems = m_HiddenColList.GetCount();
  1199. BOOL bEnableAdd = ((curselAvailable != LB_ERR) && (curselAvailable || cItems)) ? TRUE: FALSE;
  1200. BOOL bEnableRemove = ((curselShow != LB_ERR)) ? TRUE: FALSE;
  1201. BOOL bEnableMoveUp = ((curselShow != LB_ERR) && curselShow) ? TRUE: FALSE;
  1202. cItems = m_DisplayedColList.GetCount();
  1203. BOOL bEnableMoveDown = cItems && (curselShow != LB_ERR) && (cItems!=curselShow+1);
  1204. BOOL bRet = FALSE;
  1205. bRet = m_btnAdd.EnableWindow(bEnableAdd);
  1206. bRet = m_btnRemove.EnableWindow(bEnableRemove);
  1207. bRet = m_btnMoveUp.EnableWindow(bEnableMoveUp);
  1208. bRet = m_btnMoveDown.EnableWindow(bEnableMoveDown);
  1209. // Enable restore defaults only if columns are already customized before bringing the dialog
  1210. bRet = m_btnRestoreDefaultColumns.EnableWindow( (!m_bUsingDefaultColumnSettings));
  1211. // Disable Remove/Move Up/Move Down buttons for Col zero.
  1212. int nCurSel = m_DisplayedColList.GetCurSel();
  1213. WTL::CString strColumnName;
  1214. int nRet = m_DisplayedColList.GetText(nCurSel, strColumnName);
  1215. if (LB_ERR == nRet)
  1216. {
  1217. ASSERT(FALSE);
  1218. return;
  1219. }
  1220. if (0 == GetColIndex(strColumnName)) // Column 0
  1221. m_btnRemove.EnableWindow(FALSE);
  1222. }
  1223. int CColumnsDlg::GetColIndex(LPCTSTR lpszColName)
  1224. {
  1225. TStringVector::iterator itStrVec1;
  1226. USES_CONVERSION;
  1227. itStrVec1 = find(m_pStringVector->begin(), m_pStringVector->end(), lpszColName);
  1228. if (m_pStringVector->end() != itStrVec1)
  1229. return (itStrVec1 - m_pStringVector->begin());
  1230. else
  1231. // Unknown column
  1232. return -1;
  1233. }
  1234. //+-------------------------------------------------------------------
  1235. //
  1236. // Member: SetListBoxHorizontalScrollbar
  1237. //
  1238. // Synopsis: For the given list box enumerate the strings added and find
  1239. // the largest string. Calculate scrollbar size for this string
  1240. // and set it.
  1241. //
  1242. // Arguments: [listBox] - Given list box.
  1243. //
  1244. //--------------------------------------------------------------------
  1245. void CColumnsDlg::SetListBoxHorizontalScrollbar(WTL::CListBox& listBox)
  1246. {
  1247. int dx=0;
  1248. WTL::CDC dc(listBox.GetWindowDC());
  1249. if (dc.IsNull())
  1250. return;
  1251. // Find the longest string in the list box.
  1252. for (int i=0;i < listBox.GetCount();i++)
  1253. {
  1254. WTL::CString str;
  1255. int nRet = listBox.GetText( i, str );
  1256. if (nRet == LB_ERR)
  1257. return;
  1258. WTL::CSize sz;
  1259. if (! dc.GetTextExtent(str, str.GetLength(), &sz))
  1260. return;
  1261. if (sz.cx > dx)
  1262. dx = sz.cx;
  1263. }
  1264. // Set the horizontal extent so every character of all strings
  1265. // can be scrolled to.
  1266. listBox.SetHorizontalExtent(dx);
  1267. return;
  1268. }
  1269. /* CColumnsDlg::InitializeLists
  1270. *
  1271. * PURPOSE:
  1272. *
  1273. * PARAMETERS:
  1274. *
  1275. * RETURNS:
  1276. * void
  1277. */
  1278. void CColumnsDlg::InitializeLists()
  1279. {
  1280. CColumnInfoList::iterator it;
  1281. int j = 0;
  1282. if (!m_pColumnInfoList)
  1283. {
  1284. ASSERT(FALSE);
  1285. return;
  1286. }
  1287. m_HiddenColList.ResetContent();
  1288. m_DisplayedColList.ResetContent();
  1289. USES_CONVERSION;
  1290. for (it = m_pColumnInfoList->begin(); it != m_pColumnInfoList->end(); ++it)
  1291. {
  1292. if (it->IsColHidden())
  1293. {
  1294. m_HiddenColList.AddString(m_pStringVector->at(it->GetColIndex()).data());
  1295. }
  1296. else
  1297. {
  1298. m_DisplayedColList.InsertString(j++, m_pStringVector->at(it->GetColIndex()).data());
  1299. }
  1300. }
  1301. m_DisplayedColList.SetCurSel(m_DisplayedColList.GetCount()-1);
  1302. m_HiddenColList.SetCurSel(m_HiddenColList.GetCount()-1);
  1303. SetListBoxHScrollSize();
  1304. }
  1305. //+-------------------------------------------------------------------
  1306. //
  1307. // Member: CColumnSetID::Persist
  1308. //
  1309. // Synopsis: Persists object data
  1310. //
  1311. // Arguments:
  1312. //
  1313. // History: 10-10-1999 AudriusZ Created
  1314. //
  1315. //--------------------------------------------------------------------
  1316. void CColumnSetID::Persist(CPersistor &persistor)
  1317. {
  1318. DECLARE_SC(sc, TEXT("CColumnSetID::Persist"));
  1319. CXMLAutoBinary binary;
  1320. if (persistor.IsStoring() && m_vID.size()) // fill only if have data
  1321. {
  1322. sc = binary.ScAlloc(m_vID.size());
  1323. if (sc)
  1324. sc.Throw();
  1325. CXMLBinaryLock sLock(binary); // will unlock in destructor
  1326. LPBYTE pData = NULL;
  1327. sc = sLock.ScLock(&pData);
  1328. if (sc)
  1329. sc.Throw();
  1330. sc = ScCheckPointers(pData, E_UNEXPECTED);
  1331. if (sc)
  1332. sc.Throw();
  1333. std::copy(m_vID.begin(), m_vID.end(), pData);
  1334. }
  1335. persistor.PersistAttribute(XML_ATTR_COLUMN_SET_ID_PATH, binary);
  1336. if (persistor.IsLoading())
  1337. {
  1338. m_vID.clear();
  1339. if (binary.GetSize())
  1340. {
  1341. CXMLBinaryLock sLock(binary); // will unlock in destructor
  1342. LPBYTE pData = NULL;
  1343. sc = sLock.ScLock(&pData);
  1344. if (sc)
  1345. sc.Throw();
  1346. sc = ScCheckPointers(pData, E_UNEXPECTED);
  1347. if (sc)
  1348. sc.Throw();
  1349. m_vID.insert(m_vID.end(), pData, pData + binary.GetSize());
  1350. }
  1351. }
  1352. persistor.PersistAttribute(XML_ATTR_COLUMN_SET_ID_FLAGS, m_dwFlags);
  1353. }
  1354. /***************************************************************************\
  1355. *
  1356. * METHOD: ViewToColSetDataMapPersistor::Persist
  1357. *
  1358. * PURPOSE: called by the base class to create and persist the new element
  1359. *
  1360. * PARAMETERS:
  1361. * CPersistor& persistor - [in] persistor from which to persist new element
  1362. *
  1363. * RETURNS:
  1364. * void
  1365. *
  1366. * see "Data structures used to persist column information" comment
  1367. * int file colwidth.h for more information
  1368. \***************************************************************************/
  1369. void ViewToColSetDataMapPersistor::Persist(CPersistor &persistor)
  1370. {
  1371. if (persistor.IsStoring())
  1372. {
  1373. // iterate and save all elements as linear list
  1374. ViewToColSetDataMap::iterator it;
  1375. for (it = m_map.begin(); it != m_map.end(); ++it)
  1376. {
  1377. // we will sneak under child's element to persist the KEY value as an attribute
  1378. // of the child element. To do that we use tag got from _GetXMLType() of the child
  1379. CPersistor persistorChild(persistor, it->second->GetXMLType());
  1380. int view_id = it->first; // just to cast constness out (we do not have const Persist)
  1381. persistorChild.PersistAttribute(XML_ATTR_COLUMN_SET_ID_VIEW, view_id);
  1382. // note: we are asking the child to persist on the same level.
  1383. // thats to save on depth
  1384. it->second->Persist(persistorChild);
  1385. }
  1386. }
  1387. else
  1388. {
  1389. // use base class to read. it will call OnNewElement for each found
  1390. m_map.clear();
  1391. XMLListCollectionBase::Persist(persistor);
  1392. }
  1393. }
  1394. /***************************************************************************\
  1395. *
  1396. * METHOD: ViewToColSetDataMapPersistor::OnNewElement
  1397. *
  1398. * PURPOSE: called by the base class to create and persist the new element
  1399. *
  1400. * PARAMETERS:
  1401. * CPersistor& persistor - [in] persistor from which to persist new element
  1402. *
  1403. * RETURNS:
  1404. * void
  1405. *
  1406. * see "Data structures used to persist column information" comment
  1407. * int file colwidth.h for more information
  1408. \***************************************************************************/
  1409. void ViewToColSetDataMapPersistor::OnNewElement(CPersistor& persistor)
  1410. {
  1411. // we will sneak under child's element to persist the KEY value as an attribute
  1412. // of the child element. To do that we use tag got from GetXMLType() of the child
  1413. CColumnSetData setData;
  1414. CPersistor persistorChild(persistor, setData.GetXMLType());
  1415. // read the key value from the child element
  1416. int view_id = 0;
  1417. persistorChild.PersistAttribute(XML_ATTR_COLUMN_SET_ID_VIEW, view_id);
  1418. // insert value to the list
  1419. ColSetDataList::iterator it = m_list.insert(m_list.end(), setData);
  1420. // ad list iterator to the map
  1421. m_map[view_id] = it;
  1422. // persist contents of the list item
  1423. it->Persist(persistorChild);
  1424. }
  1425. /***************************************************************************\
  1426. *
  1427. * METHOD: ColSetIDToViewTableMapPersistor::Persist
  1428. *
  1429. * PURPOSE: called as a request for the object to persist it's data
  1430. *
  1431. * PARAMETERS:
  1432. * CPersistor &persistor [in] persistor to persist to/from
  1433. *
  1434. * RETURNS:
  1435. * void
  1436. *
  1437. * see "Data structures used to persist column information" comment
  1438. * int file colwidth.h for more information
  1439. \***************************************************************************/
  1440. void ColSetIDToViewTableMapPersistor::Persist(CPersistor &persistor)
  1441. {
  1442. if (persistor.IsStoring())
  1443. {
  1444. // iterate and save all elements as linear list
  1445. ColSetIDToViewTableMap::iterator it;
  1446. for (it = m_map.begin(); it != m_map.end(); ++it)
  1447. {
  1448. // we will sneak under child's element to persist the KEY value as an attribute
  1449. // of the child element. To do that we use tag got from _GetXMLType() of the child
  1450. CPersistor persistorChild(persistor, ViewToColSetDataMapPersistor::_GetXMLType());
  1451. CColumnSetID& rID = *const_cast<CColumnSetID *>(&it->first);
  1452. rID.Persist(persistorChild);
  1453. // note: we are asking the child to persist on the same level.
  1454. // thats to save on depth
  1455. ViewToColSetDataMapPersistor mapPersistor(it->second, m_list);
  1456. mapPersistor.Persist(persistorChild);
  1457. }
  1458. }
  1459. else
  1460. {
  1461. // use base class to read. it will call OnNewElement for each found
  1462. m_map.clear();
  1463. XMLListCollectionBase::Persist(persistor);
  1464. }
  1465. }
  1466. /***************************************************************************\
  1467. *
  1468. * METHOD: ColSetIDToViewTableMapPersistor::OnNewElement
  1469. *
  1470. * PURPOSE: called by the base class to create and persist the new element
  1471. *
  1472. * PARAMETERS:
  1473. * CPersistor& persistor - [in] persistor from which to persist new element
  1474. *
  1475. * RETURNS:
  1476. * void
  1477. *
  1478. * see "Data structures used to persist column information" comment
  1479. * int file colwidth.h for more information
  1480. \***************************************************************************/
  1481. void ColSetIDToViewTableMapPersistor::OnNewElement(CPersistor& persistor)
  1482. {
  1483. // we will sneak under child's element to persist the KEY value as an attribute
  1484. // of the child element. To do that we use tag got from _GetXMLType() of the child
  1485. CPersistor persistorChild(persistor, ViewToColSetDataMapPersistor::_GetXMLType());
  1486. // read the key value from the child element
  1487. // note that we are forcing CColumnSetID to share the same element,
  1488. // therefore we are not using persistor.Persist()
  1489. CColumnSetID ID;
  1490. ID.Persist(persistorChild);
  1491. // insert the new element into the map
  1492. ViewToColSetDataMap &rMap = m_map[ID];
  1493. // create the wrapper on inserted map value
  1494. // (pass a list to wrapper. we actually have it [list] for this only reason)
  1495. ViewToColSetDataMapPersistor mapPersistor(m_map[ID], m_list);
  1496. // ask wrapper to read the rest
  1497. mapPersistor.Persist(persistorChild);
  1498. }
  1499. /***************************************************************************\
  1500. *
  1501. * METHOD: SnapinToColSetIDMapPersistor::Persist
  1502. *
  1503. * PURPOSE:
  1504. *
  1505. * PARAMETERS:
  1506. * CPersistor &persistor
  1507. *
  1508. * RETURNS:
  1509. * void
  1510. *
  1511. * see "Data structures used to persist column information" comment
  1512. * int file colwidth.h for more information
  1513. \***************************************************************************/
  1514. void SnapinToColSetIDMapPersistor::Persist(CPersistor &persistor)
  1515. {
  1516. DECLARE_SC(sc, TEXT("SnapinToColSetIDMapPersistor::Persist"));
  1517. if (persistor.IsStoring())
  1518. {
  1519. // prior-to-save cleanup
  1520. sc = ScPurgeUnusedColumnData();
  1521. if (sc)
  1522. sc.Throw();
  1523. // iterate and save all elements as linear list
  1524. SnapinToColSetIDMap::iterator it;
  1525. for (it = m_map.begin(); it != m_map.end(); ++it)
  1526. {
  1527. // we will sneak under child's element to persist the KEY value as an attribute
  1528. // of the child element. To do that we use tag got from _GetXMLType() of the child
  1529. CPersistor persistorChild(persistor, ColSetIDToViewTableMapPersistor::_GetXMLType());
  1530. // write the key value.
  1531. // just to cast constness out (we do not have const Persist)
  1532. GUID& guid = *const_cast<GUID *>(&it->first);
  1533. persistorChild.PersistAttribute(XML_ATTR_COLUMN_INFO_SNAPIN, guid);
  1534. // create a wrapper on the value (which is also a map)
  1535. // (pass a list to wrapper. though it's not used for storing)
  1536. ColSetIDToViewTableMapPersistor mapPersistor(it->second, m_list);
  1537. // persist the wrapper
  1538. mapPersistor.Persist(persistorChild);
  1539. }
  1540. }
  1541. else
  1542. {
  1543. // use base class to read. it will call OnNewElement for each found
  1544. m_map.clear();
  1545. XMLListCollectionBase::Persist(persistor);
  1546. }
  1547. }
  1548. /***************************************************************************\
  1549. *
  1550. * METHOD: SnapinToColSetIDMapPersistor::OnNewElement
  1551. *
  1552. * PURPOSE: called by the base class to create and persist the new element
  1553. *
  1554. * PARAMETERS:
  1555. * CPersistor& persistor - [in] persistor from which to persist new element
  1556. *
  1557. * RETURNS:
  1558. * void
  1559. *
  1560. * see "Data structures used to persist column information" comment
  1561. * int file colwidth.h for more information
  1562. \***************************************************************************/
  1563. void SnapinToColSetIDMapPersistor::OnNewElement(CPersistor& persistor)
  1564. {
  1565. // we will sneak under child's element to persist the KEY value as an attribute
  1566. // of the child element. To do that we use tag got from _GetXMLType() of the child
  1567. CPersistor persistorChild(persistor, ColSetIDToViewTableMapPersistor::_GetXMLType());
  1568. GUID guid;
  1569. // read the key value
  1570. persistorChild.PersistAttribute(XML_ATTR_COLUMN_INFO_SNAPIN, guid);
  1571. // insert the new element into the map
  1572. ColSetIDToViewTableMap &rMap = m_map[guid];
  1573. // create the wrapper on inserted map value
  1574. // (pass a list to wrapper. we actually have it [list] for this only reason)
  1575. ColSetIDToViewTableMapPersistor mapPersistor(rMap, m_list);
  1576. // ask wrapper to read the rest
  1577. mapPersistor.Persist(persistorChild);
  1578. }
  1579. /***************************************************************************\
  1580. *
  1581. * METHOD: SnapinToColSetIDMapPersistor::ScPurgeUnusedColumnData
  1582. *
  1583. * PURPOSE: prior-to-save cleanup. removes unused snapin entries
  1584. *
  1585. * PARAMETERS:
  1586. *
  1587. * RETURNS:
  1588. * SC - result code
  1589. *
  1590. \***************************************************************************/
  1591. SC SnapinToColSetIDMapPersistor::ScPurgeUnusedColumnData()
  1592. {
  1593. DECLARE_SC(sc, TEXT("SnapinToColSetIDMapPersistor::ScPurgeUnusedColumnData"));
  1594. // get the scopetree pointer
  1595. CScopeTree *pScopeTree = CScopeTree::GetScopeTree();
  1596. // check it
  1597. sc = ScCheckPointers(pScopeTree, E_UNEXPECTED);
  1598. if (sc)
  1599. return sc;
  1600. // iterate and remove unused entries
  1601. SnapinToColSetIDMap::iterator it = m_map.begin();
  1602. while (it != m_map.end())
  1603. {
  1604. // ask the scope tree if snapin is in use
  1605. BOOL bInUse = FALSE;
  1606. sc = pScopeTree->IsSnapinInUse(it->first, &bInUse);
  1607. if (sc)
  1608. return sc;
  1609. // act depending on usage
  1610. if (bInUse)
  1611. {
  1612. ++it; // skip also the stuff currently in use
  1613. }
  1614. else
  1615. {
  1616. // to the trash can
  1617. ColSetIDToViewTableMap& colSets = it->second;
  1618. // Iterate thro' all colset ids of this snapin.
  1619. ColSetIDToViewTableMap::iterator itColumnSetIDMap = colSets.begin();
  1620. while(itColumnSetIDMap != colSets.end())
  1621. {
  1622. // Get the view map
  1623. ViewToColSetDataMap& viewIDMap = itColumnSetIDMap->second;
  1624. ViewToColSetDataMap::iterator itViewIDMap = viewIDMap.begin();
  1625. // Iterate thro' all views and remove entries
  1626. while (itViewIDMap != viewIDMap.end())
  1627. {
  1628. m_list.erase(/*(ItColSetDataList)*/itViewIDMap->second);
  1629. itViewIDMap = viewIDMap.erase(itViewIDMap);
  1630. }
  1631. itColumnSetIDMap = colSets.erase(itColumnSetIDMap);
  1632. }
  1633. it = m_map.erase(it);
  1634. }
  1635. }
  1636. return sc;
  1637. }