private async ValueTask DoExport(CancellationToken token = default) { if (string.IsNullOrEmpty(_strXslt)) { return; } CursorWait objCursorWait = await CursorWait.NewAsync(this, token : token); try { if (_strXslt == "JSON") { await ExportJson(token : token); } else { await ExportNormal(token : token); } } finally { await objCursorWait.DisposeAsync(); } }
private async void tsAttachCharacter_Click(object sender, EventArgs e) { // Prompt the user to select a save file to associate with this Contact. using (OpenFileDialog openFileDialog = new OpenFileDialog { Filter = await LanguageManager.GetStringAsync("DialogFilter_Chum5") + '|' + await LanguageManager.GetStringAsync("DialogFilter_All") }) { if (!string.IsNullOrEmpty(_objContact.FileName) && File.Exists(_objContact.FileName)) { openFileDialog.InitialDirectory = Path.GetDirectoryName(_objContact.FileName); openFileDialog.FileName = Path.GetFileName(_objContact.FileName); } if (openFileDialog.ShowDialog(this) != DialogResult.OK) { return; } using (await CursorWait.NewAsync(ParentForm)) { _objContact.FileName = openFileDialog.FileName; string strText = await LanguageManager.GetStringAsync("Tip_Contact_OpenFile"); await cmdLink.SetToolTipTextAsync(strText); // Set the relative path. Uri uriApplication = new Uri(Utils.GetStartupPath); Uri uriFile = new Uri(_objContact.FileName); Uri uriRelative = uriApplication.MakeRelativeUri(uriFile); _objContact.RelativeFileName = "../" + uriRelative; ContactDetailChanged?.Invoke(this, new TextEventArgs("File")); } } }
private async Task GenerateJson(CancellationToken token = default) { token.ThrowIfCancellationRequested(); CursorWait objCursorWait = await CursorWait.NewAsync(this, token : token); try { await cmdExport.DoThreadSafeAsync(x => x.Enabled = false, token); await cmdExportClose.DoThreadSafeAsync(x => x.Enabled = false, token); try { token.ThrowIfCancellationRequested(); string strText = JsonConvert.SerializeXmlNode(_objCharacterXml, Formatting.Indented); token.ThrowIfCancellationRequested(); await SetTextToWorkerResult(strText, token); } finally { await cmdExport.DoThreadSafeAsync(x => x.Enabled = true, token); await cmdExportClose.DoThreadSafeAsync(x => x.Enabled = true, token); } } finally { await objCursorWait.DisposeAsync(); } }
private async void cmdSelectFile_Click(object sender, EventArgs e) { // Prompt the user to select a save file to possess. using (OpenFileDialog openFileDialog = new OpenFileDialog { Filter = await LanguageManager.GetStringAsync("DialogFilter_HeroLab") + '|' + await LanguageManager.GetStringAsync("DialogFilter_All"), Multiselect = false }) { if (openFileDialog.ShowDialog(this) != DialogResult.OK) { return; } using (await CursorWait.NewAsync(this)) { string strSelectedFile = openFileDialog.FileName; TreeNode objNode = await CacheCharacters(strSelectedFile); if (objNode != null) { await treCharacterList.DoThreadSafeAsync(x => { x.Nodes.Clear(); x.Nodes.Add(objNode); x.SelectedNode = objNode.Nodes.Count > 0 ? objNode.Nodes[0] : objNode; }); } } } }
private async Task GenerateCharacterXml(CancellationToken token = default) { token.ThrowIfCancellationRequested(); CursorWait objCursorWait = await CursorWait.NewAsync(this, token : token); try { await Task.WhenAll(cmdExport.DoThreadSafeAsync(x => x.Enabled = false, token), cmdExportClose.DoThreadSafeAsync(x => x.Enabled = false, token), LanguageManager.GetStringAsync("String_Generating_Data") .ContinueWith( y => txtText.DoThreadSafeAsync(x => x.Text = y.Result, token), token).Unwrap()); token.ThrowIfCancellationRequested(); using (token.Register(() => _objCharacterXmlGeneratorCancellationTokenSource.Cancel(false))) _objCharacterXml = await _objCharacter.GenerateExportXml(_objExportCulture, _strExportLanguage, _objCharacterXmlGeneratorCancellationTokenSource .Token); token.ThrowIfCancellationRequested(); if (_objCharacterXml != null) { await DoXsltUpdate(token); } } finally { await objCursorWait.DisposeAsync(); } }
private async Task DoPrint(CancellationToken token = default) { token.ThrowIfCancellationRequested(); using (await CursorWait.NewAsync(this, true, token)) { try { token.ThrowIfCancellationRequested(); int intNodesCount = await treCharacters.DoThreadSafeFuncAsync(x => x.Nodes.Count, token); await Task.WhenAll(cmdPrint.DoThreadSafeAsync(x => x.Enabled = false, token), prgProgress.DoThreadSafeAsync(objBar => { objBar.Value = 0; objBar.Maximum = intNodesCount; }, token)); token.ThrowIfCancellationRequested(); // Parallelized load because this is one major bottleneck. Character[] lstCharacters = new Character[intNodesCount]; Task <Character>[] tskLoadingTasks = new Task <Character> [intNodesCount]; for (int i = 0; i < tskLoadingTasks.Length; ++i) { string strLoopFile = await treCharacters.DoThreadSafeFuncAsync(x => x.Nodes[i].Tag.ToString(), token); tskLoadingTasks[i] = Task.Run(() => InnerLoad(strLoopFile, token), token); } async Task <Character> InnerLoad(string strLoopFile, CancellationToken innerToken = default)
private async ValueTask RefreshSelectLifestyle() { _blnIsSelectLifestyleRefreshing = true; using (await CursorWait.NewAsync(this)) { try { Lifestyle objPreferredLifestyle = null; ListItem objPreferredLifestyleItem = default; Lifestyle objCurrentlySelectedLifestyle = await cboSelectLifestyle.DoThreadSafeFuncAsync(x => x.SelectedIndex >= 0 ?((ListItem)x.SelectedItem).Value as Lifestyle : null); using (new FetchSafelyFromPool <List <ListItem> >(Utils.ListItemListPool, out List <ListItem> lstLifestyleItems)) { foreach (Lifestyle objLifestyle in _objCharacter.Lifestyles) { ListItem objLifestyleItem = new ListItem(objLifestyle, objLifestyle.CurrentDisplayName); lstLifestyleItems.Add(new ListItem(objLifestyle, objLifestyle.CurrentDisplayName)); // We already selected a lifestyle, so keep the selection if possible despite the refresh if (objCurrentlySelectedLifestyle != null) { if (objCurrentlySelectedLifestyle == objLifestyle) { objPreferredLifestyleItem = objLifestyleItem; } } else if (objPreferredLifestyle == null || objLifestyle.ExpectedValue > objPreferredLifestyle.ExpectedValue) { objPreferredLifestyleItem = objLifestyleItem; objPreferredLifestyle = objLifestyle; } } lstLifestyleItems.Sort(CompareListItems.CompareNames); await cboSelectLifestyle.PopulateWithListItemsAsync(lstLifestyleItems); await cboSelectLifestyle.DoThreadSafeAsync(x => { x.SelectedItem = objPreferredLifestyleItem; if (x.SelectedIndex < 0 && lstLifestyleItems.Count > 0) { x.SelectedIndex = 0; } x.Enabled = lstLifestyleItems.Count > 1; }); } } finally { _blnIsSelectLifestyleRefreshing = false; } await RefreshBaseLifestyle(); } }
private async void cmdEditCharacterOption_Click(object sender, EventArgs e) { using (await CursorWait.NewAsync(this)) { object objOldSelected = await cboCharacterSetting.DoThreadSafeFuncAsync(x => x.SelectedValue); using (ThreadSafeForm <EditCharacterSettings> frmOptions = await ThreadSafeForm <EditCharacterSettings> .GetAsync( () => new EditCharacterSettings(objOldSelected as CharacterSettings))) await frmOptions.ShowDialogSafeAsync(this); await this.DoThreadSafeAsync(x => x.SuspendLayout()); try { // Populate the Gameplay Settings list. using (new FetchSafelyFromPool <List <ListItem> >( Utils.ListItemListPool, out List <ListItem> lstGameplayOptions)) { lstGameplayOptions.AddRange(SettingsManager.LoadedCharacterSettings.Values .Select(objLoopOptions => new ListItem( objLoopOptions, objLoopOptions.DisplayName))); lstGameplayOptions.Sort(CompareListItems.CompareNames); await cboCharacterSetting.PopulateWithListItemsAsync(lstGameplayOptions); await cboCharacterSetting.DoThreadSafeAsync(x => x.SelectedValue = objOldSelected); if (await cboCharacterSetting.DoThreadSafeFuncAsync(x => x.SelectedIndex) == -1 && lstGameplayOptions.Count > 0) { (bool blnSuccess, CharacterSettings objSetting) = await SettingsManager.LoadedCharacterSettings.TryGetValueAsync( GlobalSettings.DefaultCharacterSetting); await cboCharacterSetting.DoThreadSafeAsync(x => { if (blnSuccess) { x.SelectedValue = objSetting; } if (x.SelectedIndex == -1 && lstGameplayOptions.Count > 0) { x.SelectedIndex = 0; } }); } } } finally { await this.DoThreadSafeAsync(x => x.ResumeLayout()); } } }
private async void cboCharacterSetting_SelectedIndexChanged(object sender, EventArgs e) { if (_blnSkipRefresh) { return; } try { using (await CursorWait.NewAsync(this, token: _objGenericToken)) { string strSelectedSetting = (await cboCharacterSetting.DoThreadSafeFuncAsync(x => x.SelectedValue, _objGenericToken) as CharacterSettings)?.DictionaryKey; CharacterSettings objSettings = null; bool blnSuccess = false; if (!string.IsNullOrEmpty(strSelectedSetting)) { (blnSuccess, objSettings) = await SettingsManager.LoadedCharacterSettings.TryGetValueAsync(strSelectedSetting, _objGenericToken); } if (!blnSuccess) { (blnSuccess, objSettings) = await SettingsManager.LoadedCharacterSettings.TryGetValueAsync( GlobalSettings.DefaultMasterIndexSetting, _objGenericToken); if (!blnSuccess) { (blnSuccess, objSettings) = await SettingsManager.LoadedCharacterSettings.TryGetValueAsync( GlobalSettings.DefaultMasterIndexSettingDefaultValue, _objGenericToken); if (!blnSuccess) { objSettings = SettingsManager.LoadedCharacterSettings.Values.First(); } } } if (objSettings != _objSelectedSetting) { _objSelectedSetting.PropertyChanged -= OnSelectedSettingChanged; _objSelectedSetting = objSettings; _objSelectedSetting.PropertyChanged += OnSelectedSettingChanged; await LoadContent(_objGenericToken); } } } catch (OperationCanceledException) { //swallow this } }
private async void tsContactOpen_Click(object sender, EventArgs e) { if (_objSpirit.LinkedCharacter != null) { Character objOpenCharacter = await Program.OpenCharacters.ContainsAsync(_objSpirit.LinkedCharacter) ? _objSpirit.LinkedCharacter : null; using (await CursorWait.NewAsync(ParentForm)) { if (objOpenCharacter == null) { using (LoadingBar frmLoadingBar = await Program.CreateAndShowProgressBarAsync(_objSpirit.LinkedCharacter.FileName, Character.NumLoadingSections)) objOpenCharacter = await Program.LoadCharacterAsync(_objSpirit.LinkedCharacter.FileName, frmLoadingBar : frmLoadingBar); } if (!await Program.SwitchToOpenCharacter(objOpenCharacter)) { await Program.OpenCharacter(objOpenCharacter); } } } else { bool blnUseRelative = false; // Make sure the file still exists before attempting to load it. if (!File.Exists(_objSpirit.FileName)) { bool blnError = false; // If the file doesn't exist, use the relative path if one is available. if (string.IsNullOrEmpty(_objSpirit.RelativeFileName)) { blnError = true; } else if (!File.Exists(Path.GetFullPath(_objSpirit.RelativeFileName))) { blnError = true; } else { blnUseRelative = true; } if (blnError) { Program.ShowMessageBox(string.Format(GlobalSettings.CultureInfo, await LanguageManager.GetStringAsync("Message_FileNotFound"), _objSpirit.FileName), await LanguageManager.GetStringAsync("MessageTitle_FileNotFound"), MessageBoxButtons.OK, MessageBoxIcon.Error); return; } } string strFile = blnUseRelative ? Path.GetFullPath(_objSpirit.RelativeFileName) : _objSpirit.FileName; System.Diagnostics.Process.Start(strFile); } }
private async void cmdRoll_Click(object sender, EventArgs e) { using (await CursorWait.NewAsync(this)) { int intResult = 0; for (int i = 0; i < Dice; ++i) { intResult += await GlobalSettings.RandomGenerator.NextD6ModuloBiasRemovedAsync(); } await nudDiceResult.DoThreadSafeAsync(x => x.ValueAsInt = intResult); } }
private async ValueTask RefreshResultLabel() { using (await CursorWait.NewAsync(this)) { string strSpace = await LanguageManager.GetStringAsync("String_Space"); await lblResult.DoThreadSafeAsync(x => x.Text = strSpace + '+' + strSpace + Extra.ToString("#,0", GlobalSettings.CultureInfo) + ')' + strSpace + '×' + strSpace + (SelectedLifestyle?.Multiplier ?? 0).ToString( _objCharacter.Settings.NuyenFormat + '¥', GlobalSettings.CultureInfo) + strSpace + '=' + strSpace + StartingNuyen.ToString(_objCharacter.Settings.NuyenFormat + '¥', GlobalSettings.CultureInfo)); } }
private async void cboGamePlay_SelectedIndexChanged(object sender, EventArgs e) { using (await CursorWait.NewAsync(this)) { await this.DoThreadSafeAsync(x => x.SuspendLayout()); try { await ProcessGameplayIndexChanged(); } finally { await this.DoThreadSafeAsync(x => x.ResumeLayout()); } } }
private async void OnSelectedSettingChanged(object sender, PropertyChangedEventArgs e) { if (e.PropertyName == nameof(CharacterSettings.Books) || e.PropertyName == nameof(CharacterSettings.EnabledCustomDataDirectoryPaths)) { try { using (await CursorWait.NewAsync(this, token: _objGenericToken)) await LoadContent(_objGenericToken); } catch (OperationCanceledException) { //swallow this } } }
public async ValueTask ForceRepopulateCharacterSettings(CancellationToken token = default) { token.ThrowIfCancellationRequested(); using (await CursorWait.NewAsync(this, token: token)) { await this.DoThreadSafeAsync(x => x.SuspendLayout(), token); try { await PopulateCharacterSettings(token); } finally { await this.DoThreadSafeAsync(x => x.ResumeLayout(), token); } } }
private async void cmdEditCharacterSetting_Click(object sender, EventArgs e) { try { using (await CursorWait.NewAsync(this, token: _objGenericToken)) { using (ThreadSafeForm <EditCharacterSettings> frmOptions = await ThreadSafeForm <EditCharacterSettings> .GetAsync( () => new EditCharacterSettings(cboCharacterSetting.SelectedValue as CharacterSettings), _objGenericToken)) await frmOptions.ShowDialogSafeAsync(this, _objGenericToken); // Do not repopulate the character settings list because that will happen from frmCharacterSettings where appropriate } } catch (OperationCanceledException) { //swallow this } }
private static async void ObjSettingsFolderWatcherOnChanged(object sender, FileSystemEventArgs e) { using (await CursorWait.NewAsync()) { switch (e.ChangeType) { case WatcherChangeTypes.Created: AddSpecificCustomCharacterSetting(Path.GetFileName(e.FullPath)); break; case WatcherChangeTypes.Deleted: RemoveSpecificCustomCharacterSetting(Path.GetFileName(e.FullPath)); break; case WatcherChangeTypes.Changed: case WatcherChangeTypes.Renamed: ReloadSpecificCustomCharacterSetting(Path.GetFileName(e.FullPath)); break; } } }
private async void MasterIndex_Load(object sender, EventArgs e) { try { using (await CursorWait.NewAsync(this, token: _objGenericToken)) { await PopulateCharacterSettings(_objGenericToken); await LoadContent(_objGenericToken); _objSelectedSetting.PropertyChanged += OnSelectedSettingChanged; } } catch (OperationCanceledException) { //swallow this } finally { IsFinishedLoading = true; } }
private async ValueTask RefreshBaseLifestyle() { if (_blnIsSelectLifestyleRefreshing) { return; } if (await cboSelectLifestyle.DoThreadSafeFuncAsync(x => x.SelectedIndex) < 0) { return; } using (await CursorWait.NewAsync(this)) { _objLifestyle = ((ListItem)await cboSelectLifestyle.DoThreadSafeFuncAsync(x => x.SelectedItem)).Value as Lifestyle; string strDice = string.Format(GlobalSettings.CultureInfo, await LanguageManager.GetStringAsync("Label_LifestyleNuyen_ResultOf"), SelectedLifestyle?.Dice ?? 0); await lblDice.DoThreadSafeAsync(x => x.Text = strDice); await RefreshCalculation(); await cmdRoll.DoThreadSafeAsync(x => x.Enabled = SelectedLifestyle?.Dice > 0); } }
private async ValueTask RefreshCalculation() { using (await CursorWait.NewAsync(this)) { await nudDiceResult.DoThreadSafeAsync(x => { x.SuspendLayout(); try { x.MinimumAsInt = int.MinValue; // Temporarily set this to avoid crashing if we shift from something with more than 6 dice to something with less. x.MaximumAsInt = SelectedLifestyle?.Dice * 6 ?? 0; x.MinimumAsInt = SelectedLifestyle?.Dice ?? 0; } finally { x.ResumeLayout(); } }); await RefreshResultLabel(); } }
/// <summary> /// Loads the character /// </summary> /// <param name="fileName"></param> private async ValueTask LoadCharacter(string fileName) { if (File.Exists(fileName) && fileName.EndsWith(".chum5", StringComparison.OrdinalIgnoreCase)) { Character objCharacter = new Character { FileName = fileName }; using (await CursorWait.NewAsync(this)) { if (!await objCharacter.LoadAsync()) { // TODO edward setup error page await objCharacter.DisposeAsync(); return; // we obviously cannot init } await nudInit.DoThreadSafeAsync(x => x.Value = objCharacter.InitiativeDice); await txtName.DoThreadSafeAsync(x => x.Text = objCharacter.Name); if (int.TryParse( objCharacter.Initiative.SplitNoAlloc(' ', StringSplitOptions.RemoveEmptyEntries) .FirstOrDefault(), out int intTemp)) { await nudInitStart.DoThreadSafeAsync(x => x.Value = intTemp); } if (_character != null) { await _character.DisposeAsync(); _blnCharacterAdded = false; } _character = objCharacter; } } }
/// <summary> /// Update the internal XML of the Viewer window. /// </summary> private async Task RefreshCharacterXml(CancellationToken token = default) { token.ThrowIfCancellationRequested(); CursorWait objCursorWait = await CursorWait.NewAsync(this, true, token); try { await Task.WhenAll(this.DoThreadSafeAsync(() => { tsPrintPreview.Enabled = false; tsSaveAsHtml.Enabled = false; }, token), cmdPrint.DoThreadSafeAsync(x => x.Enabled = false, token), cmdSaveAsPdf.DoThreadSafeAsync(x => x.Enabled = false, token)); token.ThrowIfCancellationRequested(); Character[] aobjCharacters = await _lstCharacters.ToArrayAsync(); token.ThrowIfCancellationRequested(); _objCharacterXml = aobjCharacters.Length > 0 ? await CommonFunctions.GenerateCharactersExportXml(_objPrintCulture, _strPrintLanguage, _objRefresherCancellationTokenSource.Token, aobjCharacters) : null; token.ThrowIfCancellationRequested(); await this.DoThreadSafeAsync(() => tsSaveAsXml.Enabled = _objCharacterXml != null, token); token.ThrowIfCancellationRequested(); await RefreshSheet(token); } finally { await objCursorWait.DisposeAsync(); } }
private async void lstItems_SelectedIndexChanged(object sender, EventArgs e) { if (_blnSkipRefresh) { return; } try { using (await CursorWait.NewAsync(this, token: _objGenericToken)) { if (await lstItems.DoThreadSafeFuncAsync(x => x.SelectedValue, _objGenericToken) is MasterIndexEntry objEntry) { await Task.WhenAll( lblSourceLabel.DoThreadSafeAsync(x => x.Visible = true, _objGenericToken), lblSourceClickReminder.DoThreadSafeAsync(x => x.Visible = true, _objGenericToken), objEntry.DisplaySource.SetControlAsync(lblSource, _objGenericToken)); (bool blnSuccess, Task <string> tskNotes) = await _dicCachedNotes.TryGetValueAsync(objEntry, _objGenericToken); if (!blnSuccess) { if (!GlobalSettings.Language.Equals(GlobalSettings.DefaultLanguage, StringComparison.OrdinalIgnoreCase) && (objEntry.TranslatedNameOnPage != objEntry.EnglishNameOnPage || objEntry.Source.Page != objEntry.DisplaySource.Page)) { // don't check again it is not translated tskNotes = Task.Run(async() => { string strReturn = await CommonFunctions.GetTextFromPdfAsync( objEntry.Source.ToString(), objEntry.EnglishNameOnPage); if (string.IsNullOrEmpty(strReturn)) { strReturn = await CommonFunctions.GetTextFromPdfAsync( objEntry.DisplaySource.ToString(), objEntry.TranslatedNameOnPage); } return(strReturn); }, _objGenericToken); } else { tskNotes = Task.Run(() => CommonFunctions.GetTextFromPdfAsync( objEntry.Source.ToString(), objEntry.EnglishNameOnPage), _objGenericToken); } await _dicCachedNotes.TryAddAsync(objEntry, tskNotes, _objGenericToken); } string strNotes = await tskNotes; await txtNotes.DoThreadSafeAsync(x => { x.Text = strNotes; x.Visible = true; }, _objGenericToken); } else { await Task.WhenAll( lblSourceLabel.DoThreadSafeAsync(x => x.Visible = false, _objGenericToken), lblSourceClickReminder.DoThreadSafeAsync(x => x.Visible = false, _objGenericToken), SourceString.Blank.SetControlAsync(lblSource, _objGenericToken), txtNotes.DoThreadSafeAsync(x => x.Visible = false, _objGenericToken)); } } } catch (OperationCanceledException) { //swallow this } }
private async Task DoXsltUpdate(CancellationToken token = default) { token.ThrowIfCancellationRequested(); if (!_blnLoading) { if (_objCharacterXml != null) { _strXslt = await cboXSLT.DoThreadSafeFuncAsync(x => x.SelectedValue?.ToString(), token); if (!string.IsNullOrEmpty(_strXslt)) { CursorWait objCursorWait = await CursorWait.NewAsync(this, token : token); try { token.ThrowIfCancellationRequested(); string strText = await LanguageManager.GetStringAsync("String_Generating_Data"); await txtText.DoThreadSafeAsync(x => x.Text = strText, token); (bool blnSuccess, Tuple <string, string> strBoxText) = await _dicCache.TryGetValueAsync( new Tuple <string, string>(_strExportLanguage, _strXslt), token); token.ThrowIfCancellationRequested(); if (blnSuccess) { await txtText.DoThreadSafeAsync(x => x.Text = strBoxText.Item2, token); } else { CancellationTokenSource objNewSource = new CancellationTokenSource(); CancellationTokenSource objTemp = Interlocked.Exchange(ref _objXmlGeneratorCancellationTokenSource, objNewSource); if (objTemp?.IsCancellationRequested == false) { objTemp.Cancel(false); objTemp.Dispose(); } try { token.ThrowIfCancellationRequested(); } catch (OperationCanceledException) { Interlocked.CompareExchange(ref _objXmlGeneratorCancellationTokenSource, null, objNewSource); objNewSource.Dispose(); throw; } try { if (_tskXmlGenerator?.IsCompleted == false) { await _tskXmlGenerator; } } catch (OperationCanceledException) { // Swallow this } CancellationToken objToken = objNewSource.Token; _tskXmlGenerator = _strXslt == "JSON" ? Task.Run(() => GenerateJson(objToken), objToken) : Task.Run(() => GenerateXml(objToken), objToken); } } finally { await objCursorWait.DisposeAsync(); } } } else { token.ThrowIfCancellationRequested(); CancellationTokenSource objNewSource = new CancellationTokenSource(); CancellationTokenSource objTemp = Interlocked.Exchange(ref _objCharacterXmlGeneratorCancellationTokenSource, objNewSource); if (objTemp?.IsCancellationRequested == false) { objTemp.Cancel(false); objTemp.Dispose(); } try { token.ThrowIfCancellationRequested(); } catch (OperationCanceledException) { Interlocked.CompareExchange(ref _objCharacterXmlGeneratorCancellationTokenSource, null, objNewSource); objNewSource.Dispose(); throw; } try { if (_tskCharacterXmlGenerator?.IsCompleted == false) { await _tskCharacterXmlGenerator; } } catch (OperationCanceledException) { // Swallow this } CancellationToken objToken = objNewSource.Token; _tskCharacterXmlGenerator = Task.Run(() => GenerateCharacterXml(objToken), objToken); } } }
/// <summary> /// Create a Critter, put them into Career Mode, link them, and open the newly-created Critter. /// </summary> /// <param name="strCritterName">Name of the Critter's Metatype.</param> /// <param name="intForce">Critter's Force.</param> private async ValueTask CreateCritter(string strCritterName, int intForce) { // Code from frmMetatype. XmlDocument objXmlDocument = await _objSpirit.CharacterObject.LoadDataAsync("critters.xml"); XmlNode objXmlMetatype = objXmlDocument.SelectSingleNode("/chummer/metatypes/metatype[name = " + strCritterName.CleanXPath() + ']'); // If the Critter could not be found, show an error and get out of here. if (objXmlMetatype == null) { Program.ShowMessageBox(string.Format(GlobalSettings.CultureInfo, await LanguageManager.GetStringAsync("Message_UnknownCritterType"), strCritterName), await LanguageManager.GetStringAsync("MessageTitle_SelectCritterType"), MessageBoxButtons.OK, MessageBoxIcon.Error); return; } using (await CursorWait.NewAsync(ParentForm)) { // The Critter should use the same settings file as the character. Character objCharacter = new Character { SettingsKey = _objSpirit.CharacterObject.SettingsKey, // Override the defaults for the setting. IgnoreRules = true, IsCritter = true, Alias = strCritterName, Created = true }; try { string strCritterCharacterName = await txtCritterName.DoThreadSafeFuncAsync(x => x.Text); if (!string.IsNullOrEmpty(strCritterCharacterName)) { objCharacter.Name = strCritterCharacterName; } string strSpace = await LanguageManager.GetStringAsync("String_Space"); using (SaveFileDialog saveFileDialog = new SaveFileDialog { Filter = await LanguageManager.GetStringAsync("DialogFilter_Chum5") + '|' + await LanguageManager.GetStringAsync("DialogFilter_All"), FileName = strCritterName + strSpace + '(' + await LanguageManager.GetStringAsync(_objSpirit.RatingLabel) + strSpace + _objSpirit.Force.ToString(GlobalSettings.InvariantCultureInfo) + ").chum5" }) { if (saveFileDialog.ShowDialog(this) != DialogResult.OK) { return; } string strFileName = saveFileDialog.FileName; objCharacter.FileName = strFileName; } objCharacter.Create(objXmlMetatype["category"]?.InnerText, objXmlMetatype["id"]?.InnerText, string.Empty, objXmlMetatype, intForce); objCharacter.MetatypeBP = 0; using (LoadingBar frmLoadingBar = await Program.CreateAndShowProgressBarAsync()) { await frmLoadingBar.PerformStepAsync(objCharacter.CharacterName, LoadingBar.ProgressBarTextPatterns.Saving); if (!await objCharacter.SaveAsync()) { return; } } // Link the newly-created Critter to the Spirit. string strText = await LanguageManager.GetStringAsync( _objSpirit.EntityType == SpiritType.Spirit? "Tip_Spirit_OpenFile" : "Tip_Sprite_OpenFile"); await cmdLink.SetToolTipTextAsync(strText); ContactDetailChanged?.Invoke(this, EventArgs.Empty); await Program.OpenCharacter(objCharacter); } finally { await objCharacter .DisposeAsync(); // Fine here because Dispose()/DisposeAsync() code is skipped if the character is open in a form } } }
private async Task GenerateXml(CancellationToken token = default) { token.ThrowIfCancellationRequested(); CursorWait objCursorWait = await CursorWait.NewAsync(this, token : token); try { await cmdExport.DoThreadSafeAsync(x => x.Enabled = false, token); await cmdExportClose.DoThreadSafeAsync(x => x.Enabled = false, token); try { token.ThrowIfCancellationRequested(); string exportSheetPath = Path.Combine(Utils.GetStartupPath, "export", _strXslt + ".xsl"); XslCompiledTransform objXslTransform; try { objXslTransform = await XslManager .GetTransformForFileAsync(exportSheetPath); // Use the path for the export sheet. } catch (ArgumentException) { token.ThrowIfCancellationRequested(); string strReturn = "Last write time could not be fetched when attempting to load " + _strXslt + Environment.NewLine; Log.Debug(strReturn); await SetTextToWorkerResult(strReturn, token); return; } catch (PathTooLongException) { token.ThrowIfCancellationRequested(); string strReturn = "Last write time could not be fetched when attempting to load " + _strXslt + Environment.NewLine; Log.Debug(strReturn); await SetTextToWorkerResult(strReturn, token); return; } catch (UnauthorizedAccessException) { token.ThrowIfCancellationRequested(); string strReturn = "Last write time could not be fetched when attempting to load " + _strXslt + Environment.NewLine; Log.Debug(strReturn); await SetTextToWorkerResult(strReturn, token); return; } catch (XsltException ex) { token.ThrowIfCancellationRequested(); string strReturn = "Error attempting to load " + _strXslt + Environment.NewLine; Log.Debug(strReturn); Log.Error("ERROR Message = " + ex.Message); strReturn += ex.Message; await SetTextToWorkerResult(strReturn, token); return; } token.ThrowIfCancellationRequested(); XmlWriterSettings objSettings = objXslTransform.OutputSettings?.Clone(); if (objSettings != null) { objSettings.CheckCharacters = false; objSettings.ConformanceLevel = ConformanceLevel.Fragment; } string strText; using (MemoryStream objStream = new MemoryStream()) { using (XmlWriter objWriter = objSettings != null ? XmlWriter.Create(objStream, objSettings) : Utils.GetXslTransformXmlWriter(objStream)) { token.ThrowIfCancellationRequested(); await Task.Run(() => objXslTransform.Transform(_objCharacterXml, objWriter), token); } token.ThrowIfCancellationRequested(); objStream.Position = 0; // Read in the resulting code and pass it to the browser. using (StreamReader objReader = new StreamReader(objStream, Encoding.UTF8, true)) strText = await objReader.ReadToEndAsync(); } token.ThrowIfCancellationRequested(); await SetTextToWorkerResult(strText, token); } finally { await cmdExport.DoThreadSafeAsync(x => x.Enabled = true, token); await cmdExportClose.DoThreadSafeAsync(x => x.Enabled = true, token); } } finally { await objCursorWait.DisposeAsync(); } }
private async Task DoImport(CancellationToken token = default) { TreeNode objSelectedNode = await treCharacterList.DoThreadSafeFuncAsync(x => x.SelectedNode, token); if (objSelectedNode == null || objSelectedNode.Level <= 0) { return; } int intIndex = Convert.ToInt32(objSelectedNode.Tag, GlobalSettings.InvariantCultureInfo); if (intIndex < 0 || intIndex >= _lstCharacterCache.Count) { return; } HeroLabCharacterCache objCache = _lstCharacterCache[intIndex]; if (objCache == null) { return; } string strFile = objCache.FilePath; string strCharacterId = objCache.CharacterId; if (string.IsNullOrEmpty(strFile) || string.IsNullOrEmpty(strCharacterId)) { return; } using (await CursorWait.NewAsync(this, token: token)) { bool blnLoaded = false; Character objCharacter = new Character(); try { await Program.OpenCharacters.AddAsync(objCharacter); CharacterSettings objHeroLabSettings = SettingsManager.LoadedCharacterSettings.Values.FirstOrDefault( x => x.Name == objCache.SettingsName && x.BuildMethod == objCache.BuildMethod); if (objHeroLabSettings != null) { objCharacter.SettingsKey = objHeroLabSettings.DictionaryKey; } else { objHeroLabSettings = SettingsManager.LoadedCharacterSettings.Values.FirstOrDefault( x => x.Name.Contains(objCache.SettingsName) && x.BuildMethod == objCache.BuildMethod); if (objHeroLabSettings != null) { objCharacter.SettingsKey = objHeroLabSettings.DictionaryKey; } else { (bool blnSuccess, CharacterSettings objDefaultCharacterSettings) = await SettingsManager.LoadedCharacterSettings.TryGetValueAsync( GlobalSettings.DefaultCharacterSetting, token); if (blnSuccess && objCache.BuildMethod.UsesPriorityTables() == objDefaultCharacterSettings.BuildMethod.UsesPriorityTables()) { objCharacter.SettingsKey = objDefaultCharacterSettings.DictionaryKey; } else { objCharacter.SettingsKey = SettingsManager.LoadedCharacterSettings.Values .FirstOrDefault( x => x.BuiltInOption && x.BuildMethod == objCache.BuildMethod) ?.DictionaryKey ?? SettingsManager.LoadedCharacterSettings.Values .FirstOrDefault( x => x.BuiltInOption && x.BuildMethod.UsesPriorityTables() == objCache.BuildMethod .UsesPriorityTables()) ?.DictionaryKey ?? GlobalSettings.DefaultCharacterSetting; } } } using (ThreadSafeForm <SelectBuildMethod> frmPickBP = await ThreadSafeForm <SelectBuildMethod> .GetAsync(() => new SelectBuildMethod(objCharacter, true), token)) { if (await frmPickBP.ShowDialogSafeAsync(this, token) != DialogResult.OK) { return; } } //Timekeeper.Start("load_file"); if (!await objCharacter.LoadFromHeroLabFileAsync(strFile, strCharacterId, objCharacter.SettingsKey)) { return; } blnLoaded = true; //Timekeeper.Finish("load_file"); await Program.OpenCharacter(objCharacter, token : token); } finally { await cmdImport.DoThreadSafeAsync(x => x.Enabled = true, token); await cmdSelectFile.DoThreadSafeAsync(x => x.Enabled = true, token); if (!blnLoaded) { await Program.OpenCharacters.RemoveAsync(objCharacter); } } } await this.DoThreadSafeAsync(x => x.Close(), token); }
private async void SelectBuildMethod_Load(object sender, EventArgs e) { using (await CursorWait.NewAsync(this)) { await this.DoThreadSafeAsync(x => x.SuspendLayout()); try { // Populate the Character Settings list. using (new FetchSafelyFromPool <List <ListItem> >(Utils.ListItemListPool, out List <ListItem> lstCharacterSettings)) { foreach (CharacterSettings objLoopSetting in SettingsManager.LoadedCharacterSettings.Values) { lstCharacterSettings.Add(new ListItem(objLoopSetting, objLoopSetting.DisplayName)); } lstCharacterSettings.Sort(CompareListItems.CompareNames); await cboCharacterSetting.PopulateWithListItemsAsync(lstCharacterSettings); if (_blnForExistingCharacter) { (bool blnSuccess, CharacterSettings objSetting) = await SettingsManager.LoadedCharacterSettings.TryGetValueAsync( _objCharacter.SettingsKey); if (blnSuccess) { await cboCharacterSetting.DoThreadSafeAsync(x => x.SelectedValue = objSetting); } if (await cboCharacterSetting.DoThreadSafeFuncAsync(x => x.SelectedIndex) == -1) { CharacterSettings objSetting2; (blnSuccess, objSetting2) = await SettingsManager.LoadedCharacterSettings.TryGetValueAsync( GlobalSettings.DefaultCharacterSetting); if (blnSuccess) { await cboCharacterSetting.DoThreadSafeAsync(x => x.SelectedValue = objSetting2); } } await chkIgnoreRules.DoThreadSafeAsync(x => x.Checked = _objCharacter.IgnoreRules); } else { (bool blnSuccess, CharacterSettings objSetting) = await SettingsManager.LoadedCharacterSettings.TryGetValueAsync( GlobalSettings.DefaultCharacterSetting); if (blnSuccess) { await cboCharacterSetting.DoThreadSafeAsync(x => x.SelectedValue = objSetting); } } if (await cboCharacterSetting.DoThreadSafeFuncAsync(x => x.SelectedIndex) == -1 && lstCharacterSettings.Count > 0) { await cboCharacterSetting.DoThreadSafeAsync(x => x.SelectedIndex = 0); } } await chkIgnoreRules.SetToolTipAsync(await LanguageManager.GetStringAsync("Tip_SelectKarma_IgnoreRules")); await ProcessGameplayIndexChanged(); } finally { await this.DoThreadSafeAsync(x => x.ResumeLayout()); } } }
private async void cmdSaveAsPdf_Click(object sender, EventArgs e) { try { CursorWait objCursorWait = await CursorWait.NewAsync(this, token : _objGenericToken); try { try { // Check to see if we have any "Print to PDF" printers, as they will be a lot more reliable than wkhtmltopdf string strPdfPrinter = string.Empty; foreach (string strPrinter in PrinterSettings.InstalledPrinters) { if (strPrinter == "Microsoft Print to PDF" || strPrinter == "Foxit Reader PDF Printer" || strPrinter == "Adobe PDF") { strPdfPrinter = strPrinter; break; } } if (!string.IsNullOrEmpty(strPdfPrinter)) { DialogResult ePdfPrinterDialogResult = Program.ShowMessageBox(this, string.Format(GlobalSettings.CultureInfo, await LanguageManager.GetStringAsync("Message_Viewer_FoundPDFPrinter"), strPdfPrinter), await LanguageManager.GetStringAsync("MessageTitle_Viewer_FoundPDFPrinter"), MessageBoxButtons.YesNoCancel, MessageBoxIcon.Information); switch (ePdfPrinterDialogResult) { case DialogResult.Cancel: case DialogResult.Yes when await DoPdfPrinterShortcut(strPdfPrinter): return; case DialogResult.Yes: Program.ShowMessageBox(this, await LanguageManager.GetStringAsync( "Message_Viewer_PDFPrinterError")); break; } } } // This exception type is returned if PrinterSettings.InstalledPrinters fails catch (Win32Exception) { //swallow this } // Save the generated output as PDF. SaveFileDialog1.Filter = await LanguageManager.GetStringAsync("DialogFilter_Pdf") + '|' + await LanguageManager.GetStringAsync("DialogFilter_All"); SaveFileDialog1.Title = await LanguageManager.GetStringAsync("Button_Viewer_SaveAsPdf"); SaveFileDialog1.ShowDialog(); string strSaveFile = SaveFileDialog1.FileName; if (string.IsNullOrEmpty(strSaveFile)) { return; } if (!strSaveFile.EndsWith(".pdf", StringComparison.OrdinalIgnoreCase)) { strSaveFile += ".pdf"; } if (!Directory.Exists(Path.GetDirectoryName(strSaveFile)) || !Utils.CanWriteToPath(strSaveFile)) { Program.ShowMessageBox(this, string.Format(GlobalSettings.CultureInfo, await LanguageManager.GetStringAsync( "Message_File_Cannot_Be_Accessed"), strSaveFile)); return; } if (!await Utils.SafeDeleteFileAsync(strSaveFile, true, token: _objGenericToken)) { Program.ShowMessageBox(this, string.Format(GlobalSettings.CultureInfo, await LanguageManager.GetStringAsync( "Message_File_Cannot_Be_Accessed"), strSaveFile)); return; } // No PDF printer found, let's use wkhtmltopdf try { PdfDocument objPdfDocument = new PdfDocument { Html = webViewer.DocumentText, ExtraParams = new Dictionary <string, string>(8) { { "encoding", "UTF-8" }, { "dpi", "300" }, { "margin-top", "13" }, { "margin-bottom", "19" }, { "margin-left", "13" }, { "margin-right", "13" }, { "image-quality", "100" }, { "print-media-type", string.Empty } } }; PdfConvertEnvironment objPdfConvertEnvironment = new PdfConvertEnvironment { WkHtmlToPdfPath = Path.Combine(Utils.GetStartupPath, "wkhtmltopdf.exe") }; PdfOutput objPdfOutput = new PdfOutput { OutputFilePath = strSaveFile }; await PdfConvert.ConvertHtmlToPdfAsync(objPdfDocument, objPdfConvertEnvironment, objPdfOutput); if (!string.IsNullOrWhiteSpace(GlobalSettings.PdfAppPath)) { Uri uriPath = new Uri(strSaveFile); string strParams = GlobalSettings.PdfParameters .Replace("{page}", "1") .Replace("{localpath}", uriPath.LocalPath) .Replace("{absolutepath}", uriPath.AbsolutePath); ProcessStartInfo objPdfProgramProcess = new ProcessStartInfo { FileName = GlobalSettings.PdfAppPath, Arguments = strParams, WindowStyle = ProcessWindowStyle.Hidden }; objPdfProgramProcess.Start(); } } catch (Exception ex) { Program.ShowMessageBox(this, ex.ToString()); } } finally { await objCursorWait.DisposeAsync(); } } catch (OperationCanceledException) { //swallow this } }
/// <summary> /// Run the generated XML file through the XSL transformation engine to create the file output. /// </summary> private async Task AsyncGenerateOutput(CancellationToken token = default) { token.ThrowIfCancellationRequested(); CursorWait objCursorWait = await CursorWait.NewAsync(this, token : token); try { await Task.WhenAll(this.DoThreadSafeAsync(() => { tsPrintPreview.Enabled = false; tsSaveAsHtml.Enabled = false; }, token), cmdPrint.DoThreadSafeAsync(x => x.Enabled = false, token), cmdSaveAsPdf.DoThreadSafeAsync(x => x.Enabled = false, token)); token.ThrowIfCancellationRequested(); await SetDocumentText(await LanguageManager.GetStringAsync("String_Generating_Sheet"), token); token.ThrowIfCancellationRequested(); string strXslPath = Path.Combine(Utils.GetStartupPath, "sheets", _strSelectedSheet + ".xsl"); if (!File.Exists(strXslPath)) { string strReturn = "File not found when attempting to load " + _strSelectedSheet + Environment.NewLine; Log.Debug(strReturn); Program.ShowMessageBox(this, strReturn); return; } token.ThrowIfCancellationRequested(); XslCompiledTransform objXslTransform; try { objXslTransform = await XslManager.GetTransformForFileAsync(strXslPath); } catch (ArgumentException) { token.ThrowIfCancellationRequested(); string strReturn = "Last write time could not be fetched when attempting to load " + _strSelectedSheet + Environment.NewLine; Log.Debug(strReturn); Program.ShowMessageBox(this, strReturn); return; } catch (PathTooLongException) { token.ThrowIfCancellationRequested(); string strReturn = "Last write time could not be fetched when attempting to load " + _strSelectedSheet + Environment.NewLine; Log.Debug(strReturn); Program.ShowMessageBox(this, strReturn); return; } catch (UnauthorizedAccessException) { token.ThrowIfCancellationRequested(); string strReturn = "Last write time could not be fetched when attempting to load " + _strSelectedSheet + Environment.NewLine; Log.Debug(strReturn); Program.ShowMessageBox(this, strReturn); return; } catch (XsltException ex) { token.ThrowIfCancellationRequested(); string strReturn = "Error attempting to load " + _strSelectedSheet + Environment.NewLine; Log.Debug(strReturn); Log.Error("ERROR Message = " + ex.Message); strReturn += ex.Message; Program.ShowMessageBox(this, strReturn); return; } token.ThrowIfCancellationRequested(); XmlWriterSettings objSettings = objXslTransform.OutputSettings?.Clone(); if (objSettings != null) { objSettings.CheckCharacters = false; objSettings.ConformanceLevel = ConformanceLevel.Fragment; } using (MemoryStream objStream = new MemoryStream()) { using (XmlWriter objWriter = objSettings != null ? XmlWriter.Create(objStream, objSettings) : Utils.GetXslTransformXmlWriter(objStream)) { token.ThrowIfCancellationRequested(); await Task.Run(() => objXslTransform.Transform(_objCharacterXml, objWriter), token); } token.ThrowIfCancellationRequested(); objStream.Position = 0; // This reads from a static file, outputs to an HTML file, then has the browser read from that file. For debugging purposes. //objXSLTransform.Transform("D:\\temp\\print.xml", "D:\\temp\\output.htm"); //webBrowser1.Navigate("D:\\temp\\output.htm"); if (GlobalSettings.PrintToFileFirst) { // The DocumentStream method fails when using Wine, so we'll instead dump everything out a temporary HTML file, have the WebBrowser load that, then delete the temporary file. // Delete any old versions of the file if (!await Utils.SafeDeleteFileAsync(_strTempSheetFilePath, true, token: token)) { return; } // Read in the resulting code and pass it to the browser. using (StreamReader objReader = new StreamReader(objStream, Encoding.UTF8, true)) { string strOutput = await objReader.ReadToEndAsync(); File.WriteAllText(_strTempSheetFilePath, strOutput); } token.ThrowIfCancellationRequested(); await this.DoThreadSafeAsync(x => x.UseWaitCursor = true, token); await webViewer.DoThreadSafeAsync( x => x.Url = new Uri("file:///" + _strTempSheetFilePath), token); token.ThrowIfCancellationRequested(); } else { token.ThrowIfCancellationRequested(); // Populate the browser using DocumentText (DocumentStream would cause issues due to stream disposal). using (StreamReader objReader = new StreamReader(objStream, Encoding.UTF8, true)) { string strOutput = await objReader.ReadToEndAsync(); token.ThrowIfCancellationRequested(); await this.DoThreadSafeAsync(() => UseWaitCursor = true, token); await webViewer.DoThreadSafeAsync(x => x.DocumentText = strOutput, token); token.ThrowIfCancellationRequested(); } } } } finally { await objCursorWait.DisposeAsync(); } }