using IBKRTrader.Core.Logging; namespace IBKRTrader.UI; /// /// Bindet eine an den und färbt die Zeilen /// nach Log-Level ein. /// /// Einfärbung und Wechsel auf den UI-Thread liegen bewusst hier und nicht mehr im /// : der Core trägt seit der Linux-Portierung keine UI-Abhängigkeit /// (weder WinForms noch System.Drawing). Der Dienst meldet nur noch Einträge. /// public sealed class LogPanelController : IDisposable { private static readonly Color ColorInfo = Color.FromArgb(150, 210, 150); private static readonly Color ColorWarn = Color.FromArgb(255, 190, 60); private static readonly Color ColorError = Color.FromArgb(255, 80, 80); private readonly RichTextBox _rtb; private readonly LoggingService _logger; public LogPanelController(RichTextBox rtb, LoggingService logger) { _rtb = rtb; _logger = logger; // Dunkles Theme fürs Log-Panel. _rtb.BackColor = Color.FromArgb(20, 20, 30); _rtb.ForeColor = Color.FromArgb(200, 200, 200); _rtb.Font = new Font("Consolas", 9f); _rtb.ReadOnly = true; _rtb.WordWrap = false; _logger.EntryWritten += OnEntryWritten; _rtb.Disposed += (_, _) => Dispose(); } public void Dispose() => _logger.EntryWritten -= OnEntryWritten; /// /// Wird aus beliebigen Worker-Threads gerufen – deshalb der Wechsel auf den UI-Thread. Ein /// Fehler hier darf den schreibenden Worker niemals mitreißen. /// private void OnEntryWritten(LogEntry e) { try { if (_rtb.IsDisposed) return; var color = e.Level switch { AppLogLevel.Warn => ColorWarn, AppLogLevel.Error => ColorError, _ => ColorInfo }; var text = LoggingService.Format(e) + Environment.NewLine; if (_rtb.InvokeRequired) _rtb.BeginInvoke(() => AppendColored(text, color)); else AppendColored(text, color); } catch { /* Fenster wird gerade geschlossen */ } } private void AppendColored(string text, Color color) { if (_rtb.IsDisposed) return; _rtb.SelectionStart = _rtb.TextLength; _rtb.SelectionLength = 0; _rtb.SelectionColor = color; _rtb.AppendText(text); _rtb.SelectionColor = _rtb.ForeColor; if (_rtb.TextLength > 0) _rtb.ScrollToCaret(); } public void Clear() => _rtb.Clear(); public void CopyAll() => Clipboard.SetText(_rtb.Text); }