in src/XmlNotepad/Commands.cs [1357:1465]
public MoveNode(XmlTreeView view, XmlTreeNode source, XmlTreeNode target, InsertPosition where, bool copy)
{
XmlNode sn = source.Node;
XmlNode dn = target.Node;
this._copy = copy;
TreeView tv = view.TreeView;
XmlDocument doc = view.Model.Document;
this._view = view;
this._sourcePosition = source.Index;
view.Model.BeginUpdate();
try
{
if (copy)
{
this._wasExpanded = source.IsExpanded;
XmlTreeNode newSource = view.CreateTreeNode();
if (sn != null)
{
if (sn.NodeType == XmlNodeType.Attribute)
{
string name = GetUniqueAttributeName((XmlAttribute)sn);
XmlAttribute na = doc.CreateAttribute(name);
na.Value = sn.Value;
sn = na;
}
else
{
sn = sn.CloneNode(true);
}
newSource.Node = sn;
}
source = newSource;
}
this._sourceParent = new TreeParent(tv, doc, source);
this._tp = new TreeParent(tv, doc, target);
// normalize destination based on source node type.
// for example, if source is an attribute, then it can only be
// inserted amongst attributes of another node.
if (_tp.IsRoot && where != InsertPosition.Child)
{
if (sn is XmlAttribute)
throw new Exception(SR.RootLevelAttributes);
if (sn is XmlText || sn is XmlCDataSection)
throw new Exception(SR.RootLevelText);
if (sn is XmlElement && sn.OwnerDocument.DocumentElement != null && sn.OwnerDocument.DocumentElement != sn)
throw new Exception(SR.RootLevelElements);
if (dn is XmlDeclaration && where == InsertPosition.Before)
throw new Exception(SR.RootLevelBeforeXmlDecl);
}
if (where != InsertPosition.Child)
{
if (sn is XmlAttribute)
{
if (!(dn is XmlAttribute))
{
if (_tp.AttributeCount != 0)
{
// move target to valid location for attributes.
target = _tp.GetChild(_tp.AttributeCount - 1);
where = InsertPosition.After;
}
else
{
// append the attribute.
where = InsertPosition.Child;
target = (XmlTreeNode)target.Parent;
}
}
}
else if (dn is XmlAttribute)
{
if (!(sn is XmlAttribute))
{
int skip = _tp.AttributeCount;
if (_tp.Count > skip)
{
// Move non-attribute down to beginning of child elements.
target = _tp.GetChild(skip);
where = InsertPosition.Before;
}
else
{
// append the node.
where = InsertPosition.Child;
target = (XmlTreeNode)target.Parent;
}
}
}
}
this._source = source;
this._target = target;
this._where = where;
this._tp = new TreeParent(tv, doc, target);
if (where == InsertPosition.Child)
{
this._tp.SetParent(target);
}
}
finally
{
view.Model.EndUpdate();
}
}