|
//------------------------------------------------------------------------------
// $Workfile: XmlDocController.cpp $
// $Header: /SbjDev/XmlMvc/XmlDocController.cpp 14 11/24/08 10:33a Steve $
//
// Copyright � 2008 SbjCat
// All rights reserved.
//
//
// *** Authors ***
// Steve Johnson
//
// $Revision: 14 $
//
//-----------------------------------------------------------------------------
#include "stdafx.h"
#include "XmlDocController.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
namespace XmlMvc
{
namespace XmlDoc
{
struct ControllerImpl
{
CString sDocElementName;
MSXML2::IXMLDOMDocument2Ptr spTheProjectDoc;
MSXML2::IXMLDOMElementPtr spTheDocElement;
typedef std::map<HANDLE, MSXML2::IXMLDOMElementPtr> HandleToElement;
HandleToElement theHandleMap;
ControllerImpl()
{
}
virtual ~ControllerImpl()
{
}
HANDLE GetHandleFromNode(MSXML2::IXMLDOMElementPtr sp)
{
UINT hNext = NULL;
UINT hItem = NULL;
(void)SbjCore::Utils::Xml::GetAttribute(spTheDocElement, _T("nextSbjHandle"), hNext);
(void)SbjCore::Utils::Xml::GetAttribute(sp, _T("sbjHandle"), hItem);
if (NULL == hItem)
{
hItem = hNext;
MSXML2::IXMLDOMElementPtr spElement = sp;
(void)SbjCore::Utils::Xml::SetAttribute(sp, _T("sbjHandle"), hItem);
(void)SbjCore::Utils::Xml::SetAttribute(spTheDocElement, _T("nextSbjHandle"), ++hNext);
SbjCore::Mvc::Doc::Events::DocModified event(true);
}
return (HANDLE)hItem;
}
MSXML2::IXMLDOMElementPtr GetNodeFromHandle(HANDLE hItem)
{
HRESULT hr = S_OK;
MSXML2::IXMLDOMElementPtr spRslt = NULL;
try
{
if (hItem != SbjCore::Mvc::Model::Controller::GetItemRoot())
{
CString sXPath;
sXPath.Format(_T("descendant::*[@sbjHandle = %u]"), hItem);
spRslt = spTheDocElement->selectSingleNode((LPCTSTR)sXPath);
if (NULL == spRslt)
{
spRslt = theHandleMap[hItem];
}
}
else
{
spRslt = spTheDocElement;
}
}
catch (_com_error& e)
{
ASSERT(FALSE);
hr = e.Error();
}
return spRslt;
}
};
///////////////////////////////////////////////////////////////////
IMPLEMENT_DYNCREATE(Controller, t_Base)
Controller::Controller() :
m_pImpl(new ControllerImpl)
{
}
Controller::~Controller()
{
try
{
delete m_pImpl;
}
catch(...)
{
ASSERT(FALSE);
}
}
void Controller::SetDocElementName( LPCTSTR lpsz )
{
m_pImpl->sDocElementName = lpsz;
}
BOOL Controller::OnNewDocument()
{
bool bRslt = false;
ASSERT(!m_pImpl->sDocElementName.IsEmpty());
// if this asserts you probably forgot to set the name
// in the derived class' ctor
m_pImpl->spTheProjectDoc = SbjCore::Utils::Xml::CreateDoc(m_pImpl->sDocElementName);
if (m_pImpl->spTheProjectDoc != NULL)
{
m_pImpl->spTheDocElement = SbjCore::Utils::Xml::GetDocElement(m_pImpl->spTheProjectDoc);
if (m_pImpl->spTheDocElement != NULL)
{
m_pImpl->spTheDocElement->setAttribute(_T("nextSbjHandle"), 0xF0000001);
bRslt = true;
}
}
return bRslt;
}
BOOL Controller::OnOpenDocument( LPCTSTR lpszPathName )
{
bool bRslt = false;
ASSERT(!m_pImpl->sDocElementName.IsEmpty());
m_pImpl->spTheProjectDoc = SbjCore::Utils::Xml::CreateDoc();
if (m_pImpl->spTheProjectDoc != NULL)
{
m_pImpl->spTheDocElement = SbjCore::Utils::Xml::LoadFile(lpszPathName, m_pImpl->sDocElementName, m_pImpl->spTheProjectDoc);
if (m_pImpl->spTheDocElement != NULL)
{
MSXML2::IXMLDOMAttributePtr spAttr = m_pImpl->spTheDocElement->getAttributeNode(_T("nextSbjHandle"));
if (NULL == spAttr)
{
m_pImpl->spTheDocElement->setAttribute(_T("nextSbjHandle"), 0xF0000001);
}
bRslt = true;
}
}
return bRslt;
}
BOOL Controller::OnSaveDocument( LPCTSTR lpszPathName )
{
bool bRslt = SUCCEEDED(m_pImpl->spTheProjectDoc->save(lpszPathName));
return bRslt;
}
void Controller::Serialize( CArchive& ar )
{
ar;
}
HANDLE Controller::OnCreateItem( LPCTSTR lpszItemType )
{
MSXML2::IXMLDOMElementPtr spElement = SbjCore::Utils::Xml::CreateElement(lpszItemType);
HANDLE hItem = m_pImpl->GetHandleFromNode(spElement);
m_pImpl->theHandleMap[hItem] = spElement;
return hItem;
}
bool Controller::OnInsertChild(
const HANDLE hChild,
const HANDLE hParent,
const HANDLE hAfter)
{
HRESULT hr = S_OK;
try
{
MSXML2::IXMLDOMElementPtr spTheChild = m_pImpl->GetNodeFromHandle(hChild);
MSXML2::IXMLDOMElementPtr spTheParent = m_pImpl->GetNodeFromHandle(hParent);
MSXML2::IXMLDOMElementPtr spTheAfter = m_pImpl->GetNodeFromHandle(hAfter);
if (spTheAfter != NULL)
{
spTheParent->insertBefore(spTheChild, _variant_t(spTheAfter.GetInterfacePtr()));
}
else
{
spTheParent->appendChild(spTheChild);
}
}
catch (_com_error& e)
{
ASSERT(FALSE);
hr = e.Error();
}
catch (...)
{
ASSERT(FALSE);
}
return (S_OK == hr);
}
bool Controller::OnRemoveChild(
const HANDLE hChild)
{
HRESULT hr = E_FAIL;
try
{
MSXML2::IXMLDOMElementPtr spTheChild = m_pImpl->GetNodeFromHandle(hChild);
MSXML2::IXMLDOMElementPtr spTheParent = spTheChild->GetparentNode();
if ((spTheChild != NULL) && (spTheParent != NULL))
{
(void)spTheParent->removeChild(spTheChild);
hr = S_OK;
}
}
catch (_com_error& e)
{
ASSERT(FALSE);
hr = e.Error();
}
catch (...)
{
ASSERT(FALSE);
}
return (S_OK == hr);
}
bool Controller::OnSetItemAttrValue(
const HANDLE hItem,
const CString& sAttrName,
const _variant_t& val)
{
HRESULT hr = E_FAIL;
try
{
MSXML2::IXMLDOMElementPtr spElement = m_pImpl->GetNodeFromHandle(hItem);
if (spElement != NULL)
{
spElement->setAttribute((LPCTSTR)sAttrName, val);
hr = S_OK;
}
}
catch (_com_error& e)
{
ASSERT(FALSE);
hr = e.Error();
}
catch (...)
{
ASSERT(FALSE);
}
return (S_OK == hr);
}
_variant_t Controller::OnGetItemAttrValue(
const HANDLE hItem,
const CString& sAttrName) const
{
_variant_t v;
try
{
MSXML2::IXMLDOMElementPtr spElement = m_pImpl->GetNodeFromHandle(hItem);
if (spElement != NULL)
{
(void)SbjCore::Utils::Xml::GetAttribute(spElement, (LPCTSTR)sAttrName, v);
}
}
catch (_com_error& e)
{
HRESULT hr = e.Error();
hr;
}
catch (...)
{
ASSERT(FALSE);
}
return v;
}
CString Controller::OnAssureUniqueItemAttrValue(
const HANDLE hItem,
const CString& sAttrName,
const _variant_t& val) const
{
HRESULT hr = NULL;
MSXML2::IXMLDOMNodeListPtr spNodeList = NULL;
CString sVal;
try
{
sVal = (LPCTSTR)(_bstr_t)val;
CString sXPath;
sXPath.Format(_T("*[starts-with(@%s, '%s')]"), sAttrName, sVal);
MSXML2::IXMLDOMElementPtr spElement = m_pImpl->GetNodeFromHandle(hItem);
spNodeList = spElement->selectNodes((LPCTSTR)sXPath);
}
catch (_com_error& e)
{
hr = e.Error();
}
catch (...)
{
ASSERT(FALSE);
}
if (spNodeList != NULL)
{
int nCount = spNodeList->Getlength();
if (nCount > 0)
{
nCount++;
sVal.Format(_T("%s (%d)"), (LPCTSTR)(_bstr_t)val, nCount);
}
}
return sVal;
}
CString Controller::OnGetItemTypeName( HANDLE hItem ) const
{
MSXML2::IXMLDOMNodePtr spNode = m_pImpl->GetNodeFromHandle(hItem);
CString sName = (LPCTSTR)spNode->GetnodeName();
return sName;
}
int Controller::OnGetItemChildren(HANDLE hItem, SbjCore::Mvc::Model::ItemHandles& items) const
{
items.clear();
MSXML2::IXMLDOMNodePtr spNode = m_pImpl->GetNodeFromHandle(hItem);
MSXML2::IXMLDOMNodeListPtr spNodes(spNode->GetchildNodes());
int nCount = spNodes->Getlength();
for (int nIndex = 0; nIndex < nCount; nIndex++)
{
MSXML2::IXMLDOMNodePtr spChild = spNodes->Getitem(nIndex);
if (spChild != NULL)
{
HANDLE hChild = m_pImpl->GetHandleFromNode(spChild);
items.push_back(hChild);
}
}
return items.size();
}
int Controller::OnGetItemAttrNames( HANDLE hItem, SbjCore::Mvc::Model::ItemAttrNames& attrNames ) const
{
MSXML2::IXMLDOMElementPtr spElement = m_pImpl->GetNodeFromHandle(hItem);
MSXML2::IXMLDOMNodeListPtr spAttrList = spElement->selectNodes(_T("@*"));
int nCount = spAttrList->Getlength();
if (nCount > 0)
{
attrNames.clear();
for (int nIndex = 0; nIndex < nCount; nIndex++)
{
MSXML2::IXMLDOMNodePtr spAttr = spAttrList->nextNode();
if (spAttr != NULL)
{
CString sNodeName((LPCTSTR)spAttr->GetnodeName());
if ((!sNodeName.IsEmpty()) && (sNodeName.Compare(_T("sbjHandle")) != 0))
{
attrNames.push_back(sNodeName);
}
}
}
}
return nCount;
}
HANDLE Controller::OnGetParentItem( const HANDLE hItem ) const
{
MSXML2::IXMLDOMElementPtr spTheChild = m_pImpl->GetNodeFromHandle(hItem);
MSXML2::IXMLDOMElementPtr spTheParent = spTheChild->GetparentNode();
return m_pImpl->GetHandleFromNode(spTheParent);
}
}
}
//*** Modification History ***
// $Log: /SbjDev/XmlMvc/XmlDocController.cpp $
//
// 14 11/24/08 10:33a Steve
// Final changes before MVCChapt1 v2.0.1
//
// 13 11/12/08 2:22p Steve
// Finished Generalization of Model v2.0.1
//
// 12 10/24/08 9:03a Steve
//
// 11 10/20/08 11:06a Steve
// Removed source parameter from Event and replaced with EventT data
//
// 10 10/16/08 2:41a Steve
// Ready for publishing
//
// 9 10/14/08 1:12p Steve
// Implemented Deletes
|
By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.
If a file you wish to view isn't highlighted, and is a text file (not binary), please
let us know and we'll add colourisation support for it.
Real name is Steve Johnson. Programming since 1979. Started on a Heathkit Micro with a DEC LSI-11 and UCSD Pascal. Moved to PCs & DOS as soon as Turbo Pascal became available. Did some Assembly, ISR, TSR etc. All this while working for a Manufacturing Co. for 8 years. Had my own solo Co. doing barcode labeling software for 4 years (terrible business man, all I wanted to do was code). Since then working for various software companies. Moved to Windows around the time of 3.1 with Borland C then C++. Then on to VC++ and MFC, and just about anything I could get my hands on or had to learn for my job, and been at it ever since. Of course recently I've been playing with .NET, ASP, C#, WPF etc.