NBTExplorer/Model/TagDataNode.cs

344 lines
11 KiB
C#

using System;
using System.Collections.Generic;
using System.Windows.Forms;
using Substrate.Nbt;
namespace NBTExplorer.Model
{
public abstract class TagDataNode : DataNode
{
public abstract class Container : TagDataNode, IMetaTagContainer
{
protected Container (TagNode tag)
: base(tag)
{ }
#region ITagContainer
public virtual int TagCount
{
get { return 0; }
}
public virtual bool IsNamedContainer
{
get { return false; }
}
public virtual bool IsOrderedContainer
{
get { return false; }
}
public virtual INamedTagContainer NamedTagContainer
{
get { return null; }
}
public virtual IOrderedTagContainer OrderedTagContainer
{
get { return null; }
}
public virtual bool DeleteTag (TagNode tag)
{
return false;
}
#endregion
protected override NodeCapabilities Capabilities
{
get
{
return NodeCapabilities.Copy
| NodeCapabilities.CreateTag
| NodeCapabilities.Cut
| NodeCapabilities.Delete
| NodeCapabilities.PasteInto
| (TagParent.IsNamedContainer ? NodeCapabilities.Rename : NodeCapabilities.None)
| (TagParent.IsOrderedContainer ? NodeCapabilities.Reorder : NodeCapabilities.None)
| NodeCapabilities.Search;
}
}
public override bool HasUnexpandedChildren
{
get { return !IsExpanded && TagCount > 0; }
}
public override string NodeDisplay
{
get { return NodeDisplayPrefix + TagCount + ((TagCount == 1) ? " entry" : " entries"); }
}
}
private static Dictionary<TagType, Type> _tagRegistry;
static TagDataNode ()
{
_tagRegistry = new Dictionary<TagType, Type>();
_tagRegistry[TagType.TAG_BYTE] = typeof(TagByteDataNode);
_tagRegistry[TagType.TAG_BYTE_ARRAY] = typeof(TagByteArrayDataNode);
_tagRegistry[TagType.TAG_COMPOUND] = typeof(TagCompoundDataNode);
_tagRegistry[TagType.TAG_DOUBLE] = typeof(TagDoubleDataNode);
_tagRegistry[TagType.TAG_FLOAT] = typeof(TagFloatDataNode);
_tagRegistry[TagType.TAG_INT] = typeof(TagIntDataNode);
_tagRegistry[TagType.TAG_INT_ARRAY] = typeof(TagIntArrayDataNode);
_tagRegistry[TagType.TAG_LIST] = typeof(TagListDataNode);
_tagRegistry[TagType.TAG_LONG] = typeof(TagLongDataNode);
_tagRegistry[TagType.TAG_SHORT] = typeof(TagShortDataNode);
_tagRegistry[TagType.TAG_STRING] = typeof(TagStringDataNode);
}
static public TagDataNode CreateFromTag (TagNode tag)
{
if (tag == null || !_tagRegistry.ContainsKey(tag.GetTagType()))
return null;
return Activator.CreateInstance(_tagRegistry[tag.GetTagType()], tag) as TagDataNode;
}
static public TagNode DefaultTag (TagType type)
{
switch (type) {
case TagType.TAG_BYTE:
return new TagNodeByte(0);
case TagType.TAG_BYTE_ARRAY:
return new TagNodeByteArray(new byte[0]);
case TagType.TAG_COMPOUND:
return new TagNodeCompound();
case TagType.TAG_DOUBLE:
return new TagNodeDouble(0);
case TagType.TAG_FLOAT:
return new TagNodeFloat(0);
case TagType.TAG_INT:
return new TagNodeInt(0);
case TagType.TAG_INT_ARRAY:
return new TagNodeIntArray(new int[0]);
case TagType.TAG_LIST:
return new TagNodeList(TagType.TAG_BYTE);
case TagType.TAG_LONG:
return new TagNodeLong(0);
case TagType.TAG_SHORT:
return new TagNodeShort(0);
case TagType.TAG_STRING:
return new TagNodeString("");
default:
return new TagNodeByte(0);
}
}
private TagNode _tag;
protected TagDataNode (TagNode tag)
{
_tag = tag;
}
protected IMetaTagContainer TagParent
{
get { return base.Parent as IMetaTagContainer; }
}
protected TagNode Tag
{
get { return _tag; }
set
{
if (_tag.GetTagType() == value.GetTagType())
_tag = value;
}
}
protected override NodeCapabilities Capabilities
{
get
{
return NodeCapabilities.Copy
| NodeCapabilities.Cut
| NodeCapabilities.Delete
| NodeCapabilities.Edit
| (TagParent.IsNamedContainer ? NodeCapabilities.Rename : NodeCapabilities.None)
| (TagParent.IsOrderedContainer ? NodeCapabilities.Reorder : NodeCapabilities.None);
}
}
public override bool CanMoveNodeUp
{
get
{
if (TagParent.IsOrderedContainer)
return TagParent.OrderedTagContainer.GetTagIndex(Tag) > 0;
return false;
}
}
public override bool CanMoveNodeDown
{
get
{
if (TagParent.IsOrderedContainer)
return TagParent.OrderedTagContainer.GetTagIndex(Tag) < (TagParent.TagCount - 1);
return false;
}
}
public override string NodeName
{
get
{
if (TagParent == null || !TagParent.IsNamedContainer)
return null;
return TagParent.NamedTagContainer.GetTagName(Tag);
}
}
protected string NodeDisplayPrefix
{
get
{
string name = NodeName;
return String.IsNullOrEmpty(name) ? "" : name + ": ";
}
}
public override string NodeDisplay
{
get { return NodeDisplayPrefix + Tag.ToString(); }
}
public override bool DeleteNode ()
{
if (CanDeleteNode) {
TagParent.DeleteTag(Tag);
return Parent.Nodes.Remove(this);
}
return false;
}
public override bool RenameNode ()
{
if (CanRenameNode && TagParent.IsNamedContainer) {
EditName form = new EditName(TagParent.NamedTagContainer.GetTagName(Tag));
form.InvalidNames.AddRange(TagParent.NamedTagContainer.TagNamesInUse);
if (form.ShowDialog() == DialogResult.OK && form.IsModified) {
if (TagParent.NamedTagContainer.RenameTag(Tag, form.TagName)) {
IsModified = true;
return true;
}
}
}
return false;
}
public override bool CopyNode ()
{
if (CanCopyNode) {
NbtClipboardData clip = new NbtClipboardData(NodeName, Tag);
clip.CopyToClipboard();
return true;
}
return false;
}
public override bool CutNode ()
{
if (CanCutNode) {
NbtClipboardData clip = new NbtClipboardData(NodeName, Tag);
clip.CopyToClipboard();
TagParent.DeleteTag(Tag);
Parent.Nodes.Remove(this);
return true;
}
return false;
}
public override bool ChangeRelativePosition (int offset)
{
if (CanReoderNode) {
int curIndex = TagParent.OrderedTagContainer.GetTagIndex(Tag);
int newIndex = curIndex + offset;
if (newIndex < 0 || newIndex >= TagParent.OrderedTagContainer.TagCount)
return false;
TagParent.OrderedTagContainer.DeleteTag(Tag);
TagParent.OrderedTagContainer.InsertTag(Tag, newIndex);
DataNode parent = Parent;
parent.Nodes.Remove(this);
parent.Nodes.Insert(newIndex, this);
parent.IsModified = true;
return true;
}
return false;
}
protected bool EditScalarValue (TagNode tag)
{
EditValue form = new EditValue(tag);
if (form.ShowDialog() == DialogResult.OK) {
IsModified = true;
return true;
}
else
return false;
}
protected bool EditStringValue (TagNode tag)
{
EditString form = new EditString(tag.ToTagString().Data);
if (form.ShowDialog() == DialogResult.OK) {
tag.ToTagString().Data = form.StringValue;
IsModified = true;
return true;
}
else
return false;
}
protected bool EditByteHexValue (TagNode tag)
{
HexEditor form = new HexEditor(NodeName, tag.ToTagByteArray().Data, 1);
if (form.ShowDialog() == DialogResult.OK && form.Modified) {
Array.Copy(form.Data, tag.ToTagByteArray().Data, tag.ToTagByteArray().Length);
IsModified = true;
return true;
}
else
return false;
}
protected bool EditIntHexValue (TagNode tag)
{
TagNodeIntArray iatag = tag.ToTagIntArray();
byte[] data = new byte[iatag.Length * 4];
for (int i = 0; i < iatag.Length; i++) {
byte[] buf = BitConverter.GetBytes(iatag.Data[i]);
Array.Copy(buf, 0, data, 4 * i, 4);
}
HexEditor form = new HexEditor(NodeName, data, 4);
if (form.ShowDialog() == DialogResult.OK && form.Modified) {
for (int i = 0; i < iatag.Length; i++) {
iatag.Data[i] = BitConverter.ToInt32(form.Data, i * 4);
}
IsModified = true;
return true;
}
else
return false;
}
}
}