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.

1864 lines
50 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. ::GetModuleFileName (_Module.GetModuleInstance(), szBuffer, countof (szBuffer));
  964. HINSTANCE hinstLibrary = ::LoadLibraryEx(szBuffer, 0, LOAD_LIBRARY_AS_DATAFILE);
  965. if(!hinstLibrary)
  966. return (sc = E_UNEXPECTED);
  967. sc = ScLoadHTMLTemplate(hinstLibrary, TEXT("CTPCOMMON.HTM"), g_szTaskpadCommonHTMLTemplate);
  968. if(sc)
  969. goto Error;
  970. sc = ScLoadHTMLTemplate(hinstLibrary, TEXT("CTPVERT.HTM"), g_szVerticalTaskpadHTMLTemplate);
  971. if(sc)
  972. goto Error;
  973. sc = ScLoadHTMLTemplate(hinstLibrary, TEXT("CTPHORIZ.HTM"), g_szHorizontalTaskpadHTMLTemplate);
  974. if(sc)
  975. goto Error;
  976. sc = ScLoadHTMLTemplate(hinstLibrary, TEXT("CTPNORESULTS.HTM"), g_szNoResultsTaskpadHTMLTemplate);
  977. if(sc)
  978. goto Error;
  979. sc = ScLoadHTMLTemplate(hinstLibrary, TEXT("CTPTASK.HTM"), g_szTaskHTMLTemplate);
  980. if(sc)
  981. goto Error;
  982. bInitialized = true;
  983. Cleanup:
  984. FreeLibrary(hinstLibrary);
  985. return sc;
  986. Error:
  987. sc = E_UNEXPECTED;
  988. goto Cleanup;
  989. }
  990. /*+-------------------------------------------------------------------------*
  991. *
  992. * CConsoleTaskpad::ScGetHTML
  993. *
  994. * PURPOSE:
  995. *
  996. * PARAMETERS:
  997. * CStr & strTaskpadHTML :
  998. *
  999. * RETURNS:
  1000. * SC
  1001. *
  1002. *+-------------------------------------------------------------------------*/
  1003. SC
  1004. CConsoleTaskpad::ScGetHTML(CStr &strTaskpadHTML) const
  1005. {
  1006. DECLARE_SC(sc, TEXT("CConsoleTaskpad::ScGetHTML"));
  1007. sc = ScLoadHTMLTemplates();
  1008. if(sc)
  1009. return sc;
  1010. CStr strTasksHTML;
  1011. // get the HTML for all the tasks
  1012. for (TaskConstIter it = m_Tasks.begin(); it != m_Tasks.end(); ++it)
  1013. {
  1014. CStr strTemp;
  1015. sc = it->ScGetHTML(g_szTaskHTMLTemplate, strTemp, GetOrientation() & TVO_NO_RESULTS /*bUseLargeIcons*/, GetOrientation() & TVO_DESCRIPTIONS_AS_TEXT);
  1016. if(sc)
  1017. return sc;
  1018. strTasksHTML += strTemp;
  1019. }
  1020. strTaskpadHTML = g_szTaskpadCommonHTMLTemplate;
  1021. // append the orientation-specific portion
  1022. CStr *pstrOrientationSpecificHTML = NULL;
  1023. if(GetOrientation() & TVO_HORIZONTAL)
  1024. pstrOrientationSpecificHTML = &g_szHorizontalTaskpadHTMLTemplate;
  1025. else if (GetOrientation() & TVO_VERTICAL)
  1026. pstrOrientationSpecificHTML = &g_szVerticalTaskpadHTMLTemplate;
  1027. else
  1028. pstrOrientationSpecificHTML = &g_szNoResultsTaskpadHTMLTemplate;
  1029. sc = ScCheckPointers(pstrOrientationSpecificHTML, E_UNEXPECTED);
  1030. if(sc)
  1031. return sc;
  1032. // this replacement must be done first
  1033. sc = ScReplaceString(strTaskpadHTML, TEXT("@@ORIENTATIONSPECIFICHTML@@"), *pstrOrientationSpecificHTML);
  1034. if(sc)
  1035. return sc;
  1036. sc = ScReplaceString(strTaskpadHTML, TEXT("@@TASKS@@"), strTasksHTML);
  1037. if(sc)
  1038. return sc;
  1039. sc = ScReplaceString(strTaskpadHTML, TEXT("@@TASKWIDTH@@"), GetOrientation() & TVO_VERTICAL ? TEXT("100%") : TEXT("30%")); // only one task per row for vertical taskpads
  1040. if(sc)
  1041. return sc;
  1042. CStr strName = GetName().data();
  1043. sc = ScUseHTMLEntities(strName);
  1044. if(sc)
  1045. return sc;
  1046. CStr strDescription = GetDescription().data();
  1047. sc = ScUseHTMLEntities(strDescription);
  1048. if(sc)
  1049. return sc;
  1050. sc = ScReplaceString(strTaskpadHTML, TEXT("@@CONSOLETASKPADNAME@@"), strName);
  1051. if(sc)
  1052. return sc;
  1053. sc = ScReplaceString(strTaskpadHTML, TEXT("@@CONSOLETASKPADDESCRIPTION@@"), strDescription);
  1054. if(sc)
  1055. return sc;
  1056. if (GetOrientation() & TVO_VERTICAL)
  1057. {
  1058. // small, medium and large list sizes correspond to taskpad areas of 262, 212, and 166 pixels respectively
  1059. CStr strLeftPaneWidth;
  1060. if(GetListSize()==eSize_Small)
  1061. strLeftPaneWidth=TEXT("262");
  1062. if(GetListSize()==eSize_Medium)
  1063. strLeftPaneWidth=TEXT("212");
  1064. if(GetListSize()==eSize_Large)
  1065. strLeftPaneWidth=TEXT("166");
  1066. sc = ScReplaceString(strTaskpadHTML, TEXT("@@LEFTPANEWIDTH@@"), strLeftPaneWidth);
  1067. if(sc)
  1068. return sc;
  1069. }
  1070. else if (GetOrientation() & TVO_HORIZONTAL)
  1071. {
  1072. // small, medium and large list sizes correspond to taskpad heights of 200, 150, and 100 pixels respectively
  1073. CStr strBottomPaneHeight;
  1074. if(GetListSize()==eSize_Small)
  1075. strBottomPaneHeight=TEXT("200");
  1076. if(GetListSize()==eSize_Medium)
  1077. strBottomPaneHeight=TEXT("150");
  1078. if(GetListSize()==eSize_Large)
  1079. strBottomPaneHeight=TEXT("100");
  1080. sc = ScReplaceString(strTaskpadHTML, TEXT("@@BOTTOMPANEHEIGHT@@"), strBottomPaneHeight);
  1081. if(sc)
  1082. return sc;
  1083. }
  1084. return sc;
  1085. }
  1086. /*+-------------------------------------------------------------------------*
  1087. *
  1088. * CConsoleTaskpad::Reset
  1089. *
  1090. * PURPOSE:
  1091. *
  1092. * RETURNS:
  1093. * void
  1094. *
  1095. *+-------------------------------------------------------------------------*/
  1096. void
  1097. CConsoleTaskpad::ResetUI()
  1098. {
  1099. // reset all the contained tasks.
  1100. for (TaskIter iter = BeginTask(); iter!=EndTask(); ++iter)
  1101. {
  1102. iter->ResetUI();
  1103. }
  1104. // reset the member bookmark
  1105. m_bmTargetNode.ResetUI();
  1106. }
  1107. /*+-------------------------------------------------------------------------*
  1108. * CConsoleTaskpad::Retarget
  1109. *
  1110. *
  1111. *--------------------------------------------------------------------------*/
  1112. bool CConsoleTaskpad::Retarget (CMTNode* pMTNewNode, bool fReset)
  1113. {
  1114. /*
  1115. * if we were given a new node...
  1116. */
  1117. if (pMTNewNode != NULL)
  1118. {
  1119. // Ensure the MTNode is initialized.
  1120. if (!pMTNewNode->IsInitialized())
  1121. {
  1122. HRESULT hr = pMTNewNode->Init();
  1123. ASSERT(SUCCEEDED(hr));
  1124. }
  1125. /*
  1126. * ...if we've already been targeted to a particular node
  1127. * type, prevent retargeting to a different node type
  1128. */
  1129. if ( (!fReset) && (m_guidNodeType != GUID_NULL))
  1130. {
  1131. GUID guidNewNodeType;
  1132. pMTNewNode->GetNodeType (&guidNewNodeType);
  1133. if (guidNewNodeType != m_guidNodeType)
  1134. return (false);
  1135. }
  1136. /*
  1137. * otherwise, this is the first non-NULL node we've been
  1138. * targeted to; get its node type
  1139. */
  1140. else
  1141. pMTNewNode->GetNodeType (&m_guidNodeType);
  1142. /*
  1143. * If this is a new taskpad, default the taskpad's name
  1144. * to the target node's display name. The taskpad
  1145. * description and tooltip default to empty.
  1146. */
  1147. if (m_strName.str().empty() || fReset)
  1148. {
  1149. m_strName = pMTNewNode->GetDisplayName();
  1150. ASSERT (m_strDescription.str().empty());
  1151. ASSERT (m_strTooltip.str().empty());
  1152. }
  1153. }
  1154. m_bmTargetNode.ScRetarget(pMTNewNode, false /*bFastRetrievalOnly*/);
  1155. m_pMTNodeTarget = pMTNewNode;
  1156. SetDirty ();
  1157. return (true);
  1158. }
  1159. bool CConsoleTaskpad::Retarget (CNode* pNewNode)
  1160. {
  1161. CMTNode* pMTNewNode = (pNewNode != NULL) ? pNewNode->GetMTNode() : NULL;
  1162. return (Retarget (pMTNewNode));
  1163. }
  1164. /*+-------------------------------------------------------------------------*
  1165. * CConsoleTaskpad::SetName
  1166. *
  1167. *
  1168. *--------------------------------------------------------------------------*/
  1169. void CConsoleTaskpad::SetName (const tstring& strName)
  1170. {
  1171. SetStringMember (m_strName, strName);
  1172. }
  1173. /*+-------------------------------------------------------------------------*
  1174. * CConsoleTaskpad::SetDescription
  1175. *
  1176. *
  1177. *--------------------------------------------------------------------------*/
  1178. void CConsoleTaskpad::SetDescription (const tstring& strDescription)
  1179. {
  1180. SetStringMember (m_strDescription, strDescription);
  1181. }
  1182. void CConsoleTaskpad::SetListSize(const ListSize listSize)
  1183. {
  1184. m_listSize = listSize;
  1185. SetDirty();
  1186. }
  1187. /*+-------------------------------------------------------------------------*
  1188. * CConsoleTaskpad::SetToolTip
  1189. *
  1190. *
  1191. *--------------------------------------------------------------------------*/
  1192. void CConsoleTaskpad::SetToolTip (const tstring& strTooltip)
  1193. {
  1194. SetStringMember (m_strTooltip, strTooltip);
  1195. }
  1196. void
  1197. CConsoleTaskpad::SetNodeSpecific (bool bNodeSpecific)
  1198. {
  1199. m_bNodeSpecific = bNodeSpecific;
  1200. SetDirty();
  1201. }
  1202. void
  1203. CConsoleTaskpad::SetReplacesDefaultView(bool bReplacesDefaultView)
  1204. {
  1205. m_bReplacesDefaultView = bReplacesDefaultView;
  1206. SetDirty();
  1207. }
  1208. /*+-------------------------------------------------------------------------*
  1209. * CConsoleTaskpad::SetStringMember
  1210. *
  1211. * Changes the value of a string member variable, and marks the taskpad
  1212. * dirty, if and only if the new value is different than the old value.
  1213. *--------------------------------------------------------------------------*/
  1214. void CConsoleTaskpad::SetStringMember (
  1215. CStringTableString& strMember,
  1216. const tstring& strNewValue)
  1217. {
  1218. if (strMember != strNewValue)
  1219. {
  1220. strMember = strNewValue;
  1221. SetDirty ();
  1222. }
  1223. }
  1224. /*+-------------------------------------------------------------------------*
  1225. * CConsoleTaskpad::AddTask
  1226. *
  1227. *
  1228. *--------------------------------------------------------------------------*/
  1229. CConsoleTaskpad::TaskIter
  1230. CConsoleTaskpad::AddTask (const CConsoleTask& task)
  1231. {
  1232. return (InsertTask (m_Tasks.end(), task));
  1233. }
  1234. /*+-------------------------------------------------------------------------*
  1235. * CConsoleTaskpad::InsertTask
  1236. *
  1237. *
  1238. *--------------------------------------------------------------------------*/
  1239. CConsoleTaskpad::TaskIter
  1240. CConsoleTaskpad::InsertTask (
  1241. TaskIter itTaskBeforeWhichToInsert,
  1242. const CConsoleTask& task)
  1243. {
  1244. TaskIter itInserted = m_Tasks.insert (itTaskBeforeWhichToInsert, task);
  1245. SetDirty ();
  1246. return (itInserted);
  1247. }
  1248. /*+-------------------------------------------------------------------------*
  1249. * CConsoleTaskpad::EraseTask
  1250. *
  1251. *
  1252. *--------------------------------------------------------------------------*/
  1253. CConsoleTaskpad::TaskIter
  1254. CConsoleTaskpad::EraseTask (
  1255. TaskIter itErase)
  1256. {
  1257. SetDirty ();
  1258. return (m_Tasks.erase (itErase));
  1259. }
  1260. /*+-------------------------------------------------------------------------*
  1261. * CConsoleTaskpad::EraseTasks
  1262. *
  1263. *
  1264. *--------------------------------------------------------------------------*/
  1265. CConsoleTaskpad::TaskIter
  1266. CConsoleTaskpad::EraseTasks (
  1267. TaskIter itFirst,
  1268. TaskIter itLast)
  1269. {
  1270. SetDirty ();
  1271. return (m_Tasks.erase (itFirst, itLast));
  1272. }
  1273. /*+-------------------------------------------------------------------------*
  1274. * CConsoleTaskpad::ClearTasks
  1275. *
  1276. *
  1277. *--------------------------------------------------------------------------*/
  1278. void CConsoleTaskpad::ClearTasks ()
  1279. {
  1280. SetDirty ();
  1281. m_Tasks.clear ();
  1282. }
  1283. /*+-------------------------------------------------------------------------*
  1284. * CConsoleTaskpad::IsDirty
  1285. *
  1286. * Determines if this taskpad or any of its contained tasks is are dirty.
  1287. *--------------------------------------------------------------------------*/
  1288. bool CConsoleTaskpad::IsDirty () const
  1289. {
  1290. /*
  1291. * if the taskpad is dirty, short out
  1292. */
  1293. if (m_fDirty)
  1294. {
  1295. TraceDirtyFlag(TEXT("CConsoleTaskpad"), true);
  1296. return (true);
  1297. }
  1298. /*
  1299. * the taskpad is clean, check each task
  1300. */
  1301. for (TaskConstIter it = m_Tasks.begin(); it != m_Tasks.end(); ++it)
  1302. {
  1303. if (it->IsDirty())
  1304. {
  1305. TraceDirtyFlag(TEXT("CConsoleTaskpad"), true);
  1306. return (true);
  1307. }
  1308. }
  1309. TraceDirtyFlag(TEXT("CConsoleTaskpad"), false);
  1310. return (false);
  1311. }
  1312. /*+-------------------------------------------------------------------------*
  1313. * CConsoleTaskpad::GetTargetMTNode
  1314. *
  1315. *
  1316. *--------------------------------------------------------------------------*/
  1317. CMTNode* CConsoleTaskpad::GetTargetMTNode (IScopeTree* pScopeTree)
  1318. {
  1319. DECLARE_SC(sc, TEXT("CConsoleTaskpad::GetTargetMTNode"));
  1320. if(!HasTarget())
  1321. return NULL;
  1322. if(!m_pMTNodeTarget)
  1323. {
  1324. CMTNode *pMTNode = NULL;
  1325. bool bExactMatchFound = false; // out value from ScGetMTNode, unused
  1326. sc = m_bmTargetNode.ScGetMTNode(true /*bExactMatchRequired*/, &pMTNode, bExactMatchFound);
  1327. if(sc.IsError() || !pMTNode)
  1328. return NULL;
  1329. m_pMTNodeTarget = pMTNode;
  1330. }
  1331. return (m_pMTNodeTarget);
  1332. }
  1333. /*+-------------------------------------------------------------------------*
  1334. *
  1335. * CConsoleTaskpad::Persist
  1336. *
  1337. * PURPOSE: Persists the console taskpad to the specified persistor.
  1338. *
  1339. * PARAMETERS:
  1340. * CPersistor & persistor :
  1341. *
  1342. * RETURNS:
  1343. * void
  1344. *
  1345. *+-------------------------------------------------------------------------*/
  1346. void
  1347. CConsoleTaskpad::Persist(CPersistor &persistor)
  1348. {
  1349. persistor.PersistString(XML_ATTR_TASKPAD_NAME, m_strName);
  1350. persistor.PersistString(XML_ATTR_TASKPAD_DESCRIPTION, m_strDescription);
  1351. persistor.PersistString(XML_ATTR_TASKPAD_TOOLTIP, m_strTooltip);
  1352. // define the table to map enumeration values to strings
  1353. static const EnumLiteral mappedSize[] =
  1354. {
  1355. { eSize_Large, XML_ENUM_LIST_SIZE_LARGE },
  1356. { eSize_Medium, XML_ENUM_LIST_SIZE_MEDIUM },
  1357. { eSize_None, XML_ENUM_LIST_SIZE_NONE },
  1358. { eSize_Small, XML_ENUM_LIST_SIZE_SMALL },
  1359. };
  1360. // create wrapper to persist flag values as strings
  1361. CXMLEnumeration listSizePersistor(m_listSize, mappedSize, countof(mappedSize));
  1362. // initialize the value suitably
  1363. if(persistor.IsLoading())
  1364. m_listSize = eSize_Default;
  1365. // persist the wrapper
  1366. persistor.PersistAttribute(XML_ATTR_TASKPAD_LIST_SIZE, listSizePersistor, attr_optional); // optional because this was introduced late
  1367. persistor.PersistAttribute(XML_ATTR_TASKPAD_NODE_SPECIFIC, CXMLBoolean(m_bNodeSpecific));
  1368. persistor.PersistAttribute(XML_ATTR_REPLACES_DEFAULT_VIEW, CXMLBoolean(m_bReplacesDefaultView), attr_optional);
  1369. // define the table to map enumeration values to strings
  1370. static const EnumLiteral mappedOrientation[] =
  1371. {
  1372. { TVO_HORIZONTAL, XML_BITFLAG_TASK_ORIENT_HORIZONTAL },
  1373. { TVO_VERTICAL, XML_BITFLAG_TASK_ORIENT_VERTICAL },
  1374. { TVO_NO_RESULTS, XML_BITFLAG_TASK_ORIENT_NO_RESULTS },
  1375. { TVO_DESCRIPTIONS_AS_TEXT, XML_BITFLAG_TASK_ORIENT_DESCRIPTIONS_AS_TEXT },
  1376. };
  1377. // create wrapper to persist flag values as strings
  1378. CXMLBitFlags orientationPersistor(m_dwOrientation, mappedOrientation, countof(mappedOrientation));
  1379. // persist the wrapper
  1380. persistor.PersistAttribute(XML_ATTR_TASKPAD_ORIENTATION, orientationPersistor );
  1381. persistor.Persist(m_Tasks);
  1382. persistor.PersistAttribute(XML_ATTR_TASKPAD_NODE_TYPE, m_guidNodeType);
  1383. persistor.PersistAttribute(XML_ATTR_TASKPAD_ID, m_guidID);
  1384. persistor.Persist(m_bmTargetNode, XML_NAME_TARGET_NODE);
  1385. // either read or saved - not dirty after the operation
  1386. SetDirty(false);
  1387. }
  1388. /*+-------------------------------------------------------------------------*
  1389. * CConsoleTaskpad::ReadSerialObject
  1390. *
  1391. *
  1392. *--------------------------------------------------------------------------*/
  1393. HRESULT
  1394. CConsoleTaskpad::ReadSerialObject (IStream &stm, UINT nVersion)
  1395. {
  1396. HRESULT hr = S_FALSE; // assume unknown version
  1397. if(nVersion==1)
  1398. {
  1399. try
  1400. {
  1401. do // not a loop
  1402. {
  1403. bool fLegacyHasTarget = true; // an unused field
  1404. UINT visualPercent = 25; // replaced by m_listSize
  1405. stm >> m_strName;
  1406. stm >> m_strDescription;
  1407. stm >> m_strTooltip;
  1408. stm >> visualPercent;
  1409. m_listSize = eSize_Medium;
  1410. if(visualPercent==25)
  1411. m_listSize = eSize_Large;
  1412. else if(visualPercent==75)
  1413. m_listSize = eSize_Small;
  1414. stm >> m_bNodeSpecific;
  1415. m_bReplacesDefaultView = false; // this was introduced in mmc2.0.
  1416. stm >> m_dwOrientation;
  1417. hr = ::Read(stm, m_Tasks);
  1418. BREAK_ON_FAIL (hr);
  1419. stm >> m_guidNodeType;
  1420. stm >> m_guidID;
  1421. stm >> fLegacyHasTarget;
  1422. stm >> m_bmTargetNode;
  1423. // legacy task symbol info
  1424. {
  1425. BOOL bLegacyUseMMCSymbols = TRUE; // a now obsolete field, read for console file compatibility
  1426. tstring strFileLegacy, strFontLegacy;
  1427. DWORD dwSymbol = 0;
  1428. stm >> dwSymbol;
  1429. stm >> bLegacyUseMMCSymbols;
  1430. stm >> strFileLegacy; // obsolete
  1431. stm >> strFontLegacy; // obsolete
  1432. }
  1433. hr = S_OK; // success!
  1434. } while (false);
  1435. }
  1436. catch (_com_error& err)
  1437. {
  1438. hr = err.Error();
  1439. ASSERT (false && "Caught _com_error");
  1440. }
  1441. }
  1442. return (hr);
  1443. }
  1444. //############################################################################
  1445. //############################################################################
  1446. //
  1447. // Implementation of class CConsoleTaskpadList
  1448. //
  1449. //############################################################################
  1450. //############################################################################
  1451. /*+-------------------------------------------------------------------------*
  1452. *
  1453. * CConsoleTaskpadList::ScGetTaskpadList
  1454. *
  1455. * PURPOSE: Returns the list of all taskpads that are appropriate for the current node.
  1456. *
  1457. * PARAMETERS:
  1458. * CNode * pNode :
  1459. * CConsoleTaskpadFilteredList & filteredList : [OUT]: The list of taskpads
  1460. *
  1461. * RETURNS:
  1462. * SC
  1463. *
  1464. *+-------------------------------------------------------------------------*/
  1465. SC
  1466. CConsoleTaskpadList::ScGetTaskpadList(CNode *pNode, CConsoleTaskpadFilteredList &filteredList)
  1467. {
  1468. DECLARE_SC(sc, TEXT("CConsoleTaskpadList::ScGetTaskpadList"));
  1469. sc = ScCheckPointers(pNode);
  1470. if(sc)
  1471. return sc;
  1472. // 1. add all built- in taskpads
  1473. for(iterator iter = begin(); iter != end(); ++iter)
  1474. {
  1475. CConsoleTaskpad *pConsoleTaskpad = &*iter;
  1476. if(pConsoleTaskpad->IsValid(pNode))
  1477. {
  1478. filteredList.push_back(pConsoleTaskpad);
  1479. }
  1480. }
  1481. return sc;
  1482. }
  1483. HRESULT
  1484. CConsoleTaskpadList::ReadSerialObject (IStream &stm, UINT nVersion)
  1485. {
  1486. HRESULT hr = S_FALSE; // assume unknown version
  1487. clear();
  1488. if(nVersion == 1)
  1489. {
  1490. try
  1491. {
  1492. DWORD cItems;
  1493. stm >> cItems;
  1494. for(int i=0; i< cItems; i++)
  1495. {
  1496. CConsoleTaskpad taskpad;
  1497. hr = taskpad.Read(stm);
  1498. BREAK_ON_FAIL (hr);
  1499. push_back(taskpad);
  1500. }
  1501. }
  1502. catch (_com_error& err)
  1503. {
  1504. hr = err.Error();
  1505. ASSERT (false && "Caught _com_error");
  1506. }
  1507. }
  1508. return hr;
  1509. }
  1510. //############################################################################
  1511. //############################################################################
  1512. //
  1513. // Implementation of class CDefaultTaskpadList
  1514. //
  1515. //############################################################################
  1516. //############################################################################
  1517. HRESULT
  1518. CDefaultTaskpadList::ReadSerialObject (IStream &stm, UINT nVersion)
  1519. {
  1520. HRESULT hr = S_FALSE; // assume unknown version
  1521. clear();
  1522. if(nVersion == 1)
  1523. {
  1524. try
  1525. {
  1526. /*
  1527. * TODO: investigate using template operator>> for a map (stgio.h)
  1528. */
  1529. DWORD cItems;
  1530. stm >> cItems;
  1531. for(int i=0; i< cItems; i++)
  1532. {
  1533. GUID guidNodetype, guidTaskpad;
  1534. stm >> guidNodetype;
  1535. stm >> guidTaskpad;
  1536. operator[](guidNodetype) = guidTaskpad;
  1537. }
  1538. hr = S_OK;
  1539. }
  1540. catch (_com_error& err)
  1541. {
  1542. hr = err.Error();
  1543. ASSERT (false && "Caught _com_error");
  1544. }
  1545. }
  1546. return hr;
  1547. }