1865 lines
50 KiB
C++
1865 lines
50 KiB
C++
/*--------------------------------------------------------------------------*
|
|
*
|
|
* Microsoft Windows
|
|
* Copyright (C) Microsoft Corporation, 1992 - 1999
|
|
*
|
|
* File: task.cpp
|
|
*
|
|
* Contents: Implementation file for CConsoleTask
|
|
*
|
|
* History: 05-Oct-98 jeffro Created
|
|
*
|
|
*--------------------------------------------------------------------------*/
|
|
|
|
#include "stdafx.h"
|
|
#include "regutil.h"
|
|
#include "tasks.h"
|
|
#include "nodepath.h"
|
|
#include "conview.h"
|
|
|
|
#ifdef DBG
|
|
// Traces
|
|
CTraceTag tagCTPHTML(TEXT("Console Taskpads"), TEXT("Dump HTML"));
|
|
#endif
|
|
|
|
extern CEOTSymbol s_rgEOTSymbol[];
|
|
|
|
/*+-------------------------------------------------------------------------*
|
|
* class CGlobalConsoleTaskList
|
|
*
|
|
* PURPOSE: A global console task list that provides unique IDs for all console tasks
|
|
* When a task is instantiated, its constructor registers in the global task list,
|
|
* and obtains a globally unique ID. This ID is unique for the process and should
|
|
* not be persisted.
|
|
* The destructor of the task removes it from this list.
|
|
*
|
|
* USAGE: Call CGlobalConsoleTaskList::GetConsoleTask to obtain a pointer to the task
|
|
* that has a specified ID.
|
|
* Call CConsoleTask::GetUniqueID to get the unique ID for a task.
|
|
*
|
|
* Thus, CGlobalConsoleTaskList::GetConsoleTask(pConsoleTask->GetUniqueID()) == pConsoleTask
|
|
* is always true.
|
|
*+-------------------------------------------------------------------------*/
|
|
class CGlobalConsoleTaskList
|
|
{
|
|
private:
|
|
typedef const CConsoleTask * PCONSOLETASK;
|
|
typedef std::map<PCONSOLETASK, DWORD> t_taskIDmap;
|
|
|
|
public:
|
|
static DWORD Advise( PCONSOLETASK pConsoleTask)
|
|
{
|
|
DWORD dwOut = s_curTaskID++;
|
|
s_map[pConsoleTask] = dwOut;
|
|
return dwOut;
|
|
}
|
|
|
|
static void Unadvise(PCONSOLETASK pConsoleTask)
|
|
{
|
|
s_map.erase(pConsoleTask);
|
|
}
|
|
|
|
static CConsoleTask * GetConsoleTask(DWORD dwID)
|
|
{
|
|
t_taskIDmap::iterator iter;
|
|
for(iter = s_map.begin(); iter != s_map.end(); iter ++)
|
|
{
|
|
if(iter->second == dwID)
|
|
return const_cast<CConsoleTask *>(iter->first);
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
private:
|
|
CGlobalConsoleTaskList() {}// private, so that it cannot be instantiated
|
|
|
|
static t_taskIDmap s_map;
|
|
static DWORD s_curTaskID;
|
|
};
|
|
|
|
CGlobalConsoleTaskList::t_taskIDmap CGlobalConsoleTaskList::s_map;
|
|
DWORD CGlobalConsoleTaskList::s_curTaskID = 0;
|
|
|
|
//############################################################################
|
|
//############################################################################
|
|
//
|
|
// Implementation of class CConsoleTask
|
|
//
|
|
//############################################################################
|
|
//############################################################################
|
|
|
|
|
|
/*+-------------------------------------------------------------------------*
|
|
* CConsoleTask::CConsoleTask
|
|
*
|
|
*
|
|
*--------------------------------------------------------------------------*/
|
|
DEBUG_DECLARE_INSTANCE_COUNTER(CConsoleTask);
|
|
|
|
CConsoleTask::CConsoleTask() :
|
|
m_eConsoleTaskType (eTask_Result),
|
|
// default ctor for m_strName
|
|
// default ctor for m_strDescription
|
|
// default ctor for m_strCommand
|
|
// default ctor for m_strParameters
|
|
// default ctor for m_strDirectory
|
|
m_eWindowState (eState_Restored),
|
|
// default ctor for m_image
|
|
m_dwFlags (0),
|
|
m_bmScopeNode (false),
|
|
m_fDirty (false),
|
|
m_pctpOwner (NULL),
|
|
m_dwUniqueID (CGlobalConsoleTaskList::Advise(this)) // create a unique ID for this task
|
|
{
|
|
DEBUG_INCREMENT_INSTANCE_COUNTER(CConsoleTask);
|
|
}
|
|
|
|
/*+-------------------------------------------------------------------------*
|
|
* CConsoleTask::CConsoleTask(const CConsoleTask& other)
|
|
*
|
|
* PURPOSE: Copy ctor.
|
|
*
|
|
* PARAMETERS: const CConsoleTask& other
|
|
*
|
|
* NOTE: Calls operator=, cant use default copy ctor (see operator= imp.)
|
|
*
|
|
/*+-------------------------------------------------------------------------*/
|
|
CConsoleTask::CConsoleTask (const CConsoleTask &rhs):
|
|
m_dwUniqueID (CGlobalConsoleTaskList::Advise(this))
|
|
{
|
|
DEBUG_INCREMENT_INSTANCE_COUNTER(CConsoleTask);
|
|
*this = rhs;
|
|
}
|
|
|
|
/*+-------------------------------------------------------------------------*
|
|
*
|
|
* CConsoleTask::GetConsoleTask
|
|
*
|
|
* PURPOSE:
|
|
*
|
|
* PARAMETERS:
|
|
* DWORD dwUniqueID :
|
|
*
|
|
* RETURNS:
|
|
* CConsoleTask *
|
|
*
|
|
*+-------------------------------------------------------------------------*/
|
|
CConsoleTask *
|
|
CConsoleTask::GetConsoleTask(DWORD dwUniqueID)
|
|
{
|
|
return CGlobalConsoleTaskList::GetConsoleTask(dwUniqueID);
|
|
}
|
|
|
|
|
|
/*+-------------------------------------------------------------------------*
|
|
*
|
|
* ScReplaceString
|
|
*
|
|
* PURPOSE: Replaces all occurrences of the token by its replacement.
|
|
*
|
|
* PARAMETERS:
|
|
* CStr & str :
|
|
* LPCTSTR szToken :
|
|
* LPCTSTR szReplacement :
|
|
*
|
|
* RETURNS:
|
|
* static SC
|
|
*
|
|
*+-------------------------------------------------------------------------*/
|
|
static SC
|
|
ScReplaceString(CStr &str, LPCTSTR szToken, LPCTSTR szReplacement, bool bMustReplace = true)
|
|
{
|
|
DECLARE_SC(sc, TEXT("ScReplaceString"));
|
|
|
|
CStr strTemp = str;
|
|
str = TEXT("");
|
|
|
|
int i = strTemp.Find(szToken);
|
|
if( (-1==i) && bMustReplace)
|
|
return (sc = E_UNEXPECTED);
|
|
|
|
while(-1!=i)
|
|
{
|
|
str += strTemp.Left(i);
|
|
str += szReplacement;
|
|
|
|
strTemp = strTemp.Mid(i+_tcslen(szToken)); // the remaining string
|
|
|
|
i=strTemp.Find(szToken);
|
|
}
|
|
|
|
str += strTemp;
|
|
|
|
return sc;
|
|
}
|
|
|
|
/*+-------------------------------------------------------------------------*
|
|
*
|
|
* ScUseJavaScriptStringEntities
|
|
*
|
|
* PURPOSE: Use this to create a valid Javascript string. Replaces " by \" and
|
|
* \ by \\ in the string parameter.
|
|
*
|
|
* PARAMETERS:
|
|
* CStr & str :
|
|
*
|
|
* RETURNS:
|
|
* static SC
|
|
*
|
|
*+-------------------------------------------------------------------------*/
|
|
static SC
|
|
ScUseJavaScriptStringEntities(CStr &str)
|
|
{
|
|
DECLARE_SC(sc, TEXT("ScUseJavaScriptStringEntities"));
|
|
|
|
// NOTE: don't change the order of these string replacements
|
|
|
|
sc = ScReplaceString(str, TEXT("\\"), TEXT("\\\\"), false);
|
|
if(sc)
|
|
return sc;
|
|
|
|
sc = ScReplaceString(str, TEXT("\""), TEXT("\\\""), false);
|
|
if(sc)
|
|
return sc;
|
|
|
|
return sc;
|
|
}
|
|
|
|
/*+-------------------------------------------------------------------------*
|
|
*
|
|
* ScUseHTMLEntities
|
|
*
|
|
* PURPOSE: Replaces " by " < by < and > by > and & by & in the string parameter.
|
|
*
|
|
* PARAMETERS:
|
|
* CStr & str :
|
|
*
|
|
* RETURNS:
|
|
* static SC
|
|
*
|
|
*+-------------------------------------------------------------------------*/
|
|
static SC
|
|
ScUseHTMLEntities(CStr &str)
|
|
{
|
|
DECLARE_SC(sc, TEXT("ScUseHTMLEntities"));
|
|
|
|
sc = ScReplaceString(str, TEXT("&"), TEXT("&"), false);
|
|
if(sc)
|
|
return sc;
|
|
|
|
sc = ScReplaceString(str, TEXT("\""), TEXT("""), false);
|
|
if(sc)
|
|
return sc;
|
|
|
|
sc = ScReplaceString(str, TEXT("<"), TEXT("<"), false);
|
|
if(sc)
|
|
return sc;
|
|
|
|
sc = ScReplaceString(str, TEXT(">"), TEXT(">"), false);
|
|
if(sc)
|
|
return sc;
|
|
|
|
return sc;
|
|
}
|
|
|
|
|
|
/*+-------------------------------------------------------------------------*
|
|
*
|
|
* CConsoleTask::ScGetHTML
|
|
*
|
|
* PURPOSE: returns the HTML representation of the task.
|
|
*
|
|
* PARAMETERS:
|
|
* LPCTSTR szFmtHTML :
|
|
* CStr & strTaskHTML :
|
|
* bool bUseLargeIcons : Draw in the no-list (large icon) style
|
|
* bool bUseTextDescriptions :
|
|
*
|
|
* RETURNS:
|
|
* SC
|
|
*
|
|
*+-------------------------------------------------------------------------*/
|
|
SC
|
|
CConsoleTask::ScGetHTML(LPCTSTR szFmtHTML, CStr &strTaskHTML, bool bUseLargeIcons, bool bUseTextDescriptions) const
|
|
{
|
|
DECLARE_SC(sc, TEXT("CConsoleTask::ScGetHTML"));
|
|
USES_CONVERSION;
|
|
|
|
// the substitution parameters, in order
|
|
CStr strTableSpacing = bUseLargeIcons ? TEXT("<BR />") : TEXT("");
|
|
int iconWidth = bUseLargeIcons ? 32: 20;
|
|
int iconHeight = bUseLargeIcons ? 32: 16;
|
|
// iconWidth and iconHeight repeated
|
|
int uniqueID = GetUniqueID();
|
|
CStr strSmall = bUseLargeIcons ? TEXT("0") : TEXT("1");
|
|
CStr strHref;
|
|
CStr strID;
|
|
CStr strParameter;
|
|
CStr strOptionalTitleTag;
|
|
CStr strOptionalTextDescription;
|
|
CStr strTaskName = GetName().data();
|
|
CStr strDescription = GetDescription().data();
|
|
CStr strCommand = GetCommand().data();
|
|
|
|
// use entities for all strings
|
|
sc = ScUseHTMLEntities(strTaskName);
|
|
if(sc)
|
|
return sc;
|
|
|
|
sc = ScUseHTMLEntities(strDescription);
|
|
if(sc)
|
|
return sc;
|
|
|
|
sc = ScUseJavaScriptStringEntities(strCommand);
|
|
if(sc)
|
|
return sc;
|
|
|
|
//------
|
|
if(bUseTextDescriptions)
|
|
{
|
|
strOptionalTextDescription = TEXT("<BR />");
|
|
strOptionalTextDescription += strDescription;
|
|
}
|
|
else
|
|
{
|
|
strOptionalTitleTag.Format(TEXT("title='%s'"), (LPCTSTR) strDescription);
|
|
}
|
|
|
|
switch(GetTaskType())
|
|
{
|
|
case eTask_Scope:
|
|
{
|
|
std::wstring strTemp;
|
|
|
|
// get the bookmark of the scope node.
|
|
sc = m_bmScopeNode.ScSaveToString(&strTemp);
|
|
if(sc)
|
|
return sc;
|
|
|
|
CStr strScopeNodeBookmark = W2CT(strTemp.data()); // make sure that special characters have been converted
|
|
sc = ScUseJavaScriptStringEntities(strScopeNodeBookmark);
|
|
if(sc)
|
|
return sc;
|
|
|
|
strHref.Format(TEXT("external.ExecuteScopeNodeMenuItem(\"%s\", \"%s\");"), (LPCTSTR)strCommand, (LPCTSTR)strScopeNodeBookmark);
|
|
}
|
|
|
|
strID=L"ScopeTask";
|
|
break;
|
|
|
|
case eTask_Result:
|
|
strHref.Format(TEXT("external.ExecuteSelectionMenuItem(\"%s\");"), (LPCTSTR)strCommand);
|
|
strParameter = strCommand;
|
|
strID = TEXT("ResultTask");
|
|
break;
|
|
|
|
case eTask_CommandLine:
|
|
{
|
|
strParameter = GetParameters().data();
|
|
sc = ScUseJavaScriptStringEntities(strParameter);
|
|
if(sc)
|
|
return sc;
|
|
|
|
CStr strDirectory = GetDirectory().data();
|
|
sc = ScUseJavaScriptStringEntities(strDirectory);
|
|
if(sc)
|
|
return sc;
|
|
|
|
// get the window state
|
|
CStr strWindowState;
|
|
|
|
if(GetWindowState() ==eState_Restored)
|
|
strWindowState = XML_ENUM_WINDOW_STATE_RESTORED;
|
|
|
|
else if(GetWindowState() == eState_Minimized)
|
|
strWindowState = XML_ENUM_WINDOW_STATE_MINIMIZED;
|
|
|
|
else
|
|
strWindowState = XML_ENUM_WINDOW_STATE_MAXIMIZED;
|
|
|
|
strHref.Format(TEXT("external.ExecuteShellCommand(\"%s\", \"%s\", ParseParameters(\"%s\"), \"%s\");"),
|
|
(LPCTSTR)strCommand, (LPCTSTR)strDirectory, (LPCTSTR)strParameter, (LPCTSTR)strWindowState);
|
|
}
|
|
strID=L"CommandLineTask";
|
|
|
|
break;
|
|
|
|
case eTask_Target:
|
|
strHref.Format(TEXT("external.ExecuteScopeNodeMenuItem(\"%s\");"), (LPCTSTR)strCommand);
|
|
strParameter = strCommand;
|
|
strID = L"TargetTask";
|
|
break;
|
|
|
|
case eTask_Favorite:
|
|
{
|
|
std::wstring strTemp;
|
|
// save the memento to a string
|
|
sc = const_cast<CMemento *>(&m_memento)->ScSaveToString(&strTemp);
|
|
if(sc)
|
|
return sc;
|
|
|
|
CStr strMemento = W2CT(strTemp.data());
|
|
|
|
sc = ScUseJavaScriptStringEntities(strMemento);
|
|
if(sc)
|
|
return sc;
|
|
|
|
strHref.Format(TEXT("external.ViewMemento(\"%s\");"), (LPCTSTR)strMemento);
|
|
}
|
|
strID=L"FavoriteTask";
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
|
|
strTaskHTML.Format(szFmtHTML, (LPCTSTR) strTableSpacing, iconWidth, iconHeight, uniqueID, iconWidth, iconHeight,
|
|
uniqueID, (LPCTSTR) strSmall, uniqueID, uniqueID, (LPCTSTR) strID, (LPCTSTR) strParameter,
|
|
(LPCTSTR) strOptionalTitleTag, (LPCTSTR)strTaskName, (LPCTSTR) strOptionalTextDescription,
|
|
uniqueID, uniqueID, uniqueID, (LPCTSTR) strHref);
|
|
|
|
Trace(tagCTPHTML, TEXT("%s"), (LPCTSTR)strTaskHTML);
|
|
|
|
return sc;
|
|
}
|
|
|
|
|
|
/*+-------------------------------------------------------------------------*
|
|
*
|
|
* CConsoleTask::IsDirty
|
|
*
|
|
* PURPOSE: Determines whether the task needs to be saved.
|
|
*
|
|
* RETURNS:
|
|
* bool
|
|
*
|
|
*+-------------------------------------------------------------------------*/
|
|
bool
|
|
CConsoleTask::IsDirty() const
|
|
{
|
|
TraceDirtyFlag(TEXT("CConsoleTask"), m_fDirty);
|
|
return (m_fDirty);
|
|
}
|
|
|
|
/*+-------------------------------------------------------------------------*
|
|
* CConsoleTask::operator =
|
|
*
|
|
* PURPOSE: Assignment operator
|
|
*
|
|
* PARAMETERS: const CConsoleTask& rhs
|
|
*
|
|
* RETURNS:
|
|
* CConsoleTask &
|
|
*
|
|
/*+-------------------------------------------------------------------------*/
|
|
CConsoleTask &
|
|
CConsoleTask::operator =(const CConsoleTask& rhs)
|
|
{
|
|
if (this != &rhs)
|
|
{
|
|
m_eConsoleTaskType = rhs.m_eConsoleTaskType;
|
|
m_strName = rhs.m_strName;
|
|
m_strDescription = rhs.m_strDescription;
|
|
m_strCommand = rhs.m_strCommand;
|
|
m_strParameters = rhs.m_strParameters;
|
|
m_strDirectory = rhs.m_strDirectory;
|
|
m_eWindowState = rhs.m_eWindowState;
|
|
m_dwFlags = rhs.m_dwFlags;
|
|
m_bmScopeNode = rhs.m_bmScopeNode;
|
|
m_dwSymbol = rhs.m_dwSymbol;
|
|
m_smartIconCustomLarge = rhs.m_smartIconCustomLarge;
|
|
m_smartIconCustomSmall = rhs.m_smartIconCustomSmall;
|
|
m_memento = rhs.m_memento;
|
|
|
|
m_fDirty = rhs.m_fDirty;
|
|
m_pctpOwner = rhs.m_pctpOwner;
|
|
// m_dwUniqueID = rhs.m_dwUniqueID; DO NOT copy this ID
|
|
}
|
|
|
|
return *this;
|
|
}
|
|
|
|
/*+-------------------------------------------------------------------------*
|
|
*
|
|
* CConsoleTask::operator ==
|
|
*
|
|
* PURPOSE: Equality operator. Checks that the command string is
|
|
* equal to the given menuitem's Path or Language Independent Path.
|
|
*
|
|
*+-------------------------------------------------------------------------*/
|
|
bool
|
|
CConsoleTask::operator==(const CMenuItem & menuItem) const
|
|
{
|
|
// check that the command string matches either the path or the language independent path.
|
|
|
|
if( (m_strCommand == menuItem.GetPath()) ||
|
|
(m_strCommand == menuItem.GetLanguageIndependentPath() )
|
|
)
|
|
return true;
|
|
|
|
return false;
|
|
}
|
|
|
|
/*+-------------------------------------------------------------------------*
|
|
* CConsoleTask::~CConsoleTask
|
|
*
|
|
*
|
|
*--------------------------------------------------------------------------*/
|
|
|
|
CConsoleTask::~CConsoleTask ()
|
|
{
|
|
DEBUG_DECREMENT_INSTANCE_COUNTER(CConsoleTask);
|
|
|
|
CGlobalConsoleTaskList::Unadvise(this); // remove this task from the list.
|
|
}
|
|
|
|
|
|
/*+-------------------------------------------------------------------------*
|
|
*
|
|
* CConsoleTask::HasCustomIcon
|
|
*
|
|
* PURPOSE: Returns whether the task has a custom icon
|
|
*
|
|
* RETURNS:
|
|
* bool
|
|
*
|
|
*+-------------------------------------------------------------------------*/
|
|
bool
|
|
CConsoleTask::HasCustomIcon() const
|
|
{
|
|
if((HICON)m_smartIconCustomLarge != NULL)
|
|
{
|
|
ASSERT((HICON)m_smartIconCustomSmall != NULL);
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
|
|
/*+-------------------------------------------------------------------------*
|
|
*
|
|
* CConsoleTask::Reset
|
|
*
|
|
* PURPOSE:
|
|
*
|
|
* RETURNS:
|
|
* void
|
|
*
|
|
*+-------------------------------------------------------------------------*/
|
|
void
|
|
CConsoleTask::ResetUI()
|
|
{
|
|
m_bmScopeNode.ResetUI();
|
|
}
|
|
|
|
/*+-------------------------------------------------------------------------*
|
|
*
|
|
* CConsoleTask::SetSymbol
|
|
*
|
|
* PURPOSE:
|
|
*
|
|
* PARAMETERS:
|
|
* DWORD dwSymbol :
|
|
*
|
|
* RETURNS:
|
|
* void
|
|
*
|
|
*+-------------------------------------------------------------------------*/
|
|
void
|
|
CConsoleTask::SetSymbol(DWORD dwSymbol)
|
|
{
|
|
m_dwSymbol = dwSymbol;
|
|
m_smartIconCustomSmall.Release();
|
|
m_smartIconCustomLarge.Release();
|
|
SetDirty();
|
|
}
|
|
|
|
/*+-------------------------------------------------------------------------*
|
|
*
|
|
* CConsoleTask::SetCustomIcon
|
|
*
|
|
* PURPOSE:
|
|
*
|
|
* PARAMETERS:
|
|
* CSmartIcon& iconSmall :
|
|
* CSmartIcon& iconLarge :
|
|
*
|
|
* RETURNS:
|
|
* void
|
|
*
|
|
*+-------------------------------------------------------------------------*/
|
|
void
|
|
CConsoleTask::SetCustomIcon(CSmartIcon& iconSmall, CSmartIcon& iconLarge)
|
|
{
|
|
m_smartIconCustomSmall = iconSmall;
|
|
m_smartIconCustomLarge = iconLarge;
|
|
SetDirty();
|
|
}
|
|
|
|
|
|
/*+-------------------------------------------------------------------------*
|
|
* CConsoleTask::Enable
|
|
*
|
|
* Sets the enable state for a task.
|
|
*--------------------------------------------------------------------------*/
|
|
|
|
void CConsoleTask::Enable (bool fEnable)
|
|
{
|
|
if (fEnable)
|
|
m_dwFlags &= ~eFlag_Disabled;
|
|
else
|
|
m_dwFlags |= eFlag_Disabled;
|
|
|
|
SetDirty ();
|
|
}
|
|
|
|
void
|
|
CConsoleTask::Draw (HDC hdc, RECT *lpRect, bool bSmall) const // Draw into a DC.
|
|
{
|
|
if(HasCustomIcon())
|
|
{
|
|
DrawIconEx(hdc, lpRect->left, lpRect->top, bSmall ? m_smartIconCustomSmall : m_smartIconCustomLarge,
|
|
bSmall? 16 : 32, bSmall? 16 : 32, 0, NULL, DI_NORMAL);
|
|
return;
|
|
}
|
|
|
|
for(int i = 0; i< NUM_SYMBOLS; i++)
|
|
{
|
|
if(s_rgEOTSymbol[i].GetValue() == m_dwSymbol)
|
|
{
|
|
s_rgEOTSymbol[i].Draw(hdc, lpRect, bSmall);
|
|
return;
|
|
}
|
|
}
|
|
|
|
/*
|
|
* if we get here, we couldn't find the EOT symbol matching m_dwSymbol
|
|
*/
|
|
ASSERT (false);
|
|
}
|
|
|
|
|
|
/*+-------------------------------------------------------------------------*
|
|
* CConsoleTask::SetName
|
|
*
|
|
*
|
|
*--------------------------------------------------------------------------*/
|
|
|
|
void CConsoleTask::SetName (const tstring& strName)
|
|
{
|
|
if (m_strName != strName)
|
|
{
|
|
m_strName = strName;
|
|
SetDirty ();
|
|
}
|
|
}
|
|
|
|
|
|
/*+-------------------------------------------------------------------------*
|
|
* CConsoleTask::SetDescription
|
|
*
|
|
*
|
|
*--------------------------------------------------------------------------*/
|
|
|
|
void CConsoleTask::SetDescription (const tstring& strDescription)
|
|
{
|
|
if (m_strDescription != strDescription)
|
|
{
|
|
m_strDescription = strDescription;
|
|
SetDirty ();
|
|
}
|
|
}
|
|
|
|
/*+-------------------------------------------------------------------------*
|
|
* CConsoleTask::SetCommand
|
|
*
|
|
*
|
|
*--------------------------------------------------------------------------*/
|
|
|
|
void CConsoleTask::SetCommand (const tstring& strCommand)
|
|
{
|
|
if (m_strCommand != strCommand)
|
|
{
|
|
m_strCommand = strCommand;
|
|
SetDirty ();
|
|
}
|
|
}
|
|
|
|
/*+-------------------------------------------------------------------------*
|
|
* CConsoleTask::SetParameters
|
|
*
|
|
*
|
|
*--------------------------------------------------------------------------*/
|
|
|
|
void CConsoleTask::SetParameters (const tstring& strParameters)
|
|
{
|
|
if (m_strParameters != strParameters)
|
|
{
|
|
m_strParameters = strParameters;
|
|
SetDirty ();
|
|
}
|
|
}
|
|
|
|
/*+-------------------------------------------------------------------------*
|
|
* CConsoleTask::SetDirectory
|
|
*
|
|
*
|
|
*--------------------------------------------------------------------------*/
|
|
|
|
void CConsoleTask::SetDirectory (const tstring& strDirectory)
|
|
{
|
|
if (m_strDirectory != strDirectory)
|
|
{
|
|
m_strDirectory = strDirectory;
|
|
SetDirty ();
|
|
}
|
|
}
|
|
|
|
|
|
void CConsoleTask::SetMemento(const CMemento &memento)
|
|
{
|
|
if( m_memento != memento)
|
|
{
|
|
m_memento = memento;
|
|
SetDirty();
|
|
}
|
|
}
|
|
|
|
/*+-------------------------------------------------------------------------*
|
|
* CConsoleTask::SetWindowState
|
|
*
|
|
*
|
|
*--------------------------------------------------------------------------*/
|
|
|
|
void CConsoleTask::SetWindowState (eWindowState eNewState)
|
|
{
|
|
if (m_eWindowState != eNewState)
|
|
{
|
|
m_eWindowState = eNewState;
|
|
SetDirty ();
|
|
}
|
|
}
|
|
|
|
/*+-------------------------------------------------------------------------*
|
|
* CConsoleTask::RetargetScopeNode
|
|
*
|
|
* PURPOSE: Sets the target scope node for the task. Note: the task must be
|
|
* of type eTask_Scope.
|
|
*
|
|
* PARAMETERS:
|
|
* CNode * pNewNode:
|
|
*
|
|
* RETURNS:
|
|
* bool
|
|
*/
|
|
/*+-------------------------------------------------------------------------*/
|
|
bool
|
|
CConsoleTask::RetargetScopeNode(CNode *pNewNode)
|
|
{
|
|
bool fRet = TRUE;
|
|
|
|
ASSERT(GetTaskType() == eTask_Scope);
|
|
|
|
CMTNode* pMTNewNode = (pNewNode) ? pNewNode->GetMTNode() : NULL;
|
|
|
|
m_bmScopeNode.ScRetarget(pMTNewNode, false /*bFastRetrievalOnly*/);
|
|
|
|
SetDirty();
|
|
return fRet;
|
|
}
|
|
|
|
/*+-------------------------------------------------------------------------*
|
|
* CConsoleTask::GetScopeNode
|
|
*
|
|
* PURPOSE:
|
|
*
|
|
* PARAMETERS:
|
|
* IScopeTree * pScopeTree:
|
|
*
|
|
* RETURNS:
|
|
* CMTNode *
|
|
*
|
|
/*+-------------------------------------------------------------------------*/
|
|
CMTNode *
|
|
CConsoleTask::GetScopeNode(IScopeTree *pScopeTree) const
|
|
{
|
|
DECLARE_SC(sc, TEXT("CConsoleTask::GetScopeNode"));
|
|
|
|
CMTNode *pMTNode = NULL;
|
|
bool bExactMatchFound = false; // out value from ScGetMTNode, unused
|
|
sc = m_bmScopeNode.ScGetMTNode(true /*bExactMatchRequired*/, &pMTNode, bExactMatchFound);
|
|
if(sc.IsError())
|
|
return NULL;
|
|
|
|
return (pMTNode);
|
|
}
|
|
|
|
|
|
|
|
/*+-------------------------------------------------------------------------*
|
|
* CConsoleTask::GetScopeNode
|
|
*
|
|
* PURPOSE:
|
|
*
|
|
* PARAMETERS:
|
|
* CViewData * pViewData:
|
|
*
|
|
* RETURNS:
|
|
* CNode *
|
|
/*+-------------------------------------------------------------------------*/
|
|
std::auto_ptr<CNode>
|
|
CConsoleTask::GetScopeNode(CViewData *pViewData) const
|
|
{
|
|
return m_bmScopeNode.GetNode(pViewData);
|
|
}
|
|
|
|
|
|
/*+-------------------------------------------------------------------------*
|
|
*
|
|
* CConsoleTask::Persist
|
|
*
|
|
* PURPOSE: Persists the console task to the specified persistor.
|
|
*
|
|
*
|
|
* PARAMETERS:
|
|
* CPersistor & persistor :
|
|
*
|
|
* RETURNS:
|
|
* void
|
|
*
|
|
*+-------------------------------------------------------------------------*/
|
|
void
|
|
CConsoleTask::Persist(CPersistor &persistor)
|
|
{
|
|
|
|
persistor.PersistString(XML_ATTR_TASK_NAME, m_strName);
|
|
|
|
// define the table to map enumeration values to strings
|
|
static const EnumLiteral mappedTaskTypes[] =
|
|
{
|
|
{ eTask_Scope, XML_ENUM_TASK_TYPE_SCOPE },
|
|
{ eTask_Result, XML_ENUM_TASK_TYPE_RESULT },
|
|
{ eTask_CommandLine, XML_ENUM_TASK_TYPE_COMMANDLINE },
|
|
{ eTask_Target, XML_ENUM_TASK_TYPE_TARGET },
|
|
{ eTask_Favorite, XML_ENUM_TASK_TYPE_FAVORITE },
|
|
};
|
|
|
|
|
|
// create wrapper to persist flag values as strings
|
|
CXMLEnumeration taskTypePersistor(m_eConsoleTaskType, mappedTaskTypes, countof(mappedTaskTypes));
|
|
// persist the wrapper
|
|
persistor.PersistAttribute(XML_ATTR_TASK_TYPE, taskTypePersistor);
|
|
|
|
persistor.PersistString(XML_ATTR_TASK_DESCRIPTION, m_strDescription);
|
|
|
|
{
|
|
/* this section creates
|
|
<ConsoleTask>
|
|
<SYMBOL id = "">
|
|
<IMAGE name = "LargeIcon" ... /> NOTE: either the id or the images are present.
|
|
<IMAGE name = "SmallIcon" ... />
|
|
</SYMBOL>
|
|
</ConsoleTask>
|
|
*/
|
|
|
|
// create a child element for the symbol
|
|
CPersistor persistorSymbol(persistor, XML_TAG_EOT_SYMBOL_INFO);
|
|
|
|
if(persistorSymbol.IsLoading())
|
|
{
|
|
m_dwSymbol = (DWORD)-1; // initialize
|
|
}
|
|
|
|
if(persistorSymbol.IsLoading() ||
|
|
(persistorSymbol.IsStoring() && !HasCustomIcon() ) )
|
|
{
|
|
// save the "ID" attribute only if there is no icon
|
|
persistorSymbol.PersistAttribute(XML_ATTR_EOT_SYMBOL_DW_SYMBOL, m_dwSymbol, attr_optional);
|
|
}
|
|
|
|
if((persistorSymbol.IsStoring() && HasCustomIcon()) ||
|
|
(persistorSymbol.IsLoading() && (m_dwSymbol == (DWORD) -1) )
|
|
)
|
|
{
|
|
persistorSymbol.Persist (m_smartIconCustomSmall, XML_NAME_ICON_SMALL);
|
|
persistorSymbol.Persist (m_smartIconCustomLarge, XML_NAME_ICON_LARGE);
|
|
}
|
|
}
|
|
|
|
persistor.PersistAttribute(XML_ATTR_TASK_COMMAND, m_strCommand);
|
|
|
|
// define the table to map enumeration values to strings
|
|
static const EnumLiteral mappedTaskFlags[] =
|
|
{
|
|
{ eFlag_Disabled, XML_BITFLAG_TASK_DISABLED },
|
|
};
|
|
|
|
// create wrapper to persist flag values as strings
|
|
CXMLBitFlags taskFlagPersistor(m_dwFlags, mappedTaskFlags, countof(mappedTaskFlags));
|
|
// persist the wrapper
|
|
persistor.PersistAttribute(XML_ATTR_TASK_FLAGS, taskFlagPersistor);
|
|
|
|
switch (m_eConsoleTaskType)
|
|
{
|
|
case eTask_Scope:
|
|
persistor.Persist(m_bmScopeNode);
|
|
break;
|
|
|
|
case eTask_CommandLine:
|
|
{
|
|
CPersistor persistorCmd(persistor, XML_TAG_TASK_CMD_LINE);
|
|
persistorCmd.PersistAttribute(XML_ATTR_TASK_CMD_LINE_DIR, m_strDirectory);
|
|
|
|
// define the table to map enumeration values to strings
|
|
static const EnumLiteral windowStates[] =
|
|
{
|
|
{ eState_Restored, XML_ENUM_WINDOW_STATE_RESTORED },
|
|
{ eState_Minimized, XML_ENUM_WINDOW_STATE_MINIMIZED },
|
|
{ eState_Maximized, XML_ENUM_WINDOW_STATE_MAXIMIZED },
|
|
};
|
|
|
|
// create wrapper to persist flag values as strings
|
|
CXMLEnumeration windowStatePersistor(m_eWindowState, windowStates, countof(windowStates));
|
|
// persist the wrapper
|
|
persistorCmd.PersistAttribute(XML_ATTR_TASK_CMD_LINE_WIN_ST, windowStatePersistor);
|
|
|
|
persistorCmd.PersistAttribute(XML_ATTR_TASK_CMD_LINE_PARAMS, m_strParameters);
|
|
break;
|
|
}
|
|
|
|
case eTask_Favorite:
|
|
persistor.Persist(m_memento);
|
|
break;
|
|
}
|
|
|
|
// either read or saved - not dirty after the operation
|
|
SetDirty(false);
|
|
}
|
|
|
|
|
|
/*+-------------------------------------------------------------------------*
|
|
* CConsoleTask::ReadSerialObject
|
|
*
|
|
*
|
|
*--------------------------------------------------------------------------*/
|
|
HRESULT
|
|
CConsoleTask::ReadSerialObject (IStream &stm, UINT nVersion /*,LARGE_INTEGER nBytes*/)
|
|
{
|
|
HRESULT hr = S_FALSE; // assume unknown version
|
|
|
|
if (nVersion == 1)
|
|
{
|
|
try
|
|
{
|
|
// ugly hackery required to extract directly into an enum
|
|
stm >> *((int *) &m_eConsoleTaskType);
|
|
stm >> m_strName;
|
|
stm >> m_strDescription;
|
|
|
|
// legacy task symbol info
|
|
{
|
|
// this must be BOOL not bool to occupy the same amount of space as in legacy consoles
|
|
// See Bug #101253
|
|
BOOL bLegacyUseMMCSymbols = TRUE; // a now obsolete field, read for console file compatibility
|
|
tstring strFileLegacy, strFontLegacy;
|
|
|
|
stm >> m_dwSymbol;
|
|
stm >> bLegacyUseMMCSymbols;
|
|
stm >> strFileLegacy; // obsolete
|
|
stm >> strFontLegacy; // obsolete
|
|
}
|
|
|
|
stm >> m_strCommand;
|
|
stm >> m_dwFlags;
|
|
|
|
switch (m_eConsoleTaskType)
|
|
{
|
|
case eTask_Scope:
|
|
stm >> m_bmScopeNode;
|
|
break;
|
|
|
|
case eTask_CommandLine:
|
|
stm >> m_strDirectory;
|
|
// ugly hackery required to extract directly into an enum
|
|
stm >> *((int *) &m_eWindowState);
|
|
stm >> m_strParameters;
|
|
break;
|
|
|
|
case eTask_Favorite:
|
|
hr = m_memento.Read(stm);
|
|
if(FAILED(hr))
|
|
return hr;
|
|
break;
|
|
}
|
|
|
|
hr = S_OK;
|
|
}
|
|
catch (_com_error& err)
|
|
{
|
|
hr = err.Error();
|
|
ASSERT (false && "Caught _com_error");
|
|
}
|
|
}
|
|
|
|
return (hr);
|
|
}
|
|
|
|
|
|
|
|
/*+-------------------------------------------------------------------------*
|
|
* CConsoleTaskpad::CConsoleTaskpad
|
|
*
|
|
*
|
|
*--------------------------------------------------------------------------*/
|
|
|
|
CConsoleTaskpad::CConsoleTaskpad (CNode* pTargetNode /*=NULL*/) :
|
|
m_listSize(eSize_Default), // the default space given to a taskpad.
|
|
m_guidNodeType(GUID_NULL),
|
|
m_guidID(GUID_NULL),
|
|
m_bmTargetNode(),
|
|
m_pMTNodeTarget(NULL),
|
|
m_bNodeSpecific(false),
|
|
m_dwOrientation(TVO_VERTICAL), // the default is a vertical taskpad for consistency with the Extended view.
|
|
m_bReplacesDefaultView(true) // taskpads do not show the normal tab by default.
|
|
{
|
|
Retarget (pTargetNode);
|
|
|
|
HRESULT hr = CoCreateGuid(&m_guidID);
|
|
ASSERT(SUCCEEDED(hr));
|
|
|
|
SetDirty (false);
|
|
}
|
|
|
|
bool
|
|
CConsoleTaskpad::IsValid(CNode *pNode) const
|
|
{
|
|
ASSERT(pNode != NULL);
|
|
|
|
if(!HasTarget())
|
|
return true; // a taskpad without a target is valid for any node. $REVIEW
|
|
|
|
if(!pNode)
|
|
return false; // Cannot use a taskpad with a target.
|
|
|
|
if(IsNodeSpecific())
|
|
{
|
|
// use this taskpad if it is targetted at the same node. $OPTIMIZE.
|
|
return (*pNode->GetMTNode()->GetBookmark() == m_bmTargetNode);
|
|
}
|
|
else
|
|
{
|
|
GUID guid;
|
|
HRESULT hr = pNode->GetNodeType(&guid);
|
|
if(FAILED(hr))
|
|
return false; // don't use this taskpad.
|
|
|
|
return (MatchesNodeType(guid)); // use only if node types match.
|
|
}
|
|
|
|
|
|
}
|
|
|
|
static CStr g_szTaskpadCommonHTMLTemplate;
|
|
static CStr g_szVerticalTaskpadHTMLTemplate;
|
|
static CStr g_szHorizontalTaskpadHTMLTemplate;
|
|
static CStr g_szNoResultsTaskpadHTMLTemplate;
|
|
static CStr g_szTaskHTMLTemplate;
|
|
/*+-------------------------------------------------------------------------*
|
|
*
|
|
* ScLoadHTMLTemplate
|
|
*
|
|
* PURPOSE:
|
|
*
|
|
* PARAMETERS:
|
|
* HINSTANCE hinstLibrary :
|
|
* LPCTSTR szHTMLTemplateResourceName :
|
|
* CStr& str :
|
|
*
|
|
* RETURNS:
|
|
* SC
|
|
*
|
|
*+-------------------------------------------------------------------------*/
|
|
SC
|
|
ScLoadHTMLTemplate(HINSTANCE hinstLibrary, LPCTSTR szHTMLTemplateResourceName, CStr& str)
|
|
{
|
|
DECLARE_SC(sc, TEXT("ScLoadHTMLTemplate"));
|
|
|
|
sc = ScCheckPointers(hinstLibrary, szHTMLTemplateResourceName);
|
|
if(sc)
|
|
return sc;
|
|
|
|
HRSRC hFindRes = ::FindResource(hinstLibrary, szHTMLTemplateResourceName, RT_HTML);
|
|
if(!hFindRes)
|
|
return (sc = E_UNEXPECTED);
|
|
|
|
DWORD dwResSize = ::SizeofResource(hinstLibrary, hFindRes);
|
|
if(!dwResSize)
|
|
return (sc = E_UNEXPECTED);
|
|
|
|
HGLOBAL hRes = ::LoadResource(hinstLibrary, hFindRes);
|
|
ASSERT(hRes);
|
|
|
|
char *pvRes = (char *)::LockResource(hRes); // no need to Unlock the resource - see the SDK entry for LockResource
|
|
sc = ScCheckPointers(pvRes);
|
|
if(sc)
|
|
return sc;
|
|
|
|
std::string strTemp; // initially create an ANSI string
|
|
strTemp.assign(pvRes, dwResSize);
|
|
strTemp+="\0"; // null terminate it
|
|
|
|
USES_CONVERSION;
|
|
str = A2CT(strTemp.data());
|
|
|
|
return sc;
|
|
}
|
|
|
|
/*+-------------------------------------------------------------------------*
|
|
*
|
|
* ScLoadHTMLTemplates
|
|
*
|
|
* PURPOSE:
|
|
*
|
|
* RETURNS:
|
|
* SC
|
|
*
|
|
*+-------------------------------------------------------------------------*/
|
|
SC
|
|
ScLoadHTMLTemplates()
|
|
{
|
|
DECLARE_SC(sc, TEXT("ScLoadHTMLTemplates"));
|
|
|
|
static BOOL bInitialized = false;
|
|
if(bInitialized)
|
|
return sc;
|
|
|
|
// load the library into memory.
|
|
TCHAR szBuffer[MAX_PATH];
|
|
::GetModuleFileName (_Module.GetModuleInstance(), szBuffer, countof (szBuffer));
|
|
|
|
HINSTANCE hinstLibrary = ::LoadLibraryEx(szBuffer, 0, LOAD_LIBRARY_AS_DATAFILE);
|
|
if(!hinstLibrary)
|
|
return (sc = E_UNEXPECTED);
|
|
|
|
sc = ScLoadHTMLTemplate(hinstLibrary, TEXT("CTPCOMMON.HTM"), g_szTaskpadCommonHTMLTemplate);
|
|
if(sc)
|
|
goto Error;
|
|
|
|
sc = ScLoadHTMLTemplate(hinstLibrary, TEXT("CTPVERT.HTM"), g_szVerticalTaskpadHTMLTemplate);
|
|
if(sc)
|
|
goto Error;
|
|
|
|
sc = ScLoadHTMLTemplate(hinstLibrary, TEXT("CTPHORIZ.HTM"), g_szHorizontalTaskpadHTMLTemplate);
|
|
if(sc)
|
|
goto Error;
|
|
|
|
sc = ScLoadHTMLTemplate(hinstLibrary, TEXT("CTPNORESULTS.HTM"), g_szNoResultsTaskpadHTMLTemplate);
|
|
if(sc)
|
|
goto Error;
|
|
|
|
sc = ScLoadHTMLTemplate(hinstLibrary, TEXT("CTPTASK.HTM"), g_szTaskHTMLTemplate);
|
|
if(sc)
|
|
goto Error;
|
|
|
|
bInitialized = true;
|
|
|
|
Cleanup:
|
|
FreeLibrary(hinstLibrary);
|
|
return sc;
|
|
Error:
|
|
sc = E_UNEXPECTED;
|
|
goto Cleanup;
|
|
|
|
}
|
|
|
|
/*+-------------------------------------------------------------------------*
|
|
*
|
|
* CConsoleTaskpad::ScGetHTML
|
|
*
|
|
* PURPOSE:
|
|
*
|
|
* PARAMETERS:
|
|
* CStr & strTaskpadHTML :
|
|
*
|
|
* RETURNS:
|
|
* SC
|
|
*
|
|
*+-------------------------------------------------------------------------*/
|
|
SC
|
|
CConsoleTaskpad::ScGetHTML(CStr &strTaskpadHTML) const
|
|
{
|
|
DECLARE_SC(sc, TEXT("CConsoleTaskpad::ScGetHTML"));
|
|
|
|
sc = ScLoadHTMLTemplates();
|
|
if(sc)
|
|
return sc;
|
|
|
|
|
|
CStr strTasksHTML;
|
|
|
|
// get the HTML for all the tasks
|
|
for (TaskConstIter it = m_Tasks.begin(); it != m_Tasks.end(); ++it)
|
|
{
|
|
CStr strTemp;
|
|
sc = it->ScGetHTML(g_szTaskHTMLTemplate, strTemp, GetOrientation() & TVO_NO_RESULTS /*bUseLargeIcons*/, GetOrientation() & TVO_DESCRIPTIONS_AS_TEXT);
|
|
if(sc)
|
|
return sc;
|
|
|
|
strTasksHTML += strTemp;
|
|
}
|
|
|
|
strTaskpadHTML = g_szTaskpadCommonHTMLTemplate;
|
|
|
|
// append the orientation-specific portion
|
|
CStr *pstrOrientationSpecificHTML = NULL;
|
|
|
|
if(GetOrientation() & TVO_HORIZONTAL)
|
|
pstrOrientationSpecificHTML = &g_szHorizontalTaskpadHTMLTemplate;
|
|
|
|
else if (GetOrientation() & TVO_VERTICAL)
|
|
pstrOrientationSpecificHTML = &g_szVerticalTaskpadHTMLTemplate;
|
|
|
|
else
|
|
pstrOrientationSpecificHTML = &g_szNoResultsTaskpadHTMLTemplate;
|
|
|
|
sc = ScCheckPointers(pstrOrientationSpecificHTML, E_UNEXPECTED);
|
|
if(sc)
|
|
return sc;
|
|
|
|
// this replacement must be done first
|
|
sc = ScReplaceString(strTaskpadHTML, TEXT("@@ORIENTATIONSPECIFICHTML@@"), *pstrOrientationSpecificHTML);
|
|
if(sc)
|
|
return sc;
|
|
|
|
sc = ScReplaceString(strTaskpadHTML, TEXT("@@TASKS@@"), strTasksHTML);
|
|
if(sc)
|
|
return sc;
|
|
|
|
sc = ScReplaceString(strTaskpadHTML, TEXT("@@TASKWIDTH@@"), GetOrientation() & TVO_VERTICAL ? TEXT("100%") : TEXT("30%")); // only one task per row for vertical taskpads
|
|
if(sc)
|
|
return sc;
|
|
|
|
CStr strName = GetName().data();
|
|
sc = ScUseHTMLEntities(strName);
|
|
if(sc)
|
|
return sc;
|
|
|
|
CStr strDescription = GetDescription().data();
|
|
sc = ScUseHTMLEntities(strDescription);
|
|
if(sc)
|
|
return sc;
|
|
|
|
sc = ScReplaceString(strTaskpadHTML, TEXT("@@CONSOLETASKPADNAME@@"), strName);
|
|
if(sc)
|
|
return sc;
|
|
|
|
sc = ScReplaceString(strTaskpadHTML, TEXT("@@CONSOLETASKPADDESCRIPTION@@"), strDescription);
|
|
if(sc)
|
|
return sc;
|
|
|
|
if (GetOrientation() & TVO_VERTICAL)
|
|
{
|
|
// small, medium and large list sizes correspond to taskpad areas of 262, 212, and 166 pixels respectively
|
|
CStr strLeftPaneWidth;
|
|
if(GetListSize()==eSize_Small)
|
|
strLeftPaneWidth=TEXT("262");
|
|
if(GetListSize()==eSize_Medium)
|
|
strLeftPaneWidth=TEXT("212");
|
|
if(GetListSize()==eSize_Large)
|
|
strLeftPaneWidth=TEXT("166");
|
|
|
|
sc = ScReplaceString(strTaskpadHTML, TEXT("@@LEFTPANEWIDTH@@"), strLeftPaneWidth);
|
|
if(sc)
|
|
return sc;
|
|
}
|
|
else if (GetOrientation() & TVO_HORIZONTAL)
|
|
{
|
|
// small, medium and large list sizes correspond to taskpad heights of 200, 150, and 100 pixels respectively
|
|
CStr strBottomPaneHeight;
|
|
|
|
if(GetListSize()==eSize_Small)
|
|
strBottomPaneHeight=TEXT("200");
|
|
if(GetListSize()==eSize_Medium)
|
|
strBottomPaneHeight=TEXT("150");
|
|
if(GetListSize()==eSize_Large)
|
|
strBottomPaneHeight=TEXT("100");
|
|
|
|
sc = ScReplaceString(strTaskpadHTML, TEXT("@@BOTTOMPANEHEIGHT@@"), strBottomPaneHeight);
|
|
if(sc)
|
|
return sc;
|
|
}
|
|
|
|
return sc;
|
|
}
|
|
|
|
/*+-------------------------------------------------------------------------*
|
|
*
|
|
* CConsoleTaskpad::Reset
|
|
*
|
|
* PURPOSE:
|
|
*
|
|
* RETURNS:
|
|
* void
|
|
*
|
|
*+-------------------------------------------------------------------------*/
|
|
void
|
|
CConsoleTaskpad::ResetUI()
|
|
{
|
|
// reset all the contained tasks.
|
|
for (TaskIter iter = BeginTask(); iter!=EndTask(); ++iter)
|
|
{
|
|
iter->ResetUI();
|
|
}
|
|
|
|
// reset the member bookmark
|
|
m_bmTargetNode.ResetUI();
|
|
}
|
|
|
|
|
|
/*+-------------------------------------------------------------------------*
|
|
* CConsoleTaskpad::Retarget
|
|
*
|
|
*
|
|
*--------------------------------------------------------------------------*/
|
|
|
|
bool CConsoleTaskpad::Retarget (CMTNode* pMTNewNode, bool fReset)
|
|
{
|
|
/*
|
|
* if we were given a new node...
|
|
*/
|
|
if (pMTNewNode != NULL)
|
|
{
|
|
// Ensure the MTNode is initialized.
|
|
if (!pMTNewNode->IsInitialized())
|
|
{
|
|
HRESULT hr = pMTNewNode->Init();
|
|
ASSERT(SUCCEEDED(hr));
|
|
}
|
|
|
|
/*
|
|
* ...if we've already been targeted to a particular node
|
|
* type, prevent retargeting to a different node type
|
|
*/
|
|
if ( (!fReset) && (m_guidNodeType != GUID_NULL))
|
|
{
|
|
GUID guidNewNodeType;
|
|
pMTNewNode->GetNodeType (&guidNewNodeType);
|
|
|
|
if (guidNewNodeType != m_guidNodeType)
|
|
return (false);
|
|
}
|
|
|
|
/*
|
|
* otherwise, this is the first non-NULL node we've been
|
|
* targeted to; get its node type
|
|
*/
|
|
else
|
|
pMTNewNode->GetNodeType (&m_guidNodeType);
|
|
|
|
/*
|
|
* If this is a new taskpad, default the taskpad's name
|
|
* to the target node's display name. The taskpad
|
|
* description and tooltip default to empty.
|
|
*/
|
|
if (m_strName.str().empty() || fReset)
|
|
{
|
|
m_strName = pMTNewNode->GetDisplayName();
|
|
ASSERT (m_strDescription.str().empty());
|
|
ASSERT (m_strTooltip.str().empty());
|
|
}
|
|
}
|
|
|
|
m_bmTargetNode.ScRetarget(pMTNewNode, false /*bFastRetrievalOnly*/);
|
|
m_pMTNodeTarget = pMTNewNode;
|
|
|
|
SetDirty ();
|
|
return (true);
|
|
}
|
|
|
|
bool CConsoleTaskpad::Retarget (CNode* pNewNode)
|
|
{
|
|
CMTNode* pMTNewNode = (pNewNode != NULL) ? pNewNode->GetMTNode() : NULL;
|
|
|
|
return (Retarget (pMTNewNode));
|
|
}
|
|
|
|
|
|
/*+-------------------------------------------------------------------------*
|
|
* CConsoleTaskpad::SetName
|
|
*
|
|
*
|
|
*--------------------------------------------------------------------------*/
|
|
|
|
void CConsoleTaskpad::SetName (const tstring& strName)
|
|
{
|
|
SetStringMember (m_strName, strName);
|
|
}
|
|
|
|
|
|
/*+-------------------------------------------------------------------------*
|
|
* CConsoleTaskpad::SetDescription
|
|
*
|
|
*
|
|
*--------------------------------------------------------------------------*/
|
|
|
|
void CConsoleTaskpad::SetDescription (const tstring& strDescription)
|
|
{
|
|
SetStringMember (m_strDescription, strDescription);
|
|
}
|
|
|
|
|
|
void CConsoleTaskpad::SetListSize(const ListSize listSize)
|
|
{
|
|
m_listSize = listSize;
|
|
SetDirty();
|
|
}
|
|
|
|
/*+-------------------------------------------------------------------------*
|
|
* CConsoleTaskpad::SetToolTip
|
|
*
|
|
*
|
|
*--------------------------------------------------------------------------*/
|
|
|
|
void CConsoleTaskpad::SetToolTip (const tstring& strTooltip)
|
|
{
|
|
SetStringMember (m_strTooltip, strTooltip);
|
|
}
|
|
|
|
|
|
void
|
|
CConsoleTaskpad::SetNodeSpecific (bool bNodeSpecific)
|
|
{
|
|
m_bNodeSpecific = bNodeSpecific;
|
|
SetDirty();
|
|
}
|
|
|
|
void
|
|
CConsoleTaskpad::SetReplacesDefaultView(bool bReplacesDefaultView)
|
|
{
|
|
m_bReplacesDefaultView = bReplacesDefaultView;
|
|
SetDirty();
|
|
}
|
|
|
|
|
|
/*+-------------------------------------------------------------------------*
|
|
* CConsoleTaskpad::SetStringMember
|
|
*
|
|
* Changes the value of a string member variable, and marks the taskpad
|
|
* dirty, if and only if the new value is different than the old value.
|
|
*--------------------------------------------------------------------------*/
|
|
|
|
void CConsoleTaskpad::SetStringMember (
|
|
CStringTableString& strMember,
|
|
const tstring& strNewValue)
|
|
{
|
|
if (strMember != strNewValue)
|
|
{
|
|
strMember = strNewValue;
|
|
SetDirty ();
|
|
}
|
|
}
|
|
|
|
/*+-------------------------------------------------------------------------*
|
|
* CConsoleTaskpad::AddTask
|
|
*
|
|
*
|
|
*--------------------------------------------------------------------------*/
|
|
|
|
CConsoleTaskpad::TaskIter
|
|
CConsoleTaskpad::AddTask (const CConsoleTask& task)
|
|
{
|
|
return (InsertTask (m_Tasks.end(), task));
|
|
}
|
|
|
|
|
|
/*+-------------------------------------------------------------------------*
|
|
* CConsoleTaskpad::InsertTask
|
|
*
|
|
*
|
|
*--------------------------------------------------------------------------*/
|
|
|
|
CConsoleTaskpad::TaskIter
|
|
CConsoleTaskpad::InsertTask (
|
|
TaskIter itTaskBeforeWhichToInsert,
|
|
const CConsoleTask& task)
|
|
{
|
|
TaskIter itInserted = m_Tasks.insert (itTaskBeforeWhichToInsert, task);
|
|
SetDirty ();
|
|
|
|
return (itInserted);
|
|
}
|
|
|
|
|
|
/*+-------------------------------------------------------------------------*
|
|
* CConsoleTaskpad::EraseTask
|
|
*
|
|
*
|
|
*--------------------------------------------------------------------------*/
|
|
|
|
CConsoleTaskpad::TaskIter
|
|
CConsoleTaskpad::EraseTask (
|
|
TaskIter itErase)
|
|
{
|
|
SetDirty ();
|
|
return (m_Tasks.erase (itErase));
|
|
}
|
|
|
|
|
|
/*+-------------------------------------------------------------------------*
|
|
* CConsoleTaskpad::EraseTasks
|
|
*
|
|
*
|
|
*--------------------------------------------------------------------------*/
|
|
|
|
CConsoleTaskpad::TaskIter
|
|
CConsoleTaskpad::EraseTasks (
|
|
TaskIter itFirst,
|
|
TaskIter itLast)
|
|
{
|
|
SetDirty ();
|
|
return (m_Tasks.erase (itFirst, itLast));
|
|
}
|
|
|
|
|
|
/*+-------------------------------------------------------------------------*
|
|
* CConsoleTaskpad::ClearTasks
|
|
*
|
|
*
|
|
*--------------------------------------------------------------------------*/
|
|
|
|
void CConsoleTaskpad::ClearTasks ()
|
|
{
|
|
SetDirty ();
|
|
m_Tasks.clear ();
|
|
}
|
|
|
|
|
|
/*+-------------------------------------------------------------------------*
|
|
* CConsoleTaskpad::IsDirty
|
|
*
|
|
* Determines if this taskpad or any of its contained tasks is are dirty.
|
|
*--------------------------------------------------------------------------*/
|
|
|
|
bool CConsoleTaskpad::IsDirty () const
|
|
{
|
|
/*
|
|
* if the taskpad is dirty, short out
|
|
*/
|
|
if (m_fDirty)
|
|
{
|
|
TraceDirtyFlag(TEXT("CConsoleTaskpad"), true);
|
|
return (true);
|
|
}
|
|
|
|
/*
|
|
* the taskpad is clean, check each task
|
|
*/
|
|
for (TaskConstIter it = m_Tasks.begin(); it != m_Tasks.end(); ++it)
|
|
{
|
|
if (it->IsDirty())
|
|
{
|
|
TraceDirtyFlag(TEXT("CConsoleTaskpad"), true);
|
|
return (true);
|
|
}
|
|
}
|
|
|
|
TraceDirtyFlag(TEXT("CConsoleTaskpad"), false);
|
|
return (false);
|
|
}
|
|
|
|
|
|
/*+-------------------------------------------------------------------------*
|
|
* CConsoleTaskpad::GetTargetMTNode
|
|
*
|
|
*
|
|
*--------------------------------------------------------------------------*/
|
|
|
|
CMTNode* CConsoleTaskpad::GetTargetMTNode (IScopeTree* pScopeTree)
|
|
{
|
|
DECLARE_SC(sc, TEXT("CConsoleTaskpad::GetTargetMTNode"));
|
|
|
|
if(!HasTarget())
|
|
return NULL;
|
|
|
|
if(!m_pMTNodeTarget)
|
|
{
|
|
CMTNode *pMTNode = NULL;
|
|
bool bExactMatchFound = false; // out value from ScGetMTNode, unused
|
|
sc = m_bmTargetNode.ScGetMTNode(true /*bExactMatchRequired*/, &pMTNode, bExactMatchFound);
|
|
if(sc.IsError() || !pMTNode)
|
|
return NULL;
|
|
|
|
|
|
m_pMTNodeTarget = pMTNode;
|
|
}
|
|
|
|
return (m_pMTNodeTarget);
|
|
}
|
|
|
|
/*+-------------------------------------------------------------------------*
|
|
*
|
|
* CConsoleTaskpad::Persist
|
|
*
|
|
* PURPOSE: Persists the console taskpad to the specified persistor.
|
|
*
|
|
* PARAMETERS:
|
|
* CPersistor & persistor :
|
|
*
|
|
* RETURNS:
|
|
* void
|
|
*
|
|
*+-------------------------------------------------------------------------*/
|
|
void
|
|
CConsoleTaskpad::Persist(CPersistor &persistor)
|
|
{
|
|
persistor.PersistString(XML_ATTR_TASKPAD_NAME, m_strName);
|
|
persistor.PersistString(XML_ATTR_TASKPAD_DESCRIPTION, m_strDescription);
|
|
persistor.PersistString(XML_ATTR_TASKPAD_TOOLTIP, m_strTooltip);
|
|
|
|
// define the table to map enumeration values to strings
|
|
static const EnumLiteral mappedSize[] =
|
|
{
|
|
{ eSize_Large, XML_ENUM_LIST_SIZE_LARGE },
|
|
{ eSize_Medium, XML_ENUM_LIST_SIZE_MEDIUM },
|
|
{ eSize_None, XML_ENUM_LIST_SIZE_NONE },
|
|
{ eSize_Small, XML_ENUM_LIST_SIZE_SMALL },
|
|
};
|
|
|
|
// create wrapper to persist flag values as strings
|
|
CXMLEnumeration listSizePersistor(m_listSize, mappedSize, countof(mappedSize));
|
|
|
|
// initialize the value suitably
|
|
if(persistor.IsLoading())
|
|
m_listSize = eSize_Default;
|
|
|
|
// persist the wrapper
|
|
persistor.PersistAttribute(XML_ATTR_TASKPAD_LIST_SIZE, listSizePersistor, attr_optional); // optional because this was introduced late
|
|
|
|
persistor.PersistAttribute(XML_ATTR_TASKPAD_NODE_SPECIFIC, CXMLBoolean(m_bNodeSpecific));
|
|
persistor.PersistAttribute(XML_ATTR_REPLACES_DEFAULT_VIEW, CXMLBoolean(m_bReplacesDefaultView), attr_optional);
|
|
|
|
|
|
// define the table to map enumeration values to strings
|
|
static const EnumLiteral mappedOrientation[] =
|
|
{
|
|
{ TVO_HORIZONTAL, XML_BITFLAG_TASK_ORIENT_HORIZONTAL },
|
|
{ TVO_VERTICAL, XML_BITFLAG_TASK_ORIENT_VERTICAL },
|
|
{ TVO_NO_RESULTS, XML_BITFLAG_TASK_ORIENT_NO_RESULTS },
|
|
{ TVO_DESCRIPTIONS_AS_TEXT, XML_BITFLAG_TASK_ORIENT_DESCRIPTIONS_AS_TEXT },
|
|
};
|
|
|
|
// create wrapper to persist flag values as strings
|
|
CXMLBitFlags orientationPersistor(m_dwOrientation, mappedOrientation, countof(mappedOrientation));
|
|
// persist the wrapper
|
|
persistor.PersistAttribute(XML_ATTR_TASKPAD_ORIENTATION, orientationPersistor );
|
|
|
|
persistor.Persist(m_Tasks);
|
|
persistor.PersistAttribute(XML_ATTR_TASKPAD_NODE_TYPE, m_guidNodeType);
|
|
persistor.PersistAttribute(XML_ATTR_TASKPAD_ID, m_guidID);
|
|
|
|
persistor.Persist(m_bmTargetNode, XML_NAME_TARGET_NODE);
|
|
|
|
// either read or saved - not dirty after the operation
|
|
SetDirty(false);
|
|
}
|
|
|
|
/*+-------------------------------------------------------------------------*
|
|
* CConsoleTaskpad::ReadSerialObject
|
|
*
|
|
*
|
|
*--------------------------------------------------------------------------*/
|
|
|
|
HRESULT
|
|
CConsoleTaskpad::ReadSerialObject (IStream &stm, UINT nVersion)
|
|
{
|
|
HRESULT hr = S_FALSE; // assume unknown version
|
|
|
|
|
|
if(nVersion==1)
|
|
{
|
|
try
|
|
{
|
|
do // not a loop
|
|
{
|
|
bool fLegacyHasTarget = true; // an unused field
|
|
UINT visualPercent = 25; // replaced by m_listSize
|
|
|
|
stm >> m_strName;
|
|
stm >> m_strDescription;
|
|
stm >> m_strTooltip;
|
|
stm >> visualPercent;
|
|
|
|
m_listSize = eSize_Medium;
|
|
if(visualPercent==25)
|
|
m_listSize = eSize_Large;
|
|
else if(visualPercent==75)
|
|
m_listSize = eSize_Small;
|
|
|
|
stm >> m_bNodeSpecific;
|
|
m_bReplacesDefaultView = false; // this was introduced in mmc2.0.
|
|
stm >> m_dwOrientation;
|
|
|
|
hr = ::Read(stm, m_Tasks);
|
|
BREAK_ON_FAIL (hr);
|
|
|
|
stm >> m_guidNodeType;
|
|
stm >> m_guidID;
|
|
stm >> fLegacyHasTarget;
|
|
stm >> m_bmTargetNode;
|
|
|
|
// legacy task symbol info
|
|
{
|
|
BOOL bLegacyUseMMCSymbols = TRUE; // a now obsolete field, read for console file compatibility
|
|
tstring strFileLegacy, strFontLegacy;
|
|
DWORD dwSymbol = 0;
|
|
|
|
stm >> dwSymbol;
|
|
stm >> bLegacyUseMMCSymbols;
|
|
stm >> strFileLegacy; // obsolete
|
|
stm >> strFontLegacy; // obsolete
|
|
}
|
|
|
|
|
|
|
|
hr = S_OK; // success!
|
|
|
|
} while (false);
|
|
}
|
|
catch (_com_error& err)
|
|
{
|
|
hr = err.Error();
|
|
ASSERT (false && "Caught _com_error");
|
|
}
|
|
}
|
|
|
|
return (hr);
|
|
}
|
|
|
|
|
|
//############################################################################
|
|
//############################################################################
|
|
//
|
|
// Implementation of class CConsoleTaskpadList
|
|
//
|
|
//############################################################################
|
|
//############################################################################
|
|
/*+-------------------------------------------------------------------------*
|
|
*
|
|
* CConsoleTaskpadList::ScGetTaskpadList
|
|
*
|
|
* PURPOSE: Returns the list of all taskpads that are appropriate for the current node.
|
|
*
|
|
* PARAMETERS:
|
|
* CNode * pNode :
|
|
* CConsoleTaskpadFilteredList & filteredList : [OUT]: The list of taskpads
|
|
*
|
|
* RETURNS:
|
|
* SC
|
|
*
|
|
*+-------------------------------------------------------------------------*/
|
|
SC
|
|
CConsoleTaskpadList::ScGetTaskpadList(CNode *pNode, CConsoleTaskpadFilteredList &filteredList)
|
|
{
|
|
DECLARE_SC(sc, TEXT("CConsoleTaskpadList::ScGetTaskpadList"));
|
|
|
|
sc = ScCheckPointers(pNode);
|
|
if(sc)
|
|
return sc;
|
|
|
|
// 1. add all built- in taskpads
|
|
|
|
for(iterator iter = begin(); iter != end(); ++iter)
|
|
{
|
|
CConsoleTaskpad *pConsoleTaskpad = &*iter;
|
|
if(pConsoleTaskpad->IsValid(pNode))
|
|
{
|
|
filteredList.push_back(pConsoleTaskpad);
|
|
}
|
|
}
|
|
|
|
return sc;
|
|
}
|
|
|
|
HRESULT
|
|
CConsoleTaskpadList::ReadSerialObject (IStream &stm, UINT nVersion)
|
|
{
|
|
HRESULT hr = S_FALSE; // assume unknown version
|
|
|
|
clear();
|
|
|
|
if(nVersion == 1)
|
|
{
|
|
try
|
|
{
|
|
DWORD cItems;
|
|
stm >> cItems;
|
|
|
|
for(int i=0; i< cItems; i++)
|
|
{
|
|
CConsoleTaskpad taskpad;
|
|
hr = taskpad.Read(stm);
|
|
BREAK_ON_FAIL (hr);
|
|
push_back(taskpad);
|
|
}
|
|
}
|
|
catch (_com_error& err)
|
|
{
|
|
hr = err.Error();
|
|
ASSERT (false && "Caught _com_error");
|
|
}
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
//############################################################################
|
|
//############################################################################
|
|
//
|
|
// Implementation of class CDefaultTaskpadList
|
|
//
|
|
//############################################################################
|
|
//############################################################################
|
|
HRESULT
|
|
CDefaultTaskpadList::ReadSerialObject (IStream &stm, UINT nVersion)
|
|
{
|
|
HRESULT hr = S_FALSE; // assume unknown version
|
|
|
|
clear();
|
|
|
|
if(nVersion == 1)
|
|
{
|
|
try
|
|
{
|
|
/*
|
|
* TODO: investigate using template operator>> for a map (stgio.h)
|
|
*/
|
|
|
|
DWORD cItems;
|
|
stm >> cItems;
|
|
|
|
for(int i=0; i< cItems; i++)
|
|
{
|
|
GUID guidNodetype, guidTaskpad;
|
|
stm >> guidNodetype;
|
|
stm >> guidTaskpad;
|
|
operator[](guidNodetype) = guidTaskpad;
|
|
}
|
|
|
|
hr = S_OK;
|
|
}
|
|
catch (_com_error& err)
|
|
{
|
|
hr = err.Error();
|
|
ASSERT (false && "Caught _com_error");
|
|
}
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
|