/// <summary> /// Insert a new item before or after the sibling item. /// </summary> /// <param name="item">Item to insert.</param> /// <param name="relatedItem">Sibling item, child of this item</param> /// <param name="beforeAfter">Insert before=True or after=False</param> public void InsertItem(QbItemBase item, QbItemBase sibling, bool beforeAfter) { for (int i = 0; i < this.Items.Count; i++) { if (this.Items[i] == sibling) { if (beforeAfter) { this.Items.Insert(i, item); } else { if (i + 1 < this.Items.Count) { this.Items.Insert(i + 1, item); } else { this.Items.Add(item); } } return; } } }
/// <summary> /// Creates an array item based on the data type of the parent. /// </summary> /// <param name="parent">Must be a simple array type</param> /// <returns></returns> public static GenericQbItem CreateGenericArrayItem(QbItemBase parent) { if (parent.Format == QbFormat.ArrayPointer || parent.Format == QbFormat.ArrayValue) { //creates an item with 1 entry, bit of a hack but it looks clean from the outside //this is hard to acheive because the information in the generic item is from attributes on the QB class. QbItemBase qb = CreateQbItemType(parent.Root, parent.QbItemType); return(GetGenericItems(qb)[0]); } return(null); }
internal QbItemBase SearchItems(QbFile qbFile, List <QbItemBase> qibs, bool recursive, Predicate <QbItemBase> match) { QbItemBase ret = null; foreach (QbItemBase qib in qibs) { if (match(qib)) { return(qib); } if (recursive && qib.Items.Count != 0) { ret = SearchItems(qbFile, qib.Items, recursive, match); if (ret != null) { return(ret); } } } return(ret); }
private QbItemBase recurseIsValid(QbItemBase item) { QbItemBase res; if (item.IsValid != IsValidReturnType.Okay) { return(item); } if (item.Items.Count != 0) { foreach (QbItemBase qib in item.Items) { res = recurseIsValid(qib); if (res != null) { return(res); } } } return(null); }
public static string FormatIsValidErrorMessage(QbItemBase item, IsValidReturnType errorType) { switch (errorType) { case IsValidReturnType.ItemMustHave0Items: return(string.Format("The Selected '{0}' item is invalid, it must have 0 values", item.QbItemType.ToString())); case IsValidReturnType.ItemMustHave1Item: return(string.Format("The Selected item is invalid, it must have 1 value", item.QbItemType.ToString())); case IsValidReturnType.ItemMustHave0OrMoreItems: return(string.Format("The Selected item is invalid, it must have 0 or more values", item.QbItemType.ToString())); case IsValidReturnType.ItemMustHave1OrMoreItems: return(string.Format("The Selected item is invalid, it must have 1 or more values", item.QbItemType.ToString())); case IsValidReturnType.ArrayItemsMustBeSameType: return(string.Format("The Selected item is invalid, array items must all be the same type", item.QbItemType.ToString())); default: return(string.Empty); } }
/// <summary> /// Insert a new item before or after the sibling item. /// </summary> /// <param name="item">Item to insert.</param> /// <param name="relatedItem">Sibling item, child of this item</param> /// <param name="beforeAfter">Insert before=True or after=False</param> public void InsertItem(QbItemBase item, QbItemBase sibling, bool beforeAfter) { for (int i = 0; i < this.Items.Count; i++) { if (this.Items[i] == sibling) { if (beforeAfter) this.Items.Insert(i, item); else { if (i + 1 < this.Items.Count) this.Items.Insert(i + 1, item); else this.Items.Add(item); } return; } } }
private void addSubItemsToGui(QbItemBase parent, int indent) { foreach (QbItemBase itm in parent.Items) { addItemToGui(itm, indent); addSubItemsToGui(itm, indent + 1); } }
private void addSearchListItem(string found, QbFile qbFile, QbItemBase qib) { ListViewItem li = new ListViewItem(found); li.ImageIndex = getQbItemImageIndex(qib.QbItemType); li.SubItems.Add(qbFile.Filename); li.SubItems.Add(string.Format("{0} ({1})", qib.Position.ToString("X").PadLeft(8, '0'), qib.Position.ToString())); li.SubItems.Add(qib.QbItemType.ToString()); lstSearchResults.Items.Add(li); }
private void addItemToGui(QbItemBase itm, int indent) { //let exceptions be raised ListViewItem li = new ListViewItem(itm.QbItemType.ToString()); li.IndentCount = indent; if (itm.DebugName.Length != 0) li.SubItems.Add(itm.DebugName); else if (itm.ItemQbKey != null && itm.ItemQbKey.Crc != 0) li.SubItems.Add(itm.ItemQbKey.Crc.ToString("X").PadLeft(8, '0')); else li.SubItems.Add(string.Empty); li.SubItems.Add(getValueForList(itm)); li.SubItems.Add(string.Format("{0} ({1})", itm.Position.ToString("X").PadLeft(8, '0'), itm.Position.ToString())); li.SubItems.Add(itm.Length.ToString()); li.SubItems.Add(itm.GetType().Name); li.ImageIndex = getQbItemImageIndex(itm.QbItemType); li.Tag = itm; //hold a reference to the item lstQbItems.Items.Add(li); }
private void addItemInsertSibling(QbItemBase newItem) { try { qbAddItemFloatAdjust(newItem, false); if (_addItemParent == null) _qbFile.InsertItem(newItem, _addItemSibling, true); else _addItemParent.InsertItem(newItem, _addItemSibling, true); _qbFile.AlignPointers(); populateQbList(newItem); btnSavePak.Enabled = true; } catch (Exception ex) { showException("Failed to insert sibling item.", ex); return; } }
private void addItemChild(QbItemBase newItem) { try { qbAddItemFloatAdjust(newItem, true); if (_addItemSibling != null) _addItemSibling.AddItem(newItem); else _qbFile.AddItem(newItem); _qbFile.AlignPointers(); populateQbList(newItem); btnSavePak.Enabled = true; } catch (Exception ex) { showException("Failed to add child item.", ex); return; } }
/// <summary> /// Remove the specified item from this items children /// </summary> /// <param name="item">Item to remove</param> public void RemoveItem(QbItemBase item) { _items.Remove(item); }
public void AddItem(QbItemBase item) { _items.Add(item); }
private static QbItemBase createQbItemType(QbFile qbFile, QbItemType type, QbFormat qbFormat, bool hasQbFormat) { QbItemBase qib = null; if (qbFile.PakFormat.GetQbItemValue(type, qbFile) == 0xFFFFFFFF) { throw new ApplicationException(string.Format("'{0}' data value not known for {1}", type.ToString(), qbFile.PakFormat.FriendlyName)); } switch (type) { //case QbItemType.Unknown: // break; case QbItemType.SectionString: case QbItemType.SectionStringW: case QbItemType.ArrayString: case QbItemType.ArrayStringW: case QbItemType.StructItemString: case QbItemType.StructItemStringW: qib = new QbItemString(qbFile); break; case QbItemType.SectionArray: case QbItemType.ArrayArray: case QbItemType.StructItemArray: qib = new QbItemArray(qbFile); break; case QbItemType.SectionStruct: case QbItemType.StructItemStruct: case QbItemType.StructHeader: qib = new QbItemStruct(qbFile); break; case QbItemType.SectionScript: qib = new QbItemScript(qbFile); break; case QbItemType.SectionFloat: case QbItemType.ArrayFloat: case QbItemType.StructItemFloat: qib = new QbItemFloat(qbFile); break; case QbItemType.SectionFloatsX2: case QbItemType.SectionFloatsX3: case QbItemType.ArrayFloatsX2: case QbItemType.ArrayFloatsX3: case QbItemType.StructItemFloatsX2: case QbItemType.StructItemFloatsX3: qib = new QbItemFloatsArray(qbFile); break; case QbItemType.SectionInteger: case QbItemType.SectionStringPointer: case QbItemType.ArrayInteger: case QbItemType.ArrayStringPointer: //GH:GH case QbItemType.StructItemStringPointer: case QbItemType.StructItemInteger: qib = new QbItemInteger(qbFile); break; case QbItemType.SectionQbKey: case QbItemType.SectionQbKeyString: case QbItemType.SectionQbKeyStringQs: //GH:GH case QbItemType.ArrayQbKey: case QbItemType.ArrayQbKeyString: case QbItemType.ArrayQbKeyStringQs: //GH:GH case QbItemType.StructItemQbKey: case QbItemType.StructItemQbKeyString: case QbItemType.StructItemQbKeyStringQs: qib = new QbItemQbKey(qbFile); break; case QbItemType.Floats: qib = new QbItemFloats(qbFile); break; case QbItemType.ArrayStruct: qib = new QbItemStructArray(qbFile); break; default: throw new ApplicationException(string.Format("'{0}' is not recognised by CreateQbItemType.", type.ToString())); } if (qib != null) { qib.Create(type); } return(qib); }
public override void Construct(BinaryEndianReader br, QbItemType type) { //System.Diagnostics.Debug.WriteLine(string.Format("{0} - 0x{1}", type.ToString(), (base.StreamPos(br) - 4).ToString("X").PadLeft(8, '0'))); base.Construct(br, type); uint pointer; if (type != QbItemType.StructHeader) { _headerValue = br.ReadUInt32(base.Root.PakFormat.EndianType); } else { _headerValue = base.Root.PakFormat.GetQbItemValue(type, this.Root); } _headerType = base.Root.PakFormat.GetQbItemType(_headerValue); QbItemBase qib = null; QbItemType structType; uint structValue; if (_headerType == QbItemType.StructHeader) { pointer = br.ReadUInt32(base.Root.PakFormat.EndianType); //Should be the current stream position after reading _iniNextItemPointer = pointer; if (pointer != 0 && base.StreamPos(br) != pointer) //pointer test { throw new ApplicationException(QbFile.FormatBadPointerExceptionMessage(this, base.StreamPos(br), pointer)); } while (pointer != 0) { structValue = br.ReadUInt32(this.Root.PakFormat.EndianType); structType = this.Root.PakFormat.GetQbItemType(structValue); switch (structType) { case QbItemType.StructItemStruct: this.Root.PakFormat.StructItemChildrenType = StructItemChildrenType.StructItems; qib = new QbItemStruct(this.Root); break; case QbItemType.StructItemStringPointer: case QbItemType.StructItemInteger: this.Root.PakFormat.StructItemChildrenType = StructItemChildrenType.StructItems; qib = new QbItemInteger(this.Root); break; case QbItemType.StructItemQbKeyString: case QbItemType.StructItemQbKeyStringQs: case QbItemType.StructItemQbKey: this.Root.PakFormat.StructItemChildrenType = StructItemChildrenType.StructItems; qib = new QbItemQbKey(this.Root); break; case QbItemType.StructItemString: case QbItemType.StructItemStringW: this.Root.PakFormat.StructItemChildrenType = StructItemChildrenType.StructItems; qib = new QbItemString(this.Root); break; case QbItemType.StructItemFloat: this.Root.PakFormat.StructItemChildrenType = StructItemChildrenType.StructItems; qib = new QbItemFloat(this.Root); break; case QbItemType.StructItemFloatsX2: case QbItemType.StructItemFloatsX3: this.Root.PakFormat.StructItemChildrenType = StructItemChildrenType.StructItems; qib = new QbItemFloatsArray(this.Root); break; case QbItemType.StructItemArray: this.Root.PakFormat.StructItemChildrenType = StructItemChildrenType.StructItems; qib = new QbItemArray(this.Root); break; //Convert array types to structitems to fit in with this parser (if QbFile.HasStructItems is false then internal type will be swapped back to array) case QbItemType.ArrayStruct: structType = QbItemType.StructItemStruct; qib = new QbItemArray(this.Root); break; case QbItemType.ArrayInteger: structType = QbItemType.StructItemInteger; qib = new QbItemInteger(this.Root); break; case QbItemType.ArrayQbKeyString: structType = QbItemType.StructItemQbKeyString; qib = new QbItemQbKey(this.Root); break; case QbItemType.ArrayStringPointer: structType = QbItemType.StructItemStringPointer; qib = new QbItemInteger(this.Root); break; case QbItemType.ArrayQbKeyStringQs: structType = QbItemType.StructItemQbKeyStringQs; qib = new QbItemQbKey(this.Root); break; case QbItemType.ArrayQbKey: structType = QbItemType.StructItemQbKey; qib = new QbItemQbKey(this.Root); break; case QbItemType.ArrayString: structType = QbItemType.StructItemString; qib = new QbItemString(this.Root); break; case QbItemType.ArrayStringW: structType = QbItemType.StructItemStringW; qib = new QbItemString(this.Root); break; case QbItemType.ArrayFloat: structType = QbItemType.StructItemFloat; qib = new QbItemFloat(this.Root); break; case QbItemType.ArrayFloatsX2: structType = QbItemType.StructItemFloatsX2; qib = new QbItemFloatsArray(this.Root); break; case QbItemType.ArrayFloatsX3: structType = QbItemType.StructItemFloatsX3; qib = new QbItemFloatsArray(this.Root); break; case QbItemType.ArrayArray: structType = QbItemType.StructItemArray; qib = new QbItemArray(this.Root); break; default: qib = null; break; } if (qib != null) { if (this.Root.PakFormat.StructItemChildrenType == StructItemChildrenType.NotSet) //will have been set to structItem if qib is not null) { this.Root.PakFormat.StructItemChildrenType = StructItemChildrenType.ArrayItems; } qib.Construct(br, structType); AddItem(qib); pointer = qib.NextItemPointer; } else { throw new ApplicationException(string.Format("Location 0x{0}: Unknown item type 0x{1} in struct ", (base.StreamPos(br) - 4).ToString("X").PadLeft(8, '0'), structValue.ToString("X").PadLeft(8, '0'))); } } } else { throw new ApplicationException(string.Format("Location 0x{0}: Struct without header type", (base.StreamPos(br) - 4).ToString("X").PadLeft(8, '0'))); } base.ConstructEnd(br); }
public static void SetGenericItems(QbItemBase item, List <GenericQbItem> gItems) { MemberInfo[] ms = item.GetType().FindMembers(MemberTypes.Property, /*BindingFlags.DeclaredOnly |*/ BindingFlags.Instance | BindingFlags.Public, Type.FilterName, "*"); int i = 0; GenericQbItem gi; List <GenericQbItem> list = null; if (gItems.Count == 0) { //test if this is an array item GenericQbItem gqi = QbFile.CreateGenericArrayItem(item); //null if not an array type if (gqi != null) { //use this item to identify the array to set to 0 items MemberInfo m = Array.Find(ms, delegate(MemberInfo mi) { return(mi.Name == gqi.SourceProperty); }); if (m != null) { Type t = ((PropertyInfo)m).GetValue(item, null).GetType(); if (t == typeof(QbKey[])) { ((PropertyInfo)m).SetValue(item, new QbKey[0], null); } else if (t == typeof(float[])) { ((PropertyInfo)m).SetValue(item, new float[0], null); } else if (t == typeof(uint[])) { ((PropertyInfo)m).SetValue(item, new uint[0], null); } else if (t == typeof(int[])) { ((PropertyInfo)m).SetValue(item, new int[0], null); } else if (t == typeof(string[])) { ((PropertyInfo)m).SetValue(item, new string[0], null); } } } } while (i < gItems.Count) { gi = gItems[i++]; if (gi.ReadOnly) { continue; } //list = null; list = new List <GenericQbItem>(); list.Add(gi); while (i < gItems.Count && gi.SourceProperty == gItems[i].SourceProperty) { list.Add(gItems[i++]); } MemberInfo m = Array.Find(ms, delegate(MemberInfo mi) { return(mi.Name == gi.SourceProperty); }); if (m != null) { Type t = ((PropertyInfo)m).GetValue(item, null).GetType(); if (t == typeof(QbKey[])) { QbKey[] qb = new QbKey[list.Count]; QbKey q; string qS; for (int c = 0; c < list.Count; c++) { q = list[c].ToQbKey(); qS = item.Root.LookupDebugName(q.Crc); if (qS.Length != 0) { q = QbKey.Create(q.Crc, qS); } qb[c] = q; } ((PropertyInfo)m).SetValue(item, qb, null); } else if (t == typeof(float[])) { float[] f = new float[list.Count]; for (int c = 0; c < list.Count; c++) { f[c] = list[c].ToSingle(); } ((PropertyInfo)m).SetValue(item, f, null); } else if (t == typeof(uint[])) { uint[] ui = new uint[list.Count]; for (int c = 0; c < list.Count; c++) { ui[c] = list[c].ToUInt32(); } ((PropertyInfo)m).SetValue(item, ui, null); } else if (t == typeof(int[])) { int[] si = new int[list.Count]; for (int c = 0; c < list.Count; c++) { si[c] = list[c].ToInt32(); } ((PropertyInfo)m).SetValue(item, si, null); } else if (t == typeof(string[])) { string[] s = new string[list.Count]; for (int c = 0; c < list.Count; c++) { s[c] = list[c].ToString(); } ((PropertyInfo)m).SetValue(item, s, null); } else if (t == typeof(QbKey)) { QbKey q = gi.ToQbKey(); string qS = item.Root.LookupDebugName(q.Crc); if (qS.Length != 0) { q = QbKey.Create(q.Crc, qS); } ((PropertyInfo)m).SetValue(item, q, null); } else if (t == typeof(float)) { ((PropertyInfo)m).SetValue(item, gi.ToSingle(), null); } else if (t == typeof(uint)) { ((PropertyInfo)m).SetValue(item, gi.ToUInt32(), null); } else if (t == typeof(int)) { ((PropertyInfo)m).SetValue(item, gi.ToInt32(), null); } else if (t == typeof(string)) { ((PropertyInfo)m).SetValue(item, gi.ToString(), null); } else if (t == typeof(byte[])) { ((PropertyInfo)m).SetValue(item, gi.ToByteArray(), null); } else { throw new ApplicationException(string.Format("DataType {0} not supported.", t.Name)); } } } }
private string getValueForList(QbItemBase itm) { int max = 100; StringBuilder sb = new StringBuilder(max); if (itm is QbItemInteger) { foreach (uint i in ((QbItemInteger)itm).Values) { if (sb.Length != 0) sb.Append(", "); sb.Append(((int)i).ToString()); //default to ease for this quick list if (sb.Length > max) break; } } else if (itm is QbItemFloat) { foreach (float f in ((QbItemFloat)itm).Values) { if (sb.Length != 0) sb.Append(", "); sb.Append(f.ToString()); if (sb.Length > max) break; } } else if (itm is QbItemFloats) { foreach (float f in ((QbItemFloats)itm).Values) { if (sb.Length != 0) sb.Append(", "); sb.Append(f.ToString()); if (sb.Length > max) break; } } else if (itm is QbItemQbKey) { foreach (QbKey qb in ((QbItemQbKey)itm).Values) { if (sb.Length != 0) sb.Append(", "); if (qb.Text.Length != 0) sb.Append(qb.Text); else sb.Append(qb.Crc.ToString("X").PadLeft(8, '0')); if (sb.Length > max) break; } } else if (itm is QbItemString) { foreach (string s in ((QbItemString)itm).Strings) { if (sb.Length != 0) sb.Append(", "); sb.Append(s); if (sb.Length > max) break; } } string str = sb.ToString(); if (str.Length > max) return string.Concat(str.Substring(0, max), "..."); else return str; }
/// <summary> /// Analyse the attributes on the item and return the editable items /// </summary> /// <param name="item"></param> /// <returns></returns> public static List <GenericQbItem> GetGenericItems(QbItemBase item) { List <GenericQbItem> items = new List <GenericQbItem>(); GenericQbItem itm = null; MemberInfo[] ms = item.GetType().FindMembers(MemberTypes.Property, /*BindingFlags.DeclaredOnly |*/ BindingFlags.Instance | BindingFlags.Public, Type.FilterName, "*"); foreach (MemberInfo m in ms) { GenericEditableAttribute a = Attribute.GetCustomAttribute(m, typeof(GenericEditableAttribute)) as GenericEditableAttribute; if (a != null) { //return attribute value and pass in to generic items and return object o = ((PropertyInfo)m).GetValue(item, null); if (o == null) { continue; } if (o is byte[]) //hex { itm = new GenericQbItem(a.DefaultDisplayName, (byte[])o, a.EditType, a.ReadOnly, a.UseQbItemType, item.QbItemType, m.Name); items.Add(itm); } else if (o is string[]) { foreach (string s in ((string[])o)) { itm = new GenericQbItem(a.DefaultDisplayName, s, a.EditType, a.ReadOnly, a.UseQbItemType, item.QbItemType, m.Name); items.Add(itm); } } else if (o is string) { itm = new GenericQbItem(a.DefaultDisplayName, (string)o, a.EditType, a.ReadOnly, a.UseQbItemType, item.QbItemType, m.Name); items.Add(itm); } else if (o is uint[]) { foreach (uint s in ((uint[])o)) { itm = new GenericQbItem(a.DefaultDisplayName, s, a.EditType, a.ReadOnly, a.UseQbItemType, item.QbItemType, m.Name); items.Add(itm); } } else if (o is uint) { itm = new GenericQbItem(a.DefaultDisplayName, (uint)o, a.EditType, a.ReadOnly, a.UseQbItemType, item.QbItemType, m.Name); items.Add(itm); } else if (o is int[]) { foreach (int s in ((int[])o)) { itm = new GenericQbItem(a.DefaultDisplayName, s, a.EditType, a.ReadOnly, a.UseQbItemType, item.QbItemType, m.Name); items.Add(itm); } } else if (o is int) { itm = new GenericQbItem(a.DefaultDisplayName, (int)o, a.EditType, a.ReadOnly, a.UseQbItemType, item.QbItemType, m.Name); items.Add(itm); } else if (o is float[]) { foreach (float s in ((float[])o)) { itm = new GenericQbItem(a.DefaultDisplayName, s, a.EditType, a.ReadOnly, a.UseQbItemType, item.QbItemType, m.Name); items.Add(itm); } } else if (o is float) { itm = new GenericQbItem(a.DefaultDisplayName, (float)o, a.EditType, a.ReadOnly, a.UseQbItemType, item.QbItemType, m.Name); items.Add(itm); } else if (o is QbKey[]) { foreach (QbKey s in ((QbKey[])o)) { itm = new GenericQbItem(a.DefaultDisplayName, s, a.EditType, a.ReadOnly, a.UseQbItemType, item.QbItemType, m.Name); items.Add(itm); } } else if (o is QbKey) { itm = new GenericQbItem(a.DefaultDisplayName, (QbKey)o, a.EditType, a.ReadOnly, a.UseQbItemType, item.QbItemType, m.Name); items.Add(itm); } else { throw new ApplicationException(string.Format("Unknown generic data type item '{0}'", o.GetType().Name)); } } } return(items); }
private void lstQbItems_MouseUp(object sender, MouseEventArgs e) { try { if (lstQbItems.SelectedItems.Count == 0) gboEdit.Controls.Clear(); if (e.Button != MouseButtons.Right) return; _addItemParent = null; _addItemSibling = null; int sIdx = lstQbItems.SelectedItems.Count > 0 ? lstQbItems.SelectedIndices[0] : -1; int pIdx; //parent index ToolStripMenuItem mi; QbItemType[] types = null; if (sIdx != -1) { ListViewItem li = lstQbItems.SelectedItems[0]; _addItemSibling = (QbItemBase)li.Tag; //find parent list item if (li.IndentCount != 0) { pIdx = sIdx; while (lstQbItems.Items[--pIdx].IndentCount != li.IndentCount - 1) ; _addItemParent = (QbItemBase)lstQbItems.Items[pIdx].Tag; } for (int m = mnuInsertSibling.DropDownItems.Count - 1; m >= 0; m--) { mi = (ToolStripMenuItem)mnuInsertSibling.DropDownItems[m]; mi.Click -= new EventHandler(qbAddItemInsertSibling_Click); mnuInsertSibling.DropDownItems.Remove(mi); } for (int m = mnuAddSibling.DropDownItems.Count - 1; m >= 0; m--) { mi = (ToolStripMenuItem)mnuAddSibling.DropDownItems[m]; mi.Click -= new EventHandler(qbAddItemAddSibling_Click); mnuAddSibling.DropDownItems.Remove(mi); } } //remove items and remove event handlers for (int m = mnuAddChild.DropDownItems.Count - 1; m >= 0; m--) { mi = (ToolStripMenuItem)mnuAddChild.DropDownItems[m]; mi.Click -= new EventHandler(qbAddItemChild_Click); mnuAddChild.DropDownItems.Remove(mi); } bool pasteAddChild = false; bool pasteInsertSibling = false; bool pasteAddSibling = false; //add new menu items types = QbFile.SupportedChildTypes(_addItemSibling == null ? QbItemType.Root : _addItemSibling.QbItemType); foreach (QbItemType qbt in types) { string n = getMenuTypename(qbt); if (_copyItem != null && qbt == _copyItem.QbItemType) pasteAddChild = true; mi = (ToolStripMenuItem)mnuAddChild.DropDownItems.Add(n, imgList.Images[getQbItemImageIndex(qbt)], qbAddItemChild_Click); mi.Tag = qbt; // sIdx; //store selected index in list } if (sIdx != -1) { types = QbFile.SupportedChildTypes(_addItemParent == null || _addItemSibling.QbItemType == QbItemType.Unknown ? QbItemType.Root : _addItemParent.QbItemType); foreach (QbItemType qbt in types) { string n = getMenuTypename(qbt); if (_copyItem != null && qbt == _copyItem.QbItemType) { pasteAddSibling = true; if (_addItemSibling.QbItemType != QbItemType.Unknown) //cannot insert before unknown pasteInsertSibling = true; } if (_addItemSibling.QbItemType != QbItemType.Unknown) { mi = (ToolStripMenuItem)mnuInsertSibling.DropDownItems.Add(n, imgList.Images[getQbItemImageIndex(qbt)], qbAddItemInsertSibling_Click); mi.Tag = qbt; // sIdx; //store selected index in list } mi = (ToolStripMenuItem)mnuAddSibling.DropDownItems.Add(n, imgList.Images[getQbItemImageIndex(qbt)], qbAddItemAddSibling_Click); mi.Tag = qbt; // sIdx; //store selected index in list } } mnuQbEdit.Tag = sIdx; mnuAddChild.Enabled = (mnuAddChild.DropDownItems.Count != 0); mnuInsertSibling.Enabled = sIdx != -1 && (mnuInsertSibling.DropDownItems.Count != 0); mnuAddSibling.Enabled = sIdx != -1 && (mnuAddSibling.DropDownItems.Count != 0); mnuRemoveSibling.Enabled = _addItemSibling != null && _addItemSibling.QbItemType != QbItemType.Unknown; mnuPasteAddChild.Enabled = pasteAddChild && mnuAddChild.Enabled; mnuPasteInsertSibling.Enabled = pasteInsertSibling && mnuInsertSibling.Enabled; mnuPasteAddSibling.Enabled = pasteAddSibling && mnuAddSibling.Enabled; mnuCopyItems.Enabled = _addItemSibling != null && _addItemSibling.QbItemType != QbItemType.Unknown; if (_addItemSibling != null) //selected item mnuCopyItems.Text = string.Format("Copy ({0})", getMenuTypename(_addItemSibling.QbItemType)); else mnuCopyItems.Text = "Copy"; mnuPasteItems.Enabled = _copyItem != null; if (_copyItem != null) mnuPasteItems.Text = string.Format("Paste ({0})", getMenuTypename(_copyItem.QbItemType)); else mnuPasteItems.Text = "Paste"; mnuQbEdit.Show(lstQbItems, e.Location); } catch (Exception ex) { showException("Failed to create menu items.", ex); return; } }
/// <summary> /// Creates an array item based on the data type of the parent. /// </summary> /// <param name="parent">Must be a simple array type</param> /// <returns></returns> public static GenericQbItem CreateGenericArrayItem(QbItemBase parent) { if (parent.Format == QbFormat.ArrayPointer || parent.Format == QbFormat.ArrayValue) { //creates an item with 1 entry, bit of a hack but it looks clean from the outside //this is hard to acheive because the information in the generic item is from attributes on the QB class. QbItemBase qb = CreateQbItemType(parent.Root, parent.QbItemType); return GetGenericItems(qb)[0]; } return null; }
private void mnuCopyItems_Click(object sender, EventArgs e) { //clone so we can paste over multiple paks _copyItem = ((QbItemBase)lstQbItems.Items[(int)mnuQbEdit.Tag].Tag).Clone(); }
public static string FormatIsValidErrorMessage(QbItemBase item, IsValidReturnType errorType) { switch (errorType) { case IsValidReturnType.ItemMustHave0Items: return string.Format("The Selected '{0}' item is invalid, it must have 0 values", item.QbItemType.ToString()); case IsValidReturnType.ItemMustHave1Item: return string.Format("The Selected item is invalid, it must have 1 value", item.QbItemType.ToString()); case IsValidReturnType.ItemMustHave0OrMoreItems: return string.Format("The Selected item is invalid, it must have 0 or more values", item.QbItemType.ToString()); case IsValidReturnType.ItemMustHave1OrMoreItems: return string.Format("The Selected item is invalid, it must have 1 or more values", item.QbItemType.ToString()); case IsValidReturnType.ArrayItemsMustBeSameType: return string.Format("The Selected item is invalid, array items must all be the same type", item.QbItemType.ToString()); default: return string.Empty; } }
private void populateQbList(QbItemBase selectItem) { ListViewItem topItem = null; try { bool isRefresh = (selectItem != null); lstQbItems.BeginUpdate(); //try to preserve the top item ListViewItem top = lstQbItems.TopItem; //can return null int topIdx = 0; //if is refresh, try and select the same item if (isRefresh && top != null) { for (int i = 0; i < lstQbItems.Items.Count; i++) { if (lstQbItems.Items[i] == top) { topIdx = i; break; } } } //clear items without as much flicker as Items.Clear for (int i = lstQbItems.Items.Count - 1; i >= 0; i--) lstQbItems.Items.RemoveAt(i); foreach (QbItemBase itm in _qbFile.Items) { addItemToGui(itm, 0); addSubItemsToGui(itm, 0 + 1); } ListViewItem foundItem = null; if (selectItem != null) { foreach (ListViewItem li in lstQbItems.Items) { if (li.Tag == selectItem) { foundItem = li; break; } } } if (foundItem == null && lstQbItems.Items.Count != 0) foundItem = lstQbItems.Items[0]; if (isRefresh && top != null && lstQbItems.Items.Count != 0 && topIdx >= 0 && topIdx < lstQbItems.Items.Count) { topItem = lstQbItems.Items[topIdx]; lstQbItems.TopItem = topItem; lstQbItems.TopItem = topItem; //crazy, but stops the wrong item being set. } if (foundItem != null) { foundItem.Selected = true; foundItem.Focused = true; foundItem.EnsureVisible(); } if (lstQbItems.SelectedIndices.Count == 0 && lstQbItems.Items.Count != 0) { lstQbItems.Items[0].Selected = true; lstQbItems.Items[0].Focused = true; } if (lstQbItems.SelectedIndices.Count == 0) { gboEdit.Controls.Clear(); } tlblQbFileInfo.Text = string.Format("QB file: {0} items, {1} bytes", lstQbItems.Items.Count.ToString(), _qbFile.Length.ToString()); } catch (Exception ex) { showException("QB List Population Error", ex); clearInterfaceQb(); return; } finally { lstQbItems.EndUpdate(); } }
/// <summary> /// Analyse the attributes on the item and return the editable items /// </summary> /// <param name="item"></param> /// <returns></returns> public static List<GenericQbItem> GetGenericItems(QbItemBase item) { List<GenericQbItem> items = new List<GenericQbItem>(); GenericQbItem itm = null; MemberInfo[] ms = item.GetType().FindMembers(MemberTypes.Property, /*BindingFlags.DeclaredOnly |*/ BindingFlags.Instance | BindingFlags.Public, Type.FilterName, "*"); foreach (MemberInfo m in ms) { GenericEditableAttribute a = Attribute.GetCustomAttribute(m, typeof(GenericEditableAttribute)) as GenericEditableAttribute; if (a != null) { //return attribute value and pass in to generic items and return object o = ((PropertyInfo)m).GetValue(item, null); if (o == null) continue; if (o is byte[]) //hex { itm = new GenericQbItem(a.DefaultDisplayName, (byte[])o, a.EditType, a.ReadOnly, a.UseQbItemType, item.QbItemType, m.Name); items.Add(itm); } else if (o is string[]) { foreach (string s in ((string[])o)) { itm = new GenericQbItem(a.DefaultDisplayName, s, a.EditType, a.ReadOnly, a.UseQbItemType, item.QbItemType, m.Name); items.Add(itm); } } else if (o is string) { itm = new GenericQbItem(a.DefaultDisplayName, (string)o, a.EditType, a.ReadOnly, a.UseQbItemType, item.QbItemType, m.Name); items.Add(itm); } else if (o is uint[]) { foreach (uint s in ((uint[])o)) { itm = new GenericQbItem(a.DefaultDisplayName, s, a.EditType, a.ReadOnly, a.UseQbItemType, item.QbItemType, m.Name); items.Add(itm); } } else if (o is uint) { itm = new GenericQbItem(a.DefaultDisplayName, (uint)o, a.EditType, a.ReadOnly, a.UseQbItemType, item.QbItemType, m.Name); items.Add(itm); } else if (o is int[]) { foreach (int s in ((int[])o)) { itm = new GenericQbItem(a.DefaultDisplayName, s, a.EditType, a.ReadOnly, a.UseQbItemType, item.QbItemType, m.Name); items.Add(itm); } } else if (o is int) { itm = new GenericQbItem(a.DefaultDisplayName, (int)o, a.EditType, a.ReadOnly, a.UseQbItemType, item.QbItemType, m.Name); items.Add(itm); } else if (o is float[]) { foreach (float s in ((float[])o)) { itm = new GenericQbItem(a.DefaultDisplayName, s, a.EditType, a.ReadOnly, a.UseQbItemType, item.QbItemType, m.Name); items.Add(itm); } } else if (o is float) { itm = new GenericQbItem(a.DefaultDisplayName, (float)o, a.EditType, a.ReadOnly, a.UseQbItemType, item.QbItemType, m.Name); items.Add(itm); } else if (o is QbKey[]) { foreach (QbKey s in ((QbKey[])o)) { itm = new GenericQbItem(a.DefaultDisplayName, s, a.EditType, a.ReadOnly, a.UseQbItemType, item.QbItemType, m.Name); items.Add(itm); } } else if (o is QbKey) { itm = new GenericQbItem(a.DefaultDisplayName, (QbKey)o, a.EditType, a.ReadOnly, a.UseQbItemType, item.QbItemType, m.Name); items.Add(itm); } else throw new ApplicationException(string.Format("Unknown generic data type item '{0}'", o.GetType().Name)); } } return items; }
/// <summary> /// If the parent is a FLoatsX3 then adjust the float type. /// </summary> private void qbAddItemFloatAdjust(QbItemBase qbi, bool addChild) { if (qbi.QbItemType != QbItemType.Floats) return; if (addChild) { if (_addItemSibling.QbItemType == QbItemType.ArrayFloatsX3 || _addItemSibling.QbItemType == QbItemType.SectionFloatsX3 || _addItemSibling.QbItemType == QbItemType.StructItemFloatsX3) ((QbItemFloats)qbi).Values = new float[3]; } else { if (_addItemParent != null && (_addItemParent.QbItemType == QbItemType.ArrayFloatsX3 || _addItemParent.QbItemType == QbItemType.SectionFloatsX3 || _addItemParent.QbItemType == QbItemType.StructItemFloatsX3)) ((QbItemFloats)qbi).Values = new float[3]; } }
public static void SetGenericItems(QbItemBase item, List<GenericQbItem> gItems) { MemberInfo[] ms = item.GetType().FindMembers(MemberTypes.Property, /*BindingFlags.DeclaredOnly |*/ BindingFlags.Instance | BindingFlags.Public, Type.FilterName, "*"); int i = 0; GenericQbItem gi; List<GenericQbItem> list = null; if (gItems.Count == 0) { //test if this is an array item GenericQbItem gqi = QbFile.CreateGenericArrayItem(item); //null if not an array type if (gqi != null) { //use this item to identify the array to set to 0 items MemberInfo m = Array.Find(ms, delegate(MemberInfo mi) { return (mi.Name == gqi.SourceProperty); }); if (m != null) { Type t = ((PropertyInfo)m).GetValue(item, null).GetType(); if (t == typeof(QbKey[])) ((PropertyInfo)m).SetValue(item, new QbKey[0], null); else if (t == typeof(float[])) ((PropertyInfo)m).SetValue(item, new float[0], null); else if (t == typeof(uint[])) ((PropertyInfo)m).SetValue(item, new uint[0], null); else if (t == typeof(int[])) ((PropertyInfo)m).SetValue(item, new int[0], null); else if (t == typeof(string[])) ((PropertyInfo)m).SetValue(item, new string[0], null); } } } while (i < gItems.Count) { gi = gItems[i++]; if (gi.ReadOnly) continue; //list = null; list = new List<GenericQbItem>(); list.Add(gi); while (i < gItems.Count && gi.SourceProperty == gItems[i].SourceProperty) list.Add(gItems[i++]); MemberInfo m = Array.Find(ms, delegate(MemberInfo mi) { return (mi.Name == gi.SourceProperty); }); if (m != null) { Type t = ((PropertyInfo)m).GetValue(item, null).GetType(); if (t == typeof(QbKey[])) { QbKey[] qb = new QbKey[list.Count]; QbKey q; string qS; for (int c = 0; c < list.Count; c++) { q = list[c].ToQbKey(); qS = item.Root.LookupDebugName(q.Crc); if (qS.Length != 0) q = QbKey.Create(q.Crc, qS); qb[c] = q; } ((PropertyInfo)m).SetValue(item, qb, null); } else if (t == typeof(float[])) { float[] f = new float[list.Count]; for (int c = 0; c < list.Count; c++) f[c] = list[c].ToSingle(); ((PropertyInfo)m).SetValue(item, f, null); } else if (t == typeof(uint[])) { uint[] ui = new uint[list.Count]; for (int c = 0; c < list.Count; c++) ui[c] = list[c].ToUInt32(); ((PropertyInfo)m).SetValue(item, ui, null); } else if (t == typeof(int[])) { int[] si = new int[list.Count]; for (int c = 0; c < list.Count; c++) si[c] = list[c].ToInt32(); ((PropertyInfo)m).SetValue(item, si, null); } else if (t == typeof(string[])) { string[] s = new string[list.Count]; for (int c = 0; c < list.Count; c++) s[c] = list[c].ToString(); ((PropertyInfo)m).SetValue(item, s, null); } else if (t == typeof(QbKey)) { QbKey q = gi.ToQbKey(); string qS = item.Root.LookupDebugName(q.Crc); if (qS.Length != 0) q = QbKey.Create(q.Crc, qS); ((PropertyInfo)m).SetValue(item, q, null); } else if (t == typeof(float)) ((PropertyInfo)m).SetValue(item, gi.ToSingle(), null); else if (t == typeof(uint)) ((PropertyInfo)m).SetValue(item, gi.ToUInt32(), null); else if (t == typeof(int)) ((PropertyInfo)m).SetValue(item, gi.ToInt32(), null); else if (t == typeof(string)) ((PropertyInfo)m).SetValue(item, gi.ToString(), null); else if (t == typeof(byte[])) ((PropertyInfo)m).SetValue(item, gi.ToByteArray(), null); else { throw new ApplicationException(string.Format("DataType {0} not supported.", t.Name)); } } } }
/// <summary> /// Add an item to the child collection /// </summary> /// <param name="item"></param> public void AddItem(QbItemBase item) { _items.Add(item); }
private QbItemBase recurseIsValid(QbItemBase item) { QbItemBase res; if (item.IsValid != IsValidReturnType.Okay) return item; if (item.Items.Count != 0) { foreach (QbItemBase qib in item.Items) { res = recurseIsValid(qib); if (res != null) return res; } } return null; }
public override void Construct(BinaryEndianReader br, QbItemType type) { //System.Diagnostics.Debug.WriteLine(string.Format("{0} - 0x{1}", type.ToString(), (base.StreamPos(br) - 4).ToString("X").PadLeft(8, '0'))); base.Construct(br, type); QbItemBase qib = null; QbItemType arrayType; uint arrayValue; for (int i = 0; i < base.ItemCount; i++) { arrayValue = br.ReadUInt32(this.Root.PakFormat.EndianType); arrayType = this.Root.PakFormat.GetQbItemType(arrayValue); switch (arrayType) { case QbItemType.Floats: qib = new QbItemFloats(this.Root); break; case QbItemType.ArrayStruct: qib = new QbItemStructArray(this.Root); break; case QbItemType.ArrayFloat: qib = new QbItemFloat(this.Root); break; case QbItemType.ArrayString: case QbItemType.ArrayStringW: qib = new QbItemString(this.Root); break; case QbItemType.ArrayFloatsX2: case QbItemType.ArrayFloatsX3: qib = new QbItemFloatsArray(this.Root); break; case QbItemType.ArrayStringPointer: case QbItemType.ArrayInteger: qib = new QbItemInteger(this.Root); break; case QbItemType.ArrayArray: qib = new QbItemArray(this.Root); break; case QbItemType.ArrayQbKey: case QbItemType.ArrayQbKeyString: case QbItemType.ArrayQbKeyStringQs: //GH:GH qib = new QbItemQbKey(this.Root); break; case QbItemType.StructHeader: qib = new QbItemStruct(this.Root); break; default: throw new ApplicationException(string.Format("Location 0x{0}: Unknown array type 0x{1}", (base.StreamPos(br) - 4).ToString("X").PadLeft(8, '0'), arrayValue.ToString("X").PadLeft(8, '0'))); } qib.Construct(br, arrayType); AddItem(qib); } base.ConstructEnd(br); }