/// <summary> /// Build the Subrecord array with groups expanded. /// </summary> /// <param name="list"> /// The list. /// </param> /// <returns> /// The System.Collections.Generic.List`1[T -> TESVSnip.SubrecordStructure]. /// </returns> private static List <SubrecordStructure> BuildSubrecordStructure(IEnumerable <SubrecordBase> list) { var subrecords = new List <SubrecordStructure>(); foreach (var sr in list) { if (sr is SubrecordStructure) { subrecords.Add((SubrecordStructure)sr); } else if (sr is SubrecordGroup) { var sg = sr as SubrecordGroup; List <SubrecordStructure> sss = BuildSubrecordStructure(sg.elements); if (sss.Count > 0) { if (sg.repeat > 0) { sss[0] = new SubrecordStructure(sss[0], sss.Count, sss.Count); // replace } else if (sg.optional > 0) { sss[0] = new SubrecordStructure(sss[0], sss.Count, 0); // optional } } subrecords.AddRange(sss); } } return(subrecords); }
private RecordStructure(RecordsRecord rec, SubrecordBase[] subrecordTree, SubrecordStructure[] subrecords) { this.name = rec.name; this.description = rec.desc; this.subrecordTree = subrecordTree; this.subrecords = subrecords; }
/// <summary> /// Clear any state. /// </summary> public void ClearControl() { this.r = null; this.sr = null; this.ss = null; this.controlMap.Clear(); this.fpanel1.Controls.Clear(); Enabled = false; }
/// <summary> /// Initializes a new instance of the <see cref="SubrecordStructure"/> class. /// Clone structure with optional and repeat values overridden. /// </summary> /// <param name="src"> /// </param> /// <param name="optional"> /// </param> /// <param name="repeat"> /// </param> public SubrecordStructure(SubrecordStructure src, int optional, int repeat) : base(src, optional, repeat) { this.elements = src.elements; this.notininfo = src.notininfo; this.size = src.size; this.Condition = src.Condition; this.CondID = src.CondID; this.CondOperand = src.CondOperand; this.ContainsConditionals = src.ContainsConditionals; this.UseHexEditor = src.UseHexEditor; }
public MediumLevelRecordEditor(SubRecord sr, SubrecordStructure ss, dFormIDLookupS formIDLookup, dFormIDScan formIDScan, dLStringLookup strIDLookup) { this.InitializeComponent(); Icon = Resources.tesv_ico; SuspendLayout(); this.sr = sr; this.ss = ss; this.formIDLookup = formIDLookup; this.formIDScan = formIDScan; this.strIDLookup = strIDLookup; int offset = 0; byte[] data = sr.GetReadonlyData(); this.boxes = new List<TextBox>(ss.elements.Length); this.valueTypes = new List<ElementValueType>(ss.elements.Length); this.elements = new List<Panel>(); int groupOffset = 0; int CurrentGroup = 0; try { for (int i = 0; i < ss.elements.Length; i++) { if (ss.elements[i].optional && offset == data.Length) { this.AddElement(ss.elements[i]); } else { this.AddElement(ss.elements[i], ref offset, data, ref groupOffset, ref CurrentGroup); if (ss.elements[i].repeat > 0) { this.repeatcount++; if (offset < data.Length) { i--; } } } } if (ss.elements[ss.elements.Length - 1].repeat > 0 && this.repeatcount > 0) { this.AddElement(ss.elements[ss.elements.Length - 1]); } } catch { MessageBox.Show("The subrecord doesn't appear to conform to the expected structure.\n" + "Saving is disabled, and the formatted information may be incorrect", "Warning"); this.bSave.Enabled = false; } ResumeLayout(); }
private static bool MatchRecordCheckCondition(Dictionary<int, Conditional> conditions, SubrecordStructure ss) { if (ss.Condition == CondType.Exists) { if (conditions.ContainsKey(ss.CondID)) { return true; } else { return false; } } else if (ss.Condition == CondType.Missing) { if (conditions.ContainsKey(ss.CondID)) { return false; } else { return true; } } Conditional cond; if (!conditions.TryGetValue(ss.CondID, out cond)) { return false; } switch (cond.type) { case ElementValueType.SByte: case ElementValueType.Byte: case ElementValueType.UShort: case ElementValueType.Short: case ElementValueType.Int: case ElementValueType.UInt: case ElementValueType.FormID: { int i = Convert.ToInt32(cond.value), i2; if (!int.TryParse(ss.CondOperand, out i2)) { return false; } switch (ss.Condition) { case CondType.Equal: return i == i2; case CondType.Not: return i != i2; case CondType.Less: return i < i2; case CondType.Greater: return i > i2; case CondType.GreaterEqual: return i >= i2; case CondType.LessEqual: return i <= i2; default: return false; } } case ElementValueType.Float: { float i = (float) cond.value, i2; if (!float.TryParse(ss.CondOperand, out i2)) { return false; } switch (ss.Condition) { case CondType.Equal: return i == i2; case CondType.Not: return i != i2; case CondType.Less: return i < i2; case CondType.Greater: return i > i2; case CondType.GreaterEqual: return i >= i2; case CondType.LessEqual: return i <= i2; default: return false; } } case ElementValueType.Str4: case ElementValueType.BString: case ElementValueType.IString: case ElementValueType.String: { var s = (string) cond.value; switch (ss.Condition) { case CondType.Equal: return s == ss.CondOperand; case CondType.Not: return s != ss.CondOperand; case CondType.StartsWith: return s.StartsWith(ss.CondOperand); case CondType.EndsWith: return s.EndsWith(ss.CondOperand); case CondType.Contains: return s.Contains(ss.CondOperand); default: return false; } } case ElementValueType.LString: { int i = (int) cond.value, i2; if (!int.TryParse(ss.CondOperand, out i2)) { return false; } switch (ss.Condition) { case CondType.Equal: return i == i2; case CondType.Not: return i != i2; case CondType.Less: return i < i2; case CondType.Greater: return i > i2; case CondType.GreaterEqual: return i >= i2; case CondType.LessEqual: return i <= i2; default: return false; } } default: return false; } }
public NewMediumLevelRecordEditor(Plugin p, Record r, SubRecord sr, SubrecordStructure ss) { this.InitializeComponent(); Icon = Resources.tesv_ico; SuspendLayout(); this.sr = sr; this.ss = ss; this.p = p; this.r = r; // walk each element in standard fashion int panelOffset = 0; try { foreach (var elem in ss.elements) { Control c = null; if (elem.options != null && elem.options.Length > 1) { c = new OptionsElement(); } else if (elem.flags != null && elem.flags.Length > 1) { c = new FlagsElement(); } else { switch (elem.type) { case ElementValueType.LString: c = new LStringElement(); break; case ElementValueType.FormID: c = new FormIDElement(); break; case ElementValueType.Blob: c = new HexElement(); break; default: c = new TextElement(); break; } } if (c is IElementControl) { var ec = c as IElementControl; ec.formIDLookup = p.GetRecordByID; ec.formIDScan = p.EnumerateRecords; ec.strIDLookup = p.LookupFormStrings; ec.Element = elem; if (elem.repeat > 0) { var ge = new RepeatingElement(); c = ge; c.Left = 8; c.Width = this.fpanel1.Width - 16; c.Top = panelOffset; c.Anchor = c.Anchor | AnchorStyles.Left | AnchorStyles.Right; ge.InnerControl = ec; ge.Element = elem; ec = ge; } else if (elem.optional) { var re = new OptionalElement(); c = re; c.Left = 8; c.Width = this.fpanel1.Width - 16; c.Top = panelOffset; c.Anchor = c.Anchor | AnchorStyles.Left | AnchorStyles.Right; re.InnerControl = ec; re.Element = elem; ec = re; c = re; } else { c.Left = 8; c.Width = this.fpanel1.Width - 16; c.Top = panelOffset; c.Anchor = c.Anchor | AnchorStyles.Left | AnchorStyles.Right; } c.MinimumSize = c.Size; this.controlMap.Add(elem, ec); this.fpanel1.Controls.Add(c); panelOffset = c.Bottom; } } foreach (Element elem in r.EnumerateElements(sr, true)) { var es = elem.Structure; IElementControl c; if (this.controlMap.TryGetValue(es, out c)) { if (c is IGroupedElementControl) { var gc = c as IGroupedElementControl; gc.Elements.Add(elem.Data); } else { c.Data = elem.Data; } } } } catch { this.strWarnOnSave = "The subrecord doesn't appear to conform to the expected structure.\nThe formatted information may be incorrect."; this.Error.SetError(this.bSave, this.strWarnOnSave); this.Error.SetIconAlignment(this.bSave, ErrorIconAlignment.MiddleLeft); AcceptButton = this.bCancel; // remove save as default button when exception occurs CancelButton = this.bCancel; UpdateDefaultButton(); } ResumeLayout(); }
public void ConfigureRecords(IEnumerable<Record> records) { var recs = records.Select( x => { RecordStructure rs; return RecordStructure.Records.TryGetValue(x.Name, out rs) ? rs : null; }).Distinct(); this.rec = (recs.Count() == 1) ? recs.FirstOrDefault() : null; if (this.rec == null) { this.filterTree.Roots = null; } else { this.records = records; var srs = (from sr in this.rec.subrecords let children = sr.elements.Select(se => new BatchElement() { Name = se.name, Parent = null, Record = se, Type = BatchCondElementType.Set, Checked = false }).ToList() select new BatchSubrecord() { Name = string.Format("{0}: {1}", sr.name, sr.desc), Record = sr, Children = children, Checked = false, }).ToList(); // Construct specialized editors for FormID and related headers #if false { var elems = new List<TESVSnip.Data.SubrecordElement> { new TESVSnip.Data.SubrecordElement{name = "FormID", desc = "Form ID", hexview = true, type = "uint"}, new TESVSnip.Data.SubrecordElement{name = "Flags1", desc = "Flags 1", hexview = true, type = "uint"}, new TESVSnip.Data.SubrecordElement{name = "Flags2", desc = "Flags 2", hexview = true, type = "uint"}, new TESVSnip.Data.SubrecordElement{name = "Flags3", desc = "Flags 3", hexview = true, type = "uint"}, }; var frmHdr = new TESVSnip.Data.Subrecord { name = "Header", desc = "Record Header", Elements = elems }; var hdr = new SubrecordStructure(frmHdr); var hdrElems = hdr.elements.Select(se => new BatchElement { Name = se.name, Parent = null, Record = se, Type = BatchCondElementType.Set, Checked = false } ).ToList(); srs.Insert(0, new BatchSubrecord { Name = string.Format("{0}: {1}", hdr.name, hdr.desc), Record = hdr, Children = hdrElems, Checked = false, }); } #endif // fix parents after assignments foreach (var sr in srs) { foreach (var se in sr.Children) { se.Parent = sr; } } this.filterTree.Roots = srs; } }
public void SetContext(Record r, SubRecord sr, bool hexView) { if (this.r == r && this.sr == sr && this.hexView == hexView) { return; } if (r == null || sr == null) { this.ClearControl(); return; } // walk each element in standard fashion int panelOffset = 0; try { this.BeginUpdate(); this.ClearControl(); SuspendLayout(); this.fpanel1.SuspendLayout(); this.fpanel1.Width = Parent.Width; this.controlMap.Clear(); this.hexView = hexView; this.r = r; this.sr = sr; var p = this.GetPluginFromNode(r); this.ss = sr.Structure; // default to blob if no elements if (this.ss == null || this.ss.elements == null || hexView) { var c = new HexElement(); c.Left = 8; c.Width = this.fpanel1.Width - 16; c.Top = panelOffset; c.Anchor = c.Anchor | AnchorStyles.Left | AnchorStyles.Right; var elem = r.EnumerateElements(sr, true).FirstOrDefault(); if (elem != null) { this.controlMap.Add(elem.Structure, c); this.fpanel1.Controls.Add(c); c.Data = elem.Data; } } else { foreach (var elem in this.ss.elements) { Control c = null; if (elem.options != null && elem.options.Length > 1) { c = new OptionsElement(); } else if (elem.flags != null && elem.flags.Length > 1) { c = new FlagsElement(); } else { switch (elem.type) { case ElementValueType.LString: c = new LStringElement(); break; case ElementValueType.FormID: c = new FormIDElement(); break; case ElementValueType.Blob: c = new HexElement(); break; default: c = new TextElement(); break; } } if (c is IElementControl) { var ec = c as IElementControl; ec.formIDLookup = p.GetRecordByID; ec.formIDScan = p.EnumerateRecords; ec.strIDLookup = p.LookupFormStrings; ec.Element = elem; if (elem.repeat > 0) { var ge = new RepeatingElement(); c = ge; c.Left = 8; c.Width = this.fpanel1.Width - 16; c.Top = panelOffset; c.Anchor = c.Anchor | AnchorStyles.Left | AnchorStyles.Right; ge.InnerControl = ec; ge.Element = elem; ec = ge; } else if (elem.optional) { var re = new OptionalElement(); c = re; c.Left = 8; c.Width = this.fpanel1.Width - 16; c.Top = panelOffset; c.Anchor = c.Anchor | AnchorStyles.Left | AnchorStyles.Right; re.InnerControl = ec; re.Element = elem; ec = re; c = re; } else { c.Left = 8; c.Width = this.fpanel1.Width - 16; c.Top = panelOffset; c.Anchor = c.Anchor | AnchorStyles.Left | AnchorStyles.Right; } c.MinimumSize = c.Size; this.controlMap.Add(elem, ec); this.fpanel1.Controls.Add(c); panelOffset = c.Bottom; } } foreach (Element elem in r.EnumerateElements(sr, true)) { var es = elem.Structure; IElementControl c; if (this.controlMap.TryGetValue(es, out c)) { if (c is IGroupedElementControl) { var gc = c as IGroupedElementControl; gc.Elements.Add(elem.Data); } else { c.Data = elem.Data; } } } } Enabled = true; } catch { this.strWarnOnSave = "The subrecord doesn't appear to conform to the expected structure.\nThe formatted information may be incorrect."; } finally { this.fpanel1.ResumeLayout(); ResumeLayout(); this.EndUpdate(); Refresh(); } }
/// <summary> /// Build the Subrecord array with groups expanded. /// </summary> /// <param name="list"> /// The list. /// </param> /// <returns> /// The System.Collections.Generic.List`1[T -> TESVSnip.SubrecordStructure]. /// </returns> private static List<SubrecordStructure> BuildSubrecordStructure(IEnumerable<SubrecordBase> list) { var subrecords = new List<SubrecordStructure>(); foreach (var sr in list) { if (sr is SubrecordStructure) { subrecords.Add((SubrecordStructure)sr); } else if (sr is SubrecordGroup) { var sg = sr as SubrecordGroup; List<SubrecordStructure> sss = BuildSubrecordStructure(sg.elements); if (sss.Count > 0) { if (sg.repeat > 0) { sss[0] = new SubrecordStructure(sss[0], sss.Count, sss.Count); // replace } else if (sg.optional > 0) { sss[0] = new SubrecordStructure(sss[0], sss.Count, 0); // optional } } subrecords.AddRange(sss); } } return subrecords; }