using PrintServiceTray.Models; using PrintServiceTray.Services; namespace PrintServiceTray.Forms; public partial class ConfigurationForm : Form { private readonly ConfigurationService _configService; private PrinterConfiguration _config; private string? _selectedDocType; private List _installedPrinters; // UI Controls private ListBox _docTypeListBox = null!; private Button _newDocTypeButton = null!; private Button _deleteDocTypeButton = null!; private Panel _pageConfigPanel = null!; private RadioButton _saveGlobalRadio = null!; private RadioButton _saveLocalRadio = null!; private Button _saveButton = null!; private Button _cancelButton = null!; private Button _addPageButton = null!; private Button _removePageButton = null!; private Label _configLabel = null!; private List _pageControls = new(); public ConfigurationForm() { _configService = new ConfigurationService(); _config = _configService.Load(); _installedPrinters = _configService.GetInstalledPrinters(); InitializeComponent(); LoadDocumentTypes(); } private void InitializeComponent() { Text = "LAAPC Printer Configuration"; Size = new Size(900, 600); StartPosition = FormStartPosition.CenterScreen; FormBorderStyle = FormBorderStyle.FixedDialog; MaximizeBox = false; // Left panel - Document Types var leftPanel = new Panel { Location = new Point(10, 10), Size = new Size(250, 540), BorderStyle = BorderStyle.FixedSingle }; var docTypeLabel = new Label { Text = "Document Types:", Location = new Point(10, 10), Size = new Size(230, 20), Font = new Font(Font, FontStyle.Bold) }; _docTypeListBox = new ListBox { Location = new Point(10, 35), Size = new Size(230, 430) }; _docTypeListBox.SelectedIndexChanged += DocTypeListBox_SelectedIndexChanged; _newDocTypeButton = new Button { Text = "New", Location = new Point(10, 475), Size = new Size(110, 30) }; _newDocTypeButton.Click += NewDocType_Click; _deleteDocTypeButton = new Button { Text = "Delete", Location = new Point(130, 475), Size = new Size(110, 30) }; _deleteDocTypeButton.Click += DeleteDocType_Click; leftPanel.Controls.AddRange(new Control[] { docTypeLabel, _docTypeListBox, _newDocTypeButton, _deleteDocTypeButton }); // Right panel - Page Configuration var rightPanel = new Panel { Location = new Point(270, 10), Size = new Size(610, 540), BorderStyle = BorderStyle.FixedSingle }; _configLabel = new Label { Text = "Configuration for: (Select a document type)", Location = new Point(10, 10), Size = new Size(590, 20), Font = new Font(Font, FontStyle.Bold) }; var pageConfigLabel = new Label { Text = "Page Configuration:", Location = new Point(10, 40), Size = new Size(590, 20) }; _pageConfigPanel = new Panel { Location = new Point(10, 65), Size = new Size(590, 350), AutoScroll = true, BorderStyle = BorderStyle.FixedSingle }; _addPageButton = new Button { Text = "+ Add Page", Location = new Point(10, 425), Size = new Size(120, 30) }; _addPageButton.Click += AddPage_Click; _removePageButton = new Button { Text = "- Remove Last", Location = new Point(140, 425), Size = new Size(120, 30) }; _removePageButton.Click += RemovePage_Click; // Save options var saveToLabel = new Label { Text = "Save to:", Location = new Point(10, 465), Size = new Size(60, 20) }; _saveGlobalRadio = new RadioButton { Text = "Global (All Users)", Location = new Point(80, 465), Size = new Size(150, 20) }; _saveLocalRadio = new RadioButton { Text = "Local (My Computer)", Location = new Point(240, 465), Size = new Size(170, 20), Checked = true }; _saveButton = new Button { Text = "Save", Location = new Point(430, 495), Size = new Size(80, 35) }; _saveButton.Click += Save_Click; _cancelButton = new Button { Text = "Cancel", Location = new Point(520, 495), Size = new Size(80, 35) }; _cancelButton.Click += (s, e) => Close(); rightPanel.Controls.AddRange(new Control[] { _configLabel, pageConfigLabel, _pageConfigPanel, _addPageButton, _removePageButton, saveToLabel, _saveGlobalRadio, _saveLocalRadio, _saveButton, _cancelButton }); Controls.AddRange(new Control[] { leftPanel, rightPanel }); } private void LoadDocumentTypes() { _docTypeListBox.Items.Clear(); foreach (var docType in _config.DocumentTypes.Keys.OrderBy(k => k)) { _docTypeListBox.Items.Add(docType); } } private void DocTypeListBox_SelectedIndexChanged(object? sender, EventArgs e) { if (_docTypeListBox.SelectedItem is string docType) { _selectedDocType = docType; LoadPageConfiguration(docType); } } private void LoadPageConfiguration(string docType) { _configLabel.Text = $"Configuration for: {docType}"; _pageConfigPanel.Controls.Clear(); _pageControls.Clear(); if (!_config.DocumentTypes.TryGetValue(docType, out var config)) { config = new DocumentTypeConfig { Name = docType }; _config.DocumentTypes[docType] = config; } int yPos = 10; foreach (var page in config.Pages.OrderBy(p => p.PageNumber)) { var pageControl = new PageConfigControl(page.PageNumber, _installedPrinters, _configService); pageControl.Location = new Point(10, yPos); pageControl.LoadPage(page); _pageConfigPanel.Controls.Add(pageControl); _pageControls.Add(pageControl); yPos += pageControl.Height + 10; } if (config.Pages.Count == 0) { // Add first page by default AddPage_Click(null, EventArgs.Empty); } } private void AddPage_Click(object? sender, EventArgs e) { if (_selectedDocType == null) return; var config = _config.DocumentTypes[_selectedDocType]; int nextPageNum = config.Pages.Count > 0 ? config.Pages.Max(p => p.PageNumber) + 1 : 1; var newPage = new PageConfig { PageNumber = nextPageNum, PrinterName = _installedPrinters.FirstOrDefault() ?? "", TrayNumber = 1 }; config.Pages.Add(newPage); LoadPageConfiguration(_selectedDocType); } private void RemovePage_Click(object? sender, EventArgs e) { if (_selectedDocType == null) return; var config = _config.DocumentTypes[_selectedDocType]; if (config.Pages.Count > 0) { var lastPage = config.Pages.OrderByDescending(p => p.PageNumber).First(); config.Pages.Remove(lastPage); LoadPageConfiguration(_selectedDocType); } } private void NewDocType_Click(object? sender, EventArgs e) { var dialog = new TextInputDialog("New Document Type", "Enter document type name:"); if (dialog.ShowDialog() == DialogResult.OK && !string.IsNullOrWhiteSpace(dialog.InputText)) { var docType = dialog.InputText.Trim(); if (!_config.DocumentTypes.ContainsKey(docType)) { _config.DocumentTypes[docType] = new DocumentTypeConfig { Name = docType }; LoadDocumentTypes(); _docTypeListBox.SelectedItem = docType; } else { MessageBox.Show($"Document type '{docType}' already exists.", "Duplicate", MessageBoxButtons.OK, MessageBoxIcon.Warning); } } } private void DeleteDocType_Click(object? sender, EventArgs e) { if (_selectedDocType == null) return; var result = MessageBox.Show( $"Are you sure you want to delete '{_selectedDocType}'?", "Confirm Delete", MessageBoxButtons.YesNo, MessageBoxIcon.Question); if (result == DialogResult.Yes) { _config.DocumentTypes.Remove(_selectedDocType); _selectedDocType = null; LoadDocumentTypes(); _pageConfigPanel.Controls.Clear(); _configLabel.Text = "Configuration for: (Select a document type)"; } } private void Save_Click(object? sender, EventArgs e) { try { // Save current page configurations if (_selectedDocType != null && _config.DocumentTypes.TryGetValue(_selectedDocType, out var config)) { config.Pages.Clear(); foreach (var pageControl in _pageControls) { config.Pages.Add(pageControl.GetPageConfig()); } } bool saveGlobal = _saveGlobalRadio.Checked; _configService.Save(_config, saveGlobal); MessageBox.Show( $"Configuration saved to {(saveGlobal ? "global" : "local")} file successfully!", "Success", MessageBoxButtons.OK, MessageBoxIcon.Information); DialogResult = DialogResult.OK; Close(); } catch (Exception ex) { MessageBox.Show( $"Failed to save configuration: {ex.Message}", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } } } // Custom control for each page configuration public class PageConfigControl : UserControl { private readonly int _pageNumber; private readonly List _printers; private readonly ConfigurationService _configService; private ComboBox _printerCombo = null!; private ComboBox _trayCombo = null!; public PageConfigControl(int pageNumber, List printers, ConfigurationService configService) { _pageNumber = pageNumber; _printers = printers; _configService = configService; InitializeComponent(); } private void InitializeComponent() { Size = new Size(560, 60); BorderStyle = BorderStyle.FixedSingle; var pageLabel = new Label { Text = $"Page {_pageNumber}:", Location = new Point(10, 10), Size = new Size(70, 20), Font = new Font(Font, FontStyle.Bold) }; var printerLabel = new Label { Text = "Printer:", Location = new Point(10, 32), Size = new Size(60, 20) }; _printerCombo = new ComboBox { Location = new Point(75, 30), Size = new Size(250, 25), DropDownStyle = ComboBoxStyle.DropDownList }; _printerCombo.Items.AddRange(_printers.ToArray()); _printerCombo.SelectedIndexChanged += PrinterCombo_SelectedIndexChanged; var trayLabel = new Label { Text = "Tray:", Location = new Point(340, 32), Size = new Size(40, 20) }; _trayCombo = new ComboBox { Location = new Point(385, 30), Size = new Size(165, 25), DropDownStyle = ComboBoxStyle.DropDownList }; Controls.AddRange(new Control[] { pageLabel, printerLabel, _printerCombo, trayLabel, _trayCombo }); } public void LoadPage(PageConfig page) { _printerCombo.SelectedItem = page.PrinterName; LoadTrays(page.PrinterName); // Try to find and select the tray for (int i = 0; i < _trayCombo.Items.Count; i++) { if (_trayCombo.Items[i] is TrayItem item && item.TrayNumber == page.TrayNumber) { _trayCombo.SelectedIndex = i; break; } } } private void PrinterCombo_SelectedIndexChanged(object? sender, EventArgs e) { if (_printerCombo.SelectedItem is string printer) { LoadTrays(printer); } } private void LoadTrays(string printerName) { _trayCombo.Items.Clear(); var trays = _configService.GetPrinterTrays(printerName); foreach (var (number, name) in trays) { _trayCombo.Items.Add(new TrayItem { TrayNumber = number, TrayName = name }); } if (_trayCombo.Items.Count > 0) { _trayCombo.SelectedIndex = 0; } } public PageConfig GetPageConfig() { var selectedTray = _trayCombo.SelectedItem as TrayItem; return new PageConfig { PageNumber = _pageNumber, PrinterName = _printerCombo.SelectedItem?.ToString() ?? "", TrayNumber = selectedTray?.TrayNumber ?? 1, TrayLabel = selectedTray?.TrayName }; } private class TrayItem { public int TrayNumber { get; set; } public string TrayName { get; set; } = ""; public override string ToString() => $"Tray {TrayNumber} - {TrayName}"; } } // Simple text input dialog public class TextInputDialog : Form { private TextBox _textBox = null!; public string InputText => _textBox.Text; public TextInputDialog(string title, string prompt) { Text = title; Size = new Size(400, 150); StartPosition = FormStartPosition.CenterParent; FormBorderStyle = FormBorderStyle.FixedDialog; MaximizeBox = false; MinimizeBox = false; var promptLabel = new Label { Text = prompt, Location = new Point(20, 20), Size = new Size(360, 20) }; _textBox = new TextBox { Location = new Point(20, 50), Size = new Size(360, 25) }; var okButton = new Button { Text = "OK", DialogResult = DialogResult.OK, Location = new Point(220, 85), Size = new Size(75, 30) }; var cancelButton = new Button { Text = "Cancel", DialogResult = DialogResult.Cancel, Location = new Point(305, 85), Size = new Size(75, 30) }; AcceptButton = okButton; CancelButton = cancelButton; Controls.AddRange(new Control[] { promptLabel, _textBox, okButton, cancelButton }); } }