/// <summary> /// Show the Open File dialogue, then load the selected character. /// </summary> private void OpenFile(object sender, EventArgs e) { OpenFileDialog openFileDialog = new OpenFileDialog { Filter = "Chummer5 Files (*.chum5)|*.chum5|All Files (*.*)|*.*", Multiselect = true }; if (openFileDialog.ShowDialog(this) == DialogResult.OK) { Timekeeper.Start("load_sum"); Cursor = Cursors.WaitCursor; Character[] lstCharacters = new Character[openFileDialog.FileNames.Length]; object lstCharactersLock = new object(); Parallel.For(0, lstCharacters.Length, i => { Character objLoopCharacter = LoadCharacter(openFileDialog.FileNames[i]); lock (lstCharactersLock) lstCharacters[i] = objLoopCharacter; }); Cursor = Cursors.Default; Program.MainForm.OpenCharacterList(lstCharacters); Application.DoEvents(); Timekeeper.Finish("load_sum"); Timekeeper.Log(); } }
public void Dispose() { Timekeeper.Finish(this.OperationName); this.Stop(); switch (MyOperationType) { case OperationType.DependencyOperation: MyDependencyTelemetry.Duration = DateTimeOffset.UtcNow - MyDependencyTelemetry.Timestamp; if (MyDependencyTelemetry.ResultCode == "not disposed") { MyDependencyTelemetry.ResultCode = "OK"; } tc.TrackDependency(MyDependencyTelemetry); break; case OperationType.RequestOperation: MyRequestTelemetry.Duration = DateTimeOffset.UtcNow - MyRequestTelemetry.Timestamp; if (MyRequestTelemetry.ResponseCode == "not disposed") { MyRequestTelemetry.ResponseCode = "OK"; } tc.TrackRequest(MyRequestTelemetry); break; default: throw new NotImplementedException("Implement OperationType " + OperationName); } }
/// <summary> /// Open the correct windows for a list of characters (not thread-safe). /// </summary> /// <param name="lstCharacters">Characters for which windows should be opened.</param> public void OpenCharacterList(IEnumerable <Character> lstCharacters, bool blnIncludeInMRU = true) { if (lstCharacters == null) { return; } Cursor = Cursors.WaitCursor; foreach (Character objCharacter in lstCharacters) { if (objCharacter == null) { continue; } Timekeeper.Start("load_event_time"); // Show the character form. if (!objCharacter.Created) { frmCreate frmCharacter = new frmCreate(objCharacter) { MdiParent = this, WindowState = FormWindowState.Maximized, Loading = true }; frmCharacter.Show(); } else { frmCareer frmCharacter = new frmCareer(objCharacter) { MdiParent = this, WindowState = FormWindowState.Maximized, Loading = true }; frmCharacter.DiceRollerOpened += objCareer_DiceRollerOpened; frmCharacter.DiceRollerOpenedInt += objCareer_DiceRollerOpenedInt; frmCharacter.Show(); } if (blnIncludeInMRU) { GlobalOptions.AddToMRUList(objCharacter.FileName); } objCharacter.CharacterNameChanged += objCharacter_CharacterNameChanged; objCharacter_CharacterNameChanged(objCharacter); Timekeeper.Finish("load_event_time"); } Cursor = Cursors.Default; }
/// <summary> /// Show the Open File dialogue, then load the selected character. /// </summary> private void OpenFile(object sender, EventArgs e) { OpenFileDialog openFileDialog = new OpenFileDialog(); openFileDialog.Filter = "Chummer5 Files (*.chum5)|*.chum5|All Files (*.*)|*.*"; openFileDialog.Multiselect = true; if (openFileDialog.ShowDialog(this) == DialogResult.OK) { Timekeeper.Start("load_sum"); foreach (string strFileName in openFileDialog.FileNames) { LoadCharacter(strFileName); Timekeeper.Start("load_event_time"); Application.DoEvents(); Timekeeper.Finish("load_event_time"); } Timekeeper.Finish("load_sum"); Timekeeper.Log(); } }
protected virtual void Dispose(bool blnIsDisposing) { if (_blnDisposed) { return; } if (blnIsDisposing) { Timekeeper.Finish(OperationName); Stop(); switch (MyOperationType) { case OperationType.DependencyOperation: MyDependencyTelemetry.Duration = DateTimeOffset.UtcNow - MyDependencyTelemetry.Timestamp; if (MyDependencyTelemetry.ResultCode == "not disposed") { MyDependencyTelemetry.ResultCode = "OK"; } tc.TrackDependency(MyDependencyTelemetry); break; case OperationType.RequestOperation: MyRequestTelemetry.Duration = DateTimeOffset.UtcNow - MyRequestTelemetry.Timestamp; if (MyRequestTelemetry.ResponseCode == "not disposed") { MyRequestTelemetry.ResponseCode = "OK"; } tc.TrackRequest(MyRequestTelemetry); break; default: throw new NotImplementedException("Implement OperationType " + OperationName); } } _blnDisposed = true; }
/// <summary> /// Load a Character and open the correct window. /// </summary> /// <param name="strFileName">File to load.</param> /// <param name="blnIncludeInMRU">Whether or not the file should appear in the MRU list.</param> /// <param name="strNewName">New name for the character.</param> /// <param name="blnClearFileName">Whether or not the name of the save file should be cleared.</param> public void LoadCharacter(string strFileName, bool blnIncludeInMRU = true, string strNewName = "", bool blnClearFileName = false) { if (File.Exists(strFileName) && strFileName.EndsWith("chum5")) { Timekeeper.Start("loading"); bool blnLoaded = false; Character objCharacter = new Character(); objCharacter.FileName = strFileName; Timekeeper.Start("load_file"); blnLoaded = objCharacter.Load(); Timekeeper.Finish("load_file"); Timekeeper.Start("load_free"); if (!blnLoaded) { return; } // If a new name is given, set the character's name to match (used in cloning). if (strNewName != "") { objCharacter.Name = strNewName; } // Clear the File Name field so that this does not accidentally overwrite the original save file (used in cloning). if (blnClearFileName) { objCharacter.FileName = ""; } // Show the character form. if (!objCharacter.Created) { frmCreate frmCharacter = new frmCreate(objCharacter); frmCharacter.MdiParent = this; frmCharacter.WindowState = FormWindowState.Maximized; frmCharacter.Loading = true; frmCharacter.Show(); } else { frmCareer frmCharacter = new frmCareer(objCharacter); frmCharacter.MdiParent = this; frmCharacter.WindowState = FormWindowState.Maximized; frmCharacter.Loading = true; frmCharacter.DiceRollerOpened += objCareer_DiceRollerOpened; frmCharacter.DiceRollerOpenedInt += objCareer_DiceRollerOpenedInt; frmCharacter.Show(); } if (blnIncludeInMRU) { GlobalOptions.Instance.AddToMRUList(strFileName); } objCharacter.CharacterNameChanged += objCharacter_CharacterNameChanged; objCharacter_CharacterNameChanged(objCharacter); } else { MessageBox.Show(LanguageManager.Instance.GetString("Message_FileNotFound").Replace("{0}", strFileName), LanguageManager.Instance.GetString("MessageTitle_FileNotFound"), MessageBoxButtons.OK, MessageBoxIcon.Error); } }
public frmMain() { InitializeComponent(); Version version = Assembly.GetExecutingAssembly().GetName().Version; string strCurrentVersion = string.Format("{0}.{1}.{2}", version.Major, version.Minor, version.Build); this.Text = string.Format("Chummer 5a - Version " + strCurrentVersion); #if DEBUG Text += " DEBUG BUILD"; #endif LanguageManager.Instance.Load(GlobalOptions.Instance.Language, this); /** Dashboard **/ //this.toolsMenu.DropDownItems.Add("GM Dashboard").Click += this.dashboardToolStripMenuItem_Click; /** End Dashboard **/ // If Automatic Updates are enabled, check for updates immediately. if (GlobalOptions.Instance.AutomaticUpdate) { frmUpdate frmAutoUpdate = new frmUpdate(); frmAutoUpdate.SilentMode = true; frmAutoUpdate.Visible = false; frmAutoUpdate.ShowDialog(this); } else { #if RELEASE frmUpdate frmAutoUpdate = new frmUpdate(); frmAutoUpdate.GetChummerVersion(); Version verCurrentVersion = new Version(strCurrentVersion); Version verLatestVersion = new Version(frmAutoUpdate.LatestVersion); var result = verCurrentVersion.CompareTo(verLatestVersion); if (result != 0) { this.Text += String.Format(" - Update {0} now available!", verLatestVersion); } #endif } GlobalOptions.Instance.MRUChanged += PopulateMRU; // Delete the old executable if it exists (created by the update process). if (File.Exists("Chummer.exe.old")) { try { File.Delete("Chummer.exe.old"); } catch { } } // Populate the MRU list. PopulateMRU(); // Retrieve the arguments passed to the application. If more than 1 is passed, we're being given the name of a file to open. string[] strArgs = Environment.GetCommandLineArgs(); if (strArgs.GetUpperBound(0) > 0) { if (strArgs[1] != "/debug") { LoadCharacter(strArgs[1]); } if (strArgs.Length > 2) { if (strArgs[2] == "/test") { frmTest frmTestData = new frmTest(); frmTestData.Show(); } } } GlobalOptions.Instance.MainForm = this; // Set the Tag for each ToolStrip item so it can be translated. foreach (ToolStripMenuItem objItem in menuStrip.Items.OfType <ToolStripMenuItem>()) { if (objItem.Tag != null) { objItem.Text = LanguageManager.Instance.GetString(objItem.Tag.ToString()); } } // ToolStrip Items. foreach (ToolStrip objToolStrip in this.Controls.OfType <ToolStrip>()) { foreach (ToolStripButton objButton in objToolStrip.Items.OfType <ToolStripButton>()) { if (objButton.Tag != null) { objButton.Text = LanguageManager.Instance.GetString(objButton.Tag.ToString()); } } } // Attempt to cache the XML files that are used the most. try { Timekeeper.Start("cache_load"); XmlManager.Instance.Load("armor.xml"); XmlManager.Instance.Load("bioware.xml"); XmlManager.Instance.Load("books.xml"); XmlManager.Instance.Load("cyberware.xml"); XmlManager.Instance.Load("gear.xml"); XmlManager.Instance.Load("lifestyles.xml"); XmlManager.Instance.Load("metatypes.xml"); XmlManager.Instance.Load("qualities.xml"); XmlManager.Instance.Load("ranges.xml"); XmlManager.Instance.Load("skills.xml"); XmlManager.Instance.Load("vehicles.xml"); XmlManager.Instance.Load("weapons.xml"); Timekeeper.Finish("cache_load"); } catch { } }
public frmChummerMain() { InitializeComponent(); _strCurrentVersion = $"{_objCurrentVersion.Major}.{_objCurrentVersion.Minor}.{_objCurrentVersion.Build}"; this.Text = "Chummer 5a - Version " + _strCurrentVersion; #if DEBUG Text += " DEBUG BUILD"; #endif LanguageManager.Load(GlobalOptions.Language, this); /** Dashboard **/ //this.toolsMenu.DropDownItems.Add("GM Dashboard").Click += this.dashboardToolStripMenuItem_Click; /** End Dashboard **/ // If Automatic Updates are enabled, check for updates immediately. #if !DEBUG _workerVersionUpdateChecker.WorkerReportsProgress = false; _workerVersionUpdateChecker.WorkerSupportsCancellation = false; _workerVersionUpdateChecker.DoWork += DoCacheGitVersion; _workerVersionUpdateChecker.RunWorkerCompleted += CheckForUpdate; Application.Idle += IdleUpdateCheck; _workerVersionUpdateChecker.RunWorkerAsync(); #endif GlobalOptions.MRUChanged += PopulateMRUToolstripMenu; // Delete the old executable if it exists (created by the update process). foreach (string strLoopOldFilePath in Directory.GetFiles(Application.StartupPath, "*.old", SearchOption.AllDirectories)) { if (File.Exists(strLoopOldFilePath)) { File.Delete(strLoopOldFilePath); } } // Populate the MRU list. PopulateMRUToolstripMenu(); Program.MainForm = this; // Set the Tag for each ToolStrip item so it can be translated. foreach (ToolStripMenuItem objItem in menuStrip.Items.OfType <ToolStripMenuItem>()) { if (objItem.Tag != null) { objItem.Text = LanguageManager.GetString(objItem.Tag.ToString()); } } // ToolStrip Items. foreach (ToolStrip objToolStrip in Controls.OfType <ToolStrip>()) { foreach (ToolStripButton objButton in objToolStrip.Items.OfType <ToolStripButton>()) { if (objButton.Tag != null) { objButton.Text = LanguageManager.GetString(objButton.Tag.ToString()); } } } // Attempt to cache all XML files that are used the most. Timekeeper.Start("cache_load"); Parallel.Invoke( () => XmlManager.Load("armor.xml"), () => XmlManager.Load("bioware.xml"), () => XmlManager.Load("books.xml"), () => XmlManager.Load("complexforms.xml"), () => XmlManager.Load("contacts.xml"), () => XmlManager.Load("critters.xml"), () => XmlManager.Load("critterpowers.xml"), () => XmlManager.Load("cyberware.xml"), //() => XmlManager.Load("drugcomponents.xml"), TODO: Re-enable when Custom Drugs branch is merged () => XmlManager.Load("echoes.xml"), () => XmlManager.Load("gameplayoptions.xml"), () => XmlManager.Load("gear.xml"), () => XmlManager.Load("improvements.xml"), () => XmlManager.Load("licenses.xml"), () => XmlManager.Load("lifemodules.xml"), () => XmlManager.Load("lifestyles.xml"), () => XmlManager.Load("martialarts.xml"), () => XmlManager.Load("mentors.xml"), () => XmlManager.Load("metamagic.xml"), () => XmlManager.Load("metatypes.xml"), () => XmlManager.Load("options.xml"), () => XmlManager.Load("packs.xml"), () => XmlManager.Load("powers.xml"), () => XmlManager.Load("priorities.xml"), () => XmlManager.Load("programs.xml"), () => XmlManager.Load("qualities.xml"), () => XmlManager.Load("ranges.xml"), () => XmlManager.Load("sheets.xml"), () => XmlManager.Load("skills.xml"), () => XmlManager.Load("spells.xml"), () => XmlManager.Load("spiritpowers.xml"), () => XmlManager.Load("traditions.xml"), () => XmlManager.Load("vehicles.xml"), () => XmlManager.Load("weapons.xml") ); Timekeeper.Finish("cache_load"); frmCharacterRoster frmCharacter = new frmCharacterRoster { MdiParent = this }; _frmCharacterRoster = frmCharacter; // Retrieve the arguments passed to the application. If more than 1 is passed, we're being given the name of a file to open. string[] strArgs = Environment.GetCommandLineArgs(); string strLoop = string.Empty; List <Character> lstCharactersToLoad = new List <Character>(); object lstCharactersToLoadLock = new object(); bool blnShowTest = false; object blnShowTestLock = new object(); Parallel.For(1, strArgs.Length, i => { strLoop = strArgs[i]; if (strLoop == "/test") { lock (blnShowTestLock) blnShowTest = true; } else if (!strLoop.StartsWith('/')) { Character objLoopCharacter = LoadCharacter(strLoop); lock (lstCharactersToLoadLock) lstCharactersToLoad.Add(objLoopCharacter); } }); if (blnShowTest) { frmTest frmTestData = new frmTest(); frmTestData.Show(); } OpenCharacterList(lstCharactersToLoad); frmCharacter.WindowState = FormWindowState.Maximized; frmCharacter.Show(); }
/// <summary> /// Load a Character from a file and return it (thread-safe). /// </summary> /// <param name="strFileName">File to load.</param> /// <param name="blnIncludeInMRU">Whether or not the file should appear in the MRU list.</param> /// <param name="strNewName">New name for the character.</param> /// <param name="blnClearFileName">Whether or not the name of the save file should be cleared.</param> public Character LoadCharacter(string strFileName, string strNewName = "", bool blnClearFileName = false, bool blnShowErrors = true) { Character objCharacter = null; if (File.Exists(strFileName) && strFileName.EndsWith("chum5")) { Timekeeper.Start("loading"); bool blnLoaded = false; objCharacter = new Character { FileName = strFileName }; XmlDocument objXmlDocument = new XmlDocument(); //StreamReader is used to prevent encoding errors using (StreamReader sr = new StreamReader(strFileName, true)) { try { objXmlDocument.Load(sr); } catch (XmlException ex) { if (blnShowErrors) { MessageBox.Show(LanguageManager.GetString("Message_FailedLoad").Replace("{0}", ex.Message), LanguageManager.GetString("MessageTitle_FailedLoad"), MessageBoxButtons.OK, MessageBoxIcon.Error); } return(null); } } XmlNode objXmlCharacter = objXmlDocument.SelectSingleNode("/character"); if (!string.IsNullOrEmpty(objXmlCharacter?["appversion"]?.InnerText)) { string strVersion = objXmlCharacter["appversion"].InnerText; if (strVersion.StartsWith("0.")) { strVersion = strVersion.Substring(2); } Version.TryParse(strVersion, out Version verSavedVersion); Version.TryParse("5.188.34", out Version verCorrectedVersion); if (verCorrectedVersion != null && verSavedVersion != null) { int intResult = verSavedVersion.CompareTo(verCorrectedVersion); //Check for typo in Corrupter quality and correct it if (intResult == -1) { File.WriteAllText(strFileName, Regex.Replace(File.ReadAllText(strFileName), "Corruptor", "Corrupter")); } } } OpenCharacters.Add(objCharacter); Timekeeper.Start("load_file"); blnLoaded = objCharacter.Load(); Timekeeper.Finish("load_file"); if (!blnLoaded) { objCharacter.Dispose(); OpenCharacters.Remove(objCharacter); return(null); } // If a new name is given, set the character's name to match (used in cloning). if (!string.IsNullOrEmpty(strNewName)) { objCharacter.Name = strNewName; } // Clear the File Name field so that this does not accidentally overwrite the original save file (used in cloning). if (blnClearFileName) { objCharacter.FileName = string.Empty; } } else if (blnShowErrors) { MessageBox.Show(LanguageManager.GetString("Message_FileNotFound").Replace("{0}", strFileName), LanguageManager.GetString("MessageTitle_FileNotFound"), MessageBoxButtons.OK, MessageBoxIcon.Error); } return(objCharacter); }
/// <summary> /// Load a Character and open the correct window. /// </summary> /// <param name="strFileName">File to load.</param> /// <param name="blnIncludeInMRU">Whether or not the file should appear in the MRU list.</param> /// <param name="strNewName">New name for the character.</param> /// <param name="blnClearFileName">Whether or not the name of the save file should be cleared.</param> public void LoadCharacter(string strFileName, bool blnIncludeInMRU = true, string strNewName = "", bool blnClearFileName = false) { if (File.Exists(strFileName) && strFileName.EndsWith("chum5")) { Timekeeper.Start("loading"); Cursor.Current = Cursors.WaitCursor; bool blnLoaded = false; Character objCharacter = new Character(); objCharacter.FileName = strFileName; XmlDocument objXmlDocument = new XmlDocument(); //StreamReader is used to prevent encoding errors using (StreamReader sr = new StreamReader(strFileName, true)) { try { objXmlDocument.Load(sr); } catch (XmlException ex) { MessageBox.Show(LanguageManager.GetString("Message_FailedLoad").Replace("{0}", ex.Message), LanguageManager.GetString("MessageTitle_FailedLoad"), MessageBoxButtons.OK, MessageBoxIcon.Error); return; } } XmlNode objXmlCharacter = objXmlDocument.SelectSingleNode("/character"); if (!string.IsNullOrEmpty(objXmlCharacter?["appversion"]?.InnerText)) { Version verSavedVersion; Version verCorrectedVersion; string strVersion = objXmlCharacter["appversion"].InnerText; if (strVersion.StartsWith("0.")) { strVersion = strVersion.Substring(2); } Version.TryParse(strVersion, out verSavedVersion); Version.TryParse("5.188.34", out verCorrectedVersion); if (verCorrectedVersion != null && verSavedVersion != null) { int intResult = verSavedVersion.CompareTo(verCorrectedVersion); //Check for typo in Corrupter quality and correct it if (intResult == -1) { File.WriteAllText(strFileName, Regex.Replace(File.ReadAllText(strFileName), "Corruptor", "Corrupter")); } } } Timekeeper.Start("load_file"); blnLoaded = objCharacter.Load(); Timekeeper.Finish("load_file"); Timekeeper.Start("load_free"); if (!blnLoaded) { Cursor.Current = Cursors.Default; return; } // If a new name is given, set the character's name to match (used in cloning). if (!string.IsNullOrEmpty(strNewName)) { objCharacter.Name = strNewName; } // Clear the File Name field so that this does not accidentally overwrite the original save file (used in cloning). if (blnClearFileName) { objCharacter.FileName = string.Empty; } // Show the character form. if (!objCharacter.Created) { frmCreate frmCharacter = new frmCreate(objCharacter) { MdiParent = this, WindowState = FormWindowState.Maximized, Loading = true }; frmCharacter.Show(); } else { frmCareer frmCharacter = new frmCareer(objCharacter) { MdiParent = this, WindowState = FormWindowState.Maximized, Loading = true }; frmCharacter.DiceRollerOpened += objCareer_DiceRollerOpened; frmCharacter.DiceRollerOpenedInt += objCareer_DiceRollerOpenedInt; frmCharacter.Show(); } if (blnIncludeInMRU) { GlobalOptions.AddToMRUList(strFileName); } objCharacter.CharacterNameChanged += objCharacter_CharacterNameChanged; objCharacter_CharacterNameChanged(objCharacter); Cursor.Current = Cursors.Default; } else { MessageBox.Show(LanguageManager.GetString("Message_FileNotFound").Replace("{0}", strFileName), LanguageManager.GetString("MessageTitle_FileNotFound"), MessageBoxButtons.OK, MessageBoxIcon.Error); } }
public frmMain() { InitializeComponent(); Version version = Assembly.GetExecutingAssembly().GetName().Version; string strCurrentVersion = $"{version.Major}.{version.Minor}.{version.Build}"; Text = string.Format("Chummer 5a - Version " + strCurrentVersion); #if DEBUG Text += " DEBUG BUILD"; #endif LanguageManager.Load(GlobalOptions.Language, this); /** Dashboard **/ //this.toolsMenu.DropDownItems.Add("GM Dashboard").Click += this.dashboardToolStripMenuItem_Click; /** End Dashboard **/ // If Automatic Updates are enabled, check for updates immediately. #if RELEASE if (Utils.GitUpdateAvailable() > 0) { if (GlobalOptions.AutomaticUpdate) { frmUpdate frmAutoUpdate = new frmUpdate(); frmAutoUpdate.SilentMode = true; frmAutoUpdate.Visible = false; frmAutoUpdate.ShowDialog(this); } else { this.Text += String.Format(" - Update {0} now available!", Utils.GitVersion()); } } #endif GlobalOptions.MRUChanged += PopulateMRU; // Delete the old executable if it exists (created by the update process). foreach (string strLoopOldFilePath in Directory.GetFiles(Application.StartupPath, "*.old")) { if (File.Exists(strLoopOldFilePath)) { File.Delete(strLoopOldFilePath); } } // Populate the MRU list. PopulateMRU(); GlobalOptions.MainForm = this; // Set the Tag for each ToolStrip item so it can be translated. foreach (ToolStripMenuItem objItem in menuStrip.Items.OfType <ToolStripMenuItem>()) { if (objItem.Tag != null) { objItem.Text = LanguageManager.GetString(objItem.Tag.ToString()); } } // ToolStrip Items. foreach (ToolStrip objToolStrip in Controls.OfType <ToolStrip>()) { foreach (ToolStripButton objButton in objToolStrip.Items.OfType <ToolStripButton>()) { if (objButton.Tag != null) { objButton.Text = LanguageManager.GetString(objButton.Tag.ToString()); } } } // Attempt to cache all XML files that are used the most. Timekeeper.Start("cache_load"); XmlManager.Load("armor.xml"); XmlManager.Load("bioware.xml"); XmlManager.Load("books.xml"); XmlManager.Load("complexforms.xml"); XmlManager.Load("contacts.xml"); XmlManager.Load("critters.xml"); XmlManager.Load("critterpowers.xml"); XmlManager.Load("cyberware.xml"); // XmlManager.Load("drugcomponents.xml"); TODO: Re-enable when Custom Drugs branch is merged XmlManager.Load("echoes.xml"); XmlManager.Load("gameplayoptions.xml"); XmlManager.Load("gear.xml"); XmlManager.Load("improvements.xml"); XmlManager.Load("licenses.xml"); XmlManager.Load("lifemodules.xml"); XmlManager.Load("lifestyles.xml"); XmlManager.Load("martialarts.xml"); XmlManager.Load("mentors.xml"); XmlManager.Load("metamagic.xml"); XmlManager.Load("metatypes.xml"); XmlManager.Load("options.xml"); XmlManager.Load("packs.xml"); XmlManager.Load("powers.xml"); XmlManager.Load("priorities.xml"); XmlManager.Load("programs.xml"); XmlManager.Load("qualities.xml"); XmlManager.Load("ranges.xml"); XmlManager.Load("skills.xml"); XmlManager.Load("spells.xml"); XmlManager.Load("spiritpowers.xml"); XmlManager.Load("traditions.xml"); XmlManager.Load("vehicles.xml"); XmlManager.Load("weapons.xml"); Timekeeper.Finish("cache_load"); frmCharacterRoster frmCharacter = new frmCharacterRoster(); frmCharacter.MdiParent = this; // Retrieve the arguments passed to the application. If more than 1 is passed, we're being given the name of a file to open. string[] strArgs = Environment.GetCommandLineArgs(); string strLoop = string.Empty; for (int i = 1; i < strArgs.Length; ++i) { strLoop = strArgs[i]; if (strLoop == "/test") { frmTest frmTestData = new frmTest(); frmTestData.Show(); } else if (!strLoop.StartsWith('/')) { LoadCharacter(strLoop); } } frmCharacter.WindowState = FormWindowState.Maximized; frmCharacter.Show(); }
private void frmMasterIndex_Load(object sender, EventArgs e) { using (var op_load_frm_masterindex = Timekeeper.StartSyncron("op_load_frm_masterindex", null, CustomActivity.OperationType.RequestOperation, null)) { using (_ = Timekeeper.StartSyncron("load_frm_masterindex_populate_entries", op_load_frm_masterindex)) { ConcurrentBag <ListItem> lstItemsForLoading = new ConcurrentBag <ListItem>(); ConcurrentBag <ListItem> lstFileNamesWithItemsForLoading = new ConcurrentBag <ListItem>(); Parallel.ForEach(_lstFileNames, strFileName => { XPathNavigator xmlBaseNode = XmlManager.Load(strFileName).GetFastNavigator().SelectSingleNode("/chummer"); if (xmlBaseNode != null) { bool blnLoopFileNameHasItems = false; foreach (XPathNavigator xmlItemNode in xmlBaseNode.Select(".//*[source and page]")) { blnLoopFileNameHasItems = true; string strName = xmlItemNode.SelectSingleNode("name")?.Value; string strDisplayName = xmlItemNode.SelectSingleNode("translate")?.Value ?? strName ?? xmlItemNode.SelectSingleNode("id")?.Value ?? LanguageManager.GetString("String_Unknown"); string strSource = xmlItemNode.SelectSingleNode("source")?.Value; string strPage = xmlItemNode.SelectSingleNode("page")?.Value; string strDisplayPage = xmlItemNode.SelectSingleNode("altpage")?.Value ?? strPage; string strEnglishNameOnPage = xmlItemNode.SelectSingleNode("nameonpage")?.Value ?? strName; string strTranslatedNameOnPage = xmlItemNode.SelectSingleNode("altnameonpage")?.Value ?? strDisplayName; string strNotes = xmlItemNode.SelectSingleNode("altnotes")?.Value ?? xmlItemNode.SelectSingleNode("notes")?.Value; MasterIndexEntry objEntry = new MasterIndexEntry( strDisplayName, strFileName, new SourceString(strSource, strPage, GlobalOptions.DefaultLanguage), new SourceString(strSource, strDisplayPage, GlobalOptions.Language), strEnglishNameOnPage, strTranslatedNameOnPage); lstItemsForLoading.Add(new ListItem(objEntry, strDisplayName)); if (!string.IsNullOrEmpty(strNotes)) { _dicCachedNotes.TryAdd(objEntry, strNotes); } } if (blnLoopFileNameHasItems) { lstFileNamesWithItemsForLoading.Add(new ListItem(strFileName, strFileName)); } } }); foreach (ListItem objItem in lstItemsForLoading) { MasterIndexEntry objEntry = (MasterIndexEntry)objItem.Value; ListItem objExistingItem = _lstItems.FirstOrDefault(x => ((MasterIndexEntry)x.Value).DisplayName.Equals(objEntry.DisplayName, StringComparison.OrdinalIgnoreCase) && ((MasterIndexEntry)x.Value).DisplaySource == objEntry.DisplaySource); if (objExistingItem.Value == null) { _lstItems.Add(objItem); // Not using AddRange because of potential memory issues } else { ((MasterIndexEntry)objExistingItem.Value).FileNames.UnionWith(objEntry.FileNames); } } _lstFileNamesWithItems.AddRange(lstFileNamesWithItemsForLoading); } using (_ = Timekeeper.StartSyncron("load_frm_masterindex_sort_entries", op_load_frm_masterindex)) { _lstItems.Sort(CompareListItems.CompareNames); _lstFileNamesWithItems.Sort(CompareListItems.CompareNames); } using (_ = Timekeeper.StartSyncron("load_frm_masterindex_populate_controls", op_load_frm_masterindex)) { _lstFileNamesWithItems.Insert(0, new ListItem(string.Empty, LanguageManager.GetString("String_All"))); cboFile.BeginUpdate(); cboFile.ValueMember = nameof(ListItem.Value); cboFile.DisplayMember = nameof(ListItem.Name); cboFile.DataSource = _lstFileNamesWithItems; cboFile.SelectedIndex = 0; cboFile.EndUpdate(); lstItems.BeginUpdate(); lstItems.ValueMember = nameof(ListItem.Value); lstItems.DisplayMember = nameof(ListItem.Name); lstItems.DataSource = _lstItems; lstItems.SelectedIndex = -1; lstItems.EndUpdate(); _blnSkipRefresh = false; } } }
private void DoImport() { TreeNode objSelectedNode = treCharacterList.SelectedNode; if (objSelectedNode != null && objSelectedNode.Level > 0) { int intIndex = Convert.ToInt32(objSelectedNode.Tag); if (intIndex >= 0 && intIndex < _lstCharacterCache.Count) { string strFile = _lstCharacterCache[intIndex]?.FilePath; string strCharacterId = _lstCharacterCache[intIndex]?.CharacterId; if (!string.IsNullOrEmpty(strFile) && !string.IsNullOrEmpty(strCharacterId)) { string strFilePath = Path.Combine(Application.StartupPath, "settings", "default.xml"); Cursor objOldCursor = Cursor; if (!File.Exists(strFilePath)) { if (MessageBox.Show(LanguageManager.GetString("Message_CharacterOptions_OpenOptions", GlobalOptions.Language), LanguageManager.GetString("MessageTitle_CharacterOptions_OpenOptions", GlobalOptions.Language), MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes) { Cursor = Cursors.WaitCursor; frmOptions frmOptions = new frmOptions(); frmOptions.ShowDialog(); Cursor = objOldCursor; } } Cursor = Cursors.WaitCursor; cmdImport.Enabled = false; cmdSelectFile.Enabled = false; Character objCharacter = new Character(); string settingsPath = Path.Combine(Application.StartupPath, "settings"); string[] settingsFiles = Directory.GetFiles(settingsPath, "*.xml"); if (settingsFiles.Length > 1) { frmSelectSetting frmPickSetting = new frmSelectSetting(); frmPickSetting.ShowDialog(this); if (frmPickSetting.DialogResult == DialogResult.Cancel) { return; } objCharacter.SettingsFile = frmPickSetting.SettingsFile; } else { string strSettingsFile = settingsFiles[0]; objCharacter.SettingsFile = Path.GetFileName(strSettingsFile); } Program.MainForm.OpenCharacters.Add(objCharacter); Timekeeper.Start("load_file"); bool blnLoaded = objCharacter.LoadFromHeroLabFile(strFile, strCharacterId, objCharacter.SettingsFile); Timekeeper.Finish("load_file"); if (!blnLoaded) { Program.MainForm.OpenCharacters.Remove(objCharacter); objCharacter.DeleteCharacter(); Cursor = objOldCursor; cmdImport.Enabled = true; cmdSelectFile.Enabled = true; return; } Program.MainForm.OpenCharacter(objCharacter); Close(); } } } }
private async ValueTask LoadContent() { using (CustomActivity opLoadMasterindex = Timekeeper.StartSyncron("op_load_frm_masterindex", null, CustomActivity.OperationType.RequestOperation, null)) { _dicCachedNotes.Clear(); foreach (MasterIndexEntry objExistingEntry in _lstItems.Select(x => x.Value)) { objExistingEntry.Dispose(); } _lstItems.Clear(); _lstFileNamesWithItems.Clear(); string strSourceFilter; using (new FetchSafelyFromPool <HashSet <string> >(Utils.StringHashSetPool, out HashSet <string> setValidCodes)) { foreach (XPathNavigator xmlBookNode in (await XmlManager.LoadXPathAsync( "books.xml", _objSelectedSetting.EnabledCustomDataDirectoryPaths)) .SelectAndCacheExpression("/chummer/books/book/code")) { setValidCodes.Add(xmlBookNode.Value); } setValidCodes.IntersectWith(_objSelectedSetting.Books); strSourceFilter = setValidCodes.Count > 0 ? '(' + string.Join(" or ", setValidCodes.Select(x => "source = " + x.CleanXPath())) + ')' : "source"; } using (_ = Timekeeper.StartSyncron("load_frm_masterindex_load_andpopulate_entries", opLoadMasterindex)) { ConcurrentBag <ListItem> lstItemsForLoading = new ConcurrentBag <ListItem>(); using (_ = Timekeeper.StartSyncron("load_frm_masterindex_load_entries", opLoadMasterindex)) { ConcurrentBag <ListItem> lstFileNamesWithItemsForLoading = new ConcurrentBag <ListItem>(); // Prevents locking the UI thread while still benefitting from static scheduling of Parallel.ForEach await Task.WhenAll(_astrFileNames.Select(strFileName => Task.Run(async() => { XPathNavigator xmlBaseNode = await XmlManager.LoadXPathAsync(strFileName, _objSelectedSetting.EnabledCustomDataDirectoryPaths); xmlBaseNode = xmlBaseNode.SelectSingleNodeAndCacheExpression("/chummer"); if (xmlBaseNode == null) { return; } bool blnLoopFileNameHasItems = false; foreach (XPathNavigator xmlItemNode in xmlBaseNode.SelectAndCacheExpression( ".//*[page and " + strSourceFilter + ']')) { blnLoopFileNameHasItems = true; string strName = xmlItemNode.SelectSingleNodeAndCacheExpression("name")?.Value; string strDisplayName = xmlItemNode.SelectSingleNodeAndCacheExpression("translate")?.Value ?? strName ?? xmlItemNode.SelectSingleNodeAndCacheExpression("id")?.Value ?? await LanguageManager.GetStringAsync("String_Unknown"); string strSource = xmlItemNode.SelectSingleNodeAndCacheExpression("source")?.Value; string strPage = xmlItemNode.SelectSingleNodeAndCacheExpression("page")?.Value; string strDisplayPage = xmlItemNode.SelectSingleNodeAndCacheExpression("altpage")?.Value ?? strPage; string strEnglishNameOnPage = xmlItemNode.SelectSingleNodeAndCacheExpression("nameonpage")?.Value ?? strName; string strTranslatedNameOnPage = xmlItemNode.SelectSingleNodeAndCacheExpression("altnameonpage")?.Value ?? strDisplayName; string strNotes = xmlItemNode.SelectSingleNodeAndCacheExpression("altnotes")?.Value ?? xmlItemNode.SelectSingleNodeAndCacheExpression("notes")?.Value; MasterIndexEntry objEntry = new MasterIndexEntry( strDisplayName, strFileName, new SourceString(strSource, strPage, GlobalSettings.DefaultLanguage, GlobalSettings.InvariantCultureInfo), new SourceString(strSource, strDisplayPage, GlobalSettings.Language, GlobalSettings.CultureInfo), strEnglishNameOnPage, strTranslatedNameOnPage); lstItemsForLoading.Add(new ListItem(objEntry, strDisplayName)); if (!string.IsNullOrEmpty(strNotes)) { _dicCachedNotes.TryAdd(objEntry, strNotes); } } if (blnLoopFileNameHasItems) { lstFileNamesWithItemsForLoading.Add(new ListItem(strFileName, strFileName)); } }))); _lstFileNamesWithItems.AddRange(lstFileNamesWithItemsForLoading); } using (_ = Timekeeper.StartSyncron("load_frm_masterindex_populate_entries", opLoadMasterindex)) { string strSpace = await LanguageManager.GetStringAsync("String_Space"); string strFormat = "{0}" + strSpace + "[{1}]"; Dictionary <string, List <ListItem> > dicHelper = new Dictionary <string, List <ListItem> >(lstItemsForLoading.Count); try { foreach (ListItem objItem in lstItemsForLoading) { if (!(objItem.Value is MasterIndexEntry objEntry)) { continue; } string strKey = objEntry.DisplayName.ToUpperInvariant(); if (dicHelper.TryGetValue(strKey, out List <ListItem> lstExistingItems)) { ListItem objExistingItem = lstExistingItems.Find( x => x.Value is MasterIndexEntry y && objEntry.DisplaySource.Equals(y.DisplaySource)); if (objExistingItem.Value is MasterIndexEntry objLoopEntry) { objLoopEntry.FileNames.UnionWith(objEntry.FileNames); objEntry.Dispose(); } else { using (new FetchSafelyFromPool <List <ListItem> >( Utils.ListItemListPool, out List <ListItem> lstItemsNeedingNameChanges)) { lstItemsNeedingNameChanges.AddRange(lstExistingItems.FindAll( x => x.Value is MasterIndexEntry y && !objEntry.FileNames.IsSubsetOf(y.FileNames))); if (lstItemsNeedingNameChanges.Count == 0) { _lstItems.Add( objItem); // Not using AddRange because of potential memory issues lstExistingItems.Add(objItem); } else { ListItem objItemToAdd = new ListItem( objItem.Value, string.Format(GlobalSettings.CultureInfo, strFormat, objItem.Name, string.Join( ',' + strSpace, objEntry.FileNames))); _lstItems.Add( objItemToAdd); // Not using AddRange because of potential memory issues lstExistingItems.Add(objItemToAdd); foreach (ListItem objToRename in lstItemsNeedingNameChanges) { _lstItems.Remove(objToRename); lstExistingItems.Remove(objToRename); if (!(objToRename.Value is MasterIndexEntry objExistingEntry)) { continue; } objItemToAdd = new ListItem(objToRename.Value, string.Format( GlobalSettings.CultureInfo, strFormat, objExistingEntry.DisplayName, string.Join( ',' + strSpace, objExistingEntry.FileNames))); _lstItems.Add( objItemToAdd); // Not using AddRange because of potential memory issues lstExistingItems.Add(objItemToAdd); } } } } } else { _lstItems.Add(objItem); // Not using AddRange because of potential memory issues List <ListItem> lstHelperItems = Utils.ListItemListPool.Get(); lstHelperItems.Add(objItem); dicHelper.Add(strKey, lstHelperItems); } } } finally { foreach (List <ListItem> lstHelperItems in dicHelper.Values) { Utils.ListItemListPool.Return(lstHelperItems); } } } } using (_ = Timekeeper.StartSyncron("load_frm_masterindex_sort_entries", opLoadMasterindex)) { _lstItems.Sort(CompareListItems.CompareNames); _lstFileNamesWithItems.Sort(CompareListItems.CompareNames); } using (_ = Timekeeper.StartSyncron("load_frm_masterindex_populate_controls", opLoadMasterindex)) { _lstFileNamesWithItems.Insert(0, new ListItem(string.Empty, await LanguageManager.GetStringAsync("String_All"))); int intOldSelectedIndex = cboFile.SelectedIndex; cboFile.BeginUpdate(); cboFile.PopulateWithListItems(_lstFileNamesWithItems); try { cboFile.SelectedIndex = Math.Max(intOldSelectedIndex, 0); } // For some reason, some unit tests will fire this exception even when _lstFileNamesWithItems is explicitly checked for having enough items catch (ArgumentOutOfRangeException) { cboFile.SelectedIndex = -1; } cboFile.EndUpdate(); lstItems.BeginUpdate(); lstItems.PopulateWithListItems(_lstItems); lstItems.SelectedIndex = -1; lstItems.EndUpdate(); _blnSkipRefresh = false; } } }
private async void frmMasterIndex_Load(object sender, EventArgs e) { using (var op_load_frm_masterindex = Timekeeper.StartSyncron("op_load_frm_masterindex", null, CustomActivity.OperationType.RequestOperation, null)) { HashSet <string> setValidCodes = new HashSet <string>(); foreach (XPathNavigator xmlBookNode in (await XmlManager.LoadXPathAsync("books.xml")).Select("/chummer/books/book/code")) { setValidCodes.Add(xmlBookNode.Value); } string strSourceFilter = setValidCodes.Count > 0 ? new StringBuilder("(") .AppendJoin(" or ", setValidCodes.Select(x => "source = \'" + x + "\'")) .Append(')').ToString() : "source"; ConcurrentBag <ListItem> lstItemsForLoading = new ConcurrentBag <ListItem>(); ConcurrentBag <ListItem> lstFileNamesWithItemsForLoading = new ConcurrentBag <ListItem>(); using (_ = Timekeeper.StartSyncron("load_frm_masterindex_load_entries", op_load_frm_masterindex)) { // Prevents locking the UI thread while still benefitting from static scheduling of Parallel.ForEach await Task.Run(() => { Parallel.ForEach(_lstFileNames, strFileName => { XPathNavigator xmlBaseNode = XmlManager.LoadXPath(strFileName); xmlBaseNode = xmlBaseNode.SelectSingleNode("/chummer"); if (xmlBaseNode == null) { return; } bool blnLoopFileNameHasItems = false; foreach (XPathNavigator xmlItemNode in xmlBaseNode.Select(".//*[page and " + strSourceFilter + ']')) { blnLoopFileNameHasItems = true; string strName = xmlItemNode.SelectSingleNode("name")?.Value; string strDisplayName = xmlItemNode.SelectSingleNode("translate")?.Value ?? strName ?? xmlItemNode.SelectSingleNode("id")?.Value ?? LanguageManager.GetString("String_Unknown"); string strSource = xmlItemNode.SelectSingleNode("source")?.Value; string strPage = xmlItemNode.SelectSingleNode("page")?.Value; string strDisplayPage = xmlItemNode.SelectSingleNode("altpage")?.Value ?? strPage; string strEnglishNameOnPage = xmlItemNode.SelectSingleNode("nameonpage")?.Value ?? strName; string strTranslatedNameOnPage = xmlItemNode.SelectSingleNode("altnameonpage")?.Value ?? strDisplayName; string strNotes = xmlItemNode.SelectSingleNode("altnotes")?.Value ?? xmlItemNode.SelectSingleNode("notes")?.Value; MasterIndexEntry objEntry = new MasterIndexEntry( strDisplayName, strFileName, new SourceString(strSource, strPage, GlobalOptions.DefaultLanguage, GlobalOptions.InvariantCultureInfo), new SourceString(strSource, strDisplayPage, GlobalOptions.Language, GlobalOptions.CultureInfo), strEnglishNameOnPage, strTranslatedNameOnPage); lstItemsForLoading.Add(new ListItem(objEntry, strDisplayName)); if (!string.IsNullOrEmpty(strNotes)) { _dicCachedNotes.TryAdd(objEntry, strNotes); } } if (blnLoopFileNameHasItems) { lstFileNamesWithItemsForLoading.Add(new ListItem(strFileName, strFileName)); } }); }); } using (_ = Timekeeper.StartSyncron("load_frm_masterindex_populate_entries", op_load_frm_masterindex)) { string strSpace = LanguageManager.GetString("String_Space"); string strFormat = "{0}" + strSpace + "[{1}]"; Dictionary <string, List <ListItem> > dicHelper = new Dictionary <string, List <ListItem> >(lstItemsForLoading.Count); foreach (ListItem objItem in lstItemsForLoading) { MasterIndexEntry objEntry = (MasterIndexEntry)objItem.Value; string strKey = objEntry.DisplayName.ToUpperInvariant(); if (dicHelper.TryGetValue(strKey, out List <ListItem> lstExistingItems)) { ListItem objExistingItem = lstExistingItems.FirstOrDefault(x => objEntry.DisplaySource.Equals(((MasterIndexEntry)x.Value).DisplaySource)); if (objExistingItem.Value != null) { ((MasterIndexEntry)objExistingItem.Value).FileNames.UnionWith(objEntry.FileNames); } else { List <ListItem> lstItemsNeedingNameChanges = lstExistingItems.Where(x => !objEntry.FileNames.IsSubsetOf(((MasterIndexEntry)x.Value).FileNames)).ToList(); if (lstItemsNeedingNameChanges.Count == 0) { _lstItems.Add(objItem); // Not using AddRange because of potential memory issues lstExistingItems.Add(objItem); } else { ListItem objItemToAdd = new ListItem(objItem.Value, string.Format(GlobalOptions.CultureInfo, strFormat, objItem.Name, string.Join(',' + strSpace, objEntry.FileNames))); _lstItems.Add(objItemToAdd); // Not using AddRange because of potential memory issues lstExistingItems.Add(objItemToAdd); foreach (ListItem objToRename in lstItemsNeedingNameChanges) { _lstItems.Remove(objToRename); lstExistingItems.Remove(objToRename); MasterIndexEntry objExistingEntry = (MasterIndexEntry)objToRename.Value; objItemToAdd = new ListItem(objToRename.Value, string.Format(GlobalOptions.CultureInfo, strFormat, objExistingEntry.DisplayName, string.Join(',' + strSpace, objExistingEntry.FileNames))); _lstItems.Add(objItemToAdd); // Not using AddRange because of potential memory issues lstExistingItems.Add(objItemToAdd); } } } } else { _lstItems.Add(objItem); // Not using AddRange because of potential memory issues dicHelper.Add(strKey, new List <ListItem>(objItem.Yield())); } } _lstFileNamesWithItems.AddRange(lstFileNamesWithItemsForLoading); } using (_ = Timekeeper.StartSyncron("load_frm_masterindex_sort_entries", op_load_frm_masterindex)) { _lstItems.Sort(CompareListItems.CompareNames); _lstFileNamesWithItems.Sort(CompareListItems.CompareNames); } using (_ = Timekeeper.StartSyncron("load_frm_masterindex_populate_controls", op_load_frm_masterindex)) { _lstFileNamesWithItems.Insert(0, new ListItem(string.Empty, LanguageManager.GetString("String_All"))); cboFile.BeginUpdate(); cboFile.PopulateWithListItems(_lstFileNamesWithItems); try { cboFile.SelectedIndex = 0; } // For some reason, some unit tests will fire this exception even when _lstFileNamesWithItems is explicitly checked for having enough items catch (ArgumentOutOfRangeException) { cboFile.SelectedIndex = -1; } cboFile.EndUpdate(); lstItems.BeginUpdate(); lstItems.PopulateWithListItems(_lstItems); lstItems.SelectedIndex = -1; lstItems.EndUpdate(); _blnSkipRefresh = false; } } }
private void frmMasterIndex_Load(object sender, EventArgs e) { using (var op_load_frm_masterindex = Timekeeper.StartSyncron("op_load_frm_masterindex", null, CustomActivity.OperationType.RequestOperation, null)) { HashSet <string> setValidCodes = new HashSet <string>(); XmlNodeList lstBookNodes = XmlManager.Load("books.xml").SelectNodes("/chummer/books/book/code"); if (lstBookNodes?.Count > 0) { foreach (XmlNode xmlBookNode in lstBookNodes) { setValidCodes.Add(xmlBookNode.InnerText); } } string strSourceFilter = setValidCodes.Count > 0 ? new StringBuilder("(") .AppendJoin(" or ", setValidCodes.Select(x => "source = \'" + x + "\'")) .Append(')').ToString() : "source"; ConcurrentBag <ListItem> lstItemsForLoading = new ConcurrentBag <ListItem>(); ConcurrentBag <ListItem> lstFileNamesWithItemsForLoading = new ConcurrentBag <ListItem>(); using (_ = Timekeeper.StartSyncron("load_frm_masterindex_load_entries", op_load_frm_masterindex)) { Parallel.ForEach(_lstFileNames, strFileName => { XPathNavigator xmlBaseNode = XmlManager.Load(strFileName).GetFastNavigator().SelectSingleNode("/chummer"); if (xmlBaseNode != null) { bool blnLoopFileNameHasItems = false; foreach (XPathNavigator xmlItemNode in xmlBaseNode.Select(".//*[page and " + strSourceFilter + ']')) { blnLoopFileNameHasItems = true; string strName = xmlItemNode.SelectSingleNode("name")?.Value; string strDisplayName = xmlItemNode.SelectSingleNode("translate")?.Value ?? strName ?? xmlItemNode.SelectSingleNode("id")?.Value ?? LanguageManager.GetString("String_Unknown"); string strSource = xmlItemNode.SelectSingleNode("source")?.Value; string strPage = xmlItemNode.SelectSingleNode("page")?.Value; string strDisplayPage = xmlItemNode.SelectSingleNode("altpage")?.Value ?? strPage; string strEnglishNameOnPage = xmlItemNode.SelectSingleNode("nameonpage")?.Value ?? strName; string strTranslatedNameOnPage = xmlItemNode.SelectSingleNode("altnameonpage")?.Value ?? strDisplayName; string strNotes = xmlItemNode.SelectSingleNode("altnotes")?.Value ?? xmlItemNode.SelectSingleNode("notes")?.Value; MasterIndexEntry objEntry = new MasterIndexEntry( strDisplayName, strFileName, new SourceString(strSource, strPage, GlobalOptions.DefaultLanguage, GlobalOptions.InvariantCultureInfo), new SourceString(strSource, strDisplayPage, GlobalOptions.Language, GlobalOptions.CultureInfo), strEnglishNameOnPage, strTranslatedNameOnPage); lstItemsForLoading.Add(new ListItem(objEntry, strDisplayName)); if (!string.IsNullOrEmpty(strNotes)) { _dicCachedNotes.TryAdd(objEntry, strNotes); } } if (blnLoopFileNameHasItems) { lstFileNamesWithItemsForLoading.Add(new ListItem(strFileName, strFileName)); } } }); } using (_ = Timekeeper.StartSyncron("load_frm_masterindex_populate_entries", op_load_frm_masterindex)) { string strSpace = LanguageManager.GetString("String_Space"); Dictionary <string, List <ListItem> > dicHelper = new Dictionary <string, List <ListItem> >(lstItemsForLoading.Count); foreach (ListItem objItem in lstItemsForLoading) { MasterIndexEntry objEntry = (MasterIndexEntry)objItem.Value; string strKey = objEntry.DisplayName.ToUpperInvariant(); if (dicHelper.TryGetValue(strKey, out List <ListItem> lstExistingItems)) { ListItem objExistingItem = lstExistingItems.FirstOrDefault(x => objEntry.DisplaySource.Equals(((MasterIndexEntry)x.Value).DisplaySource)); if (objExistingItem.Value != null) { ((MasterIndexEntry)objExistingItem.Value).FileNames.UnionWith(objEntry.FileNames); } else { List <ListItem> lstItemsNeedingNameChanges = lstExistingItems.Where(x => !objEntry.FileNames.IsSubsetOf(((MasterIndexEntry)x.Value).FileNames)).ToList(); if (lstItemsNeedingNameChanges.Count == 0) { _lstItems.Add(objItem); // Not using AddRange because of potential memory issues lstExistingItems.Add(objItem); } else { ListItem objItemToAdd = new ListItem(objItem.Value, new StringBuilder(objItem.Name) .Append(strSpace).Append('[').AppendJoin(',' + strSpace, objEntry.FileNames).Append(']').ToString()); _lstItems.Add(objItemToAdd); // Not using AddRange because of potential memory issues lstExistingItems.Add(objItemToAdd); foreach (ListItem objToRename in lstItemsNeedingNameChanges) { _lstItems.Remove(objToRename); lstExistingItems.Remove(objToRename); MasterIndexEntry objExistingEntry = (MasterIndexEntry)objToRename.Value; objItemToAdd = new ListItem(objToRename.Value, new StringBuilder(objExistingEntry.DisplayName) .Append(strSpace).Append('[').AppendJoin(',' + strSpace, objExistingEntry.FileNames).Append(']').ToString()); _lstItems.Add(objItemToAdd); // Not using AddRange because of potential memory issues lstExistingItems.Add(objItemToAdd); } } } } else { _lstItems.Add(objItem); // Not using AddRange because of potential memory issues dicHelper.Add(strKey, new List <ListItem>(objItem.Yield())); } } _lstFileNamesWithItems.AddRange(lstFileNamesWithItemsForLoading); } using (_ = Timekeeper.StartSyncron("load_frm_masterindex_sort_entries", op_load_frm_masterindex)) { _lstItems.Sort(CompareListItems.CompareNames); _lstFileNamesWithItems.Sort(CompareListItems.CompareNames); } using (_ = Timekeeper.StartSyncron("load_frm_masterindex_populate_controls", op_load_frm_masterindex)) { _lstFileNamesWithItems.Insert(0, new ListItem(string.Empty, LanguageManager.GetString("String_All"))); cboFile.BeginUpdate(); cboFile.ValueMember = nameof(ListItem.Value); cboFile.DisplayMember = nameof(ListItem.Name); cboFile.DataSource = _lstFileNamesWithItems; cboFile.SelectedIndex = 0; cboFile.EndUpdate(); lstItems.BeginUpdate(); lstItems.ValueMember = nameof(ListItem.Value); lstItems.DisplayMember = nameof(ListItem.Name); lstItems.DataSource = _lstItems; lstItems.SelectedIndex = -1; lstItems.EndUpdate(); _blnSkipRefresh = false; } } }