using System.Collections.Generic; using System.Drawing.Printing; using System.Linq; using System.Threading.Tasks; using Microsoft.UI.Xaml.Controls; using Serilog; using Wino.Core.Domain.Enums; using Wino.Core.Domain.Models.Printing; namespace Wino.Mail.WinUI.Dialogs; /// /// Custom print dialog for configuring WebView2 print settings. /// public sealed partial class PrintDialog : ContentDialog { public WebView2PrintSettingsModel PrintSettings { get; set; } = new WebView2PrintSettingsModel(); public PrintDialog() { this.InitializeComponent(); } /// /// Initializes the dialog with existing print settings. /// /// The initial print settings to load. public PrintDialog(WebView2PrintSettingsModel printSettings = default!) { if (printSettings != null) PrintSettings = printSettings; this.InitializeComponent(); } private void PrintDialog_Loaded(object sender, Microsoft.UI.Xaml.RoutedEventArgs e) => LoadSettingsToUI(PrintSettings); private void OrientationRadio_SelectionChanged(object sender, SelectionChangedEventArgs e) { if (sender is RadioButtons radioButtons) { PrintSettings.Orientation = (PrintOrientation)radioButtons.SelectedIndex; } } private void PrinterComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e) { if (sender is ComboBox comboBox && comboBox.SelectedItem != null) { PrintSettings.PrinterName = comboBox.SelectedItem.ToString(); } } /// /// Sets the list of available printers for the dialog. /// /// List of available printer names. public void SetAvailablePrinters(IEnumerable printers) { var printerList = printers?.ToList() ?? new List(); if (this.FindName("PrinterComboBox") is ComboBox printerComboBox) { printerComboBox.ItemsSource = printerList; if (printerList.Any()) { // Set to first printer or to the one in settings var targetPrinter = !string.IsNullOrEmpty(PrintSettings.PrinterName) ? PrintSettings.PrinterName : printerList.First(); var index = printerList.IndexOf(targetPrinter); printerComboBox.SelectedIndex = index >= 0 ? index : 0; // Update the settings model with the selected printer PrintSettings.PrinterName = printerComboBox.SelectedItem?.ToString() ?? string.Empty; } } } /// /// Loads available printers asynchronously and sets them in the dialog. /// public async Task LoadAvailablePrintersAsync() { try { var printers = await Task.Run(() => { var printerList = new List(); // Get all installed printers using System.Drawing.Printing foreach (string printerName in PrinterSettings.InstalledPrinters) { printerList.Add(printerName); } return printerList.AsEnumerable(); }); SetAvailablePrinters(printers); } catch (System.Exception ex) { // Log the exception if logging is available Log.Error(ex, "Error getting available printers"); // Set empty list if printer discovery fails SetAvailablePrinters(Enumerable.Empty()); } } private void LoadSettingsToUI(WebView2PrintSettingsModel settings) { if (settings == null) return; // Only handle orientation manually since other properties are bound via x:Bind if (this.FindName("OrientationRadioButtons") is RadioButtons orientationRadio) { orientationRadio.SelectedIndex = (int)settings.Orientation; } } private void UpdateSettingsFromUI() { // Most properties are bound via x:Bind, only handle orientation manually if (this.FindName("OrientationRadioButtons") is RadioButtons orientationRadio) { PrintSettings.Orientation = (PrintOrientation)orientationRadio.SelectedIndex; } // Also update printer name from ComboBox since it uses ItemsSource binding if (this.FindName("PrinterComboBox") is ComboBox printerComboBox && printerComboBox.SelectedItem != null) { PrintSettings.PrinterName = printerComboBox.SelectedItem.ToString(); } } /// /// Validates the current print settings before closing the dialog. /// /// True if settings are valid, false otherwise. private bool ValidateSettings() { // Check if a printer is selected if (this.FindName("PrinterComboBox") is ComboBox printerComboBox && printerComboBox.SelectedItem == null) { return false; } // Copies validation is handled by the bound property with validation in the model if (PrintSettings.Copies <= 0) { return false; } return true; } private void ContentDialog_PrimaryButtonClick(ContentDialog sender, ContentDialogButtonClickEventArgs args) { // Update settings from UI before validation UpdateSettingsFromUI(); // Validate settings before closing if (!ValidateSettings()) { args.Cancel = true; } } private void ContentDialog_SecondaryButtonClick(ContentDialog sender, ContentDialogButtonClickEventArgs args) { // Cancel was clicked, no validation needed } }