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 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 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(); } }
/// <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(); } }
public static async Task <CursorWait> NewAsync(Control objControl = null, bool blnAppStarting = false, CancellationToken token = default) { CursorWait objReturn = new CursorWait(objControl, blnAppStarting); if (objReturn._objControl == null) { if (Interlocked.Increment(ref _intApplicationWaitCursors) == 1) { Application.UseWaitCursor = true; objReturn._blnDoUnsetCursorOnDispose = true; } return(objReturn); } Form frmControl = objReturn._objControl as Form; try { if (frmControl == null || await frmControl.DoThreadSafeFuncAsync(x => x.IsMdiChild, token)) { if (frmControl != null) { objReturn._frmControlTopParent = await frmControl.DoThreadSafeFuncAsync(x => x.MdiParent, token); } else if (objReturn._objControl is UserControl objUserControl) { objReturn._frmControlTopParent = await objUserControl.DoThreadSafeFuncAsync(x => x.ParentForm, token); } else if (objReturn._objControl != null) { for (Control objLoop = await objReturn._objControl.DoThreadSafeFuncAsync(x => x.Parent, token); objLoop != null; objLoop = await objLoop.DoThreadSafeFuncAsync(x => x.Parent, token)) { if (objLoop is Form objLoopForm) { objReturn._frmControlTopParent = objLoopForm; break; } } } } } catch (OperationCanceledException) { await objReturn.DisposeAsync(); throw; } if (objReturn._objControl != null) { if (objReturn._blnAppStartingCursor) { int intNewValue = s_DicCursorControls.AddOrUpdate(objReturn._objControl, 1, (x, y) => Interlocked.Increment(ref y)); try { await objReturn.SetControlCursorAsync(intNewValue < short.MaxValue?Cursors.AppStarting : Cursors.WaitCursor, token); } catch (OperationCanceledException) { await objReturn.DisposeAsync(); throw; } objReturn._blnDoUnsetCursorOnDispose = true; } else { s_DicCursorControls.AddOrUpdate(objReturn._objControl, short.MaxValue, (x, y) => Interlocked.Add(ref y, short.MaxValue)); try { await objReturn.SetControlCursorAsync(Cursors.WaitCursor, token); } catch (OperationCanceledException) { await objReturn.DisposeAsync(); throw; } objReturn._blnDoUnsetCursorOnDispose = true; } } return(objReturn); }
/// <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(); } }
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 } }
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 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); } } }