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.

439 lines
10 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 1999 - 1999
  6. //
  7. // File: enumcondition.cpp
  8. //
  9. //--------------------------------------------------------------------------
  10. // EnumCondition.cpp: implementation of the CEnumCondition class.
  11. //
  12. //////////////////////////////////////////////////////////////////////
  13. #include "precompiled.h"
  14. #include "EnumCondition.h"
  15. #include "EnumCondEdit.h"
  16. #include "iasdebug.h"
  17. //////////////////////////////////////////////////////////////////////
  18. // Construction/Destruction
  19. //////////////////////////////////////////////////////////////////////
  20. CEnumCondition::CEnumCondition(IIASAttributeInfo*pCondAttr)
  21. :CCondition(pCondAttr)
  22. {
  23. TRACE_FUNCTION("CEnumCondition::CEnumCondition");
  24. // no parsing needed
  25. m_fParsed = TRUE;
  26. // m_pValueIdList = pCondAttr->GetValueIdList();
  27. // m_pValueList = pCondAttr->GetValueList();
  28. }
  29. CEnumCondition::CEnumCondition(IIASAttributeInfo *pCondAttr, ATL::CString& strConditionText)
  30. :CCondition(pCondAttr, strConditionText)
  31. {
  32. TRACE_FUNCTION("CEnumCondition::CEnumCondition");
  33. // parsing needed
  34. m_fParsed = FALSE;
  35. // m_pValueIdList = pCondAttr->GetValueIdList();
  36. // m_pValueList = pCondAttr->GetValueList();
  37. }
  38. CEnumCondition::~CEnumCondition()
  39. {
  40. TRACE_FUNCTION("CEnumCondition::~CEnumCondition");
  41. // for (int iIndex=0; iIndex<m_arrSelectedList.GetSize(); iIndex++)
  42. // {
  43. // LPTSTR pszValue = m_arrSelectedList[iIndex];
  44. // if ( pszValue )
  45. // {
  46. // delete[] pszValue;
  47. // }
  48. // }
  49. // m_arrSelectedList.RemoveAll();
  50. }
  51. //+---------------------------------------------------------------------------
  52. //
  53. // Function: Edit
  54. //
  55. // Class: CEnumCondition
  56. //
  57. // Synopsis: edit the enumerated-typed condition
  58. //
  59. // Arguments: None
  60. //
  61. // Returns: HRESULT -
  62. //
  63. // History: Created Header byao 2/20/98 12:42:59 AM
  64. //
  65. //+---------------------------------------------------------------------------
  66. HRESULT CEnumCondition::Edit()
  67. {
  68. TRACE_FUNCTION("CEnumCondition::Edit");
  69. HRESULT hr = S_OK;
  70. if ( !m_fParsed )
  71. {
  72. DebugTrace(DEBUG_NAPMMC_ENUMCONDITION, "Parsing %ws", (LPCTSTR)m_strConditionText);
  73. hr = ParseConditionText();
  74. if ( FAILED(hr) )
  75. {
  76. ErrorTrace(ERROR_NAPMMC_ENUMCONDITION, "Invalid condition text, err = %x", hr);
  77. ShowErrorDialog(NULL,
  78. IDS_ERROR_PARSE_CONDITION,
  79. (LPTSTR)(LPCTSTR)m_strConditionText,
  80. hr
  81. );
  82. return hr;
  83. }
  84. }
  85. CEnumConditionEditor *pEditor = new CEnumConditionEditor();
  86. if (!pEditor)
  87. {
  88. hr = HRESULT_FROM_WIN32(GetLastError());
  89. ErrorTrace(ERROR_NAPMMC_ENUMCONDITION, "Can't create CEnumConditionEditor, err = %x", hr);
  90. ShowErrorDialog(NULL
  91. , IDS_ERROR_CANT_EDIT_CONDITION
  92. , NULL
  93. , hr
  94. );
  95. return hr;
  96. }
  97. //
  98. // set the editor parameter
  99. //
  100. CComBSTR bstrName;
  101. hr = m_spAttributeInfo->get_AttributeName( &bstrName );
  102. pEditor->m_strAttrName = bstrName;
  103. pEditor->m_spAttributeInfo = m_spAttributeInfo;
  104. pEditor->m_pSelectedList = &m_arrSelectedList; // preselected values
  105. if ( pEditor->DoModal() == IDOK)
  106. {
  107. // user clicked "OK"
  108. // get the list of valid value Ids for this attribute
  109. // _ASSERTE( m_pValueIdList->GetSize() == m_pValueList->GetSize() );
  110. //
  111. // generate the condition text
  112. //
  113. m_strConditionText = (ATL::CString) bstrName + L"=";
  114. CComQIPtr< IIASEnumerableAttributeInfo, &IID_IIASEnumerableAttributeInfo > spEnumerableAttributeInfo( m_spAttributeInfo );
  115. _ASSERTE( spEnumerableAttributeInfo );
  116. for (LONG iIndex=0; iIndex < m_arrSelectedList.size(); iIndex++ )
  117. {
  118. if ( iIndex > 0 ) m_strConditionText += L"|";
  119. // get the Value Id (we use ID instead of value name in the condition text)
  120. LONG lSize;
  121. hr = spEnumerableAttributeInfo->get_CountEnumerateID( &lSize );
  122. _ASSERTE( SUCCEEDED( hr ) );
  123. for (LONG jIndex=0; jIndex < lSize; jIndex++)
  124. {
  125. CComBSTR bstrDescription;
  126. hr = spEnumerableAttributeInfo->get_EnumerateDescription( jIndex, &bstrDescription );
  127. _ASSERTE( SUCCEEDED( hr ) );
  128. if ( wcscmp( bstrDescription, m_arrSelectedList[iIndex]) == 0 )
  129. {
  130. WCHAR wz[32];
  131. LONG lID;
  132. hr = spEnumerableAttributeInfo->get_EnumerateID( jIndex, &lID );
  133. _ASSERTE( SUCCEEDED( hr ) );
  134. // add enclosing chars ^ and $
  135. wsprintf(wz, _T("^%ld$"), lID);
  136. m_strConditionText += wz;
  137. break;
  138. }
  139. }
  140. }
  141. }
  142. // clean up
  143. if ( pEditor )
  144. {
  145. delete pEditor;
  146. }
  147. return hr;
  148. }
  149. //+---------------------------------------------------------------------------
  150. //
  151. // Function: CEnumCondition::GetDisplayText
  152. //
  153. // Synopsis: Get the displayable text format for this condition,
  154. // which should be like this:
  155. //
  156. // ServerType matches "type1|type2|type3"
  157. //
  158. // compared to the condition text:
  159. //
  160. // ServerType = type1|,type2|,type3
  161. //
  162. // Arguments: None
  163. //
  164. // Returns: ATL::CString& - the displayable text
  165. //
  166. // History: Created Header byao 2/22/98 11:41:28 PM
  167. //
  168. //+---------------------------------------------------------------------------
  169. ATL::CString CEnumCondition::GetDisplayText()
  170. {
  171. TRACE_FUNCTION("CEnumCondition::GetDisplayText");
  172. HRESULT hr = S_OK;
  173. if ( !m_fParsed)
  174. {
  175. DebugTrace(DEBUG_NAPMMC_ENUMCONDITION, "Parsing %ws", (LPCTSTR)m_strConditionText);
  176. hr = ParseConditionText();
  177. if ( FAILED(hr) )
  178. {
  179. ErrorTrace(ERROR_NAPMMC_ENUMCONDITION, "Invalid condition text, err = %x", hr);
  180. ShowErrorDialog(NULL,
  181. IDS_ERROR_PARSE_CONDITION,
  182. (LPTSTR)(LPCTSTR)m_strConditionText,
  183. hr
  184. );
  185. return ATL::CString(L"");
  186. }
  187. }
  188. ATL::CString strDispText;
  189. CComBSTR bstrName;
  190. hr = m_spAttributeInfo->get_AttributeName( &bstrName );
  191. _ASSERTE( SUCCEEDED( hr ) );
  192. strDispText = bstrName;
  193. { ATL::CString matches;
  194. matches.LoadString(IDS_TEXT_MATCHES);
  195. strDispText += matches;
  196. }
  197. strDispText += _T("\"");
  198. for (int iIndex=0; iIndex < m_arrSelectedList.size(); iIndex++ )
  199. {
  200. // add the separator between multiple values
  201. if (iIndex > 0) strDispText += _T(" OR ");
  202. strDispText += m_arrSelectedList[iIndex];
  203. }
  204. // the last " mark
  205. strDispText += _T("\"");
  206. return strDispText;
  207. }
  208. //+---------------------------------------------------------------------------
  209. //
  210. // Function: CEnumCondition::ParseConditionText
  211. //
  212. // Synopsis: Parse the condition text, to get the regular expression.
  213. //
  214. // Arguments: None
  215. //
  216. // Returns: HRESULT -
  217. //
  218. // History: Created Header byao 2/22/98 11:58:38 PM
  219. //
  220. //+---------------------------------------------------------------------------
  221. HRESULT CEnumCondition::ParseConditionText()
  222. {
  223. TRACE_FUNCTION("CEnumCondition::ParseConditionText");
  224. _ASSERTE( !m_fParsed );
  225. HRESULT hr = E_FAIL;
  226. if (m_fParsed)
  227. {
  228. // do nothing
  229. return S_OK;
  230. }
  231. if ( m_strConditionText.GetLength() == 0 )
  232. {
  233. // no parsing needed
  234. m_fParsed = TRUE;
  235. DebugTrace(DEBUG_NAPMMC_ENUMCONDITION, "Null condition text");
  236. return S_OK;
  237. }
  238. try
  239. {
  240. //
  241. // using (LPCTSTR) cast will force a deep copy
  242. //
  243. ATL::CString strTempStr = (LPCTSTR)m_strConditionText;
  244. //
  245. // parse strConditionText, return the regular expression only
  246. //
  247. // first, make a local copy of the condition text
  248. WCHAR *pwzCondText = (WCHAR*)(LPCTSTR)strTempStr;
  249. // look for the '=' in the condition text
  250. WCHAR *pwzStartPoint = NULL;
  251. WCHAR *pwzSeparator = NULL;
  252. ATL::CString *pStr;
  253. WCHAR *pwzEqualSign = wcschr(pwzCondText, _T('='));
  254. DWORD dwValueId;
  255. int iIndex;
  256. // no '=' found -- something weird has happened
  257. if ( NULL == pwzEqualSign )
  258. {
  259. hr = E_OUTOFMEMORY;
  260. throw;
  261. }
  262. // the right side of the equal sign is the list of all preselected values
  263. pwzStartPoint = pwzEqualSign +1;
  264. CComQIPtr< IIASEnumerableAttributeInfo, &IID_IIASEnumerableAttributeInfo > spEnumerableAttributeInfo( m_spAttributeInfo );
  265. _ASSERTE( spEnumerableAttributeInfo );
  266. while ( pwzStartPoint
  267. && *pwzStartPoint
  268. && (pwzSeparator = wcsstr(pwzStartPoint, _T("|") )) != NULL
  269. )
  270. {
  271. // we found the separator, stored at pwzSeparator
  272. // copy it over to the first value
  273. *pwzSeparator = _T('\0');
  274. pStr = new ATL::CString;
  275. if ( NULL == pStr )
  276. {
  277. hr = E_UNEXPECTED;
  278. throw;
  279. }
  280. // string could be enclosed by ^ and $ for matching purpose
  281. // ^
  282. if(*pwzStartPoint == L'^')
  283. {
  284. pwzStartPoint++;
  285. }
  286. // $
  287. if (pwzSeparator > pwzStartPoint && *(pwzSeparator - 1) == L'$')
  288. *( pwzSeparator - 1 ) = _T('\0');
  289. *pStr = pwzStartPoint; // copy the string, which is the value ID in string format
  290. // now we get the valud name for this
  291. dwValueId = _wtol((*pStr));
  292. // valid value id, then search for the index of this value ID
  293. LONG lSize;
  294. hr = spEnumerableAttributeInfo->get_CountEnumerateID( &lSize );
  295. _ASSERTE( SUCCEEDED( hr ) );
  296. for (iIndex=0; iIndex < lSize; iIndex++ )
  297. {
  298. LONG lID;
  299. hr = spEnumerableAttributeInfo->get_EnumerateID( iIndex, &lID );
  300. _ASSERTE( SUCCEEDED( hr ) );
  301. if ( lID == dwValueId )
  302. {
  303. CComBSTR bstrDescription;
  304. hr = spEnumerableAttributeInfo->get_EnumerateDescription( iIndex, &bstrDescription );
  305. _ASSERTE( SUCCEEDED( hr ) );
  306. m_arrSelectedList.push_back(bstrDescription );
  307. break;
  308. }
  309. }
  310. pwzStartPoint = pwzSeparator+1;
  311. }
  312. // copy the last one
  313. // todo: this is redundant code. remove later.
  314. // now we get the valud name for this
  315. // string could be enclosed by ^ and $ for matching purpose
  316. // ^
  317. if(*pwzStartPoint == L'^')
  318. {
  319. pwzStartPoint++;
  320. }
  321. // $
  322. pwzSeparator = pwzStartPoint + wcslen(pwzStartPoint);
  323. if (pwzSeparator > pwzStartPoint && *(pwzSeparator - 1) == L'$')
  324. *( pwzSeparator - 1 ) = _T('\0');
  325. dwValueId = _wtol(pwzStartPoint);
  326. LONG lSize;
  327. hr = spEnumerableAttributeInfo->get_CountEnumerateID( &lSize );
  328. _ASSERTE( SUCCEEDED( hr ) );
  329. for (iIndex=0; iIndex < lSize; iIndex++ )
  330. {
  331. LONG lID;
  332. hr = spEnumerableAttributeInfo->get_EnumerateID( iIndex, &lID );
  333. _ASSERTE( SUCCEEDED( hr ) );
  334. if ( lID == dwValueId )
  335. {
  336. CComBSTR bstrDescription;
  337. hr = spEnumerableAttributeInfo->get_EnumerateDescription( iIndex, &bstrDescription );
  338. _ASSERTE( SUCCEEDED( hr ) );
  339. m_arrSelectedList.push_back(bstrDescription );
  340. break;
  341. }
  342. }
  343. m_fParsed = TRUE;
  344. hr = S_OK;
  345. }
  346. catch(...)
  347. {
  348. // Do GetLastError for HRESULT?
  349. }
  350. return hr;
  351. }