//+------------------------------------------------------------------------- // // Microsoft Windows // Copyright (C) Microsoft Corporation, 1992 - 1999 // // File: viewpers.cpp // // Contents: View Persistence data structures. // // History: 04-Apr-99 AnandhaG Created // //-------------------------------------------------------------------------- #include "stdafx.h" #include "viewpers.h" #include "macros.h" #include "comdbg.h" #define MAX_VIEWITEMS_PERSISTED 50 //------------------------------------------------------------------ // class CViewSettingsPersistor //------------------------------------------------------------------ CViewSettingsPersistor::CViewSettingsPersistor() : m_dwMaxItems(MAX_VIEWITEMS_PERSISTED), m_bDirty(false) { // Now read the registry to see if m_dwMaxItems is specified. // Check if the settings key exists. CRegKeyEx rSettingsKey; if (rSettingsKey.ScOpen (HKEY_LOCAL_MACHINE, SETTINGS_KEY, KEY_READ).IsError()) return; // Read the values for MaxColDataPersisted. if (rSettingsKey.IsValuePresent(g_szMaxViewItemsPersisted)) { DWORD dwType = REG_DWORD; DWORD dwSize = sizeof(DWORD); SC sc = rSettingsKey.ScQueryValue (g_szMaxViewItemsPersisted, &dwType, &m_dwMaxItems, &dwSize); if (sc) sc.TraceAndClear(); } } //+------------------------------------------------------------------- // // Member: ScGetViewSettings // // Synopsis: Given the CViewSettingsID return the CViewSettings object. // // Arguments: [viewSettingsID] - [in] // [viewSettings] - [out] // // Returns: SC, S_FALSE if none found. // //-------------------------------------------------------------------- SC CViewSettingsPersistor::ScGetViewSettings(const CViewSettingsID& viewSettingsID, CViewSettings& viewSettings) { DECLARE_SC(sc, TEXT("CViewSettingsPersistor::ScGetViewSettings")); // 1. Look in the map if there is persisted data for given id. CViewSettingsIDToViewSettingsMap::iterator itViewSettingsDataMap; itViewSettingsDataMap = m_mapViewSettingsIDToViewSettings.find(viewSettingsID); if (itViewSettingsDataMap == m_mapViewSettingsIDToViewSettings.end()) return (sc = S_FALSE); // Found the data. IteratorToViewSettingsList itViewSettings = itViewSettingsDataMap->second; // 2. Copy the data. viewSettings = *itViewSettings; // 3. Move this item to the front of the queue. m_listViewSettings.erase(itViewSettings); itViewSettings = m_listViewSettings.insert(m_listViewSettings.begin(), viewSettings); itViewSettingsDataMap->second = itViewSettings; return sc; } //+------------------------------------------------------------------- // // Member: ScSetViewSettings // // Synopsis: Modify the persisted view information // for given view and bookmark (node). // // Arguments: [nViewID] - Snapin Guid // [pBookmark] - Column Set Identifier. // [viewDataSet] - View ID. // // Returns: TRUE - Loaded successfully. // // History: 04-26-1999 AnandhaG Created // //-------------------------------------------------------------------- SC CViewSettingsPersistor::ScSetViewSettings(const CViewSettingsID& viewSettingsID, const CViewSettings& viewSettings, bool bSetViewDirty) { DECLARE_SC(sc, TEXT("CViewSettingsPersistor::ScSetViewSettings")); // 1. Garbage collect if the number of items in the list are 40% more than pre-set limit. if (m_listViewSettings.size() >= (m_dwMaxItems * (1 + VIEWSETTINGS_MAXLIMIT)) ) { sc = ScGarbageCollectItems(); if (sc) sc.TraceAndClear(); } // 2. Insert the item into the front of the queue. IteratorToViewSettingsList itViewSettings; itViewSettings = m_listViewSettings.insert(m_listViewSettings.begin(), viewSettings); // 3. See if there is data persisted for this id. CViewSettingsIDToViewSettingsMap::iterator itViewSettingsDataMap; itViewSettingsDataMap = m_mapViewSettingsIDToViewSettings.find(viewSettingsID); if (itViewSettingsDataMap == m_mapViewSettingsIDToViewSettings.end()) // not found so insert data. { m_mapViewSettingsIDToViewSettings.insert( CViewSettingsIDToViewSettingsMap::value_type(viewSettingsID, itViewSettings) ); } else { // found, so replace old settings. m_listViewSettings.erase(itViewSettingsDataMap->second); itViewSettingsDataMap->second = itViewSettings; } // dirty flag accumulates. m_bDirty = (m_bDirty || bSetViewDirty); return sc; } //+------------------------------------------------------------------- // // Member: CViewSettingsPersistor::ScGetTaskpadID // // Synopsis: Given the nodetype & viewid get the taskpad id (this // is for taskpads persisted per nodetype). // // Arguments: [nViewID] - [in] // [guidNodeType] - [in] // [guidTaskpad] - [out] // // Returns: SC, S_FALSE if none found. // //-------------------------------------------------------------------- SC CViewSettingsPersistor::ScGetTaskpadID (int nViewID, const GUID& guidNodeType ,GUID& guidTaskpad) { DECLARE_SC(sc, _T("CViewSettingsPersistor::ScGetTaskpadID")); // 1. Init out param. guidTaskpad = GUID_NULL; // 2. Construct a CViewSettingsID object with given nodetype & viewid. CViewSettingsID viewSettingsID(nViewID, guidNodeType); // 3. Get the viewsettings CViewSettings viewSettings; sc = ScGetViewSettings(viewSettingsID, viewSettings); // If none exists return if (sc != S_OK) return sc; // 4. CViewSettings exists, see if there is valid taskpad-id stored. sc = viewSettings.ScGetTaskpadID(guidTaskpad); if (sc) // taskpad-id is not valid. return (sc = S_FALSE); return (sc); } //+------------------------------------------------------------------- // // Member: CViewSettingsPersistor::ScSetTaskpadID // // Synopsis: Given the nodetype & viewid set the taskpad id (this // is for taskpads persisted per nodetype). // // NOTE: NUKE ANY NODE-SPECIFIC TASKPAD-ID THAT IS STORED. // // Arguments: [nViewID] - [in] // [guidNodeType] - [in] // [bookmark] - [in] // [guidTaskpad] - [in] // [bSetDirty] - [in] set the console file dirty // // Returns: SC // //-------------------------------------------------------------------- SC CViewSettingsPersistor::ScSetTaskpadID (int nViewID, const GUID& guidNodeType, const CBookmark& bookmark, const GUID& guidTaskpad, bool bSetDirty) { DECLARE_SC(sc, _T("CViewSettingsPersistor::ScSetTaskpadID")); // 1. First nuke the the old node specific taskpad-id settings (if any). // 1.a) Construct a CViewSettingsID object with given nodetype & viewid. CViewSettingsID viewSettingsIDNodeSpecific(nViewID, bookmark); // 1.b) Get the viewsettings. CViewSettings viewSettingsNodeSpecific; sc = ScGetViewSettings(viewSettingsIDNodeSpecific, viewSettingsNodeSpecific); if (sc) return sc; // data available if ( (sc == S_OK) && (viewSettingsNodeSpecific.IsTaskpadIDValid()) ) { // 1.c) Set taskpad id invalid. viewSettingsNodeSpecific.SetTaskpadIDValid(false); if (sc) return sc; // 1.d) Save the data. sc = ScSetViewSettings(viewSettingsIDNodeSpecific, viewSettingsNodeSpecific, bSetDirty); } // 2. Now save the taskpad id for nodetype specific. // 2.a) Construct a CViewSettingsID object with given nodetype & viewid. CViewSettingsID viewSettingsID(nViewID, guidNodeType); // 2.b) The CResultViewType & view-mode data are not stored when CViewSettings is stored // per nodetype. So just set the taskpad id. CViewSettings viewSettings; sc = viewSettings.ScSetTaskpadID(guidTaskpad); if (sc) return sc; // 2.c) Save the viewsettings into the map. sc = ScSetViewSettings(viewSettingsID, viewSettings, bSetDirty); if (sc) return sc; return (sc); } //+------------------------------------------------------------------- // // Member: CViewSettingsPersistor::ScGetTaskpadID // // Synopsis: Given the bookmark & viewid get the taskpad id (this // is for taskpads persisted per node). // // Arguments: [nViewID] - [in] // [bookmark] - [in] // [guidTaskpad] - [out] // // Returns: SC, S_FALSE if none found. // //-------------------------------------------------------------------- SC CViewSettingsPersistor::ScGetTaskpadID (int nViewID, const CBookmark& bookmark,GUID& guidTaskpad) { DECLARE_SC(sc, _T("CViewSettingsPersistor::ScGetTaskpadID")); // 1. Init out param. guidTaskpad = GUID_NULL; // 2. Construct a CViewSettingsID object with given bookmark & viewid. CViewSettingsID viewSettingsID(nViewID, bookmark); // 3. Get the viewsettings CViewSettings viewSettings; sc = ScGetViewSettings(viewSettingsID, viewSettings); // If none exists return if (sc != S_OK) return sc; // 4. CViewSettings exists, see if there is valid taskpad-id stored. sc = viewSettings.ScGetTaskpadID(guidTaskpad); if (sc) // taskpad-id is not valid. return (sc = S_FALSE); return (sc); } //+------------------------------------------------------------------- // // Member: CViewSettingsPersistor::ScSetTaskpadID // // Synopsis: Given the bookmark & viewid get the taskpad id (this // is for taskpads persisted per nodetype). // // Arguments: [nViewID] - [in] // [bookmark] - [in] // [guidTaskpad] - [in] // [bSetDirty] - [in] set the console file dirty // // Returns: SC // //-------------------------------------------------------------------- SC CViewSettingsPersistor::ScSetTaskpadID (int nViewID, const CBookmark& bookmark, const GUID& guidTaskpad, bool bSetDirty) { DECLARE_SC(sc, _T("CViewSettingsPersistor::ScSetTaskpadID")); // 1. Construct a CViewSettingsID object with given bookmark & viewid. CViewSettingsID viewSettingsID(nViewID, bookmark); // 2. First get the old settings (if any) and just modify taskpad-id. CViewSettings viewSettings; sc = ScGetViewSettings(viewSettingsID, viewSettings); if (sc) return sc; // 3. If persisted data does not exist dont worry (as CResultViewType and // view mode are invalid), just set taskpad-id. sc = viewSettings.ScSetTaskpadID(guidTaskpad); if (sc) return sc; // 4. Save the viewsettings into the map. sc = ScSetViewSettings(viewSettingsID, viewSettings, bSetDirty); if (sc) return sc; return (sc); } //+------------------------------------------------------------------- // // Member: CViewSettingsPersistor::ScGetViewMode // // Synopsis: Given the viewid & bookmark (can identify a node), return // the view mode if any persisted. // // Arguments: [nViewID] - [in] // [bookmark] - [in] // [ulViewMode] - [out] // // Returns: SC, S_FALSE if none. // //-------------------------------------------------------------------- SC CViewSettingsPersistor::ScGetViewMode (int nViewID, const CBookmark& bookmark, ULONG& ulViewMode) { DECLARE_SC(sc, _T("CViewSettingsPersistor::ScGetViewMode")); // 1. Construct the viewsettings-id. CViewSettingsID viewSettingsID(nViewID, bookmark); // 2. see if ViewSettings exist. CViewSettings viewSettings; sc = ScGetViewSettings(viewSettingsID, viewSettings); if (sc != S_OK) return sc; sc = viewSettings.ScGetViewMode(ulViewMode); if (sc) return (sc = S_FALSE); return (sc); } //+------------------------------------------------------------------- // // Member: CViewSettingsPersistor::ScSetViewMode // // Synopsis: Given view-id & bookmark, set the viewmode in a node // specific viewsettings. // // Arguments: [nViewID] - [in] // [bookmark] - [in] // [ulViewMode] - [in] // // Returns: SC // //-------------------------------------------------------------------- SC CViewSettingsPersistor::ScSetViewMode (int nViewID, const CBookmark& bookmark, ULONG ulViewMode) { DECLARE_SC(sc, _T("CViewSettingsPersistor::ScSetViewMode")); // 1. Construct the viewsettings-id. CViewSettingsID viewSettingsID(nViewID, bookmark); // 2. First get the old settings (if any) and just modify viewmode. CViewSettings viewSettings; sc = ScGetViewSettings(viewSettingsID, viewSettings); if (sc) return sc; // 3. If persisted data does not exist dont worry (as CResultViewType and // taskpad-id are invalid), just set viewmode. sc = viewSettings.ScSetViewMode(ulViewMode); if (sc) return sc; // 4. Save the viewsettings into the map. sc = ScSetViewSettings(viewSettingsID, viewSettings, /*bSetDirty*/ true); if (sc) return sc; return (sc); } //+------------------------------------------------------------------- // // Member: CViewSettingsPersistor::ScGetResultViewType // // Synopsis: Given the viewid & bookmark (can identify a node), return // the CResultViewType if persisted. // // Arguments: [nViewID] - [in] // [bookmark] - [in] // [rvt] - [out] // // Returns: SC, S_FALSE if none. // //-------------------------------------------------------------------- SC CViewSettingsPersistor::ScGetResultViewType (int nViewID, const CBookmark& bookmark, CResultViewType& rvt) { DECLARE_SC(sc, _T("CViewSettingsPersistor::ScGetResultViewType")); // 1. Construct the viewsettings-id. CViewSettingsID viewSettingsID(nViewID, bookmark); // 2. see if ViewSettings exist. CViewSettings viewSettings; sc = ScGetViewSettings(viewSettingsID, viewSettings); if (sc != S_OK) return sc; sc = viewSettings.ScGetResultViewType(rvt); if (sc) return (sc = S_FALSE); return (sc); } //+------------------------------------------------------------------- // // Member: CViewSettingsPersistor::ScSetResultViewType // // Synopsis: Given view-id & bookmark, set the resultviewtype in a node // specific viewsettings. // // Arguments: [nViewID] - [in] // [bookmark] - [in] // [nViewMode] - [in] // // Returns: SC // //-------------------------------------------------------------------- SC CViewSettingsPersistor::ScSetResultViewType (int nViewID, const CBookmark& bookmark, const CResultViewType& rvt) { DECLARE_SC(sc, _T("CViewSettingsPersistor::ScSetResultViewType")); // 1. Construct the viewsettings-id. CViewSettingsID viewSettingsID(nViewID, bookmark); // 2. First get the old settings (if any) and just modify resultviewtype. CViewSettings viewSettings; sc = ScGetViewSettings(viewSettingsID, viewSettings); if (sc) return sc; // 3. If persisted data does not exist dont worry (as view-mode and // taskpad-id are invalid), just set resultviewtype. sc = viewSettings.ScSetResultViewType(rvt); if (sc) return sc; // 4. Save the viewsettings into the map. sc = ScSetViewSettings(viewSettingsID, viewSettings, /*bSetDirty*/ true); if (sc) return sc; return (sc); } //+------------------------------------------------------------------- // // Member: CViewSettingsPersistor::ScSetFavoriteViewSettings // // Synopsis: A favorite is selected and it sets viewsettings // before re-selecting the node so that after re-selection // the new settings are set for the view. So dont set the // console file dirty. // // Arguments: [nViewID] - // [bookmark] - // [viewSettings] - // // Returns: SC // //-------------------------------------------------------------------- SC CViewSettingsPersistor::ScSetFavoriteViewSettings (int nViewID, const CBookmark& bookmark, const CViewSettings& viewSettings) { DECLARE_SC(sc, _T("CViewSettingsPersistor::ScSetFavoriteViewSettings")); // 1. Construct the viewsettings-id. CViewSettingsID viewSettingsID(nViewID, bookmark); // 2. Save the viewsettings into the map. sc = ScSetViewSettings(viewSettingsID, viewSettings, /*bSetDirty*/ false); if (sc) return sc; return (sc); } //+------------------------------------------------------------------- // // Member: ScDeleteDataOfView // // Synopsis: Delete the data of given view. // // Arguments: [nViewID] - View ID. // // Returns: SC // //-------------------------------------------------------------------- SC CViewSettingsPersistor::ScDeleteDataOfView( int nViewID) { DECLARE_SC(sc, TEXT("CViewSettingsPersistor::ScDeleteDataOfView")); // Find the data for the view. CViewSettingsIDToViewSettingsMap::iterator itViewSettingsDataMap; for (itViewSettingsDataMap = m_mapViewSettingsIDToViewSettings.begin(); itViewSettingsDataMap != m_mapViewSettingsIDToViewSettings.end(); ++itViewSettingsDataMap) { const CViewSettingsID& viewSettingsID = itViewSettingsDataMap->first; if (viewSettingsID.get_ViewID() == nViewID) { // Delete the item; IteratorToViewSettingsList itViewSettings = itViewSettingsDataMap->second; itViewSettings->SetObjInvalid(TRUE); } } // Delete the invalid items. sc = ScDeleteMarkedItems(); if (sc) return sc; return sc; } //+------------------------------------------------------------------- // // Member: ScGarbageCollectItems // // Synopsis: Free least used data. // // Arguments: None. // // History: 04-26-1999 AnandhaG Created // //-------------------------------------------------------------------- SC CViewSettingsPersistor::ScGarbageCollectItems() { DECLARE_SC(sc, TEXT("CViewSettingsPersistor::ScGarbageCollectItems")); INT nItemsToBeRemoved = VIEWSETTINGS_MAXLIMIT * m_dwMaxItems; // Go thro' the list and set the nItemsToBeRemoved that was least recently // accessed to be invalid. INT nIndex = 0; IteratorToViewSettingsList itViewSettings; // Skip first m_dwMaxItems. for (itViewSettings = m_listViewSettings.begin(); ( (itViewSettings != m_listViewSettings.end()) && (nIndex <= m_dwMaxItems) ); ++itViewSettings, nIndex++) { nIndex++; } // Mark rest of the items to be garbage. while (itViewSettings != m_listViewSettings.end()) { itViewSettings->SetObjInvalid(TRUE); ++itViewSettings; } // Delete the invalid items. sc = ScDeleteMarkedItems(); if (sc) return sc; return sc; } //+------------------------------------------------------------------- // // Member: ScDeleteMarkedItems // // Synopsis: Delete invalidated items. This involves iterating thro // the maps to find the invalid items. Then deleting the // items. If the map becomes empty then delete the map. // // History: 04-26-1999 AnandhaG Created // //-------------------------------------------------------------------- SC CViewSettingsPersistor::ScDeleteMarkedItems() { DECLARE_SC(sc, TEXT("CViewSettingsPersistor::ScDeleteMarkedItems")); CViewSettingsIDToViewSettingsMap::iterator itViewSettingsDataMap = m_mapViewSettingsIDToViewSettings.begin(); // Iterate through the map to see if there are // invalidated items. while (m_mapViewSettingsIDToViewSettings.end() != itViewSettingsDataMap) { IteratorToViewSettingsList itViewSettings = itViewSettingsDataMap->second; if (itViewSettings->IsObjInvalid()) { // Delete the item ref from the map. // Erase returns iterator to next item. itViewSettingsDataMap = m_mapViewSettingsIDToViewSettings.erase(itViewSettingsDataMap); // Delete the item from the list. m_listViewSettings.erase(itViewSettings); } else ++itViewSettingsDataMap; // Item is valid so get next item. } return sc; } //+------------------------------------------------------------------- // // Member: Load // // Synopsis: Load the persisted view information. // // Arguments: [pStream]- IStream from which view data will be loaded. // // Returns: S_OK - Loaded successfully. // // History: 04-26-1999 AnandhaG Created // //-------------------------------------------------------------------- HRESULT CViewSettingsPersistor::Load (IStream* pStream) { HRESULT hr = E_FAIL; // read the column width information. try { do { // Read the version. If it did not match return INT nVersion = 0; *pStream >> nVersion; if (ViewSettingPersistenceVersion != nVersion) return S_FALSE; // Read the # of Snapins DWORD dwNumItems = 0; *pStream >> dwNumItems; m_listViewSettings.clear(); m_mapViewSettingsIDToViewSettings.clear(); for (int i = 0; i < dwNumItems; i++) { // Read the ID. CViewSettingsID viewSettingsID; *pStream >> viewSettingsID; // Read the data. CViewSettings viewSettings; viewSettings.Read(*pStream); // Insert the data into the list. IteratorToViewSettingsList itViewSettings; itViewSettings = m_listViewSettings.insert(m_listViewSettings.begin(), viewSettings); // Insert the data into the map. m_mapViewSettingsIDToViewSettings.insert( CViewSettingsIDToViewSettingsMap::value_type(viewSettingsID, itViewSettings) ); } m_listViewSettings.sort(); } while (FALSE); } catch (_com_error& err) { hr = err.Error(); } catch (...) { ASSERT (0 && "Unexpected exception"); throw; } return S_OK; } //+------------------------------------------------------------------- // // Member: Save // // Synopsis: Persist the view information. // // Arguments: [pStream]- IStream in which data is persisted. // // Returns: S_OK - Saved successfully. // // History: 04-26-1999 AnandhaG Created // //-------------------------------------------------------------------- HRESULT CViewSettingsPersistor::Save (IStream* pStream, BOOL bClearDirty) { // absolete method. // this method is left here since we use IPersistStream to export // persistence to CONUI side and need to implement it. // But this interface will never be called to save data // [we will use CPersistor-based XML saving instead] // so the method will always fail. ASSERT(FALSE && "Should never come here"); return E_NOTIMPL; } //+------------------------------------------------------------------- // // Member: Persist // // Synopsis: Persist the view information. // // Arguments: [CPersistor]- Persistor in/from which data is persisted. // // Returns: void // // History: 11-08-1999 AudriusZ Created // //-------------------------------------------------------------------- void CViewSettingsPersistor::Persist(CPersistor &persistor) { DECLARE_SC(sc, TEXT("CViewSettingsPersistor::Persist")); if (persistor.IsStoring()) { // Give ranking to each CViewSettings instance. IteratorToViewSettingsList itViewSettings; DWORD dwRank = 0; for (itViewSettings = m_listViewSettings.begin(); itViewSettings != m_listViewSettings.end(); ++itViewSettings) { dwRank++; itViewSettings->SetUsageRank(dwRank); } CViewSettingsIDToViewSettingsMap::iterator itViewSettingsDataMap; for (itViewSettingsDataMap = m_mapViewSettingsIDToViewSettings.begin(); itViewSettingsDataMap != m_mapViewSettingsIDToViewSettings.end(); ++itViewSettingsDataMap) { // Write the ID. persistor.Persist(*const_cast(&itViewSettingsDataMap->first)); // Write the data. persistor.Persist(*itViewSettingsDataMap->second); } } else { // let the base class do the job // it will call OnNewElement for every element found XMLMapCollectionBase::Persist(persistor); // some extra loading actions m_listViewSettings.sort(); } // either way we are the same as the file copy m_bDirty = false; } //+------------------------------------------------------------------- // // Member: OnNewElement // // Synopsis: Called for each new data pair read. // // Arguments: [persistKey]- Persistor from which key is to be loaded // [persistVal]- Persistor from which value is to be loaded // // Returns: void // // History: 11-08-1999 AudriusZ Created // //-------------------------------------------------------------------- void CViewSettingsPersistor::OnNewElement(CPersistor& persistKey,CPersistor& persistVal) { DECLARE_SC(sc, TEXT("CViewSettingsPersistor::OnNewElement")); // Read the ID. CViewSettingsID viewSettingsID; persistKey.Persist(viewSettingsID); // Read the data. CViewSettings viewSettings; persistVal.Persist(viewSettings); // Insert the data into the list. IteratorToViewSettingsList itViewSettings; itViewSettings = m_listViewSettings.insert(m_listViewSettings.begin(), viewSettings); // Insert the data into the map. m_mapViewSettingsIDToViewSettings.insert( CViewSettingsIDToViewSettingsMap::value_type(viewSettingsID, itViewSettings) ); }