2002-02-11 07:58:31 -06:00
|
|
|
/*************************************************************************
|
|
|
|
*
|
2008-04-11 07:59:54 -05:00
|
|
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
2002-02-11 07:58:31 -06:00
|
|
|
*
|
2008-04-11 07:59:54 -05:00
|
|
|
* Copyright 2008 by Sun Microsystems, Inc.
|
2002-02-11 07:58:31 -06:00
|
|
|
*
|
2008-04-11 07:59:54 -05:00
|
|
|
* OpenOffice.org - a multi-platform office productivity suite
|
2002-02-11 07:58:31 -06:00
|
|
|
*
|
2008-04-11 07:59:54 -05:00
|
|
|
* $RCSfile: viewstrategy.cxx,v $
|
|
|
|
* $Revision: 1.12 $
|
2002-02-11 07:58:31 -06:00
|
|
|
*
|
2008-04-11 07:59:54 -05:00
|
|
|
* This file is part of OpenOffice.org.
|
2002-02-11 07:58:31 -06:00
|
|
|
*
|
2008-04-11 07:59:54 -05:00
|
|
|
* OpenOffice.org is free software: you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU Lesser General Public License version 3
|
|
|
|
* only, as published by the Free Software Foundation.
|
2002-02-11 07:58:31 -06:00
|
|
|
*
|
2008-04-11 07:59:54 -05:00
|
|
|
* OpenOffice.org is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU Lesser General Public License version 3 for more details
|
|
|
|
* (a copy is included in the LICENSE file that accompanied this code).
|
2002-02-11 07:58:31 -06:00
|
|
|
*
|
2008-04-11 07:59:54 -05:00
|
|
|
* You should have received a copy of the GNU Lesser General Public License
|
|
|
|
* version 3 along with OpenOffice.org. If not, see
|
|
|
|
* <http://www.openoffice.org/license.html>
|
|
|
|
* for a copy of the LGPLv3 License.
|
2002-02-11 07:58:31 -06:00
|
|
|
*
|
|
|
|
************************************************************************/
|
|
|
|
|
2006-09-16 09:33:07 -05:00
|
|
|
// MARKER(update_precomp.py): autogen include statement, do not remove
|
|
|
|
#include "precompiled_configmgr.hxx"
|
|
|
|
|
2002-02-11 07:58:31 -06:00
|
|
|
#include "viewstrategy.hxx"
|
|
|
|
#include "valuenodeimpl.hxx"
|
|
|
|
#include "groupnodeimpl.hxx"
|
|
|
|
#include "setnodeimpl.hxx"
|
|
|
|
#include "change.hxx"
|
|
|
|
#include "nodevisitor.hxx"
|
|
|
|
#include "groupnodeaccess.hxx"
|
|
|
|
#include "setnodeaccess.hxx"
|
|
|
|
#include "nodechange.hxx"
|
|
|
|
#include "nodechangeimpl.hxx"
|
|
|
|
#include "nodeconverter.hxx"
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
namespace configmgr
|
|
|
|
{
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
namespace view
|
|
|
|
{
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
using configuration::SetEntry;
|
|
|
|
using configuration::ElementList;
|
|
|
|
using configuration::GroupMemberVisitor;
|
|
|
|
using configuration::SetNodeVisitor;
|
|
|
|
|
|
|
|
static
|
|
|
|
inline
|
|
|
|
data::ValueNodeAccess getMemberValueAccess( GroupNode const & _aGroupNode, Name const & _aName )
|
|
|
|
{
|
|
|
|
configuration::GroupNodeImpl* pGroupData = _aGroupNode.get_impl();
|
2007-11-23 07:50:09 -06:00
|
|
|
return pGroupData->getOriginalValueNode(_aName);
|
2002-02-11 07:58:31 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
void ViewStrategy::checkInstance(Tree const& _aTreeForThis) const
|
|
|
|
{
|
2006-06-19 17:35:12 -05:00
|
|
|
{ (void)_aTreeForThis; }
|
2002-02-11 07:58:31 -06:00
|
|
|
OSL_ENSURE( getViewBehavior(_aTreeForThis).get() == this,
|
|
|
|
"Tree operation dispatched to wrong strategy instance");
|
|
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
void ViewStrategy::collectChanges(Tree const& _aTree, NodeChanges& rChanges) const
|
|
|
|
{
|
|
|
|
checkInstance(_aTree);
|
|
|
|
doCollectChanges( getRootNode(_aTree), rChanges );
|
|
|
|
}
|
|
|
|
|
|
|
|
bool ViewStrategy::hasChanges(Tree const& _aTree) const
|
|
|
|
{
|
|
|
|
checkInstance(_aTree);
|
|
|
|
return hasChanges( getRootNode(_aTree) );
|
|
|
|
}
|
|
|
|
|
|
|
|
// mark the given node and all its ancestors (we can stop when we hit a node that already is marked)
|
|
|
|
void ViewStrategy::markChanged(Node const& _aNode)
|
|
|
|
{
|
|
|
|
Tree aTree = _aNode.tree();
|
|
|
|
checkInstance(aTree);
|
|
|
|
|
|
|
|
Node aNode = _aNode;
|
|
|
|
if (aNode.is())
|
|
|
|
{
|
|
|
|
do
|
|
|
|
{
|
|
|
|
this->doMarkChanged(aNode);
|
|
|
|
|
|
|
|
aNode = aNode.getParent();
|
|
|
|
}
|
|
|
|
while (aNode.is() && !this->hasChanges( aNode ));
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!aNode.is()) // just marked the root
|
|
|
|
{
|
|
|
|
configuration::TreeImpl* pTreeData = aTree.get_impl();
|
|
|
|
configuration::TreeImpl* pContext = pTreeData->getContextTree();
|
|
|
|
NodeOffset nContext = pTreeData->getContextNode();
|
|
|
|
if (pContext)
|
|
|
|
{
|
|
|
|
OSL_ASSERT(pContext->isValidNode(nContext));
|
|
|
|
|
2007-11-23 07:50:09 -06:00
|
|
|
view::Node aContextNode(*pContext,nContext);
|
2002-02-11 07:58:31 -06:00
|
|
|
pContext->getViewBehavior()->markChanged(aContextNode);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
std::auto_ptr<SubtreeChange> ViewStrategy::preCommitChanges(Tree const& _aTree, ElementList& _rRemovedElements)
|
|
|
|
{
|
|
|
|
checkInstance(_aTree);
|
|
|
|
return doPreCommitChanges( _aTree, _rRemovedElements);
|
|
|
|
}
|
|
|
|
|
|
|
|
void ViewStrategy::finishCommit(Tree const& _aTree, SubtreeChange& rRootChange)
|
|
|
|
{
|
|
|
|
checkInstance(_aTree);
|
|
|
|
doFinishCommit(_aTree, rRootChange);
|
|
|
|
}
|
|
|
|
|
|
|
|
void ViewStrategy::revertCommit(Tree const& _aTree, SubtreeChange& rRootChange)
|
|
|
|
{
|
|
|
|
checkInstance(_aTree);
|
|
|
|
doRevertCommit(_aTree, rRootChange);
|
|
|
|
}
|
|
|
|
|
|
|
|
void ViewStrategy::recoverFailedCommit(Tree const& _aTree, SubtreeChange& rRootChange)
|
|
|
|
{
|
|
|
|
checkInstance(_aTree);
|
|
|
|
doFailedCommit(_aTree, rRootChange);
|
|
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
void ViewStrategy::adjustToChanges(NodeChangesInformation& rLocalChanges, Node const& _aNode, SubtreeChange const& aExternalChange)
|
|
|
|
{
|
|
|
|
OSL_PRECOND( isValidNode(_aNode), "ERROR: Valid node required for adjusting to changes" );
|
|
|
|
OSL_PRECOND( getSimpleNodeName(_aNode).toString() == aExternalChange.getNodeName(), "Name of change does not match actual node" );
|
|
|
|
|
|
|
|
checkInstance(_aNode.tree());
|
|
|
|
|
|
|
|
configuration::TreeImpl * pTreeData = _aNode.tree().get_impl();
|
|
|
|
|
|
|
|
if (_aNode.isSetNode())
|
|
|
|
{
|
|
|
|
OSL_ENSURE(aExternalChange.isSetNodeChange(),"ERROR: Change type GROUP does not match set");
|
|
|
|
|
|
|
|
TreeDepth nDepth = pTreeData->getRemainingDepth(_aNode.get_offset());
|
|
|
|
|
|
|
|
implAdjustToElementChanges( rLocalChanges, SetNode(_aNode), aExternalChange, nDepth);
|
|
|
|
}
|
|
|
|
else if (_aNode.isGroupNode())
|
|
|
|
{
|
|
|
|
OSL_ENSURE(!aExternalChange.isSetNodeChange(),"ERROR: Change type SET does not match group");
|
|
|
|
|
|
|
|
GroupNode aGroupNode(_aNode);
|
|
|
|
|
|
|
|
implAdjustToValueChanges(rLocalChanges, aGroupNode, aExternalChange);
|
|
|
|
implAdjustToSubChanges( rLocalChanges, aGroupNode, aExternalChange);
|
|
|
|
}
|
|
|
|
else // might occur on external change (?)
|
|
|
|
{
|
|
|
|
OSL_ENSURE(_aNode.isValueNode(), "TreeImpl: Unknown node type to adjust to changes");
|
|
|
|
|
|
|
|
OSL_ENSURE(_aNode.get_offset() == pTreeData->root_(), "TreeImpl: Unexpected node type - non-root value element");
|
|
|
|
|
|
|
|
OSL_ENSURE(false,"ERROR: Change type does not match node: Trying to apply subtree change to value element.");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
void ViewStrategy::addLocalChangeHelper( NodeChangesInformation& rLocalChanges_, configuration::NodeChange const& aChange_)
|
|
|
|
{
|
|
|
|
aChange_.getChangeInfos(rLocalChanges_);
|
|
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// TO DO: create CommitAction class, which is returned by precommit (if applicable)
|
|
|
|
|
|
|
|
std::auto_ptr<SubtreeChange> ViewStrategy::doPreCommitChanges(Tree const& _aTree, configuration::ElementList& )
|
|
|
|
{
|
2006-06-19 17:35:12 -05:00
|
|
|
{ (void)_aTree; }
|
2002-02-11 07:58:31 -06:00
|
|
|
OSL_ENSURE(!hasChanges(getRootNode(_aTree)),"Unexpected changes in View");
|
|
|
|
return std::auto_ptr<SubtreeChange>();
|
|
|
|
}
|
|
|
|
|
|
|
|
void ViewStrategy::doFinishCommit(Tree const& _aTree, SubtreeChange& )
|
|
|
|
{
|
2006-06-19 17:35:12 -05:00
|
|
|
{ (void)_aTree; }
|
2002-02-11 07:58:31 -06:00
|
|
|
OSL_ENSURE(!hasChanges(getRootNode(_aTree)),"Unexpected changes in View");
|
|
|
|
OSL_ENSURE(false,"ERROR: Cannot finish commit for unexpected changes");
|
|
|
|
}
|
|
|
|
|
|
|
|
void ViewStrategy::doRevertCommit(Tree const& _aTree, SubtreeChange& )
|
|
|
|
{
|
2006-06-19 17:35:12 -05:00
|
|
|
{ (void)_aTree; }
|
2002-02-11 07:58:31 -06:00
|
|
|
OSL_ENSURE(!hasChanges(getRootNode(_aTree)),"Unexpected changes in View");
|
|
|
|
OSL_ENSURE(false,"ERROR: Cannot revert commit for unexpected changes");
|
|
|
|
}
|
|
|
|
|
|
|
|
void ViewStrategy::doFailedCommit(Tree const& _aTree, SubtreeChange& )
|
|
|
|
{
|
2006-06-19 17:35:12 -05:00
|
|
|
{ (void)_aTree; }
|
2002-02-11 07:58:31 -06:00
|
|
|
OSL_ENSURE(!hasChanges(getRootNode(_aTree)),"Unexpected changes in View");
|
|
|
|
OSL_ENSURE(false,"ERROR: Cannot recover commit for unexpected changes");
|
|
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
void ViewStrategy::implAdjustToElementChange(NodeChangesInformation& rLocalChanges, SetNode const& _aSetNode, Change const& rElementChange, TreeDepth nDepth)
|
|
|
|
{
|
|
|
|
using namespace configuration;
|
|
|
|
|
|
|
|
SetNodeImpl * pSetData = _aSetNode.get_impl();
|
|
|
|
|
|
|
|
OSL_ENSURE( pSetData->implHasLoadedElements() , "Unexpected call: Processing element change in uninitialized set");
|
|
|
|
|
|
|
|
Name aName = makeElementName( rElementChange.getNodeName(), Name::NoValidate() );
|
|
|
|
|
|
|
|
SetElementChangeImpl* pThisChange = 0;
|
|
|
|
if (rElementChange.ISA(AddNode))
|
|
|
|
{
|
|
|
|
AddNode const& aAddNode = static_cast<AddNode const&>(rElementChange);
|
|
|
|
|
2007-11-23 07:50:09 -06:00
|
|
|
SetNodeElement aNewElement = pSetData->makeAdditionalElement(this,aAddNode,nDepth);
|
2002-02-11 07:58:31 -06:00
|
|
|
|
2007-11-23 07:50:09 -06:00
|
|
|
pThisChange = pSetData->doAdjustToAddedElement(aName, aAddNode,aNewElement);
|
2002-02-11 07:58:31 -06:00
|
|
|
}
|
|
|
|
else if (rElementChange.ISA(RemoveNode))
|
|
|
|
{
|
|
|
|
RemoveNode const& aRemoveNode = static_cast<RemoveNode const&>(rElementChange);
|
|
|
|
|
2007-11-23 07:50:09 -06:00
|
|
|
pThisChange = pSetData->doAdjustToRemovedElement(aName, aRemoveNode);
|
2002-02-11 07:58:31 -06:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (nDepth > 0 || (NULL != pSetData->doFindElement(aName)) )// found even beyond nDepth ?
|
|
|
|
{
|
2007-11-23 07:50:09 -06:00
|
|
|
pThisChange = pSetData->doAdjustChangedElement(rLocalChanges,aName, rElementChange);
|
2002-02-11 07:58:31 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (pThisChange)
|
|
|
|
{
|
|
|
|
addLocalChangeHelper( rLocalChanges, NodeChange(pThisChange) );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void ViewStrategy::implAdjustToElementChanges(NodeChangesInformation& rLocalChanges, SetNode const& _aSetNode, SubtreeChange const& rExternalChanges, TreeDepth nDepth)
|
|
|
|
{
|
|
|
|
|
|
|
|
if (nDepth > 0)
|
|
|
|
{
|
|
|
|
configuration::SetNodeImpl * pSetData = _aSetNode.get_impl();
|
|
|
|
|
|
|
|
OSL_ENSURE( pSetData->getTemplateProvider().isValid(), "Cannot adjust SetNode to changes - node was never initialized" );
|
|
|
|
|
|
|
|
if (pSetData->implHasLoadedElements())
|
|
|
|
{
|
|
|
|
TreeDepth const nElementDepth = configuration::childDepth(nDepth);
|
|
|
|
for (SubtreeChange::ChildIterator it = rExternalChanges.begin(); it != rExternalChanges.end(); ++it)
|
|
|
|
{
|
|
|
|
this->implAdjustToElementChange(rLocalChanges, _aSetNode, *it, nElementDepth);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
OSL_ENSURE( !hasChanges(_aSetNode.node()),"Cannot have changes to consider when no elements are loaded");
|
|
|
|
|
2007-11-23 07:50:09 -06:00
|
|
|
pSetData->convertChanges( rLocalChanges, rExternalChanges, nDepth);
|
2002-02-11 07:58:31 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
configuration::ValueChangeImpl* ViewStrategy::doAdjustToValueChange(GroupNode const& _aGroupNode, Name const& _aName, ValueChange const& _rExternalChange)
|
|
|
|
{
|
|
|
|
using namespace configuration;
|
|
|
|
|
|
|
|
ValueChangeImpl* pChangeImpl = NULL;
|
|
|
|
|
|
|
|
data::ValueNodeAccess aLocalNode = getMemberValueAccess(_aGroupNode,_aName);
|
|
|
|
if (aLocalNode.isValid())
|
|
|
|
{
|
|
|
|
switch( _rExternalChange. getMode() )
|
|
|
|
{
|
|
|
|
case ValueChange::wasDefault:
|
|
|
|
case ValueChange::changeValue:
|
|
|
|
pChangeImpl = new ValueReplaceImpl( _rExternalChange.getNewValue(), _rExternalChange.getOldValue() );
|
|
|
|
break;
|
|
|
|
|
|
|
|
case ValueChange::setToDefault:
|
|
|
|
pChangeImpl = new ValueResetImpl( _rExternalChange.getNewValue(), _rExternalChange.getOldValue() );
|
|
|
|
break;
|
|
|
|
|
|
|
|
default: OSL_ENSURE(false, "Unknown change mode");
|
|
|
|
// fall thru to next case for somewhat meaningful return value
|
|
|
|
case ValueChange::changeDefault:
|
|
|
|
{
|
|
|
|
UnoAny aLocalValue = aLocalNode.getValue();
|
|
|
|
|
|
|
|
pChangeImpl = new ValueReplaceImpl( aLocalValue, aLocalValue );
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
OSL_ASSERT( pChangeImpl );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
OSL_ENSURE(false, "ERROR: Notification tries to change nonexistent value within group");
|
|
|
|
}
|
|
|
|
|
|
|
|
return pChangeImpl;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ViewStrategy::implAdjustToValueChanges(NodeChangesInformation& rLocalChanges, GroupNode const& _aGroupNode, SubtreeChange const& rExternalChanges)
|
|
|
|
{
|
|
|
|
for (SubtreeChange::ChildIterator it = rExternalChanges.begin(); it != rExternalChanges.end(); ++it)
|
|
|
|
{
|
|
|
|
using namespace configuration;
|
|
|
|
|
|
|
|
if (it->ISA(ValueChange))
|
|
|
|
{
|
|
|
|
ValueChange const& rValueChange = static_cast<ValueChange const&>(*it);
|
|
|
|
|
|
|
|
Name aValueName = makeNodeName( rValueChange.getNodeName(), Name::NoValidate() );
|
|
|
|
|
|
|
|
if (ValueChangeImpl* pThisChange = doAdjustToValueChange(_aGroupNode, aValueName, rValueChange))
|
|
|
|
{
|
|
|
|
pThisChange->setTarget(_aGroupNode,aValueName);
|
|
|
|
addLocalChangeHelper(rLocalChanges, NodeChange(pThisChange));
|
|
|
|
}
|
|
|
|
else
|
|
|
|
OSL_TRACE("WARNING: Configuration: derived class hides an external value member change from listeners");
|
|
|
|
}
|
|
|
|
else
|
|
|
|
OSL_ENSURE(it->ISA(SubtreeChange), "Unexpected change type within group");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void ViewStrategy::implAdjustToSubChanges(NodeChangesInformation& rLocalChanges, GroupNode const& _aGroupNode, SubtreeChange const& rExternalChanges)
|
|
|
|
{
|
|
|
|
using namespace configuration;
|
|
|
|
|
2004-03-23 03:33:53 -06:00
|
|
|
#if (OSL_DEBUG_LEVEL > 0)
|
|
|
|
TreeImpl * pTreeData = _aGroupNode.tree().get_impl();
|
|
|
|
#endif
|
2002-02-11 07:58:31 -06:00
|
|
|
for(SubtreeChange::ChildIterator it = rExternalChanges.begin(); it != rExternalChanges.end(); ++it)
|
|
|
|
{
|
|
|
|
if ( it->ISA(SubtreeChange) )
|
|
|
|
{
|
|
|
|
Node aSubNode = _aGroupNode.findChild( makeNodeName(it->getNodeName(), Name::NoValidate()) );
|
|
|
|
OSL_ENSURE( aSubNode.is() || pTreeData->depthTo(_aGroupNode.node().get_offset()) >= pTreeData->getAvailableDepth(), "Changed node not found in tree");
|
|
|
|
|
|
|
|
if (aSubNode.is())
|
|
|
|
{
|
|
|
|
OSL_ENSURE( pTreeData->getRemainingDepth(_aGroupNode.node().get_offset()) > 0, "Depth is smaller than expected for tree");
|
|
|
|
this->adjustToChanges(rLocalChanges, aSubNode, static_cast<SubtreeChange const&>(*it));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
OSL_ENSURE(it->ISA(ValueChange), "Unexpected change type for child of group node; change is ignored");
|
|
|
|
OSL_ENSURE( !_aGroupNode.findChild(makeNodeName(it->getNodeName(), Name::NoValidate())).is(),
|
|
|
|
"Found sub(tree) node where a value was expected");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
void ViewStrategy::doCollectChanges(Node const& _aNode, NodeChanges& ) const
|
|
|
|
{
|
2006-06-19 17:35:12 -05:00
|
|
|
{ (void)_aNode; }
|
2002-02-11 07:58:31 -06:00
|
|
|
// no-op: there are no changes to collect
|
|
|
|
OSL_ENSURE(!hasChanges(_aNode),"Unexpected changes in View");
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
UnoAny ViewStrategy::getValue(ValueNode const& _aNode) const
|
|
|
|
{
|
|
|
|
checkInstance(_aNode.tree());
|
2007-11-23 07:50:09 -06:00
|
|
|
return _aNode.get_impl()->getValue();
|
2002-02-11 07:58:31 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
UnoType ViewStrategy::getValueType(ValueNode const& _aNode) const
|
|
|
|
{
|
|
|
|
checkInstance(_aNode.tree());
|
2007-11-23 07:50:09 -06:00
|
|
|
return _aNode.get_impl()->getValueType();
|
2002-02-11 07:58:31 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// group member access
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
namespace { // helpers
|
|
|
|
using configuration::GroupMemberVisitor;
|
|
|
|
|
|
|
|
struct GroupMemberDispatch : data::NodeVisitor
|
|
|
|
{
|
|
|
|
GroupMemberDispatch(ViewStrategy& _rStrategy, GroupNode const& _aGroup, GroupMemberVisitor& rVisitor)
|
2004-03-23 03:33:53 -06:00
|
|
|
: m_rStrategy(_rStrategy)
|
|
|
|
, m_aGroup(_aGroup)
|
2002-02-11 07:58:31 -06:00
|
|
|
, m_rVisitor(rVisitor)
|
|
|
|
{}
|
|
|
|
|
|
|
|
static Result mapResult(GroupMemberVisitor::Result _aResult)
|
|
|
|
{
|
|
|
|
|
2004-03-23 03:33:53 -06:00
|
|
|
OSL_ASSERT( DONE == Result(GroupMemberVisitor::DONE) );
|
|
|
|
OSL_ASSERT( CONTINUE == Result(GroupMemberVisitor::CONTINUE) );
|
|
|
|
return Result(_aResult);
|
2002-02-11 07:58:31 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
static GroupMemberVisitor::Result unmapResult(Result _aResult)
|
|
|
|
{
|
2004-03-23 03:33:53 -06:00
|
|
|
OSL_ASSERT( DONE == Result(GroupMemberVisitor::DONE) );
|
|
|
|
OSL_ASSERT( CONTINUE == Result(GroupMemberVisitor::CONTINUE) );
|
|
|
|
return GroupMemberVisitor::Result(_aResult);
|
2002-02-11 07:58:31 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
virtual Result handle(data::ValueNodeAccess const& _aValue);
|
2007-11-23 07:50:09 -06:00
|
|
|
virtual Result handle(data::NodeAccess const& _aNonValue);
|
2002-02-11 07:58:31 -06:00
|
|
|
|
2007-11-23 07:50:09 -06:00
|
|
|
bool test_value(data::NodeAccess const & _aNode) const;
|
2002-02-11 07:58:31 -06:00
|
|
|
|
|
|
|
ViewStrategy& m_rStrategy;
|
|
|
|
GroupNode m_aGroup;
|
|
|
|
GroupMemberVisitor& m_rVisitor;
|
|
|
|
|
|
|
|
GroupMemberVisitor::Result m_aResult;
|
2006-06-19 17:35:12 -05:00
|
|
|
|
|
|
|
protected:
|
|
|
|
using NodeVisitor::handle;
|
2002-02-11 07:58:31 -06:00
|
|
|
};
|
|
|
|
|
2007-11-23 07:50:09 -06:00
|
|
|
bool GroupMemberDispatch::test_value(data::NodeAccess const& _aNode) const
|
2002-02-11 07:58:31 -06:00
|
|
|
{
|
|
|
|
Name aName = _aNode.getName();
|
|
|
|
|
|
|
|
return m_rStrategy.hasValue( m_aGroup, aName );
|
|
|
|
}
|
|
|
|
|
|
|
|
GroupMemberDispatch::Result GroupMemberDispatch::handle(data::ValueNodeAccess const& _aValue)
|
|
|
|
{
|
|
|
|
OSL_ENSURE( test_value(_aValue), "ERROR: Group MemberDispatch:Did not find a ValueMember for a value child.");
|
|
|
|
|
|
|
|
Name aValueName = _aValue.getName();
|
|
|
|
|
|
|
|
return mapResult( m_rVisitor.visit( m_rStrategy.getValue(m_aGroup,aValueName) ) );
|
|
|
|
}
|
|
|
|
|
2007-11-23 07:50:09 -06:00
|
|
|
GroupMemberDispatch::Result GroupMemberDispatch::handle(data::NodeAccess const& _aNonValue)
|
2006-06-19 17:35:12 -05:00
|
|
|
{
|
|
|
|
{ (void)_aNonValue; }
|
2002-02-11 07:58:31 -06:00
|
|
|
OSL_ENSURE( !test_value(_aNonValue), "ERROR: Group MemberDispatch:Found a ValueMember for a subtree child.");
|
|
|
|
|
|
|
|
return CONTINUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
configuration::ValueMemberNode ViewStrategy::doGetValueMember(GroupNode const& _aNode, Name const& _aName, bool ) const
|
|
|
|
{
|
|
|
|
using data::ValueNodeAccess;
|
|
|
|
|
|
|
|
ValueNodeAccess aValueData = getMemberValueAccess(_aNode,_aName);
|
|
|
|
|
|
|
|
return _aNode.get_impl()->makeValueMember( aValueData );
|
|
|
|
}
|
|
|
|
|
|
|
|
bool ViewStrategy::hasValue(GroupNode const& _aNode, Name const& _aName) const
|
|
|
|
{
|
|
|
|
checkInstance(_aNode.tree());
|
|
|
|
return getMemberValueAccess(_aNode,_aName).isValid();
|
|
|
|
}
|
|
|
|
|
2003-04-17 07:33:39 -05:00
|
|
|
bool ViewStrategy::hasValue(GroupNode const& _aNode) const
|
|
|
|
{
|
|
|
|
checkInstance(_aNode.tree());
|
|
|
|
configuration::GroupNodeImpl* pGroupNode=_aNode.get_impl();
|
2007-11-23 07:50:09 -06:00
|
|
|
data::GroupNodeAccess aGroupNodeAccess = pGroupNode->getDataAccess();
|
2003-04-17 07:33:39 -05:00
|
|
|
return aGroupNodeAccess.hasChildren();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2002-02-11 07:58:31 -06:00
|
|
|
bool ViewStrategy::areValueDefaultsAvailable(GroupNode const& _aNode) const
|
|
|
|
{
|
|
|
|
checkInstance(_aNode.tree());
|
|
|
|
|
2007-11-23 07:50:09 -06:00
|
|
|
return _aNode.get_impl()->areValueDefaultsAvailable();
|
2002-02-11 07:58:31 -06:00
|
|
|
}
|
|
|
|
|
2002-02-19 06:20:52 -06:00
|
|
|
configuration::ValueMemberNode ViewStrategy::getValue(GroupNode const& _aNode, Name const& _aName) const
|
2002-02-11 07:58:31 -06:00
|
|
|
{
|
|
|
|
checkInstance(_aNode.tree());
|
|
|
|
return doGetValueMember(_aNode,_aName,false);
|
|
|
|
}
|
|
|
|
|
|
|
|
configuration::ValueMemberUpdate ViewStrategy::getValueForUpdate(GroupNode const & _aNode, Name const& _aName)
|
|
|
|
{
|
|
|
|
checkInstance(_aNode.tree());
|
|
|
|
return ValueMemberUpdate( doGetValueMember(_aNode,_aName,true), *this );
|
|
|
|
}
|
|
|
|
|
|
|
|
GroupMemberVisitor::Result ViewStrategy::dispatchToValues(GroupNode const& _aNode, GroupMemberVisitor& _aVisitor)
|
|
|
|
{
|
|
|
|
checkInstance(_aNode.tree());
|
|
|
|
|
|
|
|
GroupMemberDispatch aDispatch(*this,_aNode,_aVisitor);
|
|
|
|
|
|
|
|
GroupMemberDispatch::Result eResult = aDispatch.visitChildren( _aNode.getAccess() );
|
|
|
|
|
|
|
|
return aDispatch.unmapResult(eResult);
|
|
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
ViewStrategy::SetNodeElement ViewStrategy::implMakeElement(SetNode const& _aNode, SetNodeEntry const& anEntry) const
|
|
|
|
{
|
|
|
|
configuration::SetNodeImpl * pNodeData = _aNode.get_impl();
|
2007-11-23 07:50:09 -06:00
|
|
|
return pNodeData->implValidateElement(pNodeData->entryToElement(anEntry));
|
2002-02-11 07:58:31 -06:00
|
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
SetEntry ViewStrategy::implFindElement(SetNode const& _aNode, Name const& aName) const
|
|
|
|
{
|
|
|
|
configuration::SetNodeImpl * pNodeData = _aNode.get_impl();
|
|
|
|
|
|
|
|
OSL_ENSURE(pNodeData->implHasLoadedElements(),"Cannot find elements in set that is not loaded");
|
|
|
|
configuration::ElementTreeImpl * pElement = pNodeData->doFindElement(aName);
|
|
|
|
|
2007-11-23 07:50:09 -06:00
|
|
|
return SetEntry(pElement);
|
2002-02-11 07:58:31 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
SetEntry ViewStrategy::findElement(SetNode const& _aNode, Name const& aName) const
|
|
|
|
{
|
|
|
|
checkInstance(_aNode.tree());
|
2007-11-23 07:50:09 -06:00
|
|
|
_aNode.get_impl()->implEnsureElementsLoaded();
|
2002-02-11 07:58:31 -06:00
|
|
|
return implFindElement(_aNode,aName);
|
|
|
|
}
|
|
|
|
|
|
|
|
SetEntry ViewStrategy::findAvailableElement(SetNode const& _aNode, Name const& aName) const
|
|
|
|
{
|
|
|
|
checkInstance(_aNode.tree());
|
|
|
|
if (_aNode.get_impl()->implHasLoadedElements())
|
|
|
|
return implFindElement(_aNode,aName);
|
|
|
|
else
|
2007-11-23 07:50:09 -06:00
|
|
|
return SetEntry(0);
|
2002-02-11 07:58:31 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
static
|
|
|
|
inline
|
|
|
|
std::auto_ptr<SubtreeChange> makeChangeToDefault(data::SetNodeAccess const & _aSetNode)
|
|
|
|
{
|
|
|
|
return std::auto_ptr<SubtreeChange>(
|
|
|
|
new SubtreeChange(
|
|
|
|
_aSetNode.getName().toString(),
|
|
|
|
_aSetNode.getElementTemplateName().toString(),
|
|
|
|
_aSetNode.getElementTemplateModule().toString(),
|
|
|
|
_aSetNode.getAttributes(),
|
|
|
|
true // to default
|
|
|
|
) );
|
|
|
|
}
|
|
|
|
|
|
|
|
std::auto_ptr<SubtreeChange> ViewStrategy::differenceToDefaultState(SetNode const& _aNode, ISubtree& _rDefaultTree) const
|
|
|
|
{
|
|
|
|
checkInstance(_aNode.tree());
|
|
|
|
std::auto_ptr<SubtreeChange> aResult;
|
|
|
|
|
|
|
|
data::SetNodeAccess aOriginalSetNode = _aNode.getAccess();
|
|
|
|
if (!aOriginalSetNode.isDefault())
|
|
|
|
{
|
|
|
|
OSL_ASSERT(aOriginalSetNode.isValid());
|
|
|
|
|
|
|
|
aResult = makeChangeToDefault( aOriginalSetNode );
|
|
|
|
|
|
|
|
configuration::SetNodeImpl * pNodeData = _aNode.get_impl();
|
|
|
|
if (this->hasChanges(_aNode.node()))
|
|
|
|
{
|
|
|
|
OSL_ENSURE(pNodeData->implHasLoadedElements(),"Unexpected: Found set with changes but elements are not loaded");
|
2007-11-23 07:50:09 -06:00
|
|
|
pNodeData->doDifferenceToDefaultState(*aResult,_rDefaultTree);
|
2002-02-11 07:58:31 -06:00
|
|
|
}
|
|
|
|
else
|
2007-11-23 07:50:09 -06:00
|
|
|
pNodeData->implDifferenceToDefaultState(*aResult,_rDefaultTree);
|
2002-02-11 07:58:31 -06:00
|
|
|
}
|
|
|
|
return aResult;
|
|
|
|
}
|
|
|
|
|
|
|
|
configuration::TemplateHolder ViewStrategy::getElementTemplate(SetNode const& _aNode) const
|
|
|
|
{
|
|
|
|
checkInstance(_aNode.tree());
|
|
|
|
return _aNode.get_impl()->getElementTemplate();
|
|
|
|
}
|
|
|
|
|
|
|
|
configuration::TemplateProvider ViewStrategy::getTemplateProvider(SetNode const& _aNode) const
|
|
|
|
{
|
|
|
|
checkInstance(_aNode.tree());
|
|
|
|
return _aNode.get_impl()->getTemplateProvider();
|
|
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
2007-11-23 07:50:09 -06:00
|
|
|
data::NodeAccess ViewStrategy::getNodeAccess(Node const& _aNode) const
|
2002-02-11 07:58:31 -06:00
|
|
|
{
|
|
|
|
checkInstance(_aNode.tree());
|
2003-04-01 06:43:09 -06:00
|
|
|
return _aNode.getAccessRef();
|
2002-02-11 07:58:31 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
Name ViewStrategy::getNodeName(Node const& _aNode) const
|
|
|
|
{
|
|
|
|
checkInstance(_aNode.tree());
|
|
|
|
return _aNode.data().getName();
|
|
|
|
}
|
|
|
|
|
|
|
|
node::Attributes ViewStrategy::getNodeAttributes(Node const& _aNode) const
|
|
|
|
{
|
|
|
|
checkInstance(_aNode.tree());
|
2007-11-23 07:50:09 -06:00
|
|
|
return _aNode.getAccessRef()->getAttributes();
|
2002-02-11 07:58:31 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
SetNodeVisitor::Result ViewStrategy::dispatchToElements(SetNode const& _aNode, SetNodeVisitor& _aVisitor)
|
|
|
|
{
|
|
|
|
checkInstance(_aNode.tree());
|
|
|
|
|
|
|
|
configuration::SetNodeImpl * pNodeData = _aNode.get_impl();
|
|
|
|
|
2007-11-23 07:50:09 -06:00
|
|
|
if (pNodeData->implLoadElements())
|
|
|
|
return pNodeData->doDispatchToElements(_aVisitor);
|
2002-02-11 07:58:31 -06:00
|
|
|
|
|
|
|
else
|
|
|
|
return SetNodeVisitor::CONTINUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool ViewStrategy::isEmpty(SetNode const& _aNode) const
|
|
|
|
{
|
|
|
|
checkInstance(_aNode.tree());
|
|
|
|
|
|
|
|
configuration::SetNodeImpl * pNodeData = _aNode.get_impl();
|
|
|
|
|
2007-11-23 07:50:09 -06:00
|
|
|
return !pNodeData->implLoadElements() || pNodeData->doIsEmpty();
|
2002-02-11 07:58:31 -06:00
|
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
void ViewStrategy::insertElement(SetNode const& _aNode, Name const& _aName, SetEntry const& _aNewEntry)
|
|
|
|
{
|
|
|
|
// cannot insert, if we cannot check for collisions
|
|
|
|
checkInstance(_aNode.tree());
|
2007-11-23 07:50:09 -06:00
|
|
|
_aNode.get_impl()->implEnsureElementsLoaded();
|
2002-02-11 07:58:31 -06:00
|
|
|
doInsertElement(_aNode,_aName,_aNewEntry);
|
|
|
|
}
|
|
|
|
|
|
|
|
void ViewStrategy::removeElement(SetNode const& _aNode, Name const& _aName)
|
|
|
|
{
|
|
|
|
// cannot remove, if we cannot check for existance
|
|
|
|
checkInstance(_aNode.tree());
|
2007-11-23 07:50:09 -06:00
|
|
|
_aNode.get_impl()->implEnsureElementsLoaded();
|
2002-02-11 07:58:31 -06:00
|
|
|
doRemoveElement(_aNode,_aName);
|
|
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
}
|
|
|
|
|