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.
1749 lines
45 KiB
1749 lines
45 KiB
/**********************************************************************/
|
|
/** Microsoft Windows/NT **/
|
|
/** Copyright(c) Microsoft Corporation, 1997 - 1999 **/
|
|
/**********************************************************************/
|
|
|
|
/*
|
|
tfsnode.cpp
|
|
|
|
FILE HISTORY:
|
|
|
|
*/
|
|
|
|
#include "stdafx.h"
|
|
#include "util.h"
|
|
#include "tfsnode.h"
|
|
|
|
DEBUG_DECLARE_INSTANCE_COUNTER(TFSNodeEnum);
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
TFSNodeEnum::TFSNodeEnum
|
|
-
|
|
Author: EricDav
|
|
---------------------------------------------------------------------------*/
|
|
TFSNodeEnum::TFSNodeEnum(TFSContainer * pContainer)
|
|
: m_cRef(1)
|
|
{
|
|
DEBUG_INCREMENT_INSTANCE_COUNTER(TFSNodeEnum);
|
|
|
|
Assert(pContainer->IsContainer());
|
|
pContainer->AddRef();
|
|
m_pNode = pContainer;
|
|
|
|
Reset();
|
|
}
|
|
|
|
TFSNodeEnum::~TFSNodeEnum()
|
|
{
|
|
DEBUG_DECREMENT_INSTANCE_COUNTER(TFSNodeEnum);
|
|
|
|
m_pNode->Release();
|
|
m_pNode = NULL;
|
|
}
|
|
|
|
IMPLEMENT_ADDREF_RELEASE(TFSNodeEnum)
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
TFSNodeEnum::QueryInterface
|
|
-
|
|
Author: EricDav
|
|
---------------------------------------------------------------------------*/
|
|
STDMETHODIMP TFSNodeEnum::QueryInterface(REFIID riid, LPVOID *ppv)
|
|
{
|
|
// Is the pointer bad?
|
|
if (ppv == NULL)
|
|
return E_INVALIDARG;
|
|
|
|
// Place NULL in *ppv in case of failure
|
|
*ppv = NULL;
|
|
|
|
// This is the non-delegating IUnknown implementation
|
|
if (riid == IID_IUnknown || riid == IID_ITFSNodeEnum)
|
|
*ppv = (LPVOID) this;
|
|
|
|
// If we're going to return an interface, AddRef it first
|
|
if (*ppv)
|
|
{
|
|
((LPUNKNOWN) *ppv)->AddRef();
|
|
return hrOK;
|
|
}
|
|
else
|
|
return E_NOINTERFACE;
|
|
}
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
TFSNodeEnum::Next
|
|
We always return one node
|
|
Author: EricDav
|
|
---------------------------------------------------------------------------*/
|
|
STDMETHODIMP
|
|
TFSNodeEnum::Next
|
|
(
|
|
ULONG uNum,
|
|
ITFSNode ** ppNode,
|
|
ULONG * pNumReturned
|
|
)
|
|
{
|
|
HRESULT hr = hrFalse;
|
|
ULONG nNumReturned = 0;
|
|
ITFSNode * pNode;
|
|
|
|
COM_PROTECT_TRY
|
|
{
|
|
|
|
if (ppNode)
|
|
*ppNode = NULL;
|
|
|
|
if ((m_pNode->IsContainer()) && (uNum >= 1) && (m_pos != NULL))
|
|
{
|
|
while (m_pos)
|
|
{
|
|
pNode = m_pNode->m_listChildren.GetNext(m_pos);
|
|
|
|
if (pNode &&
|
|
((pNode->GetVisibilityState() & TFS_VIS_DELETE) == 0))
|
|
{
|
|
*ppNode = pNode;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (*ppNode)
|
|
{
|
|
((LPUNKNOWN)*ppNode)->AddRef();
|
|
nNumReturned = 1;
|
|
hr = S_OK;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
nNumReturned = 0;
|
|
hr = S_FALSE;
|
|
}
|
|
|
|
if (pNumReturned)
|
|
*pNumReturned = nNumReturned;
|
|
}
|
|
COM_PROTECT_CATCH
|
|
|
|
if (FHrFailed(hr))
|
|
{
|
|
if (pNumReturned)
|
|
*pNumReturned = 0;
|
|
*ppNode = NULL;
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
TFSNodeEnum::Skip
|
|
-
|
|
Author: EricDav
|
|
---------------------------------------------------------------------------*/
|
|
STDMETHODIMP
|
|
TFSNodeEnum::Skip
|
|
(
|
|
ULONG uNum
|
|
)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
TFSNodeEnum::Reset
|
|
-
|
|
Author: EricDav
|
|
---------------------------------------------------------------------------*/
|
|
STDMETHODIMP
|
|
TFSNodeEnum::Reset()
|
|
{
|
|
m_pos = m_pNode->m_listChildren.GetHeadPosition();
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
TFSNodeEnum::Clone
|
|
-
|
|
Author: EricDav
|
|
---------------------------------------------------------------------------*/
|
|
STDMETHODIMP
|
|
TFSNodeEnum::Clone
|
|
(
|
|
ITFSNodeEnum **ppEnum
|
|
)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
DEBUG_DECLARE_INSTANCE_COUNTER(TFSNode);
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
TFSNode::TFSNode
|
|
-
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
TFSNode::TFSNode()
|
|
: m_cRef(1),
|
|
m_cPropSheet(0),
|
|
m_pNodeType(NULL),
|
|
m_uData(0),
|
|
m_cookie(0),
|
|
m_tfsVis(TFS_VIS_SHOW),
|
|
m_fContainer(0),
|
|
m_nImageIndex(0),
|
|
m_nOpenImageIndex(0),
|
|
m_lParam(0),
|
|
m_fDirty(0),
|
|
m_hScopeItem(0),
|
|
m_hRelativeId(0),
|
|
m_ulRelativeFlags(0),
|
|
m_fScopeLeafNode(FALSE)
|
|
{
|
|
DEBUG_INCREMENT_INSTANCE_COUNTER(TFSNode);
|
|
|
|
IfDebug(m_bCookieSet=FALSE);
|
|
}
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
TFSNode::~TFSNode
|
|
-
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
TFSNode::~TFSNode()
|
|
{
|
|
DEBUG_DECREMENT_INSTANCE_COUNTER(TFSNode);
|
|
|
|
Assert(m_cPropSheet == 0);
|
|
Assert(m_cRef == 0);
|
|
}
|
|
|
|
IMPLEMENT_ADDREF_RELEASE(TFSNode)
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
TFSNode::QueryInterface
|
|
-
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
STDMETHODIMP TFSNode::QueryInterface(REFIID riid, LPVOID *ppv)
|
|
{
|
|
// Is the pointer bad?
|
|
if (ppv == NULL)
|
|
return E_INVALIDARG;
|
|
|
|
// Place NULL in *ppv in case of failure
|
|
*ppv = NULL;
|
|
|
|
// This is the non-delegating IUnknown implementation
|
|
if (riid == IID_IUnknown || riid == IID_ITFSNode)
|
|
*ppv = (LPVOID) this;
|
|
|
|
// If we're going to return an interface, AddRef it first
|
|
if (*ppv)
|
|
{
|
|
((LPUNKNOWN) *ppv)->AddRef();
|
|
return hrOK;
|
|
}
|
|
else
|
|
return E_NOINTERFACE;
|
|
}
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
TFSNode::Construct
|
|
The pNodeType parameter must stay around for the lifetime of
|
|
the node, we do not make a copy of it!
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
HRESULT TFSNode::Construct(const GUID *pNodeType,
|
|
ITFSNodeHandler *pHandler,
|
|
ITFSResultHandler *pResultHandler,
|
|
ITFSNodeMgr *pNodeMgr)
|
|
{
|
|
m_pNodeType = pNodeType;
|
|
m_spNodeHandler.Set(pHandler);
|
|
m_spResultHandler.Set(pResultHandler);
|
|
m_spNodeMgr.Set(pNodeMgr);
|
|
|
|
return hrOK;
|
|
}
|
|
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
TFSNode::Init
|
|
Implementation of ITSFNode::Init
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
STDMETHODIMP TFSNode::Init(int nImageIndex, int nOpenImageIndex,
|
|
LPARAM lParam, MMC_COOKIE cookie
|
|
)
|
|
{
|
|
m_nImageIndex = nImageIndex;
|
|
m_nOpenImageIndex = nOpenImageIndex;
|
|
m_lParam = lParam;
|
|
m_cookie = cookie;
|
|
|
|
return hrOK;
|
|
}
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
TFSNode::GetParent
|
|
Implementation of ITFSNode::GetParent
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
STDMETHODIMP TFSNode::GetParent(ITFSNode **ppNode)
|
|
{
|
|
Assert(ppNode);
|
|
*ppNode = NULL;
|
|
|
|
SetI((LPUNKNOWN *) ppNode, m_spNodeParent);
|
|
return hrOK;
|
|
}
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
TFSNode::SetParent
|
|
-
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
STDMETHODIMP TFSNode::SetParent(ITFSNode *pNode)
|
|
{
|
|
m_spNodeParent.Set(pNode);
|
|
return hrOK;
|
|
}
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
TFSNode::GetNodeMgr
|
|
Implementation of ITFSNode::GetNodeMgr
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
STDMETHODIMP TFSNode::GetNodeMgr(ITFSNodeMgr **ppNodeMgr)
|
|
{
|
|
Assert(ppNodeMgr);
|
|
*ppNodeMgr = NULL;
|
|
SetI((LPUNKNOWN *) ppNodeMgr, m_spNodeMgr);
|
|
return hrOK;
|
|
}
|
|
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
TFSNode::IsVisible
|
|
Implementation of ITFSNode::IsVisible
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
STDMETHODIMP_(BOOL) TFSNode::IsVisible()
|
|
{
|
|
// If we are the root node, then we are ALWAYS visible
|
|
// (actually it's kind of weird because the root node is never
|
|
// shown to the user). It's an imaginary construct much as
|
|
// software is (in a way) imaginary. Software is structure
|
|
// imposed on a mass of random machine instructions and data.
|
|
|
|
return (m_tfsVis & TFS_VIS_SHOW);
|
|
}
|
|
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
TFSNode::SetVisibilityState
|
|
Implementation of ITFSNode::SetVisibilityState
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
STDMETHODIMP TFSNode::SetVisibilityState(TFSVisibility vis)
|
|
{
|
|
m_tfsVis = vis;
|
|
return hrOK;
|
|
}
|
|
|
|
STDMETHODIMP_(TFSVisibility) TFSNode::GetVisibilityState()
|
|
{
|
|
return m_tfsVis;
|
|
}
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
TFSNode::IsInUI
|
|
Implementation of ITFSNode::IsInUI
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
STDMETHODIMP_(BOOL) TFSNode::IsInUI()
|
|
{
|
|
// If we have been added to the UI, then return TRUE
|
|
return (m_hScopeItem != 0);
|
|
}
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
TFSContainer::InternalRemoveFromUI
|
|
Removes a node from the UI and sets its scope ID to zero
|
|
Author: EricDav
|
|
---------------------------------------------------------------------------*/
|
|
HRESULT TFSNode::InternalRemoveFromUI(ITFSNode *pNodeChild,
|
|
BOOL fDeleteThis)
|
|
{
|
|
HRESULT hr = hrOK;
|
|
|
|
SPIConsoleNameSpace spConsoleNS;
|
|
|
|
m_spNodeMgr->GetConsoleNameSpace(&spConsoleNS);
|
|
hr = spConsoleNS->DeleteItem(pNodeChild->GetData(TFS_DATA_SCOPEID), TRUE);
|
|
|
|
// Set the scope ID to 0 after we delete it from the UI
|
|
// and set all of the children's scope ID's to zero so that they will
|
|
// get added again later
|
|
if (SUCCEEDED(hr))
|
|
InternalZeroScopeID(pNodeChild, TRUE);
|
|
|
|
return hr;
|
|
}
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
TFSNode::InternalZeroScopeID
|
|
Recursively zeros the scope ID for all scope pane items
|
|
(container nodes only)
|
|
Author: EricDav
|
|
---------------------------------------------------------------------------*/
|
|
HRESULT TFSNode::InternalZeroScopeID(ITFSNode *pNode, BOOL fZeroChildren)
|
|
{
|
|
HRESULT hr = hrOK;
|
|
|
|
if (pNode->IsContainer())
|
|
{
|
|
if (fZeroChildren)
|
|
{
|
|
// recursively delete children
|
|
SPITFSNodeEnum spNodeEnum;
|
|
ITFSNode * pCurrentNode;
|
|
ULONG nNumReturned = 0;
|
|
|
|
pNode->GetEnum(&spNodeEnum);
|
|
|
|
spNodeEnum->Next(1, &pCurrentNode, &nNumReturned);
|
|
while (nNumReturned)
|
|
{
|
|
InternalZeroScopeID(pCurrentNode, fZeroChildren);
|
|
|
|
pCurrentNode->Release();
|
|
spNodeEnum->Next(1, &pCurrentNode, &nNumReturned);
|
|
}
|
|
}
|
|
}
|
|
|
|
// zero the scope ID for this node
|
|
pNode->SetData(TFS_DATA_SCOPEID, 0);
|
|
|
|
return hr;
|
|
}
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
TFSNode::Show
|
|
This function changes the visiblity state of the node in the UI.
|
|
Depending upon what has been set via SetVisibilityState, the function
|
|
will add or remove the node from the UI.
|
|
Author: KennT, EricDav
|
|
---------------------------------------------------------------------------*/
|
|
STDMETHODIMP TFSNode::Show()
|
|
{
|
|
AFX_MANAGE_STATE(AfxGetModuleState());
|
|
|
|
HRESULT hr = hrOK;
|
|
SCOPEDATAITEM scopedataitem;
|
|
SPIConsoleNameSpace spConsoleNS;
|
|
|
|
COM_PROTECT_TRY
|
|
{
|
|
// check to see if we should remove this node from the UI
|
|
if (IsInUI() && !IsVisible())
|
|
{
|
|
if (IsContainer())
|
|
{
|
|
CORg( InternalRemoveFromUI(this, TRUE) );
|
|
}
|
|
else
|
|
{
|
|
CORg( UpdateAllViewsHelper(reinterpret_cast<LPARAM>(this), RESULT_PANE_DELETE_ITEM) );
|
|
}
|
|
}
|
|
else
|
|
if (!IsInUI() && IsVisible())
|
|
{
|
|
// this node isn't in the UI and needs to be shown
|
|
|
|
if (IsContainer())
|
|
{
|
|
// If we're making this node visible, our parent should be also
|
|
Assert(!m_spNodeParent || m_spNodeParent->IsInUI());
|
|
|
|
//$ Review: kennt, what if our parent isn't visible?
|
|
// Do we want to act on this? Do we show all of our parents?
|
|
|
|
// add this node in the UI
|
|
CORg( InitializeScopeDataItem(&scopedataitem,
|
|
m_spNodeParent ?
|
|
m_spNodeParent->GetData(TFS_DATA_SCOPEID) :
|
|
NULL,
|
|
GetData(TFS_DATA_COOKIE),
|
|
m_nImageIndex,
|
|
m_nOpenImageIndex,
|
|
IsContainer(),
|
|
m_ulRelativeFlags,
|
|
m_hRelativeId));
|
|
|
|
CORg( m_spNodeMgr->GetConsoleNameSpace(&spConsoleNS) );
|
|
CORg( spConsoleNS->InsertItem(&scopedataitem) );
|
|
|
|
// Now that we've added the node to the scope pane, we have a HSCOPEITEM
|
|
SetData( TFS_DATA_SCOPEID, scopedataitem.ID );
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// result pane item, has to go through IComponent interface
|
|
//
|
|
hr = UpdateAllViewsHelper(reinterpret_cast<LPARAM>(this), RESULT_PANE_ADD_ITEM);
|
|
}
|
|
}
|
|
|
|
COM_PROTECT_ERROR_LABEL;
|
|
}
|
|
COM_PROTECT_CATCH
|
|
|
|
return hr;
|
|
}
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
TFSNode::ChangeNode
|
|
Implementation of ITFSnode::ChangeNode
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
HRESULT
|
|
TFSNode::ChangeNode
|
|
(
|
|
LONG_PTR changeMask
|
|
)
|
|
{
|
|
// will have to broadcast to all views
|
|
return UpdateAllViewsHelper(reinterpret_cast<LPARAM>(this), changeMask);
|
|
}
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
TFSNode::UpdateAllViewsHelper
|
|
Notifies the current view to do something. Add a node, change
|
|
a node or delete a node.
|
|
Author:
|
|
---------------------------------------------------------------------------*/
|
|
HRESULT
|
|
TFSNode::UpdateAllViewsHelper
|
|
(
|
|
LPARAM data,
|
|
LONG_PTR hint
|
|
)
|
|
{
|
|
HRESULT hr = hrOK;
|
|
SPIComponentData spCompData;
|
|
SPIConsole spConsole;
|
|
IDataObject* pDataObject;
|
|
|
|
COM_PROTECT_TRY
|
|
{
|
|
m_spNodeMgr->GetComponentData(&spCompData);
|
|
|
|
CORg ( spCompData->QueryDataObject(NULL, CCT_RESULT, &pDataObject) );
|
|
|
|
CORg ( m_spNodeMgr->GetConsole(&spConsole) );
|
|
|
|
CORg ( spConsole->UpdateAllViews(pDataObject, data, hint) );
|
|
|
|
pDataObject->Release();
|
|
|
|
COM_PROTECT_ERROR_LABEL;
|
|
}
|
|
COM_PROTECT_CATCH
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
TFSNode::GetData
|
|
Implementation of ITFSnode::GetData
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
STDMETHODIMP_(LONG_PTR) TFSNode::GetData(int nIndex)
|
|
{
|
|
AFX_MANAGE_STATE(AfxGetModuleState());
|
|
|
|
LONG_PTR uReturn = 0;
|
|
|
|
switch (nIndex)
|
|
{
|
|
case TFS_DATA_COOKIE:
|
|
Assert(m_bCookieSet);
|
|
uReturn = m_cookie;
|
|
break;
|
|
case TFS_DATA_SCOPEID:
|
|
uReturn = (LONG_PTR) m_hScopeItem;
|
|
break;
|
|
case TFS_DATA_IMAGEINDEX:
|
|
uReturn = m_nImageIndex;
|
|
break;
|
|
case TFS_DATA_OPENIMAGEINDEX:
|
|
uReturn = m_nOpenImageIndex;
|
|
break;
|
|
case TFS_DATA_PROPSHEETCOUNT:
|
|
uReturn = m_cPropSheet;
|
|
break;
|
|
case TFS_DATA_RELATIVE_FLAGS:
|
|
uReturn = m_ulRelativeFlags;
|
|
break;
|
|
case TFS_DATA_RELATIVE_SCOPEID:
|
|
uReturn = m_hRelativeId;
|
|
break;
|
|
case TFS_DATA_SCOPE_LEAF_NODE:
|
|
uReturn = m_fScopeLeafNode;
|
|
break;
|
|
case TFS_DATA_DIRTY:
|
|
uReturn = m_fDirty;
|
|
break;
|
|
case TFS_DATA_USER:
|
|
uReturn = m_uData;
|
|
break;
|
|
case TFS_DATA_TYPE:
|
|
uReturn = m_uType;
|
|
break;
|
|
case TFS_DATA_PARENT:
|
|
uReturn = m_uDataParent;
|
|
break;
|
|
default:
|
|
Panic1("Alert the troops!: invalid arg(%d) to ITFSNode::GetData",
|
|
nIndex);
|
|
break;
|
|
}
|
|
return uReturn;
|
|
}
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
TFSNode::SetData
|
|
Implementaton of ITFSNode::SetData
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
STDMETHODIMP_(LONG_PTR) TFSNode::SetData(int nIndex, LONG_PTR dwData)
|
|
{
|
|
AFX_MANAGE_STATE(AfxGetModuleState());
|
|
|
|
LONG_PTR dwOldValue = 0;
|
|
|
|
switch (nIndex)
|
|
{
|
|
case TFS_DATA_COOKIE:
|
|
IfDebug(m_bCookieSet=TRUE);
|
|
dwOldValue = m_cookie;
|
|
m_cookie = dwData;
|
|
break;
|
|
case TFS_DATA_SCOPEID:
|
|
dwOldValue = m_hScopeItem;
|
|
m_hScopeItem = (HSCOPEITEM) dwData;
|
|
break;
|
|
case TFS_DATA_IMAGEINDEX:
|
|
dwOldValue = m_nImageIndex;
|
|
m_nImageIndex = (UINT) dwData;
|
|
break;
|
|
case TFS_DATA_OPENIMAGEINDEX:
|
|
dwOldValue = m_nOpenImageIndex;
|
|
m_nOpenImageIndex = (UINT) dwData;
|
|
break;
|
|
case TFS_DATA_PROPSHEETCOUNT:
|
|
dwOldValue = m_cPropSheet;
|
|
m_cPropSheet = (UINT) dwData;
|
|
break;
|
|
case TFS_DATA_DIRTY:
|
|
dwOldValue = m_fDirty;
|
|
m_fDirty = (UINT) dwData;
|
|
break;
|
|
case TFS_DATA_RELATIVE_FLAGS:
|
|
dwOldValue = m_ulRelativeFlags;
|
|
m_ulRelativeFlags = (UINT) dwData;
|
|
break;
|
|
case TFS_DATA_RELATIVE_SCOPEID:
|
|
dwOldValue = m_hRelativeId;
|
|
m_hRelativeId = (HSCOPEITEM) dwData;
|
|
break;
|
|
case TFS_DATA_SCOPE_LEAF_NODE:
|
|
dwOldValue = m_fScopeLeafNode;
|
|
m_fScopeLeafNode = (BOOL) dwData;
|
|
break;
|
|
case TFS_DATA_USER:
|
|
dwOldValue = m_uData;
|
|
m_uData = dwData;
|
|
break;
|
|
case TFS_DATA_TYPE:
|
|
dwOldValue = m_uType;
|
|
m_uType = dwData;
|
|
break;
|
|
case TFS_DATA_PARENT:
|
|
dwOldValue = m_uDataParent;
|
|
m_uDataParent = dwData;
|
|
break;
|
|
default:
|
|
Panic1("Alert the troops!: invalid arg(%d) to ITFSNode::SetData",
|
|
nIndex);
|
|
break;
|
|
}
|
|
return dwOldValue;
|
|
}
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
TFSNode::Notify
|
|
Implementation of ITFSNode::Notify
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
STDMETHODIMP_(LONG_PTR) TFSNode::Notify(int nIndex, LPARAM lParam)
|
|
{
|
|
AFX_MANAGE_STATE(AfxGetModuleState());
|
|
|
|
LONG_PTR uReturn = 0;
|
|
|
|
switch (nIndex)
|
|
{
|
|
case TFS_NOTIFY_CREATEPROPSHEET:
|
|
{
|
|
SPITFSNodeHandler spHandler;
|
|
|
|
uReturn = InterlockedIncrement(&m_cPropSheet);
|
|
GetHandler(&spHandler);
|
|
if (spHandler)
|
|
spHandler->UserNotify(this, TFS_MSG_CREATEPROPSHEET, lParam);
|
|
}
|
|
break;
|
|
|
|
case TFS_NOTIFY_DELETEPROPSHEET:
|
|
{
|
|
SPITFSNodeHandler spHandler;
|
|
|
|
uReturn = InterlockedDecrement(&m_cPropSheet);
|
|
GetHandler(&spHandler);
|
|
if (spHandler)
|
|
spHandler->UserNotify(this, TFS_MSG_DELETEPROPSHEET, lParam);
|
|
}
|
|
break;
|
|
|
|
case TFS_NOTIFY_RESULT_CREATEPROPSHEET:
|
|
{
|
|
SPITFSResultHandler spHandler;
|
|
|
|
uReturn = InterlockedIncrement(&m_cPropSheet);
|
|
GetResultHandler(&spHandler);
|
|
if (spHandler)
|
|
spHandler->UserResultNotify(this, TFS_MSG_CREATEPROPSHEET, lParam);
|
|
}
|
|
break;
|
|
|
|
case TFS_NOTIFY_RESULT_DELETEPROPSHEET:
|
|
{
|
|
SPITFSResultHandler spHandler;
|
|
|
|
uReturn = InterlockedDecrement(&m_cPropSheet);
|
|
GetResultHandler(&spHandler);
|
|
if (spHandler)
|
|
spHandler->UserResultNotify(this, TFS_MSG_DELETEPROPSHEET, lParam);
|
|
}
|
|
break;
|
|
|
|
case TFS_NOTIFY_REMOVE_DELETED_NODES:
|
|
break;
|
|
|
|
default:
|
|
Panic1("Alert the troops!: invalid arg(%d) to ITFSNode::Notify",
|
|
nIndex);
|
|
break;
|
|
}
|
|
return uReturn;
|
|
}
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
TFSNode::GetHandler
|
|
Implementation of ITFSNode::GetHandler
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
STDMETHODIMP TFSNode::GetHandler(ITFSNodeHandler **ppNodeHandler)
|
|
{
|
|
Assert(ppNodeHandler);
|
|
*ppNodeHandler = NULL;
|
|
SetI((LPUNKNOWN *) ppNodeHandler, m_spNodeHandler);
|
|
return hrOK;
|
|
}
|
|
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
TFSNode::SetHandler
|
|
Implementation of ITFSNode::SetHandler
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
STDMETHODIMP TFSNode::SetHandler(ITFSNodeHandler *pNodeHandler)
|
|
{
|
|
m_spNodeHandler.Set(pNodeHandler);
|
|
return hrOK;
|
|
}
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
TFSNode::GetResultHandler
|
|
Implementation of ITFSNode::GetResultHandler
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
STDMETHODIMP TFSNode::GetResultHandler(ITFSResultHandler **ppResultHandler)
|
|
{
|
|
Assert(ppResultHandler);
|
|
*ppResultHandler = NULL;
|
|
SetI((LPUNKNOWN *) ppResultHandler, m_spResultHandler);
|
|
return hrOK;
|
|
}
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
TFSNode::SetResultHandler
|
|
-
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
STDMETHODIMP TFSNode::SetResultHandler(ITFSResultHandler *pResultHandler)
|
|
{
|
|
m_spResultHandler.Set(pResultHandler);
|
|
return hrOK;
|
|
}
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
TFSNode::GetString
|
|
Implementation of ITFSNode::GetString
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
STDMETHODIMP_(LPCTSTR) TFSNode::GetString(int nCol)
|
|
{
|
|
AFX_MANAGE_STATE(AfxGetModuleState());
|
|
|
|
// Need to forward this onto the handler
|
|
return m_spNodeHandler->GetString(static_cast<ITFSNode *>(this), nCol);
|
|
}
|
|
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
TFSNode::GetNodeType
|
|
Implementation of ITFSNode::GetNodeType
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
STDMETHODIMP_(const GUID *) TFSNode::GetNodeType()
|
|
{
|
|
return m_pNodeType;
|
|
}
|
|
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
TFSNode::SetNodeType
|
|
Implementation of ITFSNode::SetNodeType
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
STDMETHODIMP TFSNode::SetNodeType(const GUID *pGuid)
|
|
{
|
|
m_pNodeType = pGuid;
|
|
return hrOK;
|
|
}
|
|
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
TFSNode::IsContainer
|
|
Implementation of ITFSNode:;IsContainer
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
STDMETHODIMP_(BOOL) TFSNode::IsContainer()
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
STDMETHODIMP TFSNode::AddChild(ITFSNode *pNodeChild)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
STDMETHODIMP TFSNode::InsertChild(ITFSNode *pInsertAfterNode, ITFSNode *pNodeChild)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
STDMETHODIMP TFSNode::RemoveChild(ITFSNode *pNode)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
STDMETHODIMP TFSNode::ExtractChild(ITFSNode *pNode)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
STDMETHODIMP TFSNode::GetChildCount(int *pVisibleCount, int *pTotalCount)
|
|
{
|
|
if (pVisibleCount)
|
|
*pVisibleCount = 0;
|
|
if (pTotalCount)
|
|
*pTotalCount = 0;
|
|
return hrOK;
|
|
}
|
|
|
|
STDMETHODIMP TFSNode::GetEnum(ITFSNodeEnum **ppNodeEnum)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
STDMETHODIMP TFSNode::DeleteAllChildren(BOOL fRemoveFromUI)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
TFSNode::InitializeScopeDataItem
|
|
-
|
|
Author: EricDav, KennT
|
|
---------------------------------------------------------------------------*/
|
|
HRESULT TFSNode::InitializeScopeDataItem(LPSCOPEDATAITEM pScopeDataItem,
|
|
HSCOPEITEM pParentScopeItem,
|
|
LPARAM lParam,
|
|
int nImage,
|
|
int nOpenImage,
|
|
BOOL bHasChildren,
|
|
ULONG ulRelativeFlags,
|
|
HSCOPEITEM hSibling
|
|
)
|
|
{
|
|
AFX_MANAGE_STATE(AfxGetModuleState());
|
|
|
|
Assert(pScopeDataItem != NULL);
|
|
::ZeroMemory(pScopeDataItem, sizeof(SCOPEDATAITEM));
|
|
|
|
// set parent scope item
|
|
if (ulRelativeFlags & (SDI_NEXT | SDI_PREVIOUS))
|
|
{
|
|
pScopeDataItem->mask |= (ulRelativeFlags & (SDI_NEXT | SDI_PREVIOUS));
|
|
pScopeDataItem->mask |= SDI_FIRST;
|
|
pScopeDataItem->relativeID = hSibling;
|
|
}
|
|
else
|
|
{
|
|
if (ulRelativeFlags & SDI_FIRST)
|
|
pScopeDataItem->mask |= SDI_FIRST;
|
|
|
|
pScopeDataItem->mask |= SDI_PARENT;
|
|
pScopeDataItem->relativeID = pParentScopeItem;
|
|
}
|
|
|
|
// Add node name, we implement callback
|
|
pScopeDataItem->mask |= SDI_STR;
|
|
pScopeDataItem->displayname = MMC_CALLBACK;
|
|
|
|
// Add the lParam
|
|
pScopeDataItem->mask |= SDI_PARAM;
|
|
pScopeDataItem->lParam = lParam;
|
|
|
|
// Add close image
|
|
if (nImage != -1)
|
|
{
|
|
pScopeDataItem->mask |= SDI_IMAGE;
|
|
pScopeDataItem->nImage = nImage;
|
|
}
|
|
|
|
// Add open image
|
|
if (nOpenImage != -1)
|
|
{
|
|
pScopeDataItem->mask |= SDI_OPENIMAGE;
|
|
pScopeDataItem->nOpenImage = nOpenImage;
|
|
}
|
|
|
|
// Add button to node if the folder has children
|
|
if (bHasChildren == TRUE)
|
|
{
|
|
pScopeDataItem->mask |= SDI_CHILDREN;
|
|
pScopeDataItem->cChildren = 1;
|
|
|
|
if (m_fScopeLeafNode)
|
|
{
|
|
// Note: the bHasChildren flag is set because the node
|
|
// is really a container node or is a result container.
|
|
// If it is purely a result container, then the m_fScopeLeafNode
|
|
// will be set and we can clear the '+' symbol.
|
|
pScopeDataItem->cChildren = 0;
|
|
}
|
|
}
|
|
|
|
|
|
return hrOK;
|
|
}
|
|
|
|
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
TFSContainer::~TFSContainer
|
|
-
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
TFSContainer::~TFSContainer()
|
|
{
|
|
DeleteAllChildren(FALSE);
|
|
}
|
|
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
TFSContainer::IsContainer
|
|
Implementation of ITFSNode::IsContainer
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
STDMETHODIMP_(BOOL) TFSContainer::IsContainer()
|
|
{
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
TFSContainer::AddChild
|
|
Implementation of ITFSContainer::AddChild
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
STDMETHODIMP TFSContainer::AddChild(ITFSNode *pNodeChild)
|
|
{
|
|
return InsertChild(NULL, pNodeChild);
|
|
}
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
TFSContainer::InsertChild
|
|
Implementation of ITFSContainer::InsertChild
|
|
Author: EricDav
|
|
---------------------------------------------------------------------------*/
|
|
STDMETHODIMP TFSContainer::InsertChild(ITFSNode *pInsertAfterNode, ITFSNode *pNodeChild)
|
|
{
|
|
AFX_MANAGE_STATE(AfxGetModuleState());
|
|
|
|
SCOPEDATAITEM scopedataitem;
|
|
HRESULT hr = hrOK;
|
|
|
|
Assert(pNodeChild);
|
|
Assert(IsContainer());
|
|
|
|
// add the node to our internal tree
|
|
CORg( pNodeChild->SetParent(this) );
|
|
CORg( InternalAddToList(pInsertAfterNode, pNodeChild) );
|
|
|
|
// if we're not visible yet, we can't add this to the UI
|
|
if (!IsInUI())
|
|
{
|
|
return hrOK;
|
|
}
|
|
|
|
CORg( pNodeChild->Show() );
|
|
|
|
Error:
|
|
if (!FHrSucceeded(hr))
|
|
{
|
|
InternalRemoveFromList(pNodeChild);
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
TFSContainer::RemoveChild
|
|
Implementation of ITFSNode::RemoveChild
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
STDMETHODIMP TFSContainer::RemoveChild(ITFSNode *pNodeChild)
|
|
{
|
|
AFX_MANAGE_STATE(AfxGetModuleState());
|
|
HRESULT hr;
|
|
SPITFSNode spNode;
|
|
|
|
// This node must be kept alive during this operation
|
|
spNode.Set(pNodeChild);
|
|
hr = InternalRemoveChild(spNode, TRUE, TRUE, TRUE);
|
|
spNode->Destroy();
|
|
|
|
return hr;
|
|
}
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
TFSContainer::ExtractChild
|
|
Implementation of ITFSNode::ExtractChild
|
|
This function removes the node and all children from the UI, and
|
|
removes the node from our internal tree. It does not destroy the
|
|
node and it's children, call RemoveChild if that is required.
|
|
Author: EricDav
|
|
---------------------------------------------------------------------------*/
|
|
STDMETHODIMP TFSContainer::ExtractChild(ITFSNode *pNodeChild)
|
|
{
|
|
AFX_MANAGE_STATE(AfxGetModuleState());
|
|
|
|
return InternalRemoveChild(pNodeChild, TRUE, TRUE, FALSE);
|
|
}
|
|
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
TFSContainer::GetChildCount
|
|
-
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
STDMETHODIMP TFSContainer::GetChildCount(int *pVisibleCount, int *pTotalCount)
|
|
{
|
|
AFX_MANAGE_STATE(AfxGetModuleState());
|
|
|
|
HRESULT hr = hrOK;
|
|
|
|
COM_PROTECT_TRY
|
|
{
|
|
if (pTotalCount)
|
|
*pTotalCount = (int)m_listChildren.GetCount();
|
|
|
|
// Enumerate through all of the nodes and count the visible ones
|
|
if (pVisibleCount)
|
|
{
|
|
POSITION pos;
|
|
ITFSNode * pNode = NULL;
|
|
int cVisible = 0;
|
|
|
|
*pVisibleCount = 0;
|
|
pos = m_listChildren.GetHeadPosition();
|
|
while (pos != NULL)
|
|
{
|
|
pNode = m_listChildren.GetNext(pos);
|
|
if (pNode->IsInUI())
|
|
cVisible++;
|
|
}
|
|
*pVisibleCount = cVisible;
|
|
}
|
|
}
|
|
COM_PROTECT_CATCH
|
|
|
|
if (FHrFailed(hr))
|
|
{
|
|
if (pTotalCount)
|
|
*pTotalCount = 0;
|
|
if (pVisibleCount)
|
|
*pVisibleCount = 0;
|
|
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
TFSContainer::GetEnum
|
|
-
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
STDMETHODIMP TFSContainer::GetEnum(ITFSNodeEnum **ppNodeEnum)
|
|
{
|
|
HRESULT hr = hrOK;
|
|
TFSNodeEnum * pNodeEnum = NULL;
|
|
|
|
COM_PROTECT_TRY
|
|
{
|
|
pNodeEnum = new TFSNodeEnum(this);
|
|
}
|
|
COM_PROTECT_CATCH
|
|
|
|
*ppNodeEnum = pNodeEnum;
|
|
|
|
return hr;
|
|
}
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
TFSContainer::DeleteAllChildren
|
|
-
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
STDMETHODIMP TFSContainer::DeleteAllChildren(BOOL fRemoveFromUI)
|
|
{
|
|
AFX_MANAGE_STATE(AfxGetModuleState());
|
|
|
|
SPITFSNode spNode;
|
|
HRESULT hr = hrOK;
|
|
|
|
COM_PROTECT_TRY
|
|
{
|
|
if (fRemoveFromUI)
|
|
CORg( UpdateAllViewsHelper(reinterpret_cast<LPARAM>(this), RESULT_PANE_DELETE_ALL) );
|
|
|
|
while (!m_listChildren.IsEmpty())
|
|
{
|
|
BOOL bRemoveFromUI = FALSE;
|
|
spNode = m_listChildren.RemoveHead();
|
|
|
|
if (spNode->IsContainer() && fRemoveFromUI)
|
|
bRemoveFromUI = TRUE;
|
|
|
|
InternalRemoveChild(spNode, FALSE, bRemoveFromUI, TRUE);
|
|
|
|
spNode->Destroy();
|
|
spNode.Release();
|
|
}
|
|
|
|
COM_PROTECT_ERROR_LABEL
|
|
}
|
|
COM_PROTECT_CATCH
|
|
|
|
return hr;
|
|
}
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
TFSContainer::CompareChildNodes
|
|
-
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
STDMETHODIMP TFSContainer::CompareChildNodes(int *pnResult, ITFSNode *pNode1, ITFSNode *pNode2)
|
|
{
|
|
*pnResult = 0;
|
|
return hrOK;
|
|
}
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
TFSContainer::ChangeNode
|
|
-
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
HRESULT
|
|
TFSContainer::ChangeNode
|
|
(
|
|
LONG_PTR changeMask
|
|
)
|
|
{
|
|
HRESULT hr = hrOK;
|
|
SCOPEDATAITEM dataitemScope;
|
|
SPITFSNode spRootNode;
|
|
SPIConsoleNameSpace spConsoleNS;
|
|
|
|
COM_PROTECT_TRY
|
|
{
|
|
Assert(changeMask & (SCOPE_PANE_CHANGE_ITEM | SCOPE_PANE_STATE_NORMAL | SCOPE_PANE_STATE_BOLD | SCOPE_PANE_STATE_EXPANDEDONCE | SCOPE_PANE_STATE_CLEAR));
|
|
|
|
// this node may have been removed from the UI, but something like a
|
|
// background thread may have been holding onto it... just exit gracefully
|
|
//Assert(m_hScopeItem != 0);
|
|
if (m_hScopeItem == 0)
|
|
return S_FALSE;
|
|
|
|
if (!(changeMask & (SCOPE_PANE_CHANGE_ITEM | SCOPE_PANE_STATE_NORMAL | SCOPE_PANE_STATE_BOLD | SCOPE_PANE_STATE_EXPANDEDONCE | SCOPE_PANE_STATE_CLEAR)))
|
|
{
|
|
// the change mask is not valid for this node
|
|
return S_FALSE;
|
|
}
|
|
|
|
ZeroMemory(&dataitemScope, sizeof(dataitemScope));
|
|
|
|
CORg ( m_spNodeMgr->GetConsoleNameSpace(&spConsoleNS) );
|
|
|
|
m_spNodeMgr->GetRootNode(&spRootNode);
|
|
|
|
dataitemScope.ID = GetData(TFS_DATA_SCOPEID);
|
|
ASSERT(dataitemScope.ID != 0);
|
|
|
|
if (changeMask & SCOPE_PANE_CHANGE_ITEM_DATA)
|
|
{
|
|
dataitemScope.mask |= SDI_STR;
|
|
dataitemScope.displayname = MMC_CALLBACK;
|
|
}
|
|
|
|
if (changeMask & SCOPE_PANE_CHANGE_ITEM_ICON)
|
|
{
|
|
dataitemScope.mask |= SDI_IMAGE;
|
|
dataitemScope.nImage = (UINT)GetData(TFS_DATA_IMAGEINDEX);
|
|
dataitemScope.mask |= SDI_OPENIMAGE;
|
|
dataitemScope.nOpenImage = (UINT)GetData(TFS_DATA_OPENIMAGEINDEX);
|
|
}
|
|
|
|
if (changeMask & SCOPE_PANE_STATE_NORMAL)
|
|
{
|
|
dataitemScope.mask |= SDI_STATE;
|
|
dataitemScope.nState = MMC_SCOPE_ITEM_STATE_NORMAL;
|
|
}
|
|
|
|
if (changeMask & SCOPE_PANE_STATE_BOLD)
|
|
{
|
|
dataitemScope.mask |= SDI_STATE;
|
|
dataitemScope.nState = MMC_SCOPE_ITEM_STATE_BOLD;
|
|
}
|
|
|
|
if (changeMask & SCOPE_PANE_STATE_EXPANDEDONCE)
|
|
{
|
|
dataitemScope.mask |= SDI_STATE;
|
|
dataitemScope.nState = MMC_SCOPE_ITEM_STATE_EXPANDEDONCE;
|
|
}
|
|
|
|
if (changeMask & SCOPE_PANE_STATE_CLEAR)
|
|
{
|
|
dataitemScope.mask |= SDI_STATE;
|
|
dataitemScope.nState = 0;
|
|
}
|
|
|
|
CORg ( spConsoleNS->SetItem(&dataitemScope) );
|
|
|
|
COM_PROTECT_ERROR_LABEL;
|
|
}
|
|
COM_PROTECT_CATCH
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
TFSContainer::InternalAddToList
|
|
-
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
HRESULT TFSContainer::InternalAddToList(ITFSNode * pInsertAfterNode, ITFSNode *pNode)
|
|
{
|
|
AFX_MANAGE_STATE(AfxGetModuleState());
|
|
|
|
if (pInsertAfterNode == NULL)
|
|
{
|
|
m_listChildren.AddHead(pNode);
|
|
}
|
|
else
|
|
{
|
|
POSITION pos = m_listChildren.Find(pInsertAfterNode);
|
|
if (pos)
|
|
m_listChildren.InsertAfter(pos, pNode);
|
|
else
|
|
m_listChildren.AddHead(pNode);
|
|
}
|
|
|
|
pNode->AddRef();
|
|
|
|
return hrOK;
|
|
}
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
TFSContainer::InternalRemoveFromList
|
|
-
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
HRESULT TFSContainer::InternalRemoveFromList(ITFSNode *pNode)
|
|
{
|
|
AFX_MANAGE_STATE(AfxGetModuleState());
|
|
|
|
m_listChildren.RemoveNode(pNode);
|
|
pNode->Release();
|
|
|
|
return hrOK;
|
|
}
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
TFSContainer::InternalRemoveChild
|
|
-
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
HRESULT TFSContainer::InternalRemoveChild(ITFSNode *pNodeChild,
|
|
BOOL fRemoveFromList,
|
|
BOOL fRemoveFromUI,
|
|
BOOL fRemoveChildren)
|
|
{
|
|
AFX_MANAGE_STATE(AfxGetModuleState());
|
|
|
|
HRESULT hr = hrOK;
|
|
|
|
Assert(pNodeChild);
|
|
|
|
// Call this recursively on the children of pNodeChild
|
|
if (fRemoveChildren && pNodeChild->IsContainer())
|
|
{
|
|
pNodeChild->DeleteAllChildren(fRemoveFromUI);
|
|
}
|
|
|
|
// Remove the node from the UI
|
|
if (fRemoveFromUI)
|
|
{
|
|
if (pNodeChild->IsContainer())
|
|
{
|
|
// Check to see if we need to remove the node from the UI
|
|
if (!pNodeChild->IsInUI())
|
|
return hrOK;
|
|
|
|
CORg( InternalRemoveFromUI(pNodeChild, TRUE) );
|
|
}
|
|
else
|
|
{
|
|
CORg( UpdateAllViewsHelper(reinterpret_cast<LPARAM>(pNodeChild), RESULT_PANE_DELETE_ITEM) );
|
|
}
|
|
}
|
|
|
|
if (fRemoveFromList)
|
|
InternalRemoveFromList(pNodeChild);
|
|
|
|
pNodeChild->SetParent(NULL);
|
|
|
|
Error:
|
|
return hr;
|
|
}
|
|
|
|
STDMETHODIMP_(LONG_PTR) TFSContainer::Notify(int nIndex, LPARAM lParam)
|
|
{
|
|
LONG_PTR uReturn = 0;
|
|
HRESULT hr = hrOK;
|
|
|
|
COM_PROTECT_TRY
|
|
{
|
|
if (nIndex == TFS_NOTIFY_REMOVE_DELETED_NODES)
|
|
{
|
|
ITFSNode * pNode;
|
|
POSITION pos;
|
|
|
|
pos = m_listChildren.GetHeadPosition();
|
|
while (pos)
|
|
{
|
|
pNode = m_listChildren.GetNext(pos);
|
|
if (pNode->GetVisibilityState() & TFS_VIS_DELETE)
|
|
{
|
|
RemoveChild(pNode);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
uReturn = TFSNode::Notify(nIndex, lParam);
|
|
}
|
|
COM_PROTECT_CATCH;
|
|
|
|
return uReturn;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
CreateLeafTFSNode
|
|
-
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
TFSCORE_API(HRESULT) CreateLeafTFSNode(ITFSNode **ppNode,
|
|
const GUID *pNodeType,
|
|
ITFSNodeHandler *pNodeHandler,
|
|
ITFSResultHandler *pResultHandler,
|
|
ITFSNodeMgr *pNodeMgr)
|
|
{
|
|
AFX_MANAGE_STATE(AfxGetModuleState());
|
|
|
|
SPITFSNode spNode;
|
|
TFSNode * pNode = NULL;
|
|
HRESULT hr = hrOK;
|
|
|
|
COM_PROTECT_TRY
|
|
{
|
|
pNode = new TFSNode;
|
|
Assert(pNode);
|
|
|
|
spNode = pNode;
|
|
CORg(pNode->Construct(pNodeType, pNodeHandler, pResultHandler, pNodeMgr));
|
|
*ppNode = spNode.Transfer();
|
|
|
|
COM_PROTECT_ERROR_LABEL;
|
|
}
|
|
COM_PROTECT_CATCH
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
CreateContainerTFSNode
|
|
-
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
TFSCORE_API(HRESULT) CreateContainerTFSNode(ITFSNode **ppNode,
|
|
const GUID *pNodeType,
|
|
ITFSNodeHandler *pNodeHandler,
|
|
ITFSResultHandler *pResultHandler,
|
|
ITFSNodeMgr *pNodeMgr)
|
|
{
|
|
AFX_MANAGE_STATE(AfxGetModuleState());
|
|
|
|
SPITFSNode spNode;
|
|
TFSContainer * pContainer = NULL;
|
|
HRESULT hr = hrOK;
|
|
|
|
COM_PROTECT_TRY
|
|
{
|
|
pContainer = new TFSContainer;
|
|
Assert(pContainer);
|
|
|
|
spNode = pContainer;
|
|
CORg(pContainer->Construct(pNodeType, pNodeHandler, pResultHandler, pNodeMgr));
|
|
*ppNode = spNode.Transfer();
|
|
|
|
COM_PROTECT_ERROR_LABEL;
|
|
}
|
|
COM_PROTECT_CATCH
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
DEBUG_DECLARE_INSTANCE_COUNTER(TFSNodeMgr);
|
|
|
|
/*---------------------------------------------------------------------------
|
|
TFSNodeMgr implementation
|
|
---------------------------------------------------------------------------*/
|
|
TFSNodeMgr::TFSNodeMgr()
|
|
: m_cRef(1)
|
|
{
|
|
DEBUG_INCREMENT_INSTANCE_COUNTER(TFSNodeMgr);
|
|
}
|
|
|
|
TFSNodeMgr::~TFSNodeMgr()
|
|
{
|
|
DEBUG_DECREMENT_INSTANCE_COUNTER(TFSNodeMgr);
|
|
}
|
|
|
|
IMPLEMENT_ADDREF_RELEASE(TFSNodeMgr)
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
TFSNode::QueryInterface
|
|
-
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
STDMETHODIMP TFSNodeMgr::QueryInterface(REFIID riid, LPVOID *ppv)
|
|
{
|
|
// Is the pointer bad?
|
|
if (ppv == NULL)
|
|
return E_INVALIDARG;
|
|
|
|
// Place NULL in *ppv in case of failure
|
|
*ppv = NULL;
|
|
|
|
// This is the non-delegating IUnknown implementation
|
|
if (riid == IID_IUnknown || riid == IID_ITFSNodeMgr)
|
|
*ppv = (LPVOID) this;
|
|
|
|
// If we're going to return an interface, AddRef it first
|
|
if (*ppv)
|
|
{
|
|
((LPUNKNOWN) *ppv)->AddRef();
|
|
return hrOK;
|
|
}
|
|
else
|
|
return E_NOINTERFACE;
|
|
}
|
|
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
TFSNodeMgr::Construct
|
|
-
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
HRESULT TFSNodeMgr::Construct(IComponentData *pCompData,
|
|
IConsoleNameSpace2 *pConsoleNS)
|
|
{
|
|
m_spComponentData.Set(pCompData);
|
|
m_spConsoleNS.Set(pConsoleNS);
|
|
return hrOK;
|
|
}
|
|
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
TFSNodeMgr::GetRootNode
|
|
-
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
STDMETHODIMP TFSNodeMgr::GetRootNode(ITFSNode **ppTFSNode)
|
|
{
|
|
Assert(ppTFSNode);
|
|
SetI((LPUNKNOWN *) ppTFSNode, m_spRootNode);
|
|
return hrOK;
|
|
}
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
TFSNodeMgr::SetRootNode
|
|
-
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
STDMETHODIMP TFSNodeMgr::SetRootNode(ITFSNode *pRootNode)
|
|
{
|
|
m_spRootNode.Set(pRootNode);
|
|
return hrOK;
|
|
}
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
TFSNodeMgr::GetComponentData
|
|
-
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
STDMETHODIMP TFSNodeMgr::GetComponentData(IComponentData **ppComponentData)
|
|
{
|
|
Assert(ppComponentData);
|
|
SetI((LPUNKNOWN *) ppComponentData, m_spComponentData);
|
|
return hrOK;
|
|
}
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
TFSNodeMgr::FindNode
|
|
-
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
STDMETHODIMP TFSNodeMgr::FindNode(MMC_COOKIE cookie, ITFSNode **ppTFSNode)
|
|
{
|
|
if (cookie == 0)
|
|
{
|
|
*ppTFSNode = m_spRootNode;
|
|
}
|
|
else
|
|
{
|
|
// Call the cookie lookup routines
|
|
*ppTFSNode = (ITFSNode *) cookie;
|
|
}
|
|
Assert(*ppTFSNode);
|
|
(*ppTFSNode)->AddRef();
|
|
return hrOK;
|
|
}
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
TFSNodeMgr::RegisterCookieLookup
|
|
-
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
STDMETHODIMP TFSNodeMgr::RegisterCookieLookup()
|
|
{
|
|
return hrOK;
|
|
}
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
TFSNodeMgr::UnregisterCookieLookup
|
|
-
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
STDMETHODIMP TFSNodeMgr::UnregisterCookieLookup()
|
|
{
|
|
return hrOK;
|
|
}
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
TFSNodeMgr::IsCookieValid
|
|
-
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
STDMETHODIMP TFSNodeMgr::IsCookieValid(MMC_COOKIE cookie)
|
|
{
|
|
return hrOK;
|
|
}
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
TFSNodeMgr::SelectNode
|
|
-
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
STDMETHODIMP TFSNodeMgr::SelectNode(ITFSNode *pNode)
|
|
{
|
|
return hrOK;
|
|
}
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
TFSNodeMgr::SetResultPaneNode
|
|
-
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
STDMETHODIMP TFSNodeMgr::SetResultPaneNode(ITFSNode *pNode)
|
|
{
|
|
m_spResultPaneNode.Set(pNode);
|
|
return hrOK;
|
|
}
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
TFSNodeMgr::GetResultPaneNode
|
|
-
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
STDMETHODIMP TFSNodeMgr::GetResultPaneNode(ITFSNode **ppNode)
|
|
{
|
|
Assert(ppNode);
|
|
SetI((LPUNKNOWN *) ppNode, m_spResultPaneNode);
|
|
return hrOK;
|
|
}
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
TFSNodeMgr::GetConsoleNameSpace
|
|
-
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
STDMETHODIMP TFSNodeMgr::GetConsoleNameSpace(IConsoleNameSpace2 **ppConsoleNS)
|
|
{
|
|
Assert(ppConsoleNS);
|
|
SetI((LPUNKNOWN *) ppConsoleNS, m_spConsoleNS);
|
|
return hrOK;
|
|
}
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
TFSNodeMgr::GetConsole
|
|
-
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
STDMETHODIMP TFSNodeMgr::GetConsole(IConsole2 **ppConsole)
|
|
{
|
|
Assert(ppConsole);
|
|
SetI((LPUNKNOWN *) ppConsole, m_spConsole);
|
|
return hrOK;
|
|
}
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
TFSNodeMgr::SetConsole
|
|
-
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
STDMETHODIMP TFSNodeMgr::SetConsole(IConsoleNameSpace2 *pConsoleNS, IConsole2 *pConsole)
|
|
{
|
|
m_spConsoleNS.Set(pConsoleNS);
|
|
m_spConsole.Set(pConsole);
|
|
return hrOK;
|
|
}
|
|
|
|
|
|
STDMETHODIMP TFSNode::Destroy()
|
|
{
|
|
if (m_spNodeHandler)
|
|
{
|
|
m_spNodeHandler->DestroyHandler((ITFSNode *) this);
|
|
}
|
|
|
|
if (m_spResultHandler)
|
|
{
|
|
m_spResultHandler->DestroyResultHandler(m_cookie);
|
|
m_spResultHandler.Release();
|
|
}
|
|
|
|
//Bug 254167 We need to DestroyResultHander first before release NodeHandler
|
|
m_spNodeHandler.Release();
|
|
|
|
m_spNodeParent.Release();
|
|
m_spNodeMgr.Release();
|
|
return hrOK;
|
|
}
|
|
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
CreateTFSNodeMgr
|
|
-
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
TFSCORE_API(HRESULT) CreateTFSNodeMgr(ITFSNodeMgr **ppNodeMgr,
|
|
IComponentData *pComponentData,
|
|
IConsole2 *pConsole,
|
|
IConsoleNameSpace2 *pConsoleNameSpace)
|
|
{
|
|
AFX_MANAGE_STATE(AfxGetModuleState());
|
|
|
|
SPITFSNodeMgr spNodeMgr;
|
|
TFSNodeMgr * pTFSNodeMgr = NULL;
|
|
HRESULT hr = hrOK;
|
|
|
|
COM_PROTECT_TRY
|
|
{
|
|
pTFSNodeMgr = new TFSNodeMgr;
|
|
|
|
// Do this so that it will get freed on error
|
|
spNodeMgr = pTFSNodeMgr;
|
|
|
|
CORg( pTFSNodeMgr->Construct(pComponentData, pConsoleNameSpace) );
|
|
|
|
*ppNodeMgr = spNodeMgr.Transfer();
|
|
|
|
COM_PROTECT_ERROR_LABEL;
|
|
}
|
|
COM_PROTECT_CATCH
|
|
|
|
return hr;
|
|
}
|