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.

1871 lines
53 KiB

  1. /*--------------------------------------------------------------------------*
  2. *
  3. * Microsoft Windows
  4. * Copyright (C) Microsoft Corporation, 1992 - 1999
  5. *
  6. * File: task.cpp
  7. *
  8. * Contents: Implementation file for CConsoleTask
  9. *
  10. * History: 05-Oct-98 jeffro Created
  11. *
  12. *--------------------------------------------------------------------------*/
  13. #include "stdafx.h"
  14. #include "regutil.h"
  15. #include "tasks.h"
  16. #include "nodepath.h"
  17. #include "conview.h"
  18. #ifdef DBG
  19. // Traces
  20. CTraceTag tagCTPHTML(TEXT("Console Taskpads"), TEXT("Dump HTML"));
  21. #endif
  22. extern CEOTSymbol s_rgEOTSymbol[];
  23. /*+-------------------------------------------------------------------------*
  24. * class CGlobalConsoleTaskList
  25. *
  26. * PURPOSE: A global console task list that provides unique IDs for all console tasks
  27. * When a task is instantiated, its constructor registers in the global task list,
  28. * and obtains a globally unique ID. This ID is unique for the process and should
  29. * not be persisted.
  30. * The destructor of the task removes it from this list.
  31. *
  32. * USAGE: Call CGlobalConsoleTaskList::GetConsoleTask to obtain a pointer to the task
  33. * that has a specified ID.
  34. * Call CConsoleTask::GetUniqueID to get the unique ID for a task.
  35. *
  36. * Thus, CGlobalConsoleTaskList::GetConsoleTask(pConsoleTask->GetUniqueID()) == pConsoleTask
  37. * is always true.
  38. *+-------------------------------------------------------------------------*/
  39. class CGlobalConsoleTaskList
  40. {
  41. private:
  42. typedef const CConsoleTask * PCONSOLETASK;
  43. typedef std::map<PCONSOLETASK, DWORD> t_taskIDmap;
  44. public:
  45. static DWORD Advise( PCONSOLETASK pConsoleTask)
  46. {
  47. DWORD dwOut = s_curTaskID++;
  48. s_map[pConsoleTask] = dwOut;
  49. return dwOut;
  50. }
  51. static void Unadvise(PCONSOLETASK pConsoleTask)
  52. {
  53. s_map.erase(pConsoleTask);
  54. }
  55. static CConsoleTask * GetConsoleTask(DWORD dwID)
  56. {
  57. t_taskIDmap::iterator iter;
  58. for(iter = s_map.begin(); iter != s_map.end(); iter ++)
  59. {
  60. if(iter->second == dwID)
  61. return const_cast<CConsoleTask *>(iter->first);
  62. }
  63. return NULL;
  64. }
  65. private:
  66. CGlobalConsoleTaskList() {}// private, so that it cannot be instantiated
  67. static t_taskIDmap s_map;
  68. static DWORD s_curTaskID;
  69. };
  70. CGlobalConsoleTaskList::t_taskIDmap CGlobalConsoleTaskList::s_map;
  71. DWORD CGlobalConsoleTaskList::s_curTaskID = 0;
  72. //############################################################################
  73. //############################################################################
  74. //
  75. // Implementation of class CConsoleTask
  76. //
  77. //############################################################################
  78. //############################################################################
  79. /*+-------------------------------------------------------------------------*
  80. * CConsoleTask::CConsoleTask
  81. *
  82. *
  83. *--------------------------------------------------------------------------*/
  84. DEBUG_DECLARE_INSTANCE_COUNTER(CConsoleTask);
  85. CConsoleTask::CConsoleTask() :
  86. m_eConsoleTaskType (eTask_Result),
  87. // default ctor for m_strName
  88. // default ctor for m_strDescription
  89. // default ctor for m_strCommand
  90. // default ctor for m_strParameters
  91. // default ctor for m_strDirectory
  92. m_eWindowState (eState_Restored),
  93. // default ctor for m_image
  94. m_dwFlags (0),
  95. m_bmScopeNode (false),
  96. m_fDirty (false),
  97. m_pctpOwner (NULL),
  98. m_dwUniqueID (CGlobalConsoleTaskList::Advise(this)) // create a unique ID for this task
  99. {
  100. DEBUG_INCREMENT_INSTANCE_COUNTER(CConsoleTask);
  101. }
  102. /*+-------------------------------------------------------------------------*
  103. * CConsoleTask::CConsoleTask(const CConsoleTask& other)
  104. *
  105. * PURPOSE: Copy ctor.
  106. *
  107. * PARAMETERS: const CConsoleTask& other
  108. *
  109. * NOTE: Calls operator=, cant use default copy ctor (see operator= imp.)
  110. *
  111. /*+-------------------------------------------------------------------------*/
  112. CConsoleTask::CConsoleTask (const CConsoleTask &rhs):
  113. m_dwUniqueID (CGlobalConsoleTaskList::Advise(this))
  114. {
  115. DEBUG_INCREMENT_INSTANCE_COUNTER(CConsoleTask);
  116. *this = rhs;
  117. }
  118. /*+-------------------------------------------------------------------------*
  119. *
  120. * CConsoleTask::GetConsoleTask
  121. *
  122. * PURPOSE:
  123. *
  124. * PARAMETERS:
  125. * DWORD dwUniqueID :
  126. *
  127. * RETURNS:
  128. * CConsoleTask *
  129. *
  130. *+-------------------------------------------------------------------------*/
  131. CConsoleTask *
  132. CConsoleTask::GetConsoleTask(DWORD dwUniqueID)
  133. {
  134. return CGlobalConsoleTaskList::GetConsoleTask(dwUniqueID);
  135. }
  136. /*+-------------------------------------------------------------------------*
  137. *
  138. * ScReplaceString
  139. *
  140. * PURPOSE: Replaces all occurrences of the token by its replacement.
  141. *
  142. * PARAMETERS:
  143. * CStr & str :
  144. * LPCTSTR szToken :
  145. * LPCTSTR szReplacement :
  146. *
  147. * RETURNS:
  148. * static SC
  149. *
  150. *+-------------------------------------------------------------------------*/
  151. static SC
  152. ScReplaceString(CStr &str, LPCTSTR szToken, LPCTSTR szReplacement, bool bMustReplace = true)
  153. {
  154. DECLARE_SC(sc, TEXT("ScReplaceString"));
  155. CStr strTemp = str;
  156. str = TEXT("");
  157. int i = strTemp.Find(szToken);
  158. if( (-1==i) && bMustReplace)
  159. return (sc = E_UNEXPECTED);
  160. while(-1!=i)
  161. {
  162. str += strTemp.Left(i);
  163. str += szReplacement;
  164. strTemp = strTemp.Mid(i+_tcslen(szToken)); // the remaining string
  165. i=strTemp.Find(szToken);
  166. }
  167. str += strTemp;
  168. return sc;
  169. }
  170. /*+-------------------------------------------------------------------------*
  171. *
  172. * ScUseJavaScriptStringEntities
  173. *
  174. * PURPOSE: Use this to create a valid Javascript string. Replaces " by \" and
  175. * \ by \\ in the string parameter.
  176. *
  177. * PARAMETERS:
  178. * CStr & str :
  179. *
  180. * RETURNS:
  181. * static SC
  182. *
  183. *+-------------------------------------------------------------------------*/
  184. static SC
  185. ScUseJavaScriptStringEntities(CStr &str)
  186. {
  187. DECLARE_SC(sc, TEXT("ScUseJavaScriptStringEntities"));
  188. // NOTE: don't change the order of these string replacements
  189. sc = ScReplaceString(str, TEXT("\\"), TEXT("\\\\"), false);
  190. if(sc)
  191. return sc;
  192. sc = ScReplaceString(str, TEXT("\""), TEXT("\\\""), false);
  193. if(sc)
  194. return sc;
  195. return sc;
  196. }
  197. /*+-------------------------------------------------------------------------*
  198. *
  199. * ScUseHTMLEntities
  200. *
  201. * PURPOSE: Replaces " by &quot; < by &lt; and > by &gt; and & by &amp; in the string parameter.
  202. *
  203. * PARAMETERS:
  204. * CStr & str :
  205. *
  206. * RETURNS:
  207. * static SC
  208. *
  209. *+-------------------------------------------------------------------------*/
  210. static SC
  211. ScUseHTMLEntities(CStr &str)
  212. {
  213. DECLARE_SC(sc, TEXT("ScUseHTMLEntities"));
  214. sc = ScReplaceString(str, TEXT("&"), TEXT("&amp;"), false);
  215. if(sc)
  216. return sc;
  217. sc = ScReplaceString(str, TEXT("\""), TEXT("&quot;"), false);
  218. if(sc)
  219. return sc;
  220. sc = ScReplaceString(str, TEXT("<"), TEXT("&lt;"), false);
  221. if(sc)
  222. return sc;
  223. sc = ScReplaceString(str, TEXT(">"), TEXT("&gt;"), false);
  224. if(sc)
  225. return sc;
  226. return sc;
  227. }
  228. /*+-------------------------------------------------------------------------*
  229. *
  230. * CConsoleTask::ScGetHTML
  231. *
  232. * PURPOSE: returns the HTML representation of the task.
  233. *
  234. * PARAMETERS:
  235. * LPCTSTR szFmtHTML :
  236. * CStr & strTaskHTML :
  237. * bool bUseLargeIcons : Draw in the no-list (large icon) style
  238. * bool bUseTextDescriptions :
  239. *
  240. * RETURNS:
  241. * SC
  242. *
  243. *+-------------------------------------------------------------------------*/
  244. SC
  245. CConsoleTask::ScGetHTML(LPCTSTR szFmtHTML, CStr &strTaskHTML, bool bUseLargeIcons, bool bUseTextDescriptions) const
  246. {
  247. DECLARE_SC(sc, TEXT("CConsoleTask::ScGetHTML"));
  248. USES_CONVERSION;
  249. // the substitution parameters, in order
  250. CStr strTableSpacing = bUseLargeIcons ? TEXT("<BR />") : TEXT("");
  251. int iconWidth = bUseLargeIcons ? 32: 20;
  252. int iconHeight = bUseLargeIcons ? 32: 16;
  253. // iconWidth and iconHeight repeated
  254. int uniqueID = GetUniqueID();
  255. CStr strSmall = bUseLargeIcons ? TEXT("0") : TEXT("1");
  256. CStr strHref;
  257. CStr strID;
  258. CStr strParameter;
  259. CStr strOptionalTitleTag;
  260. CStr strOptionalTextDescription;
  261. CStr strTaskName = GetName().data();
  262. CStr strDescription = GetDescription().data();
  263. CStr strCommand = GetCommand().data();
  264. // use entities for all strings
  265. sc = ScUseHTMLEntities(strTaskName);
  266. if(sc)
  267. return sc;
  268. sc = ScUseHTMLEntities(strDescription);
  269. if(sc)
  270. return sc;
  271. sc = ScUseJavaScriptStringEntities(strCommand);
  272. if(sc)
  273. return sc;
  274. //------
  275. if(bUseTextDescriptions)
  276. {
  277. strOptionalTextDescription = TEXT("<BR />");
  278. strOptionalTextDescription += strDescription;
  279. }
  280. else
  281. {
  282. strOptionalTitleTag.Format(TEXT("title='%s'"), (LPCTSTR) strDescription);
  283. }
  284. switch(GetTaskType())
  285. {
  286. case eTask_Scope:
  287. {
  288. std::wstring strTemp;
  289. // get the bookmark of the scope node.
  290. sc = m_bmScopeNode.ScSaveToString(&strTemp);
  291. if(sc)
  292. return sc;
  293. CStr strScopeNodeBookmark = W2CT(strTemp.data()); // make sure that special characters have been converted
  294. sc = ScUseJavaScriptStringEntities(strScopeNodeBookmark);
  295. if(sc)
  296. return sc;
  297. strHref.Format(TEXT("external.ExecuteScopeNodeMenuItem(\"%s\", \"%s\");"), (LPCTSTR)strCommand, (LPCTSTR)strScopeNodeBookmark);
  298. }
  299. strID=L"ScopeTask";
  300. break;
  301. case eTask_Result:
  302. strHref.Format(TEXT("external.ExecuteSelectionMenuItem(\"%s\");"), (LPCTSTR)strCommand);
  303. strParameter = strCommand;
  304. strID = TEXT("ResultTask");
  305. break;
  306. case eTask_CommandLine:
  307. {
  308. strParameter = GetParameters().data();
  309. sc = ScUseJavaScriptStringEntities(strParameter);
  310. if(sc)
  311. return sc;
  312. CStr strDirectory = GetDirectory().data();
  313. sc = ScUseJavaScriptStringEntities(strDirectory);
  314. if(sc)
  315. return sc;
  316. // get the window state
  317. CStr strWindowState;
  318. if(GetWindowState() ==eState_Restored)
  319. strWindowState = XML_ENUM_WINDOW_STATE_RESTORED;
  320. else if(GetWindowState() == eState_Minimized)
  321. strWindowState = XML_ENUM_WINDOW_STATE_MINIMIZED;
  322. else
  323. strWindowState = XML_ENUM_WINDOW_STATE_MAXIMIZED;
  324. strHref.Format(TEXT("external.ExecuteShellCommand(\"%s\", \"%s\", ParseParameters(\"%s\"), \"%s\");"),
  325. (LPCTSTR)strCommand, (LPCTSTR)strDirectory, (LPCTSTR)strParameter, (LPCTSTR)strWindowState);
  326. }
  327. strID=L"CommandLineTask";
  328. break;
  329. case eTask_Target:
  330. strHref.Format(TEXT("external.ExecuteScopeNodeMenuItem(\"%s\");"), (LPCTSTR)strCommand);
  331. strParameter = strCommand;
  332. strID = L"TargetTask";
  333. break;
  334. case eTask_Favorite:
  335. {
  336. std::wstring strTemp;
  337. // save the memento to a string
  338. sc = const_cast<CMemento *>(&m_memento)->ScSaveToString(&strTemp);
  339. if(sc)
  340. return sc;
  341. CStr strMemento = W2CT(strTemp.data());
  342. sc = ScUseJavaScriptStringEntities(strMemento);
  343. if(sc)
  344. return sc;
  345. strHref.Format(TEXT("external.ViewMemento(\"%s\");"), (LPCTSTR)strMemento);
  346. }
  347. strID=L"FavoriteTask";
  348. break;
  349. default:
  350. break;
  351. }
  352. strTaskHTML.Format(szFmtHTML, (LPCTSTR) strTableSpacing, iconWidth, iconHeight, uniqueID, iconWidth, iconHeight,
  353. uniqueID, (LPCTSTR) strSmall, uniqueID, uniqueID, (LPCTSTR) strID, (LPCTSTR) strParameter,
  354. (LPCTSTR) strOptionalTitleTag, (LPCTSTR)strTaskName, (LPCTSTR) strOptionalTextDescription,
  355. uniqueID, uniqueID, uniqueID, (LPCTSTR) strHref);
  356. Trace(tagCTPHTML, TEXT("%s"), (LPCTSTR)strTaskHTML);
  357. return sc;
  358. }
  359. /*+-------------------------------------------------------------------------*
  360. *
  361. * CConsoleTask::IsDirty
  362. *
  363. * PURPOSE: Determines whether the task needs to be saved.
  364. *
  365. * RETURNS:
  366. * bool
  367. *
  368. *+-------------------------------------------------------------------------*/
  369. bool
  370. CConsoleTask::IsDirty() const
  371. {
  372. TraceDirtyFlag(TEXT("CConsoleTask"), m_fDirty);
  373. return (m_fDirty);
  374. }
  375. /*+-------------------------------------------------------------------------*
  376. * CConsoleTask::operator =
  377. *
  378. * PURPOSE: Assignment operator
  379. *
  380. * PARAMETERS: const CConsoleTask& rhs
  381. *
  382. * RETURNS:
  383. * CConsoleTask &
  384. *
  385. /*+-------------------------------------------------------------------------*/
  386. CConsoleTask &
  387. CConsoleTask::operator =(const CConsoleTask& rhs)
  388. {
  389. if (this != &rhs)
  390. {
  391. m_eConsoleTaskType = rhs.m_eConsoleTaskType;
  392. m_strName = rhs.m_strName;
  393. m_strDescription = rhs.m_strDescription;
  394. m_strCommand = rhs.m_strCommand;
  395. m_strParameters = rhs.m_strParameters;
  396. m_strDirectory = rhs.m_strDirectory;
  397. m_eWindowState = rhs.m_eWindowState;
  398. m_dwFlags = rhs.m_dwFlags;
  399. m_bmScopeNode = rhs.m_bmScopeNode;
  400. m_dwSymbol = rhs.m_dwSymbol;
  401. m_smartIconCustomLarge = rhs.m_smartIconCustomLarge;
  402. m_smartIconCustomSmall = rhs.m_smartIconCustomSmall;
  403. m_memento = rhs.m_memento;
  404. m_fDirty = rhs.m_fDirty;
  405. m_pctpOwner = rhs.m_pctpOwner;
  406. // m_dwUniqueID = rhs.m_dwUniqueID; DO NOT copy this ID
  407. }
  408. return *this;
  409. }
  410. /*+-------------------------------------------------------------------------*
  411. *
  412. * CConsoleTask::operator ==
  413. *
  414. * PURPOSE: Equality operator. Checks that the command string is
  415. * equal to the given menuitem's Path or Language Independent Path.
  416. *
  417. *+-------------------------------------------------------------------------*/
  418. bool
  419. CConsoleTask::operator==(const CMenuItem & menuItem) const
  420. {
  421. // check that the command string matches either the path or the language independent path.
  422. if( (m_strCommand == menuItem.GetPath()) ||
  423. (m_strCommand == menuItem.GetLanguageIndependentPath() )
  424. )
  425. return true;
  426. return false;
  427. }
  428. /*+-------------------------------------------------------------------------*
  429. * CConsoleTask::~CConsoleTask
  430. *
  431. *
  432. *--------------------------------------------------------------------------*/
  433. CConsoleTask::~CConsoleTask ()
  434. {
  435. DEBUG_DECREMENT_INSTANCE_COUNTER(CConsoleTask);
  436. CGlobalConsoleTaskList::Unadvise(this); // remove this task from the list.
  437. }
  438. /*+-------------------------------------------------------------------------*
  439. *
  440. * CConsoleTask::HasCustomIcon
  441. *
  442. * PURPOSE: Returns whether the task has a custom icon
  443. *
  444. * RETURNS:
  445. * bool
  446. *
  447. *+-------------------------------------------------------------------------*/
  448. bool
  449. CConsoleTask::HasCustomIcon() const
  450. {
  451. if((HICON)m_smartIconCustomLarge != NULL)
  452. {
  453. ASSERT((HICON)m_smartIconCustomSmall != NULL);
  454. return true;
  455. }
  456. return false;
  457. }
  458. /*+-------------------------------------------------------------------------*
  459. *
  460. * CConsoleTask::Reset
  461. *
  462. * PURPOSE:
  463. *
  464. * RETURNS:
  465. * void
  466. *
  467. *+-------------------------------------------------------------------------*/
  468. void
  469. CConsoleTask::ResetUI()
  470. {
  471. m_bmScopeNode.ResetUI();
  472. }
  473. /*+-------------------------------------------------------------------------*
  474. *
  475. * CConsoleTask::SetSymbol
  476. *
  477. * PURPOSE:
  478. *
  479. * PARAMETERS:
  480. * DWORD dwSymbol :
  481. *
  482. * RETURNS:
  483. * void
  484. *
  485. *+-------------------------------------------------------------------------*/
  486. void
  487. CConsoleTask::SetSymbol(DWORD dwSymbol)
  488. {
  489. m_dwSymbol = dwSymbol;
  490. m_smartIconCustomSmall.Release();
  491. m_smartIconCustomLarge.Release();
  492. SetDirty();
  493. }
  494. /*+-------------------------------------------------------------------------*
  495. *
  496. * CConsoleTask::SetCustomIcon
  497. *
  498. * PURPOSE:
  499. *
  500. * PARAMETERS:
  501. * CSmartIcon& iconSmall :
  502. * CSmartIcon& iconLarge :
  503. *
  504. * RETURNS:
  505. * void
  506. *
  507. *+-------------------------------------------------------------------------*/
  508. void
  509. CConsoleTask::SetCustomIcon(CSmartIcon& iconSmall, CSmartIcon& iconLarge)
  510. {
  511. m_smartIconCustomSmall = iconSmall;
  512. m_smartIconCustomLarge = iconLarge;
  513. SetDirty();
  514. }
  515. /*+-------------------------------------------------------------------------*
  516. * CConsoleTask::Enable
  517. *
  518. * Sets the enable state for a task.
  519. *--------------------------------------------------------------------------*/
  520. void CConsoleTask::Enable (bool fEnable)
  521. {
  522. if (fEnable)
  523. m_dwFlags &= ~eFlag_Disabled;
  524. else
  525. m_dwFlags |= eFlag_Disabled;
  526. SetDirty ();
  527. }
  528. void
  529. CConsoleTask::Draw (HDC hdc, RECT *lpRect, bool bSmall) const // Draw into a DC.
  530. {
  531. if(HasCustomIcon())
  532. {
  533. DrawIconEx(hdc, lpRect->left, lpRect->top, bSmall ? m_smartIconCustomSmall : m_smartIconCustomLarge,
  534. bSmall? 16 : 32, bSmall? 16 : 32, 0, NULL, DI_NORMAL);
  535. return;
  536. }
  537. for(int i = 0; i< NUM_SYMBOLS; i++)
  538. {
  539. if(s_rgEOTSymbol[i].GetValue() == m_dwSymbol)
  540. {
  541. s_rgEOTSymbol[i].Draw(hdc, lpRect, bSmall);
  542. return;
  543. }
  544. }
  545. /*
  546. * if we get here, we couldn't find the EOT symbol matching m_dwSymbol
  547. */
  548. ASSERT (false);
  549. }
  550. /*+-------------------------------------------------------------------------*
  551. * CConsoleTask::SetName
  552. *
  553. *
  554. *--------------------------------------------------------------------------*/
  555. void CConsoleTask::SetName (const tstring& strName)
  556. {
  557. if (m_strName != strName)
  558. {
  559. m_strName = strName;
  560. SetDirty ();
  561. }
  562. }
  563. /*+-------------------------------------------------------------------------*
  564. * CConsoleTask::SetDescription
  565. *
  566. *
  567. *--------------------------------------------------------------------------*/
  568. void CConsoleTask::SetDescription (const tstring& strDescription)
  569. {
  570. if (m_strDescription != strDescription)
  571. {
  572. m_strDescription = strDescription;
  573. SetDirty ();
  574. }
  575. }
  576. /*+-------------------------------------------------------------------------*
  577. * CConsoleTask::SetCommand
  578. *
  579. *
  580. *--------------------------------------------------------------------------*/
  581. void CConsoleTask::SetCommand (const tstring& strCommand)
  582. {
  583. if (m_strCommand != strCommand)
  584. {
  585. m_strCommand = strCommand;
  586. SetDirty ();
  587. }
  588. }
  589. /*+-------------------------------------------------------------------------*
  590. * CConsoleTask::SetParameters
  591. *
  592. *
  593. *--------------------------------------------------------------------------*/
  594. void CConsoleTask::SetParameters (const tstring& strParameters)
  595. {
  596. if (m_strParameters != strParameters)
  597. {
  598. m_strParameters = strParameters;
  599. SetDirty ();
  600. }
  601. }
  602. /*+-------------------------------------------------------------------------*
  603. * CConsoleTask::SetDirectory
  604. *
  605. *
  606. *--------------------------------------------------------------------------*/
  607. void CConsoleTask::SetDirectory (const tstring& strDirectory)
  608. {
  609. if (m_strDirectory != strDirectory)
  610. {
  611. m_strDirectory = strDirectory;
  612. SetDirty ();
  613. }
  614. }
  615. void CConsoleTask::SetMemento(const CMemento &memento)
  616. {
  617. if( m_memento != memento)
  618. {
  619. m_memento = memento;
  620. SetDirty();
  621. }
  622. }
  623. /*+-------------------------------------------------------------------------*
  624. * CConsoleTask::SetWindowState
  625. *
  626. *
  627. *--------------------------------------------------------------------------*/
  628. void CConsoleTask::SetWindowState (eWindowState eNewState)
  629. {
  630. if (m_eWindowState != eNewState)
  631. {
  632. m_eWindowState = eNewState;
  633. SetDirty ();
  634. }
  635. }
  636. /*+-------------------------------------------------------------------------*
  637. * CConsoleTask::RetargetScopeNode
  638. *
  639. * PURPOSE: Sets the target scope node for the task. Note: the task must be
  640. * of type eTask_Scope.
  641. *
  642. * PARAMETERS:
  643. * CNode * pNewNode:
  644. *
  645. * RETURNS:
  646. * bool
  647. */
  648. /*+-------------------------------------------------------------------------*/
  649. bool
  650. CConsoleTask::RetargetScopeNode(CNode *pNewNode)
  651. {
  652. bool fRet = TRUE;
  653. ASSERT(GetTaskType() == eTask_Scope);
  654. CMTNode* pMTNewNode = (pNewNode) ? pNewNode->GetMTNode() : NULL;
  655. m_bmScopeNode.ScRetarget(pMTNewNode, false /*bFastRetrievalOnly*/);
  656. SetDirty();
  657. return fRet;
  658. }
  659. /*+-------------------------------------------------------------------------*
  660. * CConsoleTask::GetScopeNode
  661. *
  662. * PURPOSE:
  663. *
  664. * PARAMETERS:
  665. * IScopeTree * pScopeTree:
  666. *
  667. * RETURNS:
  668. * CMTNode *
  669. *
  670. /*+-------------------------------------------------------------------------*/
  671. CMTNode *
  672. CConsoleTask::GetScopeNode(IScopeTree *pScopeTree) const
  673. {
  674. DECLARE_SC(sc, TEXT("CConsoleTask::GetScopeNode"));
  675. CMTNode *pMTNode = NULL;
  676. bool bExactMatchFound = false; // out value from ScGetMTNode, unused
  677. sc = m_bmScopeNode.ScGetMTNode(true /*bExactMatchRequired*/, &pMTNode, bExactMatchFound);
  678. if(sc.IsError())
  679. return NULL;
  680. return (pMTNode);
  681. }
  682. /*+-------------------------------------------------------------------------*
  683. * CConsoleTask::GetScopeNode
  684. *
  685. * PURPOSE:
  686. *
  687. * PARAMETERS:
  688. * CViewData * pViewData:
  689. *
  690. * RETURNS:
  691. * CNode *
  692. /*+-------------------------------------------------------------------------*/
  693. std::auto_ptr<CNode>
  694. CConsoleTask::GetScopeNode(CViewData *pViewData) const
  695. {
  696. return m_bmScopeNode.GetNode(pViewData);
  697. }
  698. /*+-------------------------------------------------------------------------*
  699. *
  700. * CConsoleTask::Persist
  701. *
  702. * PURPOSE: Persists the console task to the specified persistor.
  703. *
  704. *
  705. * PARAMETERS:
  706. * CPersistor & persistor :
  707. *
  708. * RETURNS:
  709. * void
  710. *
  711. *+-------------------------------------------------------------------------*/
  712. void
  713. CConsoleTask::Persist(CPersistor &persistor)
  714. {
  715. persistor.PersistString(XML_ATTR_TASK_NAME, m_strName);
  716. // define the table to map enumeration values to strings
  717. static const EnumLiteral mappedTaskTypes[] =
  718. {
  719. { eTask_Scope, XML_ENUM_TASK_TYPE_SCOPE },
  720. { eTask_Result, XML_ENUM_TASK_TYPE_RESULT },
  721. { eTask_CommandLine, XML_ENUM_TASK_TYPE_COMMANDLINE },
  722. { eTask_Target, XML_ENUM_TASK_TYPE_TARGET },
  723. { eTask_Favorite, XML_ENUM_TASK_TYPE_FAVORITE },
  724. };
  725. // create wrapper to persist flag values as strings
  726. CXMLEnumeration taskTypePersistor(m_eConsoleTaskType, mappedTaskTypes, countof(mappedTaskTypes));
  727. // persist the wrapper
  728. persistor.PersistAttribute(XML_ATTR_TASK_TYPE, taskTypePersistor);
  729. persistor.PersistString(XML_ATTR_TASK_DESCRIPTION, m_strDescription);
  730. {
  731. /* this section creates
  732. <ConsoleTask>
  733. <SYMBOL id = "">
  734. <IMAGE name = "LargeIcon" ... /> NOTE: either the id or the images are present.
  735. <IMAGE name = "SmallIcon" ... />
  736. </SYMBOL>
  737. </ConsoleTask>
  738. */
  739. // create a child element for the symbol
  740. CPersistor persistorSymbol(persistor, XML_TAG_EOT_SYMBOL_INFO);
  741. if(persistorSymbol.IsLoading())
  742. {
  743. m_dwSymbol = (DWORD)-1; // initialize
  744. }
  745. if(persistorSymbol.IsLoading() ||
  746. (persistorSymbol.IsStoring() && !HasCustomIcon() ) )
  747. {
  748. // save the "ID" attribute only if there is no icon
  749. persistorSymbol.PersistAttribute(XML_ATTR_EOT_SYMBOL_DW_SYMBOL, m_dwSymbol, attr_optional);
  750. }
  751. if((persistorSymbol.IsStoring() && HasCustomIcon()) ||
  752. (persistorSymbol.IsLoading() && (m_dwSymbol == (DWORD) -1) )
  753. )
  754. {
  755. persistorSymbol.Persist (m_smartIconCustomSmall, XML_NAME_ICON_SMALL);
  756. persistorSymbol.Persist (m_smartIconCustomLarge, XML_NAME_ICON_LARGE);
  757. }
  758. }
  759. persistor.PersistAttribute(XML_ATTR_TASK_COMMAND, m_strCommand);
  760. // define the table to map enumeration values to strings
  761. static const EnumLiteral mappedTaskFlags[] =
  762. {
  763. { eFlag_Disabled, XML_BITFLAG_TASK_DISABLED },
  764. };
  765. // create wrapper to persist flag values as strings
  766. CXMLBitFlags taskFlagPersistor(m_dwFlags, mappedTaskFlags, countof(mappedTaskFlags));
  767. // persist the wrapper
  768. persistor.PersistAttribute(XML_ATTR_TASK_FLAGS, taskFlagPersistor);
  769. switch (m_eConsoleTaskType)
  770. {
  771. case eTask_Scope:
  772. persistor.Persist(m_bmScopeNode);
  773. break;
  774. case eTask_CommandLine:
  775. {
  776. CPersistor persistorCmd(persistor, XML_TAG_TASK_CMD_LINE);
  777. persistorCmd.PersistAttribute(XML_ATTR_TASK_CMD_LINE_DIR, m_strDirectory);
  778. // define the table to map enumeration values to strings
  779. static const EnumLiteral windowStates[] =
  780. {
  781. { eState_Restored, XML_ENUM_WINDOW_STATE_RESTORED },
  782. { eState_Minimized, XML_ENUM_WINDOW_STATE_MINIMIZED },
  783. { eState_Maximized, XML_ENUM_WINDOW_STATE_MAXIMIZED },
  784. };
  785. // create wrapper to persist flag values as strings
  786. CXMLEnumeration windowStatePersistor(m_eWindowState, windowStates, countof(windowStates));
  787. // persist the wrapper
  788. persistorCmd.PersistAttribute(XML_ATTR_TASK_CMD_LINE_WIN_ST, windowStatePersistor);
  789. persistorCmd.PersistAttribute(XML_ATTR_TASK_CMD_LINE_PARAMS, m_strParameters);
  790. break;
  791. }
  792. case eTask_Favorite:
  793. persistor.Persist(m_memento);
  794. break;
  795. }
  796. // either read or saved - not dirty after the operation
  797. SetDirty(false);
  798. }
  799. /*+-------------------------------------------------------------------------*
  800. * CConsoleTask::ReadSerialObject
  801. *
  802. *
  803. *--------------------------------------------------------------------------*/
  804. HRESULT
  805. CConsoleTask::ReadSerialObject (IStream &stm, UINT nVersion /*,LARGE_INTEGER nBytes*/)
  806. {
  807. HRESULT hr = S_FALSE; // assume unknown version
  808. if (nVersion == 1)
  809. {
  810. try
  811. {
  812. // ugly hackery required to extract directly into an enum
  813. stm >> *((int *) &m_eConsoleTaskType);
  814. stm >> m_strName;
  815. stm >> m_strDescription;
  816. // legacy task symbol info
  817. {
  818. // this must be BOOL not bool to occupy the same amount of space as in legacy consoles
  819. // See Bug #101253
  820. BOOL bLegacyUseMMCSymbols = TRUE; // a now obsolete field, read for console file compatibility
  821. tstring strFileLegacy, strFontLegacy;
  822. stm >> m_dwSymbol;
  823. stm >> bLegacyUseMMCSymbols;
  824. stm >> strFileLegacy; // obsolete
  825. stm >> strFontLegacy; // obsolete
  826. }
  827. stm >> m_strCommand;
  828. stm >> m_dwFlags;
  829. switch (m_eConsoleTaskType)
  830. {
  831. case eTask_Scope:
  832. stm >> m_bmScopeNode;
  833. break;
  834. case eTask_CommandLine:
  835. stm >> m_strDirectory;
  836. // ugly hackery required to extract directly into an enum
  837. stm >> *((int *) &m_eWindowState);
  838. stm >> m_strParameters;
  839. break;
  840. case eTask_Favorite:
  841. hr = m_memento.Read(stm);
  842. if(FAILED(hr))
  843. return hr;
  844. break;
  845. }
  846. hr = S_OK;
  847. }
  848. catch (_com_error& err)
  849. {
  850. hr = err.Error();
  851. ASSERT (false && "Caught _com_error");
  852. }
  853. }
  854. return (hr);
  855. }
  856. /*+-------------------------------------------------------------------------*
  857. * CConsoleTaskpad::CConsoleTaskpad
  858. *
  859. *
  860. *--------------------------------------------------------------------------*/
  861. CConsoleTaskpad::CConsoleTaskpad (CNode* pTargetNode /*=NULL*/) :
  862. m_listSize(eSize_Default), // the default space given to a taskpad.
  863. m_guidNodeType(GUID_NULL),
  864. m_guidID(GUID_NULL),
  865. m_bmTargetNode(),
  866. m_pMTNodeTarget(NULL),
  867. m_bNodeSpecific(false),
  868. m_dwOrientation(TVO_VERTICAL), // the default is a vertical taskpad for consistency with the Extended view.
  869. m_bReplacesDefaultView(true) // taskpads do not show the normal tab by default.
  870. {
  871. Retarget (pTargetNode);
  872. HRESULT hr = CoCreateGuid(&m_guidID);
  873. ASSERT(SUCCEEDED(hr));
  874. SetDirty (false);
  875. }
  876. bool
  877. CConsoleTaskpad::IsValid(CNode *pNode) const
  878. {
  879. ASSERT(pNode != NULL);
  880. if(!HasTarget())
  881. return true; // a taskpad without a target is valid for any node. $REVIEW
  882. if(!pNode)
  883. return false; // Cannot use a taskpad with a target.
  884. if(IsNodeSpecific())
  885. {
  886. // use this taskpad if it is targetted at the same node. $OPTIMIZE.
  887. return (*pNode->GetMTNode()->GetBookmark() == m_bmTargetNode);
  888. }
  889. else
  890. {
  891. GUID guid;
  892. HRESULT hr = pNode->GetNodeType(&guid);
  893. if(FAILED(hr))
  894. return false; // don't use this taskpad.
  895. return (MatchesNodeType(guid)); // use only if node types match.
  896. }
  897. }
  898. static CStr g_szTaskpadCommonHTMLTemplate;
  899. static CStr g_szVerticalTaskpadHTMLTemplate;
  900. static CStr g_szHorizontalTaskpadHTMLTemplate;
  901. static CStr g_szNoResultsTaskpadHTMLTemplate;
  902. static CStr g_szTaskHTMLTemplate;
  903. /*+-------------------------------------------------------------------------*
  904. *
  905. * ScLoadHTMLTemplate
  906. *
  907. * PURPOSE:
  908. *
  909. * PARAMETERS:
  910. * HINSTANCE hinstLibrary :
  911. * LPCTSTR szHTMLTemplateResourceName :
  912. * CStr& str :
  913. *
  914. * RETURNS:
  915. * SC
  916. *
  917. *+-------------------------------------------------------------------------*/
  918. SC
  919. ScLoadHTMLTemplate(HINSTANCE hinstLibrary, LPCTSTR szHTMLTemplateResourceName, CStr& str)
  920. {
  921. DECLARE_SC(sc, TEXT("ScLoadHTMLTemplate"));
  922. sc = ScCheckPointers(hinstLibrary, szHTMLTemplateResourceName);
  923. if(sc)
  924. return sc;
  925. HRSRC hFindRes = ::FindResource(hinstLibrary, szHTMLTemplateResourceName, RT_HTML);
  926. if(!hFindRes)
  927. return (sc = E_UNEXPECTED);
  928. DWORD dwResSize = ::SizeofResource(hinstLibrary, hFindRes);
  929. if(!dwResSize)
  930. return (sc = E_UNEXPECTED);
  931. HGLOBAL hRes = ::LoadResource(hinstLibrary, hFindRes);
  932. ASSERT(hRes);
  933. char *pvRes = (char *)::LockResource(hRes); // no need to Unlock the resource - see the SDK entry for LockResource
  934. sc = ScCheckPointers(pvRes);
  935. if(sc)
  936. return sc;
  937. std::string strTemp; // initially create an ANSI string
  938. strTemp.assign(pvRes, dwResSize);
  939. strTemp+="\0"; // null terminate it
  940. USES_CONVERSION;
  941. str = A2CT(strTemp.data());
  942. return sc;
  943. }
  944. /*+-------------------------------------------------------------------------*
  945. *
  946. * ScLoadHTMLTemplates
  947. *
  948. * PURPOSE:
  949. *
  950. * RETURNS:
  951. * SC
  952. *
  953. *+-------------------------------------------------------------------------*/
  954. SC
  955. ScLoadHTMLTemplates()
  956. {
  957. DECLARE_SC(sc, TEXT("ScLoadHTMLTemplates"));
  958. static BOOL bInitialized = false;
  959. if(bInitialized)
  960. return sc;
  961. // load the library into memory.
  962. TCHAR szBuffer[MAX_PATH];
  963. DWORD cchSize = countof(szBuffer);
  964. DWORD dwRet = ::GetModuleFileName(_Module.GetModuleInstance(), szBuffer, cchSize);
  965. if(0==dwRet)
  966. return (sc = E_UNEXPECTED);
  967. // NTRAID#NTBUG9-616478-2002/05/07-ronmart-prefast warning 53: Call to 'GetModuleFileNameW' may not zero-terminate string
  968. szBuffer[cchSize - 1] = 0;
  969. HINSTANCE hinstLibrary = ::LoadLibraryEx(szBuffer, 0, LOAD_LIBRARY_AS_DATAFILE);
  970. if(!hinstLibrary)
  971. return (sc = E_UNEXPECTED);
  972. sc = ScLoadHTMLTemplate(hinstLibrary, TEXT("CTPCOMMON.HTM"), g_szTaskpadCommonHTMLTemplate);
  973. if(sc)
  974. goto Error;
  975. sc = ScLoadHTMLTemplate(hinstLibrary, TEXT("CTPVERT.HTM"), g_szVerticalTaskpadHTMLTemplate);
  976. if(sc)
  977. goto Error;
  978. sc = ScLoadHTMLTemplate(hinstLibrary, TEXT("CTPHORIZ.HTM"), g_szHorizontalTaskpadHTMLTemplate);
  979. if(sc)
  980. goto Error;
  981. sc = ScLoadHTMLTemplate(hinstLibrary, TEXT("CTPNORESULTS.HTM"), g_szNoResultsTaskpadHTMLTemplate);
  982. if(sc)
  983. goto Error;
  984. sc = ScLoadHTMLTemplate(hinstLibrary, TEXT("CTPTASK.HTM"), g_szTaskHTMLTemplate);
  985. if(sc)
  986. goto Error;
  987. bInitialized = true;
  988. Cleanup:
  989. FreeLibrary(hinstLibrary);
  990. return sc;
  991. Error:
  992. sc = E_UNEXPECTED;
  993. goto Cleanup;
  994. }
  995. /*+-------------------------------------------------------------------------*
  996. *
  997. * CConsoleTaskpad::ScGetHTML
  998. *
  999. * PURPOSE:
  1000. *
  1001. * PARAMETERS:
  1002. * CStr & strTaskpadHTML :
  1003. *
  1004. * RETURNS:
  1005. * SC
  1006. *
  1007. *+-------------------------------------------------------------------------*/
  1008. SC
  1009. CConsoleTaskpad::ScGetHTML(CStr &strTaskpadHTML) const
  1010. {
  1011. DECLARE_SC(sc, TEXT("CConsoleTaskpad::ScGetHTML"));
  1012. sc = ScLoadHTMLTemplates();
  1013. if(sc)
  1014. return sc;
  1015. CStr strTasksHTML;
  1016. // get the HTML for all the tasks
  1017. for (TaskConstIter it = m_Tasks.begin(); it != m_Tasks.end(); ++it)
  1018. {
  1019. CStr strTemp;
  1020. sc = it->ScGetHTML(g_szTaskHTMLTemplate, strTemp, GetOrientation() & TVO_NO_RESULTS /*bUseLargeIcons*/, GetOrientation() & TVO_DESCRIPTIONS_AS_TEXT);
  1021. if(sc)
  1022. return sc;
  1023. strTasksHTML += strTemp;
  1024. }
  1025. strTaskpadHTML = g_szTaskpadCommonHTMLTemplate;
  1026. // append the orientation-specific portion
  1027. CStr *pstrOrientationSpecificHTML = NULL;
  1028. if(GetOrientation() & TVO_HORIZONTAL)
  1029. pstrOrientationSpecificHTML = &g_szHorizontalTaskpadHTMLTemplate;
  1030. else if (GetOrientation() & TVO_VERTICAL)
  1031. pstrOrientationSpecificHTML = &g_szVerticalTaskpadHTMLTemplate;
  1032. else
  1033. pstrOrientationSpecificHTML = &g_szNoResultsTaskpadHTMLTemplate;
  1034. sc = ScCheckPointers(pstrOrientationSpecificHTML, E_UNEXPECTED);
  1035. if(sc)
  1036. return sc;
  1037. // this replacement must be done first
  1038. sc = ScReplaceString(strTaskpadHTML, TEXT("@@ORIENTATIONSPECIFICHTML@@"), *pstrOrientationSpecificHTML);
  1039. if(sc)
  1040. return sc;
  1041. sc = ScReplaceString(strTaskpadHTML, TEXT("@@TASKS@@"), strTasksHTML);
  1042. if(sc)
  1043. return sc;
  1044. sc = ScReplaceString(strTaskpadHTML, TEXT("@@TASKWIDTH@@"), GetOrientation() & TVO_VERTICAL ? TEXT("100%") : TEXT("30%")); // only one task per row for vertical taskpads
  1045. if(sc)
  1046. return sc;
  1047. CStr strName = GetName().data();
  1048. sc = ScUseHTMLEntities(strName);
  1049. if(sc)
  1050. return sc;
  1051. CStr strDescription = GetDescription().data();
  1052. sc = ScUseHTMLEntities(strDescription);
  1053. if(sc)
  1054. return sc;
  1055. sc = ScReplaceString(strTaskpadHTML, TEXT("@@CONSOLETASKPADNAME@@"), strName);
  1056. if(sc)
  1057. return sc;
  1058. sc = ScReplaceString(strTaskpadHTML, TEXT("@@CONSOLETASKPADDESCRIPTION@@"), strDescription);
  1059. if(sc)
  1060. return sc;
  1061. if (GetOrientation() & TVO_VERTICAL)
  1062. {
  1063. // small, medium and large list sizes correspond to taskpad areas of 262, 212, and 166 pixels respectively
  1064. CStr strLeftPaneWidth;
  1065. if(GetListSize()==eSize_Small)
  1066. strLeftPaneWidth=TEXT("262");
  1067. if(GetListSize()==eSize_Medium)
  1068. strLeftPaneWidth=TEXT("212");
  1069. if(GetListSize()==eSize_Large)
  1070. strLeftPaneWidth=TEXT("166");
  1071. sc = ScReplaceString(strTaskpadHTML, TEXT("@@LEFTPANEWIDTH@@"), strLeftPaneWidth);
  1072. if(sc)
  1073. return sc;
  1074. }
  1075. else if (GetOrientation() & TVO_HORIZONTAL)
  1076. {
  1077. // small, medium and large list sizes correspond to taskpad heights of 200, 150, and 100 pixels respectively
  1078. CStr strBottomPaneHeight;
  1079. if(GetListSize()==eSize_Small)
  1080. strBottomPaneHeight=TEXT("200");
  1081. if(GetListSize()==eSize_Medium)
  1082. strBottomPaneHeight=TEXT("150");
  1083. if(GetListSize()==eSize_Large)
  1084. strBottomPaneHeight=TEXT("100");
  1085. sc = ScReplaceString(strTaskpadHTML, TEXT("@@BOTTOMPANEHEIGHT@@"), strBottomPaneHeight);
  1086. if(sc)
  1087. return sc;
  1088. }
  1089. return sc;
  1090. }
  1091. /*+-------------------------------------------------------------------------*
  1092. *
  1093. * CConsoleTaskpad::Reset
  1094. *
  1095. * PURPOSE:
  1096. *
  1097. * RETURNS:
  1098. * void
  1099. *
  1100. *+-------------------------------------------------------------------------*/
  1101. void
  1102. CConsoleTaskpad::ResetUI()
  1103. {
  1104. // reset all the contained tasks.
  1105. for (TaskIter iter = BeginTask(); iter!=EndTask(); ++iter)
  1106. {
  1107. iter->ResetUI();
  1108. }
  1109. // reset the member bookmark
  1110. m_bmTargetNode.ResetUI();
  1111. }
  1112. /*+-------------------------------------------------------------------------*
  1113. * CConsoleTaskpad::Retarget
  1114. *
  1115. *
  1116. *--------------------------------------------------------------------------*/
  1117. bool CConsoleTaskpad::Retarget (CMTNode* pMTNewNode, bool fReset)
  1118. {
  1119. /*
  1120. * if we were given a new node...
  1121. */
  1122. if (pMTNewNode != NULL)
  1123. {
  1124. // Ensure the MTNode is initialized.
  1125. if (!pMTNewNode->IsInitialized())
  1126. {
  1127. HRESULT hr = pMTNewNode->Init();
  1128. ASSERT(SUCCEEDED(hr));
  1129. }
  1130. /*
  1131. * ...if we've already been targeted to a particular node
  1132. * type, prevent retargeting to a different node type
  1133. */
  1134. if ( (!fReset) && (m_guidNodeType != GUID_NULL))
  1135. {
  1136. GUID guidNewNodeType;
  1137. pMTNewNode->GetNodeType (&guidNewNodeType);
  1138. if (guidNewNodeType != m_guidNodeType)
  1139. return (false);
  1140. }
  1141. /*
  1142. * otherwise, this is the first non-NULL node we've been
  1143. * targeted to; get its node type
  1144. */
  1145. else
  1146. pMTNewNode->GetNodeType (&m_guidNodeType);
  1147. /*
  1148. * If this is a new taskpad, default the taskpad's name
  1149. * to the target node's display name. The taskpad
  1150. * description and tooltip default to empty.
  1151. */
  1152. if (m_strName.str().empty() || fReset)
  1153. {
  1154. m_strName = pMTNewNode->GetDisplayName();
  1155. ASSERT (m_strDescription.str().empty());
  1156. ASSERT (m_strTooltip.str().empty());
  1157. }
  1158. }
  1159. m_bmTargetNode.ScRetarget(pMTNewNode, false /*bFastRetrievalOnly*/);
  1160. m_pMTNodeTarget = pMTNewNode;
  1161. SetDirty ();
  1162. return (true);
  1163. }
  1164. bool CConsoleTaskpad::Retarget (CNode* pNewNode)
  1165. {
  1166. CMTNode* pMTNewNode = (pNewNode != NULL) ? pNewNode->GetMTNode() : NULL;
  1167. return (Retarget (pMTNewNode));
  1168. }
  1169. /*+-------------------------------------------------------------------------*
  1170. * CConsoleTaskpad::SetName
  1171. *
  1172. *
  1173. *--------------------------------------------------------------------------*/
  1174. void CConsoleTaskpad::SetName (const tstring& strName)
  1175. {
  1176. SetStringMember (m_strName, strName);
  1177. }
  1178. /*+-------------------------------------------------------------------------*
  1179. * CConsoleTaskpad::SetDescription
  1180. *
  1181. *
  1182. *--------------------------------------------------------------------------*/
  1183. void CConsoleTaskpad::SetDescription (const tstring& strDescription)
  1184. {
  1185. SetStringMember (m_strDescription, strDescription);
  1186. }
  1187. void CConsoleTaskpad::SetListSize(const ListSize listSize)
  1188. {
  1189. m_listSize = listSize;
  1190. SetDirty();
  1191. }
  1192. /*+-------------------------------------------------------------------------*
  1193. * CConsoleTaskpad::SetToolTip
  1194. *
  1195. *
  1196. *--------------------------------------------------------------------------*/
  1197. void CConsoleTaskpad::SetToolTip (const tstring& strTooltip)
  1198. {
  1199. SetStringMember (m_strTooltip, strTooltip);
  1200. }
  1201. void
  1202. CConsoleTaskpad::SetNodeSpecific (bool bNodeSpecific)
  1203. {
  1204. m_bNodeSpecific = bNodeSpecific;
  1205. SetDirty();
  1206. }
  1207. void
  1208. CConsoleTaskpad::SetReplacesDefaultView(bool bReplacesDefaultView)
  1209. {
  1210. m_bReplacesDefaultView = bReplacesDefaultView;
  1211. SetDirty();
  1212. }
  1213. /*+-------------------------------------------------------------------------*
  1214. * CConsoleTaskpad::SetStringMember
  1215. *
  1216. * Changes the value of a string member variable, and marks the taskpad
  1217. * dirty, if and only if the new value is different than the old value.
  1218. *--------------------------------------------------------------------------*/
  1219. void CConsoleTaskpad::SetStringMember (
  1220. CStringTableString& strMember,
  1221. const tstring& strNewValue)
  1222. {
  1223. if (strMember != strNewValue)
  1224. {
  1225. strMember = strNewValue;
  1226. SetDirty ();
  1227. }
  1228. }
  1229. /*+-------------------------------------------------------------------------*
  1230. * CConsoleTaskpad::AddTask
  1231. *
  1232. *
  1233. *--------------------------------------------------------------------------*/
  1234. CConsoleTaskpad::TaskIter
  1235. CConsoleTaskpad::AddTask (const CConsoleTask& task)
  1236. {
  1237. return (InsertTask (m_Tasks.end(), task));
  1238. }
  1239. /*+-------------------------------------------------------------------------*
  1240. * CConsoleTaskpad::InsertTask
  1241. *
  1242. *
  1243. *--------------------------------------------------------------------------*/
  1244. CConsoleTaskpad::TaskIter
  1245. CConsoleTaskpad::InsertTask (
  1246. TaskIter itTaskBeforeWhichToInsert,
  1247. const CConsoleTask& task)
  1248. {
  1249. TaskIter itInserted = m_Tasks.insert (itTaskBeforeWhichToInsert, task);
  1250. SetDirty ();
  1251. return (itInserted);
  1252. }
  1253. /*+-------------------------------------------------------------------------*
  1254. * CConsoleTaskpad::EraseTask
  1255. *
  1256. *
  1257. *--------------------------------------------------------------------------*/
  1258. CConsoleTaskpad::TaskIter
  1259. CConsoleTaskpad::EraseTask (
  1260. TaskIter itErase)
  1261. {
  1262. SetDirty ();
  1263. return (m_Tasks.erase (itErase));
  1264. }
  1265. /*+-------------------------------------------------------------------------*
  1266. * CConsoleTaskpad::EraseTasks
  1267. *
  1268. *
  1269. *--------------------------------------------------------------------------*/
  1270. CConsoleTaskpad::TaskIter
  1271. CConsoleTaskpad::EraseTasks (
  1272. TaskIter itFirst,
  1273. TaskIter itLast)
  1274. {
  1275. SetDirty ();
  1276. return (m_Tasks.erase (itFirst, itLast));
  1277. }
  1278. /*+-------------------------------------------------------------------------*
  1279. * CConsoleTaskpad::ClearTasks
  1280. *
  1281. *
  1282. *--------------------------------------------------------------------------*/
  1283. void CConsoleTaskpad::ClearTasks ()
  1284. {
  1285. SetDirty ();
  1286. m_Tasks.clear ();
  1287. }
  1288. /*+-------------------------------------------------------------------------*
  1289. * CConsoleTaskpad::IsDirty
  1290. *
  1291. * Determines if this taskpad or any of its contained tasks is are dirty.
  1292. *--------------------------------------------------------------------------*/
  1293. bool CConsoleTaskpad::IsDirty () const
  1294. {
  1295. /*
  1296. * if the taskpad is dirty, short out
  1297. */
  1298. if (m_fDirty)
  1299. {
  1300. TraceDirtyFlag(TEXT("CConsoleTaskpad"), true);
  1301. return (true);
  1302. }
  1303. /*
  1304. * the taskpad is clean, check each task
  1305. */
  1306. for (TaskConstIter it = m_Tasks.begin(); it != m_Tasks.end(); ++it)
  1307. {
  1308. if (it->IsDirty())
  1309. {
  1310. TraceDirtyFlag(TEXT("CConsoleTaskpad"), true);
  1311. return (true);
  1312. }
  1313. }
  1314. TraceDirtyFlag(TEXT("CConsoleTaskpad"), false);
  1315. return (false);
  1316. }
  1317. /*+-------------------------------------------------------------------------*
  1318. * CConsoleTaskpad::GetTargetMTNode
  1319. *
  1320. *
  1321. *--------------------------------------------------------------------------*/
  1322. CMTNode* CConsoleTaskpad::GetTargetMTNode (IScopeTree* pScopeTree)
  1323. {
  1324. DECLARE_SC(sc, TEXT("CConsoleTaskpad::GetTargetMTNode"));
  1325. if(!HasTarget())
  1326. return NULL;
  1327. if(!m_pMTNodeTarget)
  1328. {
  1329. CMTNode *pMTNode = NULL;
  1330. bool bExactMatchFound = false; // out value from ScGetMTNode, unused
  1331. sc = m_bmTargetNode.ScGetMTNode(true /*bExactMatchRequired*/, &pMTNode, bExactMatchFound);
  1332. if(sc.IsError() || !pMTNode)
  1333. return NULL;
  1334. m_pMTNodeTarget = pMTNode;
  1335. }
  1336. return (m_pMTNodeTarget);
  1337. }
  1338. /*+-------------------------------------------------------------------------*
  1339. *
  1340. * CConsoleTaskpad::Persist
  1341. *
  1342. * PURPOSE: Persists the console taskpad to the specified persistor.
  1343. *
  1344. * PARAMETERS:
  1345. * CPersistor & persistor :
  1346. *
  1347. * RETURNS:
  1348. * void
  1349. *
  1350. *+-------------------------------------------------------------------------*/
  1351. void
  1352. CConsoleTaskpad::Persist(CPersistor &persistor)
  1353. {
  1354. persistor.PersistString(XML_ATTR_TASKPAD_NAME, m_strName);
  1355. persistor.PersistString(XML_ATTR_TASKPAD_DESCRIPTION, m_strDescription);
  1356. persistor.PersistString(XML_ATTR_TASKPAD_TOOLTIP, m_strTooltip);
  1357. // define the table to map enumeration values to strings
  1358. static const EnumLiteral mappedSize[] =
  1359. {
  1360. { eSize_Large, XML_ENUM_LIST_SIZE_LARGE },
  1361. { eSize_Medium, XML_ENUM_LIST_SIZE_MEDIUM },
  1362. { eSize_None, XML_ENUM_LIST_SIZE_NONE },
  1363. { eSize_Small, XML_ENUM_LIST_SIZE_SMALL },
  1364. };
  1365. // create wrapper to persist flag values as strings
  1366. CXMLEnumeration listSizePersistor(m_listSize, mappedSize, countof(mappedSize));
  1367. // initialize the value suitably
  1368. if(persistor.IsLoading())
  1369. m_listSize = eSize_Default;
  1370. // persist the wrapper
  1371. persistor.PersistAttribute(XML_ATTR_TASKPAD_LIST_SIZE, listSizePersistor, attr_optional); // optional because this was introduced late
  1372. persistor.PersistAttribute(XML_ATTR_TASKPAD_NODE_SPECIFIC, CXMLBoolean(m_bNodeSpecific));
  1373. persistor.PersistAttribute(XML_ATTR_REPLACES_DEFAULT_VIEW, CXMLBoolean(m_bReplacesDefaultView), attr_optional);
  1374. // define the table to map enumeration values to strings
  1375. static const EnumLiteral mappedOrientation[] =
  1376. {
  1377. { TVO_HORIZONTAL, XML_BITFLAG_TASK_ORIENT_HORIZONTAL },
  1378. { TVO_VERTICAL, XML_BITFLAG_TASK_ORIENT_VERTICAL },
  1379. { TVO_NO_RESULTS, XML_BITFLAG_TASK_ORIENT_NO_RESULTS },
  1380. { TVO_DESCRIPTIONS_AS_TEXT, XML_BITFLAG_TASK_ORIENT_DESCRIPTIONS_AS_TEXT },
  1381. };
  1382. // create wrapper to persist flag values as strings
  1383. CXMLBitFlags orientationPersistor(m_dwOrientation, mappedOrientation, countof(mappedOrientation));
  1384. // persist the wrapper
  1385. persistor.PersistAttribute(XML_ATTR_TASKPAD_ORIENTATION, orientationPersistor );
  1386. persistor.Persist(m_Tasks);
  1387. persistor.PersistAttribute(XML_ATTR_TASKPAD_NODE_TYPE, m_guidNodeType);
  1388. persistor.PersistAttribute(XML_ATTR_TASKPAD_ID, m_guidID);
  1389. persistor.Persist(m_bmTargetNode, XML_NAME_TARGET_NODE);
  1390. // either read or saved - not dirty after the operation
  1391. SetDirty(false);
  1392. }
  1393. /*+-------------------------------------------------------------------------*
  1394. * CConsoleTaskpad::ReadSerialObject
  1395. *
  1396. *
  1397. *--------------------------------------------------------------------------*/
  1398. HRESULT
  1399. CConsoleTaskpad::ReadSerialObject (IStream &stm, UINT nVersion)
  1400. {
  1401. HRESULT hr = S_FALSE; // assume unknown version
  1402. if(nVersion==1)
  1403. {
  1404. try
  1405. {
  1406. do // not a loop
  1407. {
  1408. bool fLegacyHasTarget = true; // an unused field
  1409. UINT visualPercent = 25; // replaced by m_listSize
  1410. stm >> m_strName;
  1411. stm >> m_strDescription;
  1412. stm >> m_strTooltip;
  1413. stm >> visualPercent;
  1414. m_listSize = eSize_Medium;
  1415. if(visualPercent==25)
  1416. m_listSize = eSize_Large;
  1417. else if(visualPercent==75)
  1418. m_listSize = eSize_Small;
  1419. stm >> m_bNodeSpecific;
  1420. m_bReplacesDefaultView = false; // this was introduced in mmc2.0.
  1421. stm >> m_dwOrientation;
  1422. hr = ::Read(stm, m_Tasks);
  1423. BREAK_ON_FAIL (hr);
  1424. stm >> m_guidNodeType;
  1425. stm >> m_guidID;
  1426. stm >> fLegacyHasTarget;
  1427. stm >> m_bmTargetNode;
  1428. // legacy task symbol info
  1429. {
  1430. BOOL bLegacyUseMMCSymbols = TRUE; // a now obsolete field, read for console file compatibility
  1431. tstring strFileLegacy, strFontLegacy;
  1432. DWORD dwSymbol = 0;
  1433. stm >> dwSymbol;
  1434. stm >> bLegacyUseMMCSymbols;
  1435. stm >> strFileLegacy; // obsolete
  1436. stm >> strFontLegacy; // obsolete
  1437. }
  1438. hr = S_OK; // success!
  1439. } while (false);
  1440. }
  1441. catch (_com_error& err)
  1442. {
  1443. hr = err.Error();
  1444. ASSERT (false && "Caught _com_error");
  1445. }
  1446. }
  1447. return (hr);
  1448. }
  1449. //############################################################################
  1450. //############################################################################
  1451. //
  1452. // Implementation of class CConsoleTaskpadList
  1453. //
  1454. //############################################################################
  1455. //############################################################################
  1456. /*+-------------------------------------------------------------------------*
  1457. *
  1458. * CConsoleTaskpadList::ScGetTaskpadList
  1459. *
  1460. * PURPOSE: Returns the list of all taskpads that are appropriate for the current node.
  1461. *
  1462. * PARAMETERS:
  1463. * CNode * pNode :
  1464. * CConsoleTaskpadFilteredList & filteredList : [OUT]: The list of taskpads
  1465. *
  1466. * RETURNS:
  1467. * SC
  1468. *
  1469. *+-------------------------------------------------------------------------*/
  1470. SC
  1471. CConsoleTaskpadList::ScGetTaskpadList(CNode *pNode, CConsoleTaskpadFilteredList &filteredList)
  1472. {
  1473. DECLARE_SC(sc, TEXT("CConsoleTaskpadList::ScGetTaskpadList"));
  1474. sc = ScCheckPointers(pNode);
  1475. if(sc)
  1476. return sc;
  1477. // 1. add all built- in taskpads
  1478. for(iterator iter = begin(); iter != end(); ++iter)
  1479. {
  1480. CConsoleTaskpad *pConsoleTaskpad = &*iter;
  1481. if(pConsoleTaskpad->IsValid(pNode))
  1482. {
  1483. filteredList.push_back(pConsoleTaskpad);
  1484. }
  1485. }
  1486. return sc;
  1487. }
  1488. HRESULT
  1489. CConsoleTaskpadList::ReadSerialObject (IStream &stm, UINT nVersion)
  1490. {
  1491. HRESULT hr = S_FALSE; // assume unknown version
  1492. clear();
  1493. if(nVersion == 1)
  1494. {
  1495. try
  1496. {
  1497. DWORD cItems;
  1498. stm >> cItems;
  1499. for(int i=0; i< cItems; i++)
  1500. {
  1501. CConsoleTaskpad taskpad;
  1502. hr = taskpad.Read(stm);
  1503. BREAK_ON_FAIL (hr);
  1504. push_back(taskpad);
  1505. }
  1506. }
  1507. catch (_com_error& err)
  1508. {
  1509. hr = err.Error();
  1510. ASSERT (false && "Caught _com_error");
  1511. }
  1512. }
  1513. return hr;
  1514. }
  1515. //############################################################################
  1516. //############################################################################
  1517. //
  1518. // Implementation of class CDefaultTaskpadList
  1519. //
  1520. //############################################################################
  1521. //############################################################################
  1522. HRESULT
  1523. CDefaultTaskpadList::ReadSerialObject (IStream &stm, UINT nVersion)
  1524. {
  1525. HRESULT hr = S_FALSE; // assume unknown version
  1526. clear();
  1527. if(nVersion == 1)
  1528. {
  1529. try
  1530. {
  1531. /*
  1532. * TODO: investigate using template operator>> for a map (stgio.h)
  1533. */
  1534. DWORD cItems;
  1535. stm >> cItems;
  1536. for(int i=0; i< cItems; i++)
  1537. {
  1538. GUID guidNodetype, guidTaskpad;
  1539. stm >> guidNodetype;
  1540. stm >> guidTaskpad;
  1541. operator[](guidNodetype) = guidTaskpad;
  1542. }
  1543. hr = S_OK;
  1544. }
  1545. catch (_com_error& err)
  1546. {
  1547. hr = err.Error();
  1548. ASSERT (false && "Caught _com_error");
  1549. }
  1550. }
  1551. return hr;
  1552. }