private void _GenerateRelations(ExcelFile excelFile) { if ((excelFile == null)) { return; } Type type = excelFile.Attributes.RowType; int col; String mainTableName = excelFile.StringId; DataTable mainDataTable = XlsDataSet.Tables[mainTableName]; // remove all extra generated columns on this table for (col = 0; col < mainDataTable.Columns.Count; col++) { DataColumn dc = mainDataTable.Columns[col]; if (!(dc.ExtendedProperties.Contains(ColumnKeys.IsRelationGenerated))) { continue; } mainDataTable.Columns.Remove(dc); } col = 1; // regenerate relations foreach (FieldInfo fieldInfo in type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)) { if (fieldInfo.IsPrivate) { if (fieldInfo.FieldType == typeof(ExcelFile.RowHeader)) { col++; } continue; } OutputAttribute excelOutputAttribute = ExcelFile.GetExcelAttribute(fieldInfo); if ((excelOutputAttribute == null)) { col++; continue; } DataColumn dcChild = mainDataTable.Columns[col]; if ((excelOutputAttribute.IsStringIndex)) { DataTable dtStrings = XlsDataSet.Tables[StringsTableName] ?? _LoadStringsTable(); if (dtStrings != null) { DataColumn dcParent = dtStrings.Columns["ReferenceId"]; String relationName = String.Format("{0}_{1}_{2}", excelFile.StringId, dcChild.ColumnName, ColumnKeys.IsStringIndex); // parent and child are swapped here for StringId relations DataRelation relation = new DataRelation(relationName, dcChild, dcParent, false); XlsDataSet.Relations.Add(relation); DataColumn dcString = mainDataTable.Columns.Add(dcChild.ColumnName + "_string", typeof(String)); dcString.SetOrdinal(col + 1); dcString.ExtendedProperties.Add(ExcelFile.ColumnTypeKeys.IsRelationGenerated, true); // need to use MIN (and thus Child) for cases of strings with same reference id (e.g. Items; SINGULAR and PLURAL, etc) dcString.Expression = "MIN(Child(" + relationName + ").String)"; col++; } } if (excelOutputAttribute.IsTableIndex) { String tableStringId = excelOutputAttribute.TableStringId; DataTable dt = XlsDataSet.Tables[tableStringId] ?? _LoadRelatedTable(tableStringId); if (dt != null) { DataColumn dcParent = dt.Columns["Index"]; String relatedColumn = dt.Columns[2].ColumnName; // todo if (dcChild.ExtendedProperties.ContainsKey(ExcelFile.ColumnTypeKeys.IsArray) && (bool)dcChild.ExtendedProperties[ExcelFile.ColumnTypeKeys.IsArray]) { //if (excelFile.StringId == "ITEMS") //{ // int bp = 0; //} col++; continue; } //String relationNameOld = excelFile.StringId + dcChild.ColumnName + ExcelFile.ColumnTypeKeys.IsTableIndex; String relationName = String.Format("{0}_{1}_{2}", excelFile.StringId, dcChild.ColumnName, ExcelFile.ColumnTypeKeys.IsTableIndex); DataRelation relation = new DataRelation(relationName, dcParent, dcChild, false); //if (relationName == "PLAYERS_paperdollSkill_IsTableIndex") //{ // int bp = 0; //} XlsDataSet.Relations.Add(relation); DataColumn dcString = mainDataTable.Columns.Add(dcChild.ColumnName + "_string", typeof(String), String.Format("Parent({0}).{1}", relationName, relatedColumn)); dcString.SetOrdinal(col + 1); dcString.ExtendedProperties.Add(ExcelFile.ColumnTypeKeys.IsRelationGenerated, true); col++; } } col++; } }
//private void _tableData_DataGridView_ColumnAdded(object sender, DataGridViewColumnEventArgs e) //{ // //Debug.WriteLine("Column Added: " + e.Column.Name); //} //private void _tableData_DataGridView_ColumnRemoved(object sender, DataGridViewColumnEventArgs e) //{ // Debug.WriteLine("[" + _dataFile.StringId + "] Column Removed: " + e.Column.Name); //} //private void Columns_CollectionChanged(object sender, CollectionChangeEventArgs e) //{ // //Debug.WriteLine("[" + _dataFile.StringId + "] Column Collection Changed (Action = " + e.Action + ", Element = " + e.Element + ")"); //} //private void _tableData_DataGridView_DataBindingComplete(object sender, DataGridViewBindingCompleteEventArgs e) //{ // int bp = 0; //} //private void _tableData_DataGridView_DataMemberChanged(object sender, EventArgs e) //{ // int bp = 0; //} //private void _tableData_DataGridView_DataSourceChanged(object sender, EventArgs e) //{ // int bp = 0; //} #endregion /// <summary> /// Defines the row view section of the form. /// </summary> private void _CreateRowView() { _rows_LayoutPanel.SuspendLayout(); int column = 0; TextBox relationTextBox = null; foreach (DataColumn dc in _dataTable.Columns) { column++; new Label { Text = dc.ColumnName, Parent = _rows_LayoutPanel, AutoSize = true, Dock = DockStyle.Fill }; column++; if (dc.ExtendedProperties.ContainsKey(ExcelFile.ColumnTypeKeys.IsBool) && (bool)dc.ExtendedProperties[ExcelFile.ColumnTypeKeys.IsBool]) { CheckBox checkBox = new CheckBox { Parent = _rows_LayoutPanel, AutoSize = true, Dock = DockStyle.Fill, Name = dc.ColumnName, CheckAlign = ContentAlignment.MiddleLeft }; checkBox.CheckedChanged += _RowView_CheckBox_ItemCheck; _specialControls.Add(dc.ColumnName, checkBox); } else if (dc.ExtendedProperties.ContainsKey(ExcelFile.ColumnTypeKeys.IsBitmask) && (bool)dc.ExtendedProperties[ExcelFile.ColumnTypeKeys.IsBitmask]) { CheckedListBox checkedListBox = new CheckedListBox { Parent = _rows_LayoutPanel, AutoSize = true, Dock = DockStyle.Fill, MultiColumn = false, Name = dc.ColumnName }; checkedListBox.ItemCheck += _RowView_CheckedListBox_ItemCheck; _specialControls.Add(dc.ColumnName, checkedListBox); OutputAttribute attribute = ExcelFile.GetExcelAttribute(_dataFile.DataType.GetField(dc.ColumnName)); // Populate the checklist by either a enum or (less commonly) table indices if (!String.IsNullOrEmpty(attribute.TableStringId)) { // TODO: should perhaps use object delegator here, it might be faster // so far its only its runtime is only 1n so doesnt really matter. // DataTable dataTable = _fileManager.GetDataTable(attribute.TableStringId); foreach (DataRow row in dataTable.Rows) { checkedListBox.Items.Add(row[2], false); } } else { Type cellType = dc.DataType; foreach (Enum type in Enum.GetValues(cellType)) { checkedListBox.Items.Add(type, false); } } } else if (dc.ExtendedProperties.ContainsKey(ExcelFile.ColumnTypeKeys.IsEnum) && (bool)dc.ExtendedProperties[ExcelFile.ColumnTypeKeys.IsEnum]) { ComboBox comboBox = new ComboBox { Parent = _rows_LayoutPanel, Dock = DockStyle.Fill, Name = dc.ColumnName }; // todo: consider lookomg into overloaded FindString or FindExactString methods and check (change) the startIndex parameter Binding comboBoxBinding = comboBox.DataBindings.Add("SelectedIndex", _dataTable, dc.ColumnName, true); comboBoxBinding.Format += _ComboBoxFormat; comboBox.SelectedIndexChanged += _RowView_ComboList_ItemChange; // need order as VALUE order - Enum.GetValues provides sorted as UNSIGNED values e.g. {0, 1, 2, 3, -3, -2, -1} instead of {-3, -2, -1, 0, 1, 2, 3} List <Enum> enumValues = Enum.GetValues(dc.DataType).Cast <Enum>().ToList(); enumValues.Sort(); // List sort works as SIGNED comboBox.Items.AddRange(enumValues.ToArray()); comboBox.Tag = Math.Abs(Convert.ToInt32(enumValues.Min())); // we need a minimum value to get our base offset } else { TextBox textBox = new TextBox { Text = String.Empty, Parent = _rows_LayoutPanel, AutoSize = true, Dock = DockStyle.Fill, Name = dc.ColumnName }; textBox.DataBindings.Add("Text", _dataTable, dc.ColumnName); if ((dc.ExtendedProperties.ContainsKey(ExcelFile.ColumnTypeKeys.IsRelationGenerated) && (bool)dc.ExtendedProperties[ExcelFile.ColumnTypeKeys.IsRelationGenerated]) || column == 0) { textBox.ReadOnly = true; if (relationTextBox != null) { relationTextBox.TextChanged += (sender, e) => textBox.ResetText(); } } if ((dc.ExtendedProperties.ContainsKey(ExcelFile.ColumnTypeKeys.IsStringIndex) && (bool)dc.ExtendedProperties[ExcelFile.ColumnTypeKeys.IsStringIndex]) || (dc.ExtendedProperties.ContainsKey(ExcelFile.ColumnTypeKeys.IsStringOffset) && (bool)dc.ExtendedProperties[ExcelFile.ColumnTypeKeys.IsStringOffset])) { relationTextBox = textBox; } else { relationTextBox = null; } } } new Label { Text = String.Empty, Parent = _rows_LayoutPanel, AutoSize = true, Dock = DockStyle.Fill }; _rows_LayoutPanel.ResumeLayout(); _rows_LayoutPanel.Width += 10; // fixes mouse scroll wheel // todo: this is dodgy and causes focused elements within the layoutpanel to lose focus (e.g. a text box) - rather anoying _rows_LayoutPanel.Click += (sender, e) => _rows_LayoutPanel.Focus(); _rows_LayoutPanel.MouseEnter += (sender, e) => _rows_LayoutPanel.Focus(); }
private DataTable _LoadExcelTable(ExcelFile excelFile, bool doRelations, bool force) { String tableName = excelFile.StringId; DataTable dataTable = XlsDataSet.Tables[tableName]; if (dataTable != null && !force) { return(dataTable); } if (dataTable != null) { XlsDataSet.Relations.Clear(); XlsDataSet.Tables.Remove(tableName); } dataTable = XlsDataSet.Tables.Add(tableName); dataTable.TableName = tableName; dataTable.ExtendedProperties.Add("FileHeader", excelFile._excelFileHeader.DeepClone()); Type dataType = excelFile.Attributes.RowType; List <OutputAttribute> outputAttributes = new List <OutputAttribute>(); #region Generate Columns DataColumn indexColumn = dataTable.Columns.Add("Index"); indexColumn.AutoIncrement = true; indexColumn.Unique = true; dataTable.PrimaryKey = new[] { indexColumn }; outputAttributes.Add(null); FieldInfo[] fieldInfos = dataType.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (FieldInfo fieldInfo in fieldInfos) { OutputAttribute excelAttribute = ExcelFile.GetExcelAttribute(fieldInfo); // The only private field we add is the TableHeader if (fieldInfo.IsPrivate) { if (fieldInfo.FieldType != typeof(ExcelFile.RowHeader)) { continue; } outputAttributes.Add(null); dataTable.Columns.Add(fieldInfo.Name, typeof(String)); continue; } Type fieldType = fieldInfo.FieldType; bool isArray = false; bool isEnum = false; if (fieldInfo.FieldType.BaseType == typeof(Array)) { fieldType = typeof(String); isArray = true; } else if (fieldInfo.FieldType.BaseType == typeof(Enum) && excelAttribute == null) { fieldType = fieldInfo.FieldType; isEnum = true; } DataColumn dataColumn = dataTable.Columns.Add(fieldInfo.Name, fieldType); if (isArray) { dataColumn.ExtendedProperties.Add(ColumnKeys.IsArray, true); } else if (isEnum) { dataColumn.ExtendedProperties.Add(ColumnKeys.IsEnum, true); } if (excelAttribute == null) { outputAttributes.Add(null); continue; } outputAttributes.Add(excelAttribute); if (excelAttribute.IsStringOffset) { dataColumn.DataType = typeof(String); dataColumn.ExtendedProperties.Add(ColumnKeys.IsStringOffset, true); dataColumn.DefaultValue = String.Empty; } if (excelAttribute.IsScript) { dataColumn.DataType = typeof(String); dataColumn.ExtendedProperties.Add(ColumnKeys.IsScript, true); dataColumn.DefaultValue = String.Empty; } if (excelAttribute.IsSecondaryString) { dataColumn.DataType = typeof(String); dataColumn.ExtendedProperties.Add(ColumnKeys.IsSecondaryString, true); dataColumn.DefaultValue = String.Empty; } if (excelAttribute.IsStringIndex) { dataColumn.ExtendedProperties.Add(ColumnKeys.IsStringIndex, true); // Add new column for the string DataColumn dataColumnString = dataTable.Columns.Add(fieldInfo.Name + "_string", typeof(String)); dataColumnString.DefaultValue = String.Empty; outputAttributes.Add(null); dataColumnString.ExtendedProperties.Add(ColumnKeys.IsRelationGenerated, true); } if (excelAttribute.IsTableIndex) { dataColumn.ExtendedProperties.Add(ColumnKeys.IsTableIndex, true); // Add new column for the string DataColumn dataColumnString = dataTable.Columns.Add(fieldInfo.Name + "_string", typeof(String)); dataColumnString.DefaultValue = String.Empty; outputAttributes.Add(null); dataColumnString.ExtendedProperties.Add(ColumnKeys.IsRelationGenerated, true); } if (excelAttribute.IsBitmask) { dataColumn.ExtendedProperties.Add(ColumnKeys.IsBitmask, true); } if (excelAttribute.IsBool) { dataColumn.ExtendedProperties.Add(ColumnKeys.IsBool, true); } } if (excelFile.Attributes.HasStats) // items, missiles, monsters, objects, players { DataColumn extendedDataColumn = dataTable.Columns.Add("Stats"); extendedDataColumn.DataType = typeof(String); extendedDataColumn.ExtendedProperties.Add(ExcelFile.ColumnTypeKeys.IsStats, true); outputAttributes.Add(null); } #endregion #region Generate Rows int row = 1; object[] baseRow = new object[outputAttributes.Count]; ObjectDelegator objectDelegator = new ObjectDelegator(fieldInfos); foreach (Object tableRow in excelFile.Rows) { int col = 1; foreach (FieldInfo fieldInfo in fieldInfos) { Object value = objectDelegator[fieldInfo.Name](tableRow); if (fieldInfo.IsPrivate) { if (fieldInfo.FieldType != typeof(ExcelFile.RowHeader)) { continue; } baseRow[col++] = FileTools.ObjectToStringGeneric(value, ","); continue; } OutputAttribute excelOutputAttribute = outputAttributes[col]; if (excelOutputAttribute == null) { if (value.GetType().BaseType == typeof(Array)) { value = ((Array)value).ToString(","); } baseRow[col++] = value; continue; } if (excelOutputAttribute.IsStringOffset) { int valueInt = (int)value; baseRow[col++] = (valueInt != -1) ? excelFile.ReadStringTable(valueInt) : String.Empty; continue; } if (excelOutputAttribute.IsSecondaryString) { int valueInt = (int)value; baseRow[col++] = (valueInt != -1) ? excelFile.ReadSecondaryStringTable(valueInt) : String.Empty; continue; } if (excelOutputAttribute.IsScript) { int scriptOffset = (int)value; if (scriptOffset == 0) { baseRow[col++] = String.Empty; continue; } String script; if (scriptOffset == 9649 && excelFile.StringId == "SKILLS") // todo: not sure what's with this script... { /* Compiled Bytes: * 26,30,700,6,26,1,399,358,669,616562688,711,26,62,3,17,669,641728512,26,8,711,26,62,3,17,358,669,322961408,26,5,700,6,26,1,399,358,388,0 * * Ending Stack (FIFO): * SetStat669('sfx_attack_pct', 'all', 30 * ($sklvl - 1)) * SetStat669('sfx_duration_pct', 'all', get_skill_level(@unit, 'Shield_Mastery')) * SetStat669('damage_percent_skill', 8 * get_skill_level(@unit, 'Shield_Mastery')) * SetStat669('damage_percent_skill', 8 * get_skill_level(@unit, 'Shield_Mastery')) + 5 * ($sklvl - 1) * * The last SetStat has strange overhang - decompiling wrong? * Or is it "supposed" to be there? * i.e. It's actually decompiling correctly, but because I've assumed such scripts to be wrong (as the end +5... segment is useless) we get the Stack exception */ int[] scriptCode = excelFile.ReadScriptTable(scriptOffset); script = scriptCode != null?FileTools.ArrayToStringGeneric(scriptCode, ",") : "ScriptError"; baseRow[col++] = script; continue; } //if (fieldInfo.Name == "props1" && row == 45) //{ // int bp = 0; //} ExcelScript excelScript = new ExcelScript(this); try { if (ExcelScript.DebugEnabled) { int[] scriptCode = excelFile.ReadScriptTable(scriptOffset); script = scriptCode != null?FileTools.ArrayToStringGeneric(scriptCode, ",") : String.Empty; script = excelScript.Decompile(excelFile.ScriptBuffer, scriptOffset, script, excelFile.StringId, row, col, fieldInfo.Name); } else { script = excelScript.Decompile(excelFile.ScriptBuffer, scriptOffset); } //if (script.StartsWith("GetStat666('skill_points_bonus_total', '') > -1;")) //{ // int bp = 0; //} } catch (Exception) { int[] scriptCode = excelFile.ReadScriptTable(scriptOffset); script = scriptCode != null?FileTools.ArrayToStringGeneric(scriptCode, ",") : "ScriptError"; } baseRow[col++] = script; continue; } if (excelOutputAttribute.IsTableIndex || excelOutputAttribute.IsStringIndex) { if (value.GetType().BaseType == typeof(Array)) { value = ((Array)value).ToString(","); } else { value = (int)value; } baseRow[col++] = value; col++; // for _strings relational column continue; } // Else its something else, ie bitmask, bool, table/string index baseRow[col++] = value; } // stats, only a component of the UnitData row type if (excelFile.Attributes.HasStats) { baseRow[col++] = FileTools.ArrayToStringGeneric(excelFile.ReadStats(row - 1), ","); } dataTable.Rows.Add(baseRow); row++; } #endregion // Generate Relationships as required if (doRelations) { _GenerateRelations(excelFile); } return(dataTable); }