Example #1
0
        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();
            }
        }
Example #2
0
        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"));
                }
            }
        }
Example #3
0
        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();
            }
        }
Example #4
0
        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;
                        });
                    }
                }
            }
        }
Example #5
0
        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();
            }
        }
Example #6
0
        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());
                }
            }
        }
Example #9
0
        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
            }
        }
Example #10
0
        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);
            }
        }
Example #11
0
        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));
            }
        }
Example #13
0
        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());
                }
            }
        }
Example #14
0
 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
         }
     }
 }
Example #15
0
        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);
                }
            }
        }
Example #16
0
 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
     }
 }
Example #17
0
        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;
                }
            }
        }
Example #18
0
        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();
     }
 }
Example #21
0
        /// <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();
            }
        }
Example #23
0
        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
            }
        }
Example #24
0
        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);
                }
            }
        }
Example #25
0
        /// <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
                }
            }
        }
Example #26
0
        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();
            }
        }
Example #27
0
        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);
        }
Example #28
0
        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();
            }
        }