Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

731 lines
21 KiB

  1. /** Copyright (c) 2000 Microsoft Corporation
  2. ******************************************************************************
  3. ** Module Name:
  4. **
  5. ** NewsHeadlines.cpp
  6. **
  7. ** Astract:
  8. **
  9. ** Implementation of CNewsHeadlines
  10. **
  11. ** Author:
  12. **
  13. ** Martha Arellano (t-alopez) 03-Oct-2000
  14. **
  15. **
  16. ** Revision History:
  17. **
  18. ** Martha Arellano (t-alopez) 05-Oct-2000 Added timestamp, frequency and link
  19. ** to xml file format
  20. **
  21. ** Added get_Provider_Frequency() to interface
  22. **
  23. ** 06-Oct-2000 Added Delete_Provider(nBlockIndex) to interface
  24. **
  25. ** Added get_Provider_URL(nBlockIndex) to interface
  26. **
  27. ** 11-Oct-2000 Added date in newsver and timestamp in provider
  28. **
  29. ** 15-Nov-2000 Added Provider Icon, Position and Headline Expires attr
  30. **
  31. ** 07-Dec-2000 Added Get_UpdateHeadlines to get_Stream()
  32. **
  33. ******************************************************************************
  34. **/
  35. #include "stdafx.h"
  36. /////////////////////////////////////////////////////////////////////////////
  37. // CONFIG MAP
  38. /////////////////////////////////////////////////////////////////////////////
  39. /*
  40. <NEWSHEADLINES TIMESTAMP="10/3/2000" DATE="10/4/2000">
  41. <NEWSBLOCK PROVIDER="Windows Family" LINK="http://www.microsoft.com/family" ICON="logo.gif"
  42. POSITION="horizontal" FREQUENCY=5 TIMESTAMP="10/4/2000" >
  43. <HEADLINE ICON="" TITLE="Visit the Windows Family home page for current headlines"
  44. LINK="http://www.microsoft.com/windows" DESCRIPTION="Some description (if necessary)" />
  45. </NEWSBLOCK>
  46. </NEWSHEADLINES>
  47. */
  48. CFG_BEGIN_FIELDS_MAP(News::Headlines::Headline)
  49. CFG_ATTRIBUTE( L"ICON" , wstring, m_strIcon ),
  50. CFG_ATTRIBUTE( L"TITLE" , wstring, m_strTitle ),
  51. CFG_ATTRIBUTE( L"LINK" , wstring, m_strLink ),
  52. CFG_ATTRIBUTE( L"DESCRIPTION" , wstring, m_strDescription ),
  53. CFG_ATTRIBUTE( L"EXPIRES" , DATE_CIM, m_dtExpires ),
  54. CFG_ATTRIBUTE( L"UPDATEHEADLINES" , bool , m_fUpdateHeadlines ),
  55. CFG_END_FIELDS_MAP()
  56. CFG_BEGIN_CHILD_MAP(News::Headlines::Headline)
  57. CFG_END_CHILD_MAP()
  58. DEFINE_CFG_OBJECT(News::Headlines::Headline, L"HEADLINE")
  59. DEFINE_CONFIG_METHODS__NOCHILD(News::Headlines::Headline)
  60. ////////////////////
  61. CFG_BEGIN_FIELDS_MAP(News::Headlines::Newsblock)
  62. CFG_ATTRIBUTE( L"PROVIDER" , wstring , m_strProvider ),
  63. CFG_ATTRIBUTE( L"LINK" , wstring , m_strLink ),
  64. CFG_ATTRIBUTE( L"ICON" , wstring , m_strIcon ),
  65. CFG_ATTRIBUTE( L"POSITION" , wstring , m_strPosition ),
  66. CFG_ATTRIBUTE( L"TIMESTAMP", DATE_CIM, m_dtTimestamp ),
  67. CFG_ATTRIBUTE( L"FREQUENCY", int , m_nFrequency ),
  68. CFG_END_FIELDS_MAP()
  69. CFG_BEGIN_CHILD_MAP(News::Headlines::Newsblock)
  70. CFG_CHILD(News::Headlines::Headline)
  71. CFG_END_CHILD_MAP()
  72. DEFINE_CFG_OBJECT(News::Headlines::Newsblock,L"NEWSBLOCK")
  73. DEFINE_CONFIG_METHODS_CREATEINSTANCE_SECTION(News::Headlines::Newsblock,tag,defSubType)
  74. if(tag == _cfg_table_tags[0])
  75. {
  76. defSubType = &(*(m_vecHeadlines.insert( m_vecHeadlines.end() )));
  77. return S_OK;
  78. }
  79. DEFINE_CONFIG_METHODS_SAVENODE_SECTION(News::Headlines::Newsblock,xdn)
  80. hr = MPC::Config::SaveList( m_vecHeadlines, xdn );
  81. DEFINE_CONFIG_METHODS_END(News::Headlines::Newsblock)
  82. ////////////////////
  83. CFG_BEGIN_FIELDS_MAP(News::Headlines)
  84. CFG_ATTRIBUTE( L"TIMESTAMP" , DATE_CIM, m_dtTimestamp ),
  85. CFG_ATTRIBUTE( L"DATE" , DATE_CIM, m_dtDate ),
  86. CFG_END_FIELDS_MAP()
  87. CFG_BEGIN_CHILD_MAP(News::Headlines)
  88. CFG_CHILD(News::Headlines::Newsblock)
  89. CFG_END_CHILD_MAP()
  90. DEFINE_CFG_OBJECT(News::Headlines,L"NEWSHEADLINES")
  91. DEFINE_CONFIG_METHODS_CREATEINSTANCE_SECTION(News::Headlines,tag,defSubType)
  92. if(tag == _cfg_table_tags[0])
  93. {
  94. defSubType = &(*(m_vecNewsblocks.insert( m_vecNewsblocks.end() )));
  95. return S_OK;
  96. }
  97. DEFINE_CONFIG_METHODS_SAVENODE_SECTION(News::Headlines,xdn)
  98. hr = MPC::Config::SaveList( m_vecNewsblocks, xdn );
  99. DEFINE_CONFIG_METHODS_END(News::Headlines)
  100. /////////////////////////////////////////////////////////////////////////////
  101. /////////////////////////////////////////////////////////////////////////////
  102. /////////////////////////////////////////////////////////////////////////////
  103. //
  104. // Convert a date from CIM format to number of milliseconds since January 1, 1970.
  105. //
  106. static HRESULT local_ConvertDate( /*[in]*/ MPC::XmlUtil& xml ,
  107. /*[in]*/ LPCWSTR szTag ,
  108. /*[in]*/ LPCWSTR szAttrib ,
  109. /*[in]*/ IXMLDOMNode* pxdnNode )
  110. {
  111. __HCP_FUNC_ENTRY( "local_ConvertDate" );
  112. HRESULT hr;
  113. bool fFound;
  114. MPC::wstring strValue;
  115. DATE dDate;
  116. DATE dDateBase;
  117. CComVariant v;
  118. __MPC_EXIT_IF_METHOD_FAILS(hr, xml.GetAttribute( szTag, szAttrib, strValue, fFound, pxdnNode ));
  119. if(fFound)
  120. {
  121. __MPC_EXIT_IF_METHOD_FAILS(hr, MPC::ConvertStringToDate( strValue, dDate, /*fGMT*/false, /*fCIM*/true, 0 ));
  122. {
  123. SYSTEMTIME st;
  124. st.wYear = (WORD)1970;
  125. st.wMonth = (WORD)1;
  126. st.wDay = (WORD)1;
  127. st.wHour = (WORD)0;
  128. st.wMinute = (WORD)0;
  129. st.wSecond = (WORD)0;
  130. st.wMilliseconds = (WORD)0;
  131. ::SystemTimeToVariantTime( &st, &dDateBase );
  132. }
  133. v = (dDate - dDateBase) * 86400.0 * 1000.0; __MPC_EXIT_IF_METHOD_FAILS(hr, v.ChangeType( VT_BSTR ));
  134. __MPC_EXIT_IF_METHOD_FAILS(hr, xml.ModifyAttribute( szTag, szAttrib, v.bstrVal, fFound, pxdnNode ));
  135. }
  136. hr = S_OK;
  137. __HCP_FUNC_CLEANUP;
  138. __HCP_FUNC_EXIT(hr);
  139. }
  140. /////////////////////////////////////////////////////////////////////////////
  141. News::Headlines::Headline::Headline()
  142. {
  143. // MPC::wstring m_strIcon;
  144. // MPC::wstring m_strTitle;
  145. // MPC::wstring m_strLink;
  146. // MPC::wstring m_strDescription;
  147. m_dtExpires = 0; // DATE m_dtExpires;
  148. m_fUpdateHeadlines = false; // bool m_fUpdateHeadlines;
  149. }
  150. News::Headlines::Headline::Headline( /*[in]*/ const MPC::wstring& strIcon ,
  151. /*[in]*/ const MPC::wstring& strTitle ,
  152. /*[in]*/ const MPC::wstring& strLink ,
  153. /*[in]*/ const MPC::wstring& strDescription ,
  154. /*[in]*/ DATE dtExpires ,
  155. /*[in]*/ bool fUpdateHeadlines)
  156. {
  157. m_strIcon = strIcon; // MPC::wstring m_strIcon;
  158. m_strTitle = strTitle; // MPC::wstring m_strTitle;
  159. m_strLink = strLink; // MPC::wstring m_strLink;
  160. m_strDescription = strDescription; // MPC::wstring m_strDescription;
  161. m_dtExpires = dtExpires; // DATE m_dtExpires;
  162. m_fUpdateHeadlines = fUpdateHeadlines; // bool m_fUpdateHeadlines;
  163. }
  164. ////////////////////
  165. News::Headlines::Newsblock::Newsblock()
  166. {
  167. // MPC::wstring m_strProvider;
  168. // MPC::wstring m_strLink;
  169. // MPC::wstring m_strIcon;
  170. // MPC::wstring m_strPosition;
  171. m_dtTimestamp = 0; // DATE m_dtTimestamp;
  172. m_nFrequency = 0; // int m_nFrequency;
  173. //
  174. // HeadlineList m_vecHeadlines;
  175. }
  176. //
  177. // Routine Description:
  178. //
  179. // Determines if its time to update or not, the newsblock
  180. //
  181. // Arguments:
  182. //
  183. // nBlockIndex Newsblock index
  184. //
  185. // Return Value:
  186. //
  187. // returns TRUE if its time to update the newsblock
  188. //
  189. //
  190. bool News::Headlines::Newsblock::TimeToUpdate()
  191. {
  192. if(m_nFrequency)
  193. {
  194. DATE dtNow = MPC::GetLocalTime() - m_nFrequency;
  195. // then we check if its time to download newsver.xml
  196. if(dtNow >= m_dtTimestamp) return true;
  197. }
  198. return false;
  199. }
  200. HRESULT News::Headlines::Newsblock::Copy( /*[in]*/ const Newsblock& block ,
  201. /*[in]*/ const MPC::wstring& strLangSKU ,
  202. /*[in]*/ int nProvID )
  203. {
  204. __HCP_FUNC_ENTRY( "News::Headlines::Newsblock::Copy" );
  205. HRESULT hr;
  206. //
  207. // copy the member variables
  208. *this = block;
  209. //
  210. // set the time we are modifying the Newsblock
  211. m_dtTimestamp = MPC::GetLocalTime();
  212. // check when we have incomplete information and we won't download the icon
  213. // when there is no Icon
  214. // when there is no Provider's name
  215. // when the Icon URL is missing a '/'
  216. if(!m_strIcon .empty() &&
  217. !m_strProvider.empty() )
  218. {
  219. MPC::wstring szEnd;
  220. GetFileName( m_strIcon, szEnd);
  221. if(!szEnd.empty())
  222. {
  223. MPC::wstring strPath = HC_HELPSET_ROOT HC_HELPSET_SUB_SYSTEM L"\\News\\";
  224. MPC::wstring strOthers;
  225. MPC::wstring strImgPath;
  226. WCHAR wzProvID[64];
  227. bool fUseIcon = false;
  228. __MPC_EXIT_IF_METHOD_FAILS(hr, MPC::SubstituteEnvVariables( strPath ));
  229. __MPC_EXIT_IF_METHOD_FAILS(hr, MPC::MakeDir ( strPath ));
  230. // add Lang and SKU
  231. strOthers = strLangSKU + L'_';
  232. strOthers += _itow( nProvID, wzProvID, 10 ); // add Provider's ID
  233. strOthers += L'_';
  234. strOthers += szEnd; // add the icon's name
  235. // form the path to this image file
  236. strImgPath = strPath;
  237. strImgPath += strOthers;
  238. // we check if we have that file already
  239. if(MPC::FileSystemObject::IsFile( strImgPath.c_str() ))
  240. {
  241. fUseIcon = true;
  242. }
  243. else
  244. {
  245. CComPtr<IStream> streamIn;
  246. // then, we download the new image
  247. if(SUCCEEDED(News::LoadFileFromServer( m_strIcon.c_str(), streamIn )))
  248. {
  249. CComPtr<MPC::FileStream> streamImg;
  250. if(SUCCEEDED(MPC::CreateInstance ( &streamImg )) &&
  251. SUCCEEDED(streamImg->InitForWrite( strImgPath.c_str() )) )
  252. {
  253. if(SUCCEEDED(MPC::BaseStream::TransferData( streamIn, streamImg )))
  254. {
  255. fUseIcon = true;
  256. }
  257. }
  258. }
  259. }
  260. if(fUseIcon)
  261. {
  262. m_strIcon = L"hcp://system/news/";
  263. m_strIcon += strOthers;
  264. }
  265. else
  266. {
  267. m_strIcon .erase();
  268. m_strPosition.erase();
  269. }
  270. }
  271. }
  272. hr = S_OK;
  273. __HCP_FUNC_CLEANUP;
  274. __HCP_FUNC_EXIT(hr);
  275. }
  276. void News::Headlines::Newsblock::GetFileName( MPC::wstring strURL, MPC::wstring& strFileName )
  277. {
  278. MPC::wstring::size_type pos;
  279. if(!strURL.empty())
  280. {
  281. if((pos = strURL.find_last_of( '/' )) == strURL.length() - 1)
  282. {
  283. strURL.resize( strURL.length() - 1 );
  284. pos = strURL.find_last_of( '/' );
  285. }
  286. if(pos != MPC::wstring::npos)
  287. {
  288. strFileName.assign( strURL, pos, strURL.length() - pos );
  289. // Go thro the string and delete all invalid characters
  290. pos = 0;
  291. while(!strFileName.empty() && pos < strFileName.length())
  292. {
  293. if((strFileName[pos] == '\\') || (strFileName[pos] == '/') || (strFileName[pos] == ':') ||
  294. (strFileName[pos] == '*') || (strFileName[pos] == '?') || (strFileName[pos] == '"') ||
  295. (strFileName[pos] == '<') || (strFileName[pos] == '>') || (strFileName[pos] == '|'))
  296. {
  297. strFileName.erase( pos, 1 );
  298. }
  299. else
  300. {
  301. pos++;
  302. }
  303. }
  304. }
  305. }
  306. }
  307. ////////////////////////////////////////////////////////////////////////////////
  308. News::Headlines::Headlines()
  309. {
  310. m_dtTimestamp = 0; // DATE m_dtTimestamp;
  311. m_dtDate = 0; // DATE m_dtDate;
  312. //
  313. // NewsblockList m_vecNewsblocks;
  314. }
  315. //
  316. // Routine Description:
  317. //
  318. // Clears the News::Headlines Class' variables and lists, so it can be loaded againg
  319. //
  320. // Arguments:
  321. //
  322. // None
  323. //
  324. //
  325. HRESULT News::Headlines::Clear()
  326. {
  327. __HCP_FUNC_ENTRY( "News::Headlines::Clear" );
  328. HRESULT hr;
  329. m_dtTimestamp = 0;
  330. m_dtDate = 0;
  331. m_vecNewsblocks.clear();
  332. hr = S_OK;
  333. __HCP_FUNC_EXIT(hr);
  334. }
  335. //
  336. // Routine Description:
  337. //
  338. // Loads the specified file and validates it (from the local disk or from the server)
  339. //
  340. // Arguments:
  341. //
  342. // strPath the path for the news headlines file (or newsblock)
  343. //
  344. //
  345. HRESULT News::Headlines::Load( /*[in]*/ const MPC::wstring& strPath )
  346. {
  347. __HCP_FUNC_ENTRY( "News::Headlines::Load" );
  348. HRESULT hr;
  349. CComPtr<IStream> stream;
  350. // we load the file
  351. __MPC_EXIT_IF_METHOD_FAILS(hr, News::LoadXMLFile( strPath.c_str(), stream ));
  352. __MPC_EXIT_IF_METHOD_FAILS(hr, MPC::Config::LoadStream( this, stream ));
  353. //validate file
  354. //
  355. if(m_vecNewsblocks.size() == 0)
  356. {
  357. __MPC_SET_WIN32_ERROR_AND_EXIT(hr, ERROR_INVALID_DATA);
  358. }
  359. hr = S_OK;
  360. __HCP_FUNC_CLEANUP;
  361. __HCP_FUNC_EXIT(hr);
  362. }
  363. //
  364. // Routine Description:
  365. //
  366. // The newsheadlines file is saved in the local user disk
  367. //
  368. // the timestamp is updated
  369. //
  370. // Arguments:
  371. //
  372. // strPath the path and name of the newsheadlines file
  373. //
  374. //
  375. HRESULT News::Headlines::Save( /*[in]*/ const MPC::wstring& strPath )
  376. {
  377. __HCP_FUNC_ENTRY( "News::Headlines::Save" );
  378. HRESULT hr;
  379. // the date is updated every time it is saved
  380. m_dtDate = MPC::GetLocalTime();
  381. // we save the file
  382. __MPC_EXIT_IF_METHOD_FAILS(hr, MPC::Config::SaveFile( this, strPath.c_str() ));
  383. hr = S_OK;
  384. __HCP_FUNC_CLEANUP;
  385. __HCP_FUNC_EXIT(hr);
  386. }
  387. //
  388. // Routine Description:
  389. //
  390. // Reloads the newsheadlines file and then returns it as a stream
  391. //
  392. // We check the Expires attribute in each headline, if it has expired then its deleted
  393. // if a provider loses all its headlines, then the provider (newsblock) is deleted too
  394. //
  395. // If all Newsblocks are deleted, we return ERROR_INVALID_DATA, to display the offline message
  396. //
  397. // We save the changes in the News Headlines file
  398. //
  399. // Arguments:
  400. //
  401. // strPath path for the newsheadlines file
  402. //
  403. // Return Value:
  404. //
  405. // pVal IStream with the newsheadlines xml content
  406. //
  407. //
  408. HRESULT News::Headlines:: get_Stream( /*[in ]*/ long lLCID ,
  409. /*[in ]*/ const MPC::wstring& strSKU ,
  410. /*[in ]*/ const MPC::wstring& strPath ,
  411. /*[out]*/ IUnknown* *pVal )
  412. {
  413. __HCP_FUNC_ENTRY( "News::Headlines::get_Stream" );
  414. HRESULT hr;
  415. MPC::XmlUtil xml;
  416. UpdateHeadlines uhUpdate;
  417. CComPtr<IStream> stream;
  418. bool fModified = false;
  419. DATE dtNow = MPC::GetLocalTime();
  420. NewsblockIter itNewsblock;
  421. // we clear the object
  422. Clear();
  423. // we load the News Headlines file
  424. __MPC_EXIT_IF_METHOD_FAILS(hr, News::LoadXMLFile( strPath.c_str(), stream ));
  425. __MPC_EXIT_IF_METHOD_FAILS(hr, MPC::Config::LoadStream( this, stream ));
  426. // ****** delete expired headlines
  427. // for each newsblock
  428. itNewsblock = m_vecNewsblocks.begin();
  429. while(itNewsblock != m_vecNewsblocks.end())
  430. {
  431. Newsblock& nb = *itNewsblock;
  432. HeadlineIter itHeadline = nb.m_vecHeadlines.begin();
  433. while(itHeadline != nb.m_vecHeadlines.end())
  434. {
  435. // check each headline if it has expired
  436. if(itHeadline->m_dtExpires < dtNow)
  437. {
  438. // if expired, deleted
  439. nb.m_vecHeadlines.erase( itHeadline );
  440. fModified = true;
  441. }
  442. else
  443. {
  444. // we go to the next headline
  445. itHeadline++;
  446. }
  447. }
  448. // if the Newsblock has no headlines valid
  449. if(itNewsblock->m_vecHeadlines.empty())
  450. {
  451. // we delete it
  452. m_vecNewsblocks.erase( itNewsblock );
  453. }
  454. else
  455. {
  456. // we go to the next Newsblock
  457. itNewsblock++;
  458. }
  459. }
  460. if(fModified)
  461. {
  462. // if we deleted headlines or newsblocks we save the News Headlines file
  463. __MPC_EXIT_IF_METHOD_FAILS(hr, Save( strPath ));
  464. }
  465. // if there aren't Newsblocks left, we return an error
  466. if(m_vecNewsblocks.empty())
  467. {
  468. __MPC_SET_WIN32_ERROR_AND_EXIT(hr, ERROR_INVALID_DATA);
  469. }
  470. __MPC_EXIT_IF_METHOD_FAILS(hr, MPC::Config::SaveXmlUtil( this, xml ));
  471. __MPC_EXIT_IF_METHOD_FAILS(hr, local_ConvertDate( xml, NULL, L"TIMESTAMP", NULL ));
  472. __MPC_EXIT_IF_METHOD_FAILS(hr, local_ConvertDate( xml, NULL, L"DATE" , NULL ));
  473. __MPC_EXIT_IF_METHOD_FAILS(hr, xml.SaveAsStream( pVal ));
  474. hr = S_OK;
  475. __HCP_FUNC_CLEANUP;
  476. __HCP_FUNC_EXIT(hr);
  477. }
  478. //
  479. // Routine Description:
  480. //
  481. // Checks to see if there atleast a single Newsblock which has an icon
  482. //
  483. // Arguments:
  484. //
  485. // None
  486. //
  487. // Return Value:
  488. //
  489. // true or false
  490. //
  491. bool News::Headlines::CheckIfImagesExist()
  492. {
  493. // Note that this function does NOT check to see if a headline has an icon. This is because headline icons are not
  494. // being processed (even though the ICON attribute exists in the HEADLINE tag).
  495. NewsblockIter itNewsblock;
  496. itNewsblock = m_vecNewsblocks.begin();
  497. while(itNewsblock != m_vecNewsblocks.end())
  498. {
  499. if(!itNewsblock->m_strIcon.empty())
  500. {
  501. return true;
  502. }
  503. else
  504. {
  505. itNewsblock++;
  506. }
  507. }
  508. return false;
  509. }
  510. //
  511. // Routine Description:
  512. //
  513. // Sets the News Headlines timestamp to the current time
  514. // This method should be called when all the newsblocks are retrieved
  515. //
  516. // Arguments:
  517. //
  518. // None
  519. //
  520. // Return Value:
  521. //
  522. // None
  523. //
  524. //
  525. void News::Headlines::set_Timestamp()
  526. {
  527. m_dtTimestamp = MPC::GetLocalTime();
  528. }
  529. News::Headlines::Newsblock* News::Headlines::get_Newsblock( /*[in]*/ size_t nBlockIndex )
  530. {
  531. if(nBlockIndex >= m_vecNewsblocks.size()) return NULL;
  532. return &(m_vecNewsblocks[ nBlockIndex ]);
  533. }
  534. ////////////////////////////////////////
  535. //
  536. // Routine Description:
  537. //
  538. // From the provided newsblock this method gets the first two headlines
  539. // and adds it to the first newsblock
  540. //
  541. // Arguments:
  542. //
  543. // None
  544. //
  545. // Return Value:
  546. //
  547. // None
  548. //
  549. //
  550. HRESULT News::Headlines::AddHomepageHeadlines( /*[in]*/ const Headlines::Newsblock& block )
  551. {
  552. __HCP_FUNC_ENTRY( "News::Headlines::AddHomepageHeadlines" );
  553. HRESULT hr;
  554. size_t nIndex = 0;
  555. NewsblockIter itNewsblock;
  556. HeadlineIter itHeadline;
  557. // Add 2 headlines to the first newsblock
  558. itNewsblock = m_vecNewsblocks.begin();
  559. while ( itNewsblock && ( ++nIndex <= NUMBER_OF_OEM_HEADLINES ) )
  560. {
  561. // If a headline already exists delete it before adding a new one
  562. if ( nIndex < itNewsblock->m_vecHeadlines.size() )
  563. {
  564. itHeadline = itNewsblock->m_vecHeadlines.begin();
  565. std::advance( itHeadline, nIndex );
  566. // Delete the existing headline before adding it
  567. itNewsblock->m_vecHeadlines.erase( itHeadline );
  568. // Add the headline
  569. itNewsblock->m_vecHeadlines.insert( itHeadline, block.m_vecHeadlines[nIndex - 1] );
  570. }
  571. else
  572. {
  573. // Insert the headline to the end of the list
  574. itNewsblock->m_vecHeadlines.insert( itNewsblock->m_vecHeadlines.end(), block.m_vecHeadlines[nIndex - 1] );
  575. }
  576. }
  577. hr = S_OK;
  578. return S_OK;
  579. }
  580. ////////////////////////////////////////
  581. HRESULT News::Headlines::AddNewsblock( /*[in]*/ const Headlines::Newsblock& block ,
  582. /*[in]*/ const MPC::wstring& strLangSKU )
  583. {
  584. __HCP_FUNC_ENTRY( "News::Headlines::AddNewsblock" );
  585. HRESULT hr;
  586. NewsblockIter itNewsblock;
  587. itNewsblock = m_vecNewsblocks.insert( m_vecNewsblocks.end() );
  588. __MPC_EXIT_IF_METHOD_FAILS(hr, itNewsblock->Copy( block, strLangSKU, m_vecNewsblocks.size()-1 ));
  589. hr = S_OK;
  590. __HCP_FUNC_CLEANUP;
  591. __HCP_FUNC_EXIT(hr);
  592. }