diff --git a/src/Directory.Packages.props b/src/Directory.Packages.props index 918e0294..1fb4dceb 100644 --- a/src/Directory.Packages.props +++ b/src/Directory.Packages.props @@ -12,6 +12,7 @@ + diff --git a/src/LogExpert.Audio/AudioPlayer.cs b/src/LogExpert.Audio/AudioPlayer.cs new file mode 100644 index 00000000..9902e1c5 --- /dev/null +++ b/src/LogExpert.Audio/AudioPlayer.cs @@ -0,0 +1,155 @@ +using System.Media; +using System.Runtime.InteropServices; +using System.Runtime.Versioning; + +using NAudio; +using NAudio.Wave; + +using NLog; + +namespace LogExpert.Audio; + +/// +/// Plays short audio cues (alerts) from arbitrary audio files supported by NAudio +/// (WAV, MP3, AIFF, ...). Falls back to the Windows default beep when the path is +/// empty or the file cannot be opened. +/// +/// All playback is fire-and-forget; callers never block. A single, process-wide +/// cooldown is maintained by so that bursts of trigger +/// hits cannot produce overlapping or rapid-fire sounds. The cooldown is global +/// across all callers. +/// +/// +[SupportedOSPlatform("windows")] +public static class AudioPlayer +{ + private static readonly Logger _logger = LogManager.GetCurrentClassLogger(); + + private static readonly object _gate = new(); + private static DateTime _lastPlayUtc = DateTime.MinValue; + private static int _activeCooldownSeconds; + + /// + /// Plays the given audio file fire-and-forget. When + /// is null, empty or whitespace, the Windows default beep is played instead. + /// When the file cannot be opened the failure is logged and the default beep + /// is played as a fallback so the user still gets feedback. + /// + /// Absolute path to an audio file readable by NAudio, + /// or /empty for the default system beep. + public static void Play (string? filePath) + { + if (string.IsNullOrWhiteSpace(filePath)) + { + PlaySystemBeep(); + return; + } + + if (!File.Exists(filePath)) + { + _logger.Warn("Audio alert file not found: {0}. Falling back to system beep.", filePath); + PlaySystemBeep(); + return; + } + + try + { + var reader = new AudioFileReader(filePath); + var output = new WaveOutEvent(); + output.PlaybackStopped += (_, _) => + { + try + { + output.Dispose(); + reader.Dispose(); + } + catch (Exception disposeEx) when (disposeEx is MmException or + IOException or + ObjectDisposedException or + InvalidOperationException or + NullReferenceException) + { + _logger.Debug(disposeEx, "Error disposing audio playback resources."); + } + }; + + output.Init(reader); + output.Play(); + } + catch (Exception ex) when (ex is MmException or + IOException or + UnauthorizedAccessException or + InvalidOperationException or + COMException or + FormatException) + { + _logger.Warn(ex, "Failed to play audio alert file '{0}'. Falling back to system beep.", filePath); + PlaySystemBeep(); + } + } + + /// + /// Plays the given audio file, applying a single process-wide cooldown. + /// Returns when the sound was actually played, or + /// when the call was suppressed because the cooldown + /// from a previous play is still active. + /// + /// Cooldown semantics (Option-1 "active cooldown wins"): the cooldown of the + /// most recently played alert gates every subsequent call until it expires, + /// regardless of the cooldown value passed in for the new attempt. + /// + /// + /// Audio file path, or null/empty for the system beep. + /// Minimum seconds before the next alert may + /// play after this one. Values <= 0 disable throttling for the next call. + /// if played, if suppressed. + public static bool PlayThrottled (string? filePath, int cooldownSeconds) + { + if (cooldownSeconds < 0) + { + cooldownSeconds = 0; + } + + lock (_gate) + { + var now = DateTime.UtcNow; + if (_activeCooldownSeconds > 0 && + (now - _lastPlayUtc).TotalSeconds < _activeCooldownSeconds) + { + return false; + } + + _lastPlayUtc = now; + _activeCooldownSeconds = cooldownSeconds; + } + + Play(filePath); + return true; + } + + private static void PlaySystemBeep () + { + try + { + SystemSounds.Beep.Play(); + } + catch (Exception ex) + { + _logger.Debug(ex, "Failed to play system beep."); + } + } + + /// + /// Test-only: resets the process-wide cooldown state so unit tests are + /// isolated from each other. Not intended for production use. + /// + [System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] + public static void ResetCooldownStateForTesting () + { + lock (_gate) + { + _lastPlayUtc = DateTime.MinValue; + _activeCooldownSeconds = 0; + } + } +} diff --git a/src/LogExpert.Audio/LogExpert.Audio.csproj b/src/LogExpert.Audio/LogExpert.Audio.csproj new file mode 100644 index 00000000..34a9c761 --- /dev/null +++ b/src/LogExpert.Audio/LogExpert.Audio.csproj @@ -0,0 +1,15 @@ + + + + net10.0-windows + LogExpert.Audio + LogExpert.Audio + true + + + + + + + + diff --git a/src/LogExpert.Core/Classes/Highlight/HighlightEntry.cs b/src/LogExpert.Core/Classes/Highlight/HighlightEntry.cs index b4f18867..976e772a 100644 --- a/src/LogExpert.Core/Classes/Highlight/HighlightEntry.cs +++ b/src/LogExpert.Core/Classes/Highlight/HighlightEntry.cs @@ -59,7 +59,7 @@ public Regex Regex ? RegexHelper.GetOrCreateCached(SearchText, IsCaseSensitive ? RegexOptions.None : RegexOptions.IgnoreCase) - : RegexHelper.GetOrCreateCached(System.Text.RegularExpressions.Regex.Escape(SearchText), + : RegexHelper.GetOrCreateCached(Regex.Escape(SearchText), IsCaseSensitive ? RegexOptions.None : RegexOptions.IgnoreCase); @@ -76,6 +76,25 @@ public Regex Regex public bool IsBold { get; set; } + /// + /// When true, a sound is played whenever a newly tailed line matches this + /// entry. The sound is throttled globally across all log windows; see + /// . + /// + public bool AlertOnHit { get; set; } + + /// + /// Absolute path to an audio file to play when fires. + /// When empty or null, the Windows default beep is played instead. + /// + public string SoundFilePath { get; set; } = string.Empty; + + /// + /// Minimum seconds between two alert plays (process-wide, across all + /// highlight entries and log windows). 0 disables throttling. + /// + public int CooldownSeconds { get; set; } = 2; + public bool NoBackground { get; set; } public object Clone () @@ -94,6 +113,9 @@ public object Clone () ActionEntry = ActionEntry != null ? (ActionEntry)ActionEntry.Clone() : null, IsWordMatch = IsWordMatch, IsBold = IsBold, + AlertOnHit = AlertOnHit, + SoundFilePath = SoundFilePath, + CooldownSeconds = CooldownSeconds, BookmarkComment = BookmarkComment, NoBackground = NoBackground, IsSearchHit = IsSearchHit diff --git a/src/LogExpert.Resources/Resources.Designer.cs b/src/LogExpert.Resources/Resources.Designer.cs index 074a9a5d..be43c9d7 100644 --- a/src/LogExpert.Resources/Resources.Designer.cs +++ b/src/LogExpert.Resources/Resources.Designer.cs @@ -820,6 +820,15 @@ public static string HighlightDialog_UI_Button_BookmarkComment { } } + /// + /// Looks up a localized string similar to Browse.... + /// + public static string HighlightDialog_UI_Button_BrowseSoundFile { + get { + return ResourceManager.GetString("HighlightDialog_UI_Button_BrowseSoundFile", resourceCulture); + } + } + /// /// Looks up a localized string similar to &Copy. /// @@ -892,6 +901,15 @@ public static string HighlightDialog_UI_Button_SelectPlugin { } } + /// + /// Looks up a localized string similar to Alert on hit. + /// + public static string HighlightDialog_UI_CheckBox_AlertOnHit { + get { + return ResourceManager.GetString("HighlightDialog_UI_CheckBox_AlertOnHit", resourceCulture); + } + } + /// /// Looks up a localized string similar to Bold. /// @@ -1064,6 +1082,15 @@ public static string HighlightDialog_UI_Label_BackgroundColor { } } + /// + /// Looks up a localized string similar to Cooldown:. + /// + public static string HighlightDialog_UI_Label_Cooldown { + get { + return ResourceManager.GetString("HighlightDialog_UI_Label_Cooldown", resourceCulture); + } + } + /// /// Looks up a localized string similar to Foreground color. /// @@ -1082,6 +1109,24 @@ public static string HighlightDialog_UI_Label_SearchString { } } + /// + /// Looks up a localized string similar to seconds. + /// + public static string HighlightDialog_UI_Label_Seconds { + get { + return ResourceManager.GetString("HighlightDialog_UI_Label_Seconds", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Sound file:. + /// + public static string HighlightDialog_UI_Label_SoundFile { + get { + return ResourceManager.GetString("HighlightDialog_UI_Label_SoundFile", resourceCulture); + } + } + /// /// Looks up a localized string similar to New group. /// @@ -1091,6 +1136,15 @@ public static string HighlightDialog_UI_NewGroup_BaseName { } } + /// + /// Looks up a localized string similar to Audio files (*.wav;*.mp3;*.wma;*.aiff;*.aif)|*.wav;*.mp3;*.wma;*.aiff;*.aif|All files (*.*)|*.*. + /// + public static string HighlightDialog_UI_OpenFileFilter_Audio { + get { + return ResourceManager.GetString("HighlightDialog_UI_OpenFileFilter_Audio", resourceCulture); + } + } + /// /// Looks up a localized string similar to Settings could not be imported: {0}. /// @@ -1136,6 +1190,60 @@ public static string HighlightDialog_UI_Title_ExportSettings { } } + /// + /// Looks up a localized string similar to (preview). + /// + public static string HighlightEntryEditDialog_UI_Preview_Placeholder { + get { + return ResourceManager.GetString("HighlightEntryEditDialog_UI_Preview_Placeholder", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Actions. + /// + public static string HighlightEntryEditDialog_UI_Tab_Actions { + get { + return ResourceManager.GetString("HighlightEntryEditDialog_UI_Tab_Actions", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Coloring. + /// + public static string HighlightEntryEditDialog_UI_Tab_Coloring { + get { + return ResourceManager.GetString("HighlightEntryEditDialog_UI_Tab_Coloring", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Line Match Criteria. + /// + public static string HighlightEntryEditDialog_UI_Tab_LineMatchCriteria { + get { + return ResourceManager.GetString("HighlightEntryEditDialog_UI_Tab_LineMatchCriteria", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Add Highlight. + /// + public static string HighlightEntryEditDialog_UI_Title_Add { + get { + return ResourceManager.GetString("HighlightEntryEditDialog_UI_Title_Add", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Edit Highlight — "{0}". + /// + public static string HighlightEntryEditDialog_UI_Title_EditFormat { + get { + return ResourceManager.GetString("HighlightEntryEditDialog_UI_Title_EditFormat", resourceCulture); + } + } + /// /// Looks up a localized string similar to Choose file.... /// @@ -1478,6 +1586,15 @@ public static string LogExpert_Common_UI_Button_Delete { } } + /// + /// Looks up a localized string similar to &Edit. + /// + public static string LogExpert_Common_UI_Button_Edit { + get { + return ResourceManager.GetString("LogExpert_Common_UI_Button_Edit", resourceCulture); + } + } + /// /// Looks up a localized string similar to Export.... /// diff --git a/src/LogExpert.Resources/Resources.de.resx b/src/LogExpert.Resources/Resources.de.resx index 25039580..71acdd17 100644 --- a/src/LogExpert.Resources/Resources.de.resx +++ b/src/LogExpert.Resources/Resources.de.resx @@ -2166,4 +2166,43 @@ LogExpert neu starten, um die Änderungen zu übernehmen? Scanne Lesezeichen beendet / abgebrochen! + + Alarm bei Treffer + + + Sounddatei: + + + Durchsuchen... + + + Abklingzeit: + + + Sekunden + + + Audiodateien (*.wav;*.mp3;*.wma;*.aiff;*.aif)|*.wav;*.mp3;*.wma;*.aiff;*.aif|Alle Dateien (*.*)|*.* + + + Highlight hinzufügen + + + Hervorhebung bearbeiten – „{0}“ + + + Kriterien für Linienübereinstimmung + + + Farben + + + Aktionen + + + &Bearbeiten + + + (Vorschau) + \ No newline at end of file diff --git a/src/LogExpert.Resources/Resources.resx b/src/LogExpert.Resources/Resources.resx index baae535d..156adced 100644 --- a/src/LogExpert.Resources/Resources.resx +++ b/src/LogExpert.Resources/Resources.resx @@ -1491,7 +1491,8 @@ Checked tools will appear in the icon bar. All other tools are available in the &Search for: - + @MutedRule(PunctuationTail) + &Case sensitive @@ -1535,9 +1536,30 @@ Checked tools will appear in the icon bar. All other tools are available in the Highlighting and action triggers + + Add Highlight + + + Edit Highlight — "{0}" + + + Line Match Criteria + + + Coloring + + + Actions + + + (preview) + &Add + + &Edit + &Delete @@ -1607,6 +1629,24 @@ Checked tools will appear in the icon bar. All other tools are available in the Plugin + + Alert on hit + + + Sound file: + + + Browse... + + + Cooldown: + + + seconds + + + Audio files (*.wav;*.mp3;*.wma;*.aiff;*.aif)|*.wav;*.mp3;*.wma;*.aiff;*.aif|All files (*.*)|*.* + Word mode @@ -1665,7 +1705,8 @@ Checked tools will appear in the icon bar. All other tools are available in the This feature is pre-beta and does not work :) Usage: Select a range in the log window and press "Recalc". This will search for text ranges similar to the selected one. - + @MutedRule(PunctuationTail) + Fuzzy @@ -1941,12 +1982,14 @@ Regex search/replace on current selected line &Add Plugin... + @MutedRule(PunctuationTail) &Remove &View Hash... + @MutedRule(PunctuationTail) Plugin Name @@ -2052,6 +2095,7 @@ Continue? Plugin &Trust Management... + @MutedRule(PunctuationTail) Invalid regex pattern: {0} diff --git a/src/LogExpert.Resources/Resources.zh-CN.resx b/src/LogExpert.Resources/Resources.zh-CN.resx index 2c106f32..56fc04a6 100644 --- a/src/LogExpert.Resources/Resources.zh-CN.resx +++ b/src/LogExpert.Resources/Resources.zh-CN.resx @@ -2083,4 +2083,43 @@ YY[YY] = 年 扫描书签已完成/取消! + + 命中警报 + + + 声音文件: + + + 浏览... + + + 冷却: + + + + + + 音频文件 (*.wav;*.mp3;*.wma;*.aiff;*.aif)|*.wav;*.mp3;*.wma;*.aiff;*.aif|所有文件 (*.*)|*.* + + + 添加亮点 + + + 编辑突出显示 —“{0}” + + + 线路匹配标准 + + + 着色 + + + 动作 + + + 编辑 + + + (预览) + \ No newline at end of file diff --git a/src/LogExpert.Tests/Audio/AudioPlayerTests.cs b/src/LogExpert.Tests/Audio/AudioPlayerTests.cs new file mode 100644 index 00000000..491929c0 --- /dev/null +++ b/src/LogExpert.Tests/Audio/AudioPlayerTests.cs @@ -0,0 +1,115 @@ +using System; +using System.IO; +using System.Threading; + +using LogExpert.Audio; + +using NUnit.Framework; + +namespace LogExpert.Tests.Audio; + +[TestFixture] +[Platform("Win")] +[NonParallelizable] // AudioPlayer uses process-wide static state +public class AudioPlayerTests +{ + [SetUp] + public void SetUp () + { + AudioPlayer.ResetCooldownStateForTesting(); + } + + [TearDown] + public void TearDown () + { + AudioPlayer.ResetCooldownStateForTesting(); + } + + [Test] + public void Play_NullPath_DoesNotThrow () + { + Assert.DoesNotThrow(() => AudioPlayer.Play(null)); + } + + [Test] + public void Play_EmptyPath_DoesNotThrow () + { + Assert.DoesNotThrow(() => AudioPlayer.Play(string.Empty)); + } + + [Test] + public void Play_WhitespacePath_DoesNotThrow () + { + Assert.DoesNotThrow(() => AudioPlayer.Play(" ")); + } + + [Test] + public void Play_NonExistentPath_FallsBackSilently () + { + var missing = Path.Combine(Path.GetTempPath(), $"definitely-missing-{Guid.NewGuid():N}.wav"); + Assert.DoesNotThrow(() => AudioPlayer.Play(missing)); + } + + [Test] + public void PlayThrottled_FirstCall_ReturnsTrue () + { + var played = AudioPlayer.PlayThrottled(null, cooldownSeconds: 10); + Assert.That(played, Is.True); + } + + [Test] + public void PlayThrottled_SecondCallWithinCooldown_ReturnsFalse () + { + Assume.That(AudioPlayer.PlayThrottled(null, cooldownSeconds: 30), Is.True); + + var second = AudioPlayer.PlayThrottled(null, cooldownSeconds: 30); + + Assert.That(second, Is.False, "Second call inside the active cooldown window must be suppressed."); + } + + [Test] + public void PlayThrottled_ZeroCooldown_AllowsImmediateNextCall () + { + Assume.That(AudioPlayer.PlayThrottled(null, cooldownSeconds: 0), Is.True); + + var second = AudioPlayer.PlayThrottled(null, cooldownSeconds: 0); + + Assert.That(second, Is.True, "A zero cooldown must not suppress the next call."); + } + + [Test] + public void PlayThrottled_NegativeCooldown_NormalizedToZero () + { + Assume.That(AudioPlayer.PlayThrottled(null, cooldownSeconds: -5), Is.True); + + var second = AudioPlayer.PlayThrottled(null, cooldownSeconds: -5); + + Assert.That(second, Is.True, "Negative cooldown must be treated as 0 and not suppress."); + } + + [Test] + public void PlayThrottled_ActiveCooldownWins_LongFirstGatesShortSecond () + { + // ADR 0001 decision 2: the cooldown of the most recently played alert + // gates every subsequent attempt, regardless of the new attempt's value. + Assume.That(AudioPlayer.PlayThrottled(null, cooldownSeconds: 60), Is.True); + + var shortAttempt = AudioPlayer.PlayThrottled(null, cooldownSeconds: 0); + + Assert.That(shortAttempt, Is.False, + "A short/zero cooldown must not bypass an already-active long cooldown."); + } + + [Test] + public void PlayThrottled_AfterCooldownExpires_PlaysAgain () + { + Assume.That(AudioPlayer.PlayThrottled(null, cooldownSeconds: 1), Is.True); + + // Wait slightly more than the cooldown window. + Thread.Sleep(1100); + + var second = AudioPlayer.PlayThrottled(null, cooldownSeconds: 1); + + Assert.That(second, Is.True, "After the cooldown window elapses the next call must play."); + } +} diff --git a/src/LogExpert.Tests/Highlight/HighlightEntryAlertTests.cs b/src/LogExpert.Tests/Highlight/HighlightEntryAlertTests.cs new file mode 100644 index 00000000..e5c9ed5c --- /dev/null +++ b/src/LogExpert.Tests/Highlight/HighlightEntryAlertTests.cs @@ -0,0 +1,59 @@ +using LogExpert.Core.Classes.Highlight; + +using NUnit.Framework; + +namespace LogExpert.Tests.Highlight; + +[TestFixture] +public class HighlightEntryAlertTests +{ + [Test] + public void Defaults_AlertOnHitIsFalse_CooldownIsTwo_SoundFileIsEmpty () + { + var entry = new HighlightEntry(); + + Assert.Multiple(() => + { + Assert.That(entry.AlertOnHit, Is.False); + Assert.That(entry.CooldownSeconds, Is.EqualTo(2)); + Assert.That(entry.SoundFilePath, Is.EqualTo(string.Empty)); + }); + } + + [Test] + public void Clone_CopiesAlertFields () + { + var entry = new HighlightEntry + { + SearchText = "ERROR", + AlertOnHit = true, + SoundFilePath = @"C:\sounds\alert.wav", + CooldownSeconds = 15, + }; + + var clone = (HighlightEntry)entry.Clone(); + + Assert.Multiple(() => + { + Assert.That(clone.AlertOnHit, Is.True); + Assert.That(clone.SoundFilePath, Is.EqualTo(@"C:\sounds\alert.wav")); + Assert.That(clone.CooldownSeconds, Is.EqualTo(15)); + Assert.That(clone, Is.Not.SameAs(entry)); + }); + } + + [Test] + public void Clone_DefaultsRoundTrip () + { + var entry = new HighlightEntry { SearchText = "x" }; + + var clone = (HighlightEntry)entry.Clone(); + + Assert.Multiple(() => + { + Assert.That(clone.AlertOnHit, Is.False); + Assert.That(clone.SoundFilePath, Is.EqualTo(string.Empty)); + Assert.That(clone.CooldownSeconds, Is.EqualTo(2)); + }); + } +} diff --git a/src/LogExpert.Tests/LogExpert.Tests.csproj b/src/LogExpert.Tests/LogExpert.Tests.csproj index d0c080df..f35a6ca8 100644 --- a/src/LogExpert.Tests/LogExpert.Tests.csproj +++ b/src/LogExpert.Tests/LogExpert.Tests.csproj @@ -21,6 +21,7 @@ + diff --git a/src/LogExpert.UI/Controls/ColorComboBox.cs b/src/LogExpert.UI/Controls/ColorComboBox.cs index af12e836..68d1a4f0 100644 --- a/src/LogExpert.UI/Controls/ColorComboBox.cs +++ b/src/LogExpert.UI/Controls/ColorComboBox.cs @@ -7,12 +7,6 @@ namespace LogExpert.UI.Controls; [SupportedOSPlatform("windows")] internal class ColorComboBox : ComboBox { - #region Fields - - private Color _customColor = Color.FromKnownColor(KnownColor.Black); - - #endregion - #region cTor public ColorComboBox () @@ -23,7 +17,7 @@ public ColorComboBox () { Items.AddRange( [ - _customColor, + CustomColor, Color.Black, Color.White, Color.Gray, @@ -53,14 +47,14 @@ public ColorComboBox () [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)] public Color CustomColor { - get => _customColor; + get; set { - _customColor = value; + field = value; Items.RemoveAt(0); - Items.Insert(0, _customColor); + Items.Insert(0, field); } - } + } = Color.FromKnownColor(KnownColor.Black); public Color SelectedColor => (Color)(SelectedIndex != -1 ? Items[SelectedIndex] : null); diff --git a/src/LogExpert.UI/Controls/LogWindow/LogWindow.cs b/src/LogExpert.UI/Controls/LogWindow/LogWindow.cs index 4b80fb49..eb838d32 100644 --- a/src/LogExpert.UI/Controls/LogWindow/LogWindow.cs +++ b/src/LogExpert.UI/Controls/LogWindow/LogWindow.cs @@ -8,6 +8,7 @@ using ColumnizerLib; using ColumnizerLib.Extensions; +using LogExpert.Audio; using LogExpert.Core.Callback; using LogExpert.Core.Classes; using LogExpert.Core.Classes.Bookmark; @@ -3166,6 +3167,7 @@ private void CheckFilterAndHighlight (LogEventArgs e) var matchingList = FindMatchingHighlightEntries(line); LaunchHighlightPlugins(matchingList, i); var (suppressLed, stopTail, setBookmark, bookmarkComment) = GetHighlightActions(matchingList); + TriggerAudioAlert(matchingList); if (setBookmark) { var capturedLineNum = i; @@ -3217,6 +3219,7 @@ private void CheckFilterAndHighlight (LogEventArgs e) var matchingList = FindMatchingHighlightEntries(line); LaunchHighlightPlugins(matchingList, i); var (suppressLed, stopTail, setBookmark, bookmarkComment) = GetHighlightActions(matchingList); + TriggerAudioAlert(matchingList); if (setBookmark) { var capturedLineNum = i; @@ -3782,6 +3785,27 @@ private static (bool NoLed, bool StopTail, bool SetBookmark, string BookmarkComm return (noLed, stopTail, setBookmark, bookmarkComment); } + /// + /// Fires an audio alert for the first matching highlight entry that has + /// enabled. Iteration stops after the + /// first such entry; the process-wide cooldown maintained by + /// would suppress subsequent plays anyway. + /// Called only from the tail trigger path. + /// + private static void TriggerAudioAlert (IList matchingList) + { + if (matchingList == null || matchingList.Count == 0) + { + return; + } + + foreach (var entry in matchingList.Where(entry => entry.AlertOnHit)) + { + _ = AudioPlayer.PlayThrottled(entry.SoundFilePath, entry.CooldownSeconds); + break; + } + } + private void StopTimespreadThread () { _timeSpreadCalc.Stop(); diff --git a/src/LogExpert.UI/Dialogs/Highlight/HighlightDialog.Designer.cs b/src/LogExpert.UI/Dialogs/Highlight/HighlightDialog.Designer.cs new file mode 100644 index 00000000..bc99f4a9 --- /dev/null +++ b/src/LogExpert.UI/Dialogs/Highlight/HighlightDialog.Designer.cs @@ -0,0 +1,373 @@ +using LogExpert.UI.Controls; + +namespace LogExpert.Dialogs; + +partial class HighlightDialog +{ + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose (bool disposing) + { + if (disposing && components != null) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent () + { + components = new System.ComponentModel.Container(); + var resources = new System.ComponentModel.ComponentResourceManager(typeof(HighlightDialog)); + listBoxHighlight = new ListBox(); + btnAdd = new Button(); + btnEdit = new Button(); + btnDelete = new Button(); + btnMoveUp = new Button(); + btnMoveDown = new Button(); + btnOk = new Button(); + btnCancel = new Button(); + helpProvider = new HelpProvider(); + btnExportGroup = new Button(); + btnImportGroup = new Button(); + btnMoveGroupDown = new Button(); + btnMoveGroupUp = new Button(); + labelAssignNamesToGroups = new Label(); + btnCopyGroup = new Button(); + btnDeleteGroup = new Button(); + btnNewGroup = new Button(); + comboBoxGroups = new ComboBox(); + toolTip = new ToolTip(components); + pnlBackground = new Panel(); + groupBoxGroups = new GroupBox(); + pnlBackground.SuspendLayout(); + groupBoxGroups.SuspendLayout(); + SuspendLayout(); + // + // listBoxHighlight + // + listBoxHighlight.Anchor = AnchorStyles.Top; + listBoxHighlight.DrawMode = DrawMode.OwnerDrawFixed; + listBoxHighlight.FormattingEnabled = true; + listBoxHighlight.Location = new Point(12, 145); + listBoxHighlight.Margin = new Padding(4, 5, 4, 5); + listBoxHighlight.Name = "listBoxHighlight"; + listBoxHighlight.Size = new Size(460, 212); + listBoxHighlight.TabIndex = 0; + listBoxHighlight.SelectedIndexChanged += OnListBoxHighlightSelectedIndexChanged; + listBoxHighlight.DoubleClick += OnBtnEditClick; + // + // btnAdd + // + btnAdd.Anchor = AnchorStyles.Top; + btnAdd.Location = new Point(478, 142); + btnAdd.Margin = new Padding(4, 5, 4, 5); + btnAdd.Name = "btnAdd"; + btnAdd.Size = new Size(85, 35); + btnAdd.TabIndex = 1; + btnAdd.Text = "&Add"; + toolTip.SetToolTip(btnAdd, "Create a new highlight item (opens the editor dialog)"); + btnAdd.UseVisualStyleBackColor = true; + btnAdd.Click += OnAddButtonClick; + // + // btnEdit + // + btnEdit.Anchor = AnchorStyles.Top; + btnEdit.Location = new Point(478, 187); + btnEdit.Margin = new Padding(4, 5, 4, 5); + btnEdit.Name = "btnEdit"; + btnEdit.Size = new Size(85, 35); + btnEdit.TabIndex = 2; + btnEdit.Text = "&Edit"; + toolTip.SetToolTip(btnEdit, "Edit the selected highlight in the editor dialog"); + btnEdit.UseVisualStyleBackColor = true; + btnEdit.Click += OnBtnEditClick; + // + // btnDelete + // + btnDelete.Anchor = AnchorStyles.Top; + btnDelete.Location = new Point(478, 232); + btnDelete.Margin = new Padding(4, 5, 4, 5); + btnDelete.Name = "btnDelete"; + btnDelete.Size = new Size(85, 35); + btnDelete.TabIndex = 3; + btnDelete.Text = "D&elete"; + toolTip.SetToolTip(btnDelete, "Delete the current highlight"); + btnDelete.UseVisualStyleBackColor = true; + btnDelete.Click += OnDeleteButtonClick; + // + // btnMoveUp + // + btnMoveUp.Anchor = AnchorStyles.Top; + btnMoveUp.Location = new Point(478, 277); + btnMoveUp.Margin = new Padding(4, 5, 4, 5); + btnMoveUp.Name = "btnMoveUp"; + btnMoveUp.Size = new Size(85, 35); + btnMoveUp.TabIndex = 4; + btnMoveUp.Text = "&Up"; + toolTip.SetToolTip(btnMoveUp, "Move the current highlight one position up"); + btnMoveUp.UseVisualStyleBackColor = true; + btnMoveUp.Click += OnBtnMoveUpClick; + // + // btnMoveDown + // + btnMoveDown.Anchor = AnchorStyles.Top; + btnMoveDown.Location = new Point(478, 319); + btnMoveDown.Margin = new Padding(4, 5, 4, 5); + btnMoveDown.Name = "btnMoveDown"; + btnMoveDown.Size = new Size(85, 35); + btnMoveDown.TabIndex = 5; + btnMoveDown.Text = "&Down"; + toolTip.SetToolTip(btnMoveDown, "Move the current highlight one position down"); + btnMoveDown.UseVisualStyleBackColor = true; + btnMoveDown.Click += OnBtnMoveDownClick; + // + // btnOk + // + btnOk.Anchor = AnchorStyles.Top; + btnOk.DialogResult = DialogResult.OK; + btnOk.Location = new Point(387, 364); + btnOk.Margin = new Padding(4, 5, 4, 5); + btnOk.Name = "btnOk"; + btnOk.Size = new Size(85, 35); + btnOk.TabIndex = 9; + btnOk.Text = "OK"; + btnOk.UseVisualStyleBackColor = true; + btnOk.Click += OnBtnOkClick; + // + // btnCancel + // + btnCancel.Anchor = AnchorStyles.Top; + btnCancel.DialogResult = DialogResult.Cancel; + btnCancel.Location = new Point(478, 364); + btnCancel.Margin = new Padding(4, 5, 4, 5); + btnCancel.Name = "btnCancel"; + btnCancel.Size = new Size(85, 35); + btnCancel.TabIndex = 10; + btnCancel.Text = "Cancel"; + btnCancel.UseVisualStyleBackColor = true; + // + // helpProvider + // + helpProvider.HelpNamespace = "LogExpert.chm"; + helpProvider.Tag = ""; + // + // btnExportGroup + // + btnExportGroup.Anchor = AnchorStyles.Top; + btnExportGroup.Location = new Point(108, 364); + btnExportGroup.Margin = new Padding(4, 5, 4, 5); + btnExportGroup.Name = "btnExportGroup"; + btnExportGroup.Size = new Size(85, 35); + btnExportGroup.TabIndex = 2; + btnExportGroup.Text = "Export"; + toolTip.SetToolTip(btnExportGroup, "Export highlight groups"); + btnExportGroup.UseVisualStyleBackColor = true; + btnExportGroup.Click += OnBtnExportGroupClick; + // + // btnImportGroup + // + btnImportGroup.Anchor = AnchorStyles.Top; + btnImportGroup.Location = new Point(12, 364); + btnImportGroup.Margin = new Padding(4, 5, 4, 5); + btnImportGroup.Name = "btnImportGroup"; + btnImportGroup.Size = new Size(85, 35); + btnImportGroup.TabIndex = 1; + btnImportGroup.Text = "Import"; + toolTip.SetToolTip(btnImportGroup, "Import highlight groups"); + btnImportGroup.UseVisualStyleBackColor = true; + btnImportGroup.Click += OnBtnImportGroupClick; + // + // btnMoveGroupDown + // + btnMoveGroupDown.Anchor = AnchorStyles.None; + btnMoveGroupDown.Location = new Point(383, 53); + btnMoveGroupDown.Margin = new Padding(4, 5, 4, 5); + btnMoveGroupDown.Name = "btnMoveGroupDown"; + btnMoveGroupDown.Size = new Size(85, 35); + btnMoveGroupDown.TabIndex = 6; + btnMoveGroupDown.Text = "Down"; + toolTip.SetToolTip(btnMoveGroupDown, "Move the current highlight group one position down"); + btnMoveGroupDown.UseVisualStyleBackColor = true; + btnMoveGroupDown.Click += OnBtnGroupDownClick; + // + // btnMoveGroupUp + // + btnMoveGroupUp.Anchor = AnchorStyles.None; + btnMoveGroupUp.Location = new Point(290, 53); + btnMoveGroupUp.Margin = new Padding(4, 5, 4, 5); + btnMoveGroupUp.Name = "btnMoveGroupUp"; + btnMoveGroupUp.Size = new Size(85, 35); + btnMoveGroupUp.TabIndex = 5; + btnMoveGroupUp.Text = "Up"; + toolTip.SetToolTip(btnMoveGroupUp, "Move the current highlight group one position up"); + btnMoveGroupUp.UseVisualStyleBackColor = true; + btnMoveGroupUp.Click += OnBtnGroupUpClick; + // + // labelAssignNamesToGroups + // + labelAssignNamesToGroups.Anchor = AnchorStyles.None; + labelAssignNamesToGroups.AutoSize = true; + labelAssignNamesToGroups.Location = new Point(8, 93); + labelAssignNamesToGroups.Margin = new Padding(4, 0, 4, 0); + labelAssignNamesToGroups.Name = "labelAssignNamesToGroups"; + labelAssignNamesToGroups.Size = new Size(276, 15); + labelAssignNamesToGroups.TabIndex = 4; + labelAssignNamesToGroups.Text = "You can assign groups to file names in the settings."; + // + // btnCopyGroup + // + btnCopyGroup.Anchor = AnchorStyles.None; + btnCopyGroup.Location = new Point(104, 53); + btnCopyGroup.Margin = new Padding(4, 5, 4, 5); + btnCopyGroup.Name = "btnCopyGroup"; + btnCopyGroup.Size = new Size(85, 35); + btnCopyGroup.TabIndex = 4; + btnCopyGroup.Text = "Copy Group"; + toolTip.SetToolTip(btnCopyGroup, "Copy the current highlight group into a new one"); + btnCopyGroup.UseVisualStyleBackColor = true; + btnCopyGroup.Click += OnBtnCopyGroupClick; + // + // btnDeleteGroup + // + btnDeleteGroup.Anchor = AnchorStyles.None; + btnDeleteGroup.Location = new Point(197, 53); + btnDeleteGroup.Margin = new Padding(4, 5, 4, 5); + btnDeleteGroup.Name = "btnDeleteGroup"; + btnDeleteGroup.Size = new Size(85, 35); + btnDeleteGroup.TabIndex = 2; + btnDeleteGroup.Text = "Delete Group"; + toolTip.SetToolTip(btnDeleteGroup, "Delete the current highlight group"); + btnDeleteGroup.UseVisualStyleBackColor = true; + btnDeleteGroup.Click += OnBtnDelGroupClick; + // + // btnNewGroup + // + btnNewGroup.Anchor = AnchorStyles.None; + btnNewGroup.Location = new Point(8, 53); + btnNewGroup.Margin = new Padding(4, 5, 4, 5); + btnNewGroup.Name = "btnNewGroup"; + btnNewGroup.Size = new Size(85, 35); + btnNewGroup.TabIndex = 3; + btnNewGroup.Text = "New group"; + toolTip.SetToolTip(btnNewGroup, "Create a new empty highlight group"); + btnNewGroup.UseVisualStyleBackColor = true; + btnNewGroup.Click += OnBtnNewGroupClick; + // + // comboBoxGroups + // + comboBoxGroups.Anchor = AnchorStyles.None; + comboBoxGroups.DisplayMember = "GroupName"; + comboBoxGroups.DrawMode = DrawMode.OwnerDrawFixed; + comboBoxGroups.Location = new Point(8, 19); + comboBoxGroups.Margin = new Padding(4, 5, 4, 5); + comboBoxGroups.Name = "comboBoxGroups"; + comboBoxGroups.Size = new Size(460, 24); + comboBoxGroups.TabIndex = 0; + toolTip.SetToolTip(comboBoxGroups, "Choose a group to create different highlight settings. Type in a name to change in the name of a group."); + comboBoxGroups.DrawItem += OnCmbBoxGroupDrawItem; + comboBoxGroups.SelectionChangeCommitted += OnCmbBoxGroupSelectionChangeCommitted; + comboBoxGroups.TextUpdate += OnCmbBoxGroupTextUpdate; + // + // pnlBackground + // + pnlBackground.Anchor = AnchorStyles.Top; + pnlBackground.AutoScroll = true; + pnlBackground.Controls.Add(btnExportGroup); + pnlBackground.Controls.Add(listBoxHighlight); + pnlBackground.Controls.Add(btnImportGroup); + pnlBackground.Controls.Add(btnAdd); + pnlBackground.Controls.Add(btnEdit); + pnlBackground.Controls.Add(btnDelete); + pnlBackground.Controls.Add(btnMoveUp); + pnlBackground.Controls.Add(btnMoveDown); + pnlBackground.Controls.Add(btnOk); + pnlBackground.Controls.Add(btnCancel); + pnlBackground.Controls.Add(groupBoxGroups); + pnlBackground.Location = new Point(0, 0); + pnlBackground.Name = "pnlBackground"; + pnlBackground.Size = new Size(576, 511); + pnlBackground.TabIndex = 23; + // + // groupBoxGroups + // + groupBoxGroups.Anchor = AnchorStyles.Top; + groupBoxGroups.Controls.Add(btnMoveGroupDown); + groupBoxGroups.Controls.Add(btnMoveGroupUp); + groupBoxGroups.Controls.Add(labelAssignNamesToGroups); + groupBoxGroups.Controls.Add(btnCopyGroup); + groupBoxGroups.Controls.Add(btnDeleteGroup); + groupBoxGroups.Controls.Add(btnNewGroup); + groupBoxGroups.Controls.Add(comboBoxGroups); + groupBoxGroups.Location = new Point(4, 14); + groupBoxGroups.Margin = new Padding(4, 5, 4, 5); + groupBoxGroups.Name = "groupBoxGroups"; + groupBoxGroups.Padding = new Padding(4, 5, 4, 5); + groupBoxGroups.Size = new Size(568, 117); + groupBoxGroups.TabIndex = 22; + groupBoxGroups.TabStop = false; + groupBoxGroups.Text = "Groups"; + // + // HighlightDialog + // + AcceptButton = btnOk; + CancelButton = btnCancel; + ClientSize = new Size(576, 411); + Controls.Add(pnlBackground); + DoubleBuffered = true; + helpProvider.SetHelpKeyword(this, "Highlighting.htm"); + helpProvider.SetHelpNavigator(this, HelpNavigator.Topic); + helpProvider.SetHelpString(this, ""); + Icon = (Icon)resources.GetObject("$this.Icon"); + Margin = new Padding(4, 5, 4, 5); + MaximizeBox = false; + MinimizeBox = false; + MinimumSize = new Size(592, 430); + Name = "HighlightDialog"; + helpProvider.SetShowHelp(this, true); + StartPosition = FormStartPosition.CenterParent; + Text = "Highlighting and action triggers"; + Shown += OnHighlightDialogShown; + pnlBackground.ResumeLayout(false); + groupBoxGroups.ResumeLayout(false); + groupBoxGroups.PerformLayout(); + ResumeLayout(false); + } + + #endregion + + private System.Windows.Forms.ListBox listBoxHighlight; + private System.Windows.Forms.Button btnAdd; + private System.Windows.Forms.Button btnEdit; + private System.Windows.Forms.Button btnDelete; + private System.Windows.Forms.Button btnMoveUp; + private System.Windows.Forms.Button btnMoveDown; + private System.Windows.Forms.Button btnOk; + private System.Windows.Forms.Button btnCancel; + private System.Windows.Forms.HelpProvider helpProvider; + private System.Windows.Forms.Button btnDeleteGroup; + private System.Windows.Forms.Button btnNewGroup; + private System.Windows.Forms.Button btnCopyGroup; + private System.Windows.Forms.ToolTip toolTip; + private System.Windows.Forms.Label labelAssignNamesToGroups; + private System.Windows.Forms.Button btnMoveGroupUp; + private System.Windows.Forms.Button btnMoveGroupDown; + private System.Windows.Forms.Button btnImportGroup; + private System.Windows.Forms.Button btnExportGroup; + private System.Windows.Forms.Panel pnlBackground; + private System.Windows.Forms.ComboBox comboBoxGroups; + private GroupBox groupBoxGroups; +} diff --git a/src/LogExpert.UI/Dialogs/HighlightDialog.cs b/src/LogExpert.UI/Dialogs/Highlight/HighlightDialog.cs similarity index 56% rename from src/LogExpert.UI/Dialogs/HighlightDialog.cs rename to src/LogExpert.UI/Dialogs/Highlight/HighlightDialog.cs index bbce0951..89b324de 100644 --- a/src/LogExpert.UI/Dialogs/HighlightDialog.cs +++ b/src/LogExpert.UI/Dialogs/Highlight/HighlightDialog.cs @@ -1,17 +1,14 @@ using System.ComponentModel; -using System.Globalization; using System.Runtime.Versioning; using System.Security; -using System.Text.RegularExpressions; using ColumnizerLib; using LogExpert.Core.Classes.Highlight; using LogExpert.Core.Entities; -using LogExpert.Core.Helpers; using LogExpert.Core.Interfaces; -using LogExpert.UI.Controls; using LogExpert.UI.Dialogs; +using LogExpert.UI.Dialogs.Highlight; using LogExpert.UI.Entities; namespace LogExpert.Dialogs; @@ -21,9 +18,6 @@ internal partial class HighlightDialog : Form { #region Private Fields - private readonly Image _applyButtonImage; - private string _bookmarkComment; - private ActionEntry _currentActionEntry = new(); private HighlightGroup _currentGroup; private List _highlightGroupList; @@ -45,8 +39,6 @@ public HighlightDialog (IConfigManager configManager) ConfigManager = configManager; Load += OnHighlightDialogLoad; listBoxHighlight.DrawItem += OnHighlightListBoxDrawItem; - _applyButtonImage = btnApply.Image; - btnApply.Image = null; ResumeLayout(); } @@ -59,14 +51,10 @@ private void ApplyResources () btnOk.Text = Resources.LogExpert_Common_UI_Button_OK; btnCancel.Text = Resources.LogExpert_Common_UI_Button_Cancel; btnAdd.Text = Resources.LogExpert_Common_UI_Button_Add; + btnEdit.Text = Resources.LogExpert_Common_UI_Button_Edit; btnDelete.Text = Resources.LogExpert_Common_UI_Button_Delete; btnMoveUp.Text = Resources.LogExpert_Common_UI_Button_MoveUp; btnMoveDown.Text = Resources.LogExpert_Common_UI_Button_MoveDown; - btnApply.Text = Resources.LogExpert_Common_UI_Button_Apply; - btnCustomForeColor.Text = Resources.HighlightDialog_UI_Button_CustomForeColor; - btnCustomBackColor.Text = Resources.HighlightDialog_UI_Button_CustomBackColor; - btnBookmarkComment.Text = Resources.HighlightDialog_UI_Button_BookmarkComment; - btnSelectPlugin.Text = Resources.HighlightDialog_UI_Button_SelectPlugin; btnImportGroup.Text = Resources.LogExpert_Common_UI_Button_Import; btnExportGroup.Text = Resources.LogExpert_Common_UI_Button_Export; btnMoveGroupDown.Text = Resources.HighlightDialog_UI_Button_GroupDown; @@ -75,24 +63,7 @@ private void ApplyResources () btnDeleteGroup.Text = Resources.HighlightDialog_UI_Button_DeleteGroup; btnNewGroup.Text = Resources.HighlightDialog_UI_Button_NewGroup; - labelForgroundColor.Text = Resources.HighlightDialog_UI_Label_ForegroundColor; - labelBackgroundColor.Text = Resources.HighlightDialog_UI_Label_BackgroundColor; - labelSearchString.Text = Resources.HighlightDialog_UI_Label_SearchString; labelAssignNamesToGroups.Text = Resources.HighlightDialog_UI_Label_AssignNamesToGroups; - - checkBoxRegex.Text = Resources.HighlightDialog_UI_CheckBox_RegEx; - checkBoxCaseSensitive.Text = Resources.HighlightDialog_UI_CheckBox_CaseSensitive; - checkBoxDontDirtyLed.Text = Resources.HighlightDialog_UI_CheckBox_DontDirtyLed; - checkBoxBookmark.Text = Resources.HighlightDialog_UI_CheckBox_Bookmark; - checkBoxStopTail.Text = Resources.HighlightDialog_UI_CheckBox_StopTail; - checkBoxPlugin.Text = Resources.HighlightDialog_UI_CheckBox_Plugin; - checkBoxWordMatch.Text = Resources.HighlightDialog_UI_CheckBox_WordMatch; - checkBoxBold.Text = Resources.HighlightDialog_UI_CheckBox_Bold; - checkBoxNoBackground.Text = Resources.HighlightDialog_UI_CheckBox_NoBackground; - - groupBoxLineMatchCriteria.Text = Resources.HighlightDialog_UI_GroupBox_LineMatchCriteria; - groupBoxColoring.Text = Resources.HighlightDialog_UI_GroupBox_Coloring; - groupBoxActions.Text = Resources.HighlightDialog_UI_GroupBox_Actions; groupBoxGroups.Text = Resources.HighlightDialog_UI_GroupBox_Groups; } @@ -121,8 +92,6 @@ public List HighlightGroupList [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)] public string PreSelectedGroupName { get; set; } - private bool IsDirty => btnApply.Image == _applyButtonImage; - private IConfigManager ConfigManager { get; } #endregion @@ -131,26 +100,38 @@ public List HighlightGroupList private void OnAddButtonClick (object sender, EventArgs e) { - AddNewEntry(); - Dirty(); - } + if (_currentGroup == null) + { + return; + } - private void OnBtnApplyClick (object sender, EventArgs e) - { - SaveEntry(); + var entry = new HighlightEntry + { + ForegroundColor = Color.White, + BackgroundColor = Color.Gray, + }; + + using var dlg = new HighlightEntryDialog(entry, KeywordActionList, isNew: true); + if (dlg.ShowDialog(this) == DialogResult.OK) + { + _currentGroup.HighlightEntryList.Add(entry); + _ = listBoxHighlight.Items.Add(entry); + listBoxHighlight.SelectedItem = entry; + ReEvaluateHighlightButtonStates(); + } } - private void OnBtnBookmarkCommentClick (object sender, EventArgs e) + private void OnBtnEditClick (object sender, EventArgs e) { - BookmarkCommentDlg dlg = new() + if (listBoxHighlight.SelectedItem is not HighlightEntry entry) { - Comment = _bookmarkComment - }; + return; + } - if (dlg.ShowDialog() == DialogResult.OK) + using var dlg = new HighlightEntryDialog(entry, KeywordActionList, isNew: false); + if (dlg.ShowDialog(this) == DialogResult.OK) { - _bookmarkComment = dlg.Comment; - Dirty(); + listBoxHighlight.Refresh(); } } @@ -162,23 +143,11 @@ private void OnBtnCopyGroupClick (object sender, EventArgs e) newGroup.GroupName = $"{Resources.HighlightDialog_UI_Snippet_CopyOf} {newGroup.GroupName}"; HighlightGroupList.Add(newGroup); - FillGroupComboBox(); + FillGroupListBoxGroups(); SelectGroup(HighlightGroupList.Count - 1); } } - private void OnBtnCustomBackColorClick (object sender, EventArgs e) - { - ChooseColor(colorBoxBackground); - Dirty(); - } - - private void OnBtnCustomForeColorClick (object sender, EventArgs e) - { - ChooseColor(colorBoxForeground); - Dirty(); - } - private void OnBtnDelGroupClick (object sender, EventArgs e) { // the last group cannot be deleted @@ -191,7 +160,7 @@ private void OnBtnDelGroupClick (object sender, EventArgs e) { var index = comboBoxGroups.SelectedIndex; HighlightGroupList.RemoveAt(comboBoxGroups.SelectedIndex); - FillGroupComboBox(); + FillGroupListBoxGroups(); if (index < HighlightGroupList.Count) { SelectGroup(index); @@ -228,7 +197,7 @@ private void OnBtnGroupDownClick (object sender, EventArgs e) { _highlightGroupList.Reverse(index, 2); comboBoxGroups.Refresh(); - FillGroupComboBox(); + FillGroupListBoxGroups(); SelectGroup(index + 1); } } @@ -240,7 +209,7 @@ private void OnBtnGroupUpClick (object sender, EventArgs e) { _highlightGroupList.Reverse(index - 1, 2); comboBoxGroups.Refresh(); - FillGroupComboBox(); + FillGroupListBoxGroups(); SelectGroup(index - 1); } } @@ -294,10 +263,9 @@ or PathTooLongException _highlightGroupList = ConfigManager.Settings.Preferences.HighlightGroupList; - FillGroupComboBox(); + FillGroupListBoxGroups(); _ = MessageBox.Show(this, Resources.HighlightDialog_UI_SettingsImported, Resources.LogExpert_Common_UI_Title_LogExpert); - } private void OnBtnMoveDownClick (object sender, EventArgs e) @@ -347,61 +315,13 @@ private void OnBtnNewGroupClick (object sender, EventArgs e) HighlightGroup newGroup = new() { GroupName = name }; HighlightGroupList.Add(newGroup); - FillGroupComboBox(); + FillGroupListBoxGroups(); SelectGroup(HighlightGroupList.Count - 1); } private void OnBtnOkClick (object sender, EventArgs e) { - // Apply pending changes if closing the form. - if (IsDirty) - { - // cannot call 'this.applyButton.PerformClick();' because it prohibits the OK button to terminate the dialog - OnBtnApplyClick(btnApply, EventArgs.Empty); - } - } - - private void OnChkBoxBoldCheckedChanged (object sender, EventArgs e) - { - Dirty(); - } - - private void OnChkBoxNoBackgroundCheckedChanged (object sender, EventArgs e) - { - colorBoxBackground.Enabled = !checkBoxNoBackground.Checked; - btnCustomBackColor.Enabled = !checkBoxNoBackground.Checked; - Dirty(); - } - - private void OnChkBoxPluginCheckedChanged (object sender, EventArgs e) - { - Dirty(); - btnSelectPlugin.Enabled = checkBoxPlugin.Checked; - } - - private void OnChkBoxRegexMouseUp (object sender, MouseEventArgs e) - { - if (e.Button == MouseButtons.Right) - { - RegexHelperDialog dlg = new() - { - Owner = this, - CaseSensitive = checkBoxCaseSensitive.Checked, - Pattern = textBoxSearchString.Text - }; - - if (dlg.ShowDialog() == DialogResult.OK) - { - checkBoxCaseSensitive.Checked = dlg.CaseSensitive; - textBoxSearchString.Text = dlg.Pattern; - } - } - } - - private void OnChkBoxWordMatchCheckedChanged (object sender, EventArgs e) - { - Dirty(); - checkBoxNoBackground.Enabled = checkBoxWordMatch.Checked; + // All edits are committed via the sub-dialog. Nothing to flush here. } private void OnCmbBoxGroupDrawItem (object sender, DrawItemEventArgs e) @@ -455,13 +375,6 @@ private void OnDeleteButtonClick (object sender, EventArgs e) private void OnHighlightDialogLoad (object sender, EventArgs e) { - colorBoxForeground.SelectedIndex = 1; - colorBoxBackground.SelectedIndex = 2; - btnApply.Enabled = false; - btnApply.Image = null; - btnBookmarkComment.Enabled = false; - btnSelectPlugin.Enabled = false; - ReEvaluateHighlightButtonStates(); } @@ -502,125 +415,16 @@ private void OnHighlightListBoxDrawItem (object sender, DrawItemEventArgs e) private void OnListBoxHighlightSelectedIndexChanged (object sender, EventArgs e) { - StartEditEntry(); - } - - private void OnPluginButtonClick (object sender, EventArgs e) - { - KeywordActionDlg dlg = new(_currentActionEntry, KeywordActionList); - - if (dlg.ShowDialog() == DialogResult.OK) - { - _currentActionEntry = dlg.ActionEntry; - Dirty(); - } + ReEvaluateHighlightButtonStates(); } #endregion #region Private Methods - private void AddNewEntry () - { - { - try - { - CheckRegex(); - - HighlightEntry entry = new() - { - SearchText = textBoxSearchString.Text, - ForegroundColor = colorBoxForeground.SelectedColor, - BackgroundColor = colorBoxBackground.SelectedColor, - IsRegex = checkBoxRegex.Checked, - IsCaseSensitive = checkBoxCaseSensitive.Checked, - IsLedSwitch = checkBoxDontDirtyLed.Checked, - IsStopTail = checkBoxStopTail.Checked, - IsSetBookmark = checkBoxBookmark.Checked, - IsActionEntry = checkBoxPlugin.Checked, - ActionEntry = _currentActionEntry, - IsWordMatch = checkBoxWordMatch.Checked, - IsBold = checkBoxBold.Checked, - NoBackground = checkBoxNoBackground.Checked - }; - - _ = listBoxHighlight.Items.Add(entry); - - // Select the newly created item - _currentGroup.HighlightEntryList.Add(entry); - listBoxHighlight.SelectedItem = entry; - } - catch (Exception ex) when (ex is ArgumentException - or RegexMatchTimeoutException - or ArgumentNullException - or InvalidOperationException - or SystemException) - { - _ = MessageBox.Show(string.Format(CultureInfo.InvariantCulture, Resources.HighlightDialog_UI_ErrorDuringAddOfHighLightEntry, ex.Message), - Resources.LogExpert_Common_UI_Title_Error, - MessageBoxButtons.OK, - MessageBoxIcon.Error); - } - } - } - - private void ChangeToDirty (object sender, EventArgs e) - { - Dirty(); - } - - private void CheckRegex () - { - if (checkBoxRegex.Checked) - { - if (string.IsNullOrWhiteSpace(textBoxSearchString.Text)) - { - throw new ArgumentException(Resources.HighlightDialog_RegexError); - } - - // Use RegexHelper for safer validation with timeout protection - var (isValid, error) = RegexHelper.IsValidPattern(textBoxSearchString.Text); - if (!isValid) - { - throw new ArgumentException(error ?? Resources.HighlightDialog_RegexError); - } - } - } - - private static void ChooseColor (ColorComboBox comboBox) - { - ColorDialog colorDialog = new() - { - AllowFullOpen = true, - ShowHelp = false, - Color = comboBox.CustomColor - }; - - if (colorDialog.ShowDialog() == DialogResult.OK) - { - comboBox.CustomColor = colorDialog.Color; - comboBox.SelectedIndex = 0; - } - - colorDialog.Dispose(); - } - - private void Dirty () - { - var index = listBoxHighlight.SelectedIndex; - if (index > -1) - { - btnApply.Enabled = true; - btnApply.Image = _applyButtonImage; - } - - btnAdd.Enabled = textBoxSearchString.Text.Length > 0; - } - - private void FillGroupComboBox () + private void FillGroupListBoxGroups () { SelectGroup(-1); - comboBoxGroups.Items.Clear(); foreach (var group in HighlightGroupList) @@ -658,7 +462,7 @@ private void InitData () HighlightGroupList.Add(highlightGroup); } - FillGroupComboBox(); + FillGroupListBoxGroups(); _currentGroup = null; var groupToSelect = PreSelectedGroupName; @@ -685,7 +489,7 @@ private void InitData () private void ReEvaluateGroupButtonStates () { - // Refresh button states based on the selection in the combobox + // Refresh button states based on the selection in the listBoxGroups var atLeastOneSelected = comboBoxGroups.SelectedItem != null; var moreThanOne = comboBoxGroups.Items.Count > 1; var firstSelected = atLeastOneSelected && comboBoxGroups.SelectedIndex == 0; @@ -699,59 +503,24 @@ private void ReEvaluateGroupButtonStates () private void ReEvaluateHighlightButtonStates () { - // Refresh button states based on the selection in the combobox + // Refresh button states based on the selection in the listbox var atLeastOneSelected = listBoxHighlight.SelectedItem != null; var moreThanOne = listBoxHighlight.Items.Count > 1; var firstSelected = atLeastOneSelected && listBoxHighlight.SelectedIndex == 0; var lastSelected = atLeastOneSelected && listBoxHighlight.SelectedIndex == listBoxHighlight.Items.Count - 1; + btnEdit.Enabled = atLeastOneSelected; btnDelete.Enabled = atLeastOneSelected; btnMoveUp.Enabled = atLeastOneSelected && moreThanOne && !firstSelected; btnMoveDown.Enabled = atLeastOneSelected && moreThanOne && !lastSelected; } - private void SaveEntry () - { - try - { - CheckRegex(); - - var entry = (HighlightEntry)listBoxHighlight.SelectedItem; - - entry.ForegroundColor = (Color)colorBoxForeground.SelectedItem; - entry.BackgroundColor = (Color)colorBoxBackground.SelectedItem; - entry.SearchText = textBoxSearchString.Text; - entry.IsRegex = checkBoxRegex.Checked; - entry.IsCaseSensitive = checkBoxCaseSensitive.Checked; - btnApply.Enabled = false; - btnApply.Image = null; - entry.IsLedSwitch = checkBoxDontDirtyLed.Checked; - entry.IsSetBookmark = checkBoxBookmark.Checked; - entry.IsStopTail = checkBoxStopTail.Checked; - entry.IsActionEntry = checkBoxPlugin.Checked; - entry.ActionEntry = (ActionEntry)_currentActionEntry.Clone(); - entry.BookmarkComment = _bookmarkComment; - entry.IsWordMatch = checkBoxWordMatch.Checked; - entry.IsBold = checkBoxBold.Checked; - entry.NoBackground = checkBoxNoBackground.Checked; - listBoxHighlight.Refresh(); - } - catch (Exception ex) when (ex is ArgumentException - or RegexMatchTimeoutException - or ArgumentNullException - or InvalidOperationException - or SystemException) - { - _ = MessageBox.Show(string.Format(CultureInfo.InvariantCulture, Resources.HighlightDialog_UI_ErrorDuringSavingOfHighlightEntry, ex.Message), Resources.LogExpert_Common_UI_Title_Error); - } - } - private void SelectGroup (int index) { if (index >= 0 && index < HighlightGroupList.Count) { _currentGroup = HighlightGroupList[index]; - comboBoxGroups.Items[index] = _currentGroup; + //listBoxGroups.Items[index] = _currentGroup; comboBoxGroups.SelectedIndex = index; comboBoxGroups.SelectedItem = _currentGroup; FillHighlightListBox(); @@ -767,55 +536,5 @@ private void SelectGroup (int index) ReEvaluateGroupButtonStates(); } - private void StartEditEntry () - { - var entry = (HighlightEntry)listBoxHighlight.SelectedItem; - - if (entry != null) - { - textBoxSearchString.Text = entry.SearchText; - - colorBoxForeground.CustomColor = entry.ForegroundColor; - colorBoxBackground.CustomColor = entry.BackgroundColor; - - if (colorBoxForeground.Items.Contains(entry.ForegroundColor)) - { - colorBoxForeground.SelectedIndex = colorBoxForeground.Items.Cast().ToList().LastIndexOf(entry.ForegroundColor); - } - else - { - colorBoxForeground.SelectedItem = entry.ForegroundColor; - } - - if (colorBoxForeground.Items.Contains(entry.ForegroundColor)) - { - colorBoxBackground.SelectedIndex = colorBoxBackground.Items.Cast().ToList().LastIndexOf(entry.BackgroundColor); - } - else - { - colorBoxBackground.SelectedItem = entry.BackgroundColor; - } - - checkBoxRegex.Checked = entry.IsRegex; - checkBoxCaseSensitive.Checked = entry.IsCaseSensitive; - checkBoxDontDirtyLed.Checked = entry.IsLedSwitch; - checkBoxBookmark.Checked = entry.IsSetBookmark; - checkBoxStopTail.Checked = entry.IsStopTail; - checkBoxPlugin.Checked = entry.IsActionEntry; - btnSelectPlugin.Enabled = checkBoxPlugin.Checked; - btnBookmarkComment.Enabled = checkBoxBookmark.Checked; - _currentActionEntry = entry.ActionEntry != null ? (ActionEntry)entry.ActionEntry.Clone() : new ActionEntry(); - _bookmarkComment = entry.BookmarkComment; - checkBoxWordMatch.Checked = entry.IsWordMatch; - checkBoxBold.Checked = entry.IsBold; - checkBoxNoBackground.Checked = entry.NoBackground; - } - - btnApply.Enabled = false; - btnApply.Image = null; - - ReEvaluateHighlightButtonStates(); - } - #endregion } diff --git a/src/LogExpert.UI/Dialogs/HighlightDialog.resx b/src/LogExpert.UI/Dialogs/Highlight/HighlightDialog.resx similarity index 87% rename from src/LogExpert.UI/Dialogs/HighlightDialog.resx rename to src/LogExpert.UI/Dialogs/Highlight/HighlightDialog.resx index 1a094326..dee8bb50 100644 --- a/src/LogExpert.UI/Dialogs/HighlightDialog.resx +++ b/src/LogExpert.UI/Dialogs/Highlight/HighlightDialog.resx @@ -120,24 +120,10 @@ 144, 17 - - - - iVBORw0KGgoAAAANSUhEUgAAACMAAAAjCAYAAAAe2bNZAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 - YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAG8SURBVFhH7Ze/K0ZRGMe/5EdKShSbwb9gsdgYSMkgqywS - g52y2ClloJhNBqWI0aBkl0kWg0Fsfva8neft9O3c9z7nPedOfOoM7/1+n+95zr3vPfde4J8/wCKASwAv - AJ4AnACYY1OVvAL4MY57Ls7FY2AyGRcA9gEcArgJ6DIOOCwFDu9gQ4DuQF0S/RnChjNk1MgS4kjKSiou - QPO+WGjEQwWNKJo7y0IRVTUiyD5kzn+LMRto5wNe/gQLjBrbWGiCLZc1RMfHrQs2mQzseVmfLFrmWbKY - DGx6OR8sOkrnuXOGKxYi2C05I4p6JllQ9M8rzxqms2wldEYaNSKoT65GkGdnOGLBKy5qaCeiEUG9Cywo - 585wy4KjqKH1yEYE9Y+yoMwUTKb0Bhra9n7HbPON5qlTZmqlhpppRCibp4aaeljw6Ets5Nhad23sWrZ5 - 8XyzYEDzW1gIoeYRFohBPmBAXtoti62zEVtgRF5XNVduBjNalLMhzZMvjGj8hkzXtwDdvZMX54essWjg - NFcjityCfuAKGwKcUc07G1KYovCYMcBhuRgLTBYasv90cXGVyKNhHsAqgGUA02z4Jwe/XobopVEN3UwA - AAAASUVORK5CYII= - - 17, 17 + AAABAAEAEBAQAAAABAAoAQAAFgAAACgAAAAQAAAAIAAAAAEABAAAAAAAgAAAAAAAAAAAAAAAEAAAABAA diff --git a/src/LogExpert.UI/Dialogs/Highlight/HighlightEntryDialog.Designer.cs b/src/LogExpert.UI/Dialogs/Highlight/HighlightEntryDialog.Designer.cs new file mode 100644 index 00000000..f660de5b --- /dev/null +++ b/src/LogExpert.UI/Dialogs/Highlight/HighlightEntryDialog.Designer.cs @@ -0,0 +1,500 @@ +using LogExpert.UI.Controls; + +namespace LogExpert.UI.Dialogs.Highlight; + +partial class HighlightEntryDialog +{ + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent () + { + components = new System.ComponentModel.Container(); + _toolTip = new ToolTip(components); + _previewLabel = new Label(); + _tabControl = new TabControl(); + _tabLineMatch = new TabPage(); + _labelSearchString = new Label(); + _textBoxSearchString = new TextBox(); + _checkBoxCaseSensitive = new CheckBox(); + _checkBoxRegex = new CheckBox(); + _tabColoring = new TabPage(); + _labelForeColor = new Label(); + _colorBoxForeground = new ColorComboBox(); + _btnCustomForeColor = new Button(); + _labelBackColor = new Label(); + _colorBoxBackground = new ColorComboBox(); + _btnCustomBackColor = new Button(); + _checkBoxBold = new CheckBox(); + _checkBoxWordMatch = new CheckBox(); + _checkBoxNoBackground = new CheckBox(); + _tabActions = new TabPage(); + _checkBoxBookmark = new CheckBox(); + _btnBookmarkComment = new Button(); + _checkBoxStopTail = new CheckBox(); + _checkBoxDontDirtyLed = new CheckBox(); + _checkBoxPlugin = new CheckBox(); + _btnSelectPlugin = new Button(); + _checkBoxAlertOnHit = new CheckBox(); + _labelSoundFile = new Label(); + _textBoxSoundFile = new TextBox(); + _btnBrowseSoundFile = new Button(); + _labelCooldown = new Label(); + _numericCooldownSeconds = new NumericUpDown(); + _labelCooldownSeconds = new Label(); + _btnOk = new Button(); + _btnCancel = new Button(); + _tabControl.SuspendLayout(); + _tabLineMatch.SuspendLayout(); + _tabColoring.SuspendLayout(); + _tabActions.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)_numericCooldownSeconds).BeginInit(); + SuspendLayout(); + // + // _previewLabel + // + _previewLabel.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right; + _previewLabel.AutoEllipsis = true; + _previewLabel.BorderStyle = BorderStyle.FixedSingle; + _previewLabel.Location = new Point(12, 12); + _previewLabel.Name = "_previewLabel"; + _previewLabel.Padding = new Padding(6, 0, 6, 0); + _previewLabel.Size = new Size(560, 34); + _previewLabel.TabIndex = 0; + _previewLabel.Text = "(preview)"; + _previewLabel.TextAlign = ContentAlignment.MiddleLeft; + _previewLabel.UseMnemonic = false; + // + // _tabControl + // + _tabControl.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right; + _tabControl.Controls.Add(_tabLineMatch); + _tabControl.Controls.Add(_tabColoring); + _tabControl.Controls.Add(_tabActions); + _tabControl.Location = new Point(12, 54); + _tabControl.Name = "_tabControl"; + _tabControl.SelectedIndex = 0; + _tabControl.Size = new Size(560, 320); + _tabControl.TabIndex = 1; + // + // _tabLineMatch + // + _tabLineMatch.Controls.Add(_labelSearchString); + _tabLineMatch.Controls.Add(_textBoxSearchString); + _tabLineMatch.Controls.Add(_checkBoxCaseSensitive); + _tabLineMatch.Controls.Add(_checkBoxRegex); + _tabLineMatch.Location = new Point(4, 24); + _tabLineMatch.Name = "_tabLineMatch"; + _tabLineMatch.Padding = new Padding(8); + _tabLineMatch.Size = new Size(552, 292); + _tabLineMatch.TabIndex = 0; + _tabLineMatch.Text = "Line Match"; + _tabLineMatch.UseVisualStyleBackColor = true; + // + // _labelSearchString + // + _labelSearchString.AutoSize = true; + _labelSearchString.Location = new Point(12, 16); + _labelSearchString.Name = "_labelSearchString"; + _labelSearchString.Size = new Size(0, 15); + _labelSearchString.TabIndex = 0; + // + // _textBoxSearchString + // + _textBoxSearchString.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right; + _textBoxSearchString.Location = new Point(12, 36); + _textBoxSearchString.Name = "_textBoxSearchString"; + _textBoxSearchString.Size = new Size(520, 23); + _textBoxSearchString.TabIndex = 1; + _textBoxSearchString.TextChanged += OnSearchStringChanged; + _textBoxSearchString.MouseUp += OnSearchStringMouseUp; + // + // _checkBoxCaseSensitive + // + _checkBoxCaseSensitive.AutoSize = true; + _checkBoxCaseSensitive.Location = new Point(12, 75); + _checkBoxCaseSensitive.Name = "_checkBoxCaseSensitive"; + _checkBoxCaseSensitive.Size = new Size(100, 19); + _checkBoxCaseSensitive.TabIndex = 2; + _checkBoxCaseSensitive.Text = "Case Sensitive"; + _checkBoxCaseSensitive.UseVisualStyleBackColor = true; + // + // _checkBoxRegex + // + _checkBoxRegex.AutoSize = true; + _checkBoxRegex.Location = new Point(180, 75); + _checkBoxRegex.Name = "_checkBoxRegex"; + _checkBoxRegex.Size = new Size(57, 19); + _checkBoxRegex.TabIndex = 3; + _checkBoxRegex.Text = "Regex"; + _checkBoxRegex.UseVisualStyleBackColor = true; + _checkBoxRegex.MouseUp += OnRegexMouseUp; + // + // _tabColoring + // + _tabColoring.Controls.Add(_labelForeColor); + _tabColoring.Controls.Add(_colorBoxForeground); + _tabColoring.Controls.Add(_btnCustomForeColor); + _tabColoring.Controls.Add(_labelBackColor); + _tabColoring.Controls.Add(_colorBoxBackground); + _tabColoring.Controls.Add(_btnCustomBackColor); + _tabColoring.Controls.Add(_checkBoxBold); + _tabColoring.Controls.Add(_checkBoxWordMatch); + _tabColoring.Controls.Add(_checkBoxNoBackground); + _tabColoring.Location = new Point(4, 24); + _tabColoring.Name = "_tabColoring"; + _tabColoring.Padding = new Padding(8); + _tabColoring.Size = new Size(552, 292); + _tabColoring.TabIndex = 1; + _tabColoring.Text = "Coloring"; + _tabColoring.UseVisualStyleBackColor = true; + // + // _labelForeColor + // + _labelForeColor.AutoSize = true; + _labelForeColor.Location = new Point(12, 16); + _labelForeColor.Name = "_labelForeColor"; + _labelForeColor.Size = new Size(0, 15); + _labelForeColor.TabIndex = 0; + // + // _colorBoxForeground + // + _colorBoxForeground.CustomColor = Color.Black; + _colorBoxForeground.DrawMode = DrawMode.OwnerDrawFixed; + _colorBoxForeground.DropDownStyle = ComboBoxStyle.DropDownList; + _colorBoxForeground.FormattingEnabled = true; + _colorBoxForeground.Items.AddRange(new object[] { Color.Black, Color.Black, Color.White, Color.Gray, Color.DarkGray, Color.Blue, Color.LightBlue, Color.DarkBlue, Color.Green, Color.LightGreen, Color.DarkGreen, Color.Olive, Color.Red, Color.Pink, Color.Purple, Color.IndianRed, Color.DarkCyan, Color.Yellow }); + _colorBoxForeground.Location = new Point(12, 36); + _colorBoxForeground.Name = "_colorBoxForeground"; + _colorBoxForeground.Size = new Size(180, 24); + _colorBoxForeground.TabIndex = 1; + _colorBoxForeground.SelectedIndexChanged += OnColorOrStyleChanged; + // + // _btnCustomForeColor + // + _btnCustomForeColor.Location = new Point(200, 33); + _btnCustomForeColor.Name = "_btnCustomForeColor"; + _btnCustomForeColor.Size = new Size(95, 30); + _btnCustomForeColor.TabIndex = 2; + _btnCustomForeColor.Text = "Fore Color"; + _btnCustomForeColor.UseVisualStyleBackColor = true; + _btnCustomForeColor.Click += OnBtnCustomForeColorClicked; + // + // _labelBackColor + // + _labelBackColor.AutoSize = true; + _labelBackColor.Location = new Point(12, 80); + _labelBackColor.Name = "_labelBackColor"; + _labelBackColor.Size = new Size(0, 15); + _labelBackColor.TabIndex = 3; + // + // _colorBoxBackground + // + _colorBoxBackground.CustomColor = Color.Black; + _colorBoxBackground.DrawMode = DrawMode.OwnerDrawFixed; + _colorBoxBackground.DropDownStyle = ComboBoxStyle.DropDownList; + _colorBoxBackground.FormattingEnabled = true; + _colorBoxBackground.Items.AddRange(new object[] { Color.Black, Color.Black, Color.White, Color.Gray, Color.DarkGray, Color.Blue, Color.LightBlue, Color.DarkBlue, Color.Green, Color.LightGreen, Color.DarkGreen, Color.Olive, Color.Red, Color.Pink, Color.Purple, Color.IndianRed, Color.DarkCyan, Color.Yellow }); + _colorBoxBackground.Location = new Point(12, 100); + _colorBoxBackground.Name = "_colorBoxBackground"; + _colorBoxBackground.Size = new Size(180, 24); + _colorBoxBackground.TabIndex = 4; + _colorBoxBackground.SelectedIndexChanged += OnColorOrStyleChanged; + // + // _btnCustomBackColor + // + _btnCustomBackColor.Location = new Point(200, 97); + _btnCustomBackColor.Name = "_btnCustomBackColor"; + _btnCustomBackColor.Size = new Size(95, 30); + _btnCustomBackColor.TabIndex = 5; + _btnCustomBackColor.Text = "Back Color"; + _btnCustomBackColor.UseVisualStyleBackColor = true; + _btnCustomBackColor.Click += OnBtnCustomBackColorClicked; + // + // _checkBoxBold + // + _checkBoxBold.AutoSize = true; + _checkBoxBold.Location = new Point(12, 150); + _checkBoxBold.Name = "_checkBoxBold"; + _checkBoxBold.Size = new Size(50, 19); + _checkBoxBold.TabIndex = 6; + _checkBoxBold.Text = "Bold"; + _checkBoxBold.UseVisualStyleBackColor = true; + _checkBoxBold.CheckedChanged += OnColorOrStyleChanged; + // + // _checkBoxWordMatch + // + _checkBoxWordMatch.AutoSize = true; + _checkBoxWordMatch.Location = new Point(12, 180); + _checkBoxWordMatch.Name = "_checkBoxWordMatch"; + _checkBoxWordMatch.Size = new Size(89, 19); + _checkBoxWordMatch.TabIndex = 7; + _checkBoxWordMatch.Text = "Word Mode"; + _checkBoxWordMatch.UseVisualStyleBackColor = true; + _checkBoxWordMatch.CheckedChanged += OnWordMatchChanged; + // + // _checkBoxNoBackground + // + _checkBoxNoBackground.AutoSize = true; + _checkBoxNoBackground.Location = new Point(180, 180); + _checkBoxNoBackground.Name = "_checkBoxNoBackground"; + _checkBoxNoBackground.Size = new Size(109, 19); + _checkBoxNoBackground.TabIndex = 8; + _checkBoxNoBackground.Text = "No Background"; + _checkBoxNoBackground.UseVisualStyleBackColor = true; + _checkBoxNoBackground.CheckedChanged += OnNoBackgroundChanged; + // + // _tabActions + // + _tabActions.Controls.Add(_checkBoxBookmark); + _tabActions.Controls.Add(_btnBookmarkComment); + _tabActions.Controls.Add(_checkBoxStopTail); + _tabActions.Controls.Add(_checkBoxDontDirtyLed); + _tabActions.Controls.Add(_checkBoxPlugin); + _tabActions.Controls.Add(_btnSelectPlugin); + _tabActions.Controls.Add(_checkBoxAlertOnHit); + _tabActions.Controls.Add(_labelSoundFile); + _tabActions.Controls.Add(_textBoxSoundFile); + _tabActions.Controls.Add(_btnBrowseSoundFile); + _tabActions.Controls.Add(_labelCooldown); + _tabActions.Controls.Add(_numericCooldownSeconds); + _tabActions.Controls.Add(_labelCooldownSeconds); + _tabActions.Location = new Point(4, 24); + _tabActions.Name = "_tabActions"; + _tabActions.Padding = new Padding(8); + _tabActions.Size = new Size(552, 292); + _tabActions.TabIndex = 2; + _tabActions.Text = "Actions"; + _tabActions.UseVisualStyleBackColor = true; + // + // _checkBoxBookmark + // + _checkBoxBookmark.AutoSize = true; + _checkBoxBookmark.Location = new Point(12, 16); + _checkBoxBookmark.Name = "_checkBoxBookmark"; + _checkBoxBookmark.Size = new Size(80, 19); + _checkBoxBookmark.TabIndex = 0; + _checkBoxBookmark.Text = "Bookmark"; + _checkBoxBookmark.UseVisualStyleBackColor = true; + _checkBoxBookmark.CheckedChanged += OnBookmarkChanged; + // + // _btnBookmarkComment + // + _btnBookmarkComment.Location = new Point(200, 12); + _btnBookmarkComment.Name = "_btnBookmarkComment"; + _btnBookmarkComment.Size = new Size(120, 28); + _btnBookmarkComment.TabIndex = 1; + _btnBookmarkComment.Text = "Bookmark Comment"; + _btnBookmarkComment.UseVisualStyleBackColor = true; + _btnBookmarkComment.Click += OnBookmarkCommentClick; + // + // _checkBoxStopTail + // + _checkBoxStopTail.AutoSize = true; + _checkBoxStopTail.Location = new Point(12, 48); + _checkBoxStopTail.Name = "_checkBoxStopTail"; + _checkBoxStopTail.Size = new Size(71, 19); + _checkBoxStopTail.TabIndex = 2; + _checkBoxStopTail.Text = "Stop Tail"; + _checkBoxStopTail.UseVisualStyleBackColor = true; + // + // _checkBoxDontDirtyLed + // + _checkBoxDontDirtyLed.AutoSize = true; + _checkBoxDontDirtyLed.Location = new Point(12, 78); + _checkBoxDontDirtyLed.Name = "_checkBoxDontDirtyLed"; + _checkBoxDontDirtyLed.Size = new Size(102, 19); + _checkBoxDontDirtyLed.TabIndex = 3; + _checkBoxDontDirtyLed.Text = "Dont Dirty Led"; + _checkBoxDontDirtyLed.UseVisualStyleBackColor = true; + // + // _checkBoxPlugin + // + _checkBoxPlugin.AutoSize = true; + _checkBoxPlugin.Location = new Point(12, 108); + _checkBoxPlugin.Name = "_checkBoxPlugin"; + _checkBoxPlugin.Size = new Size(60, 19); + _checkBoxPlugin.TabIndex = 4; + _checkBoxPlugin.Text = "Plugin"; + _checkBoxPlugin.UseVisualStyleBackColor = true; + _checkBoxPlugin.CheckedChanged += OnPluginChanged; + // + // _btnSelectPlugin + // + _btnSelectPlugin.Location = new Point(200, 104); + _btnSelectPlugin.Name = "_btnSelectPlugin"; + _btnSelectPlugin.Size = new Size(120, 28); + _btnSelectPlugin.TabIndex = 5; + _btnSelectPlugin.Text = "Select Plugin"; + _btnSelectPlugin.UseVisualStyleBackColor = true; + _btnSelectPlugin.Click += OnSelectPluginClick; + // + // _checkBoxAlertOnHit + // + _checkBoxAlertOnHit.AutoSize = true; + _checkBoxAlertOnHit.Location = new Point(12, 148); + _checkBoxAlertOnHit.Name = "_checkBoxAlertOnHit"; + _checkBoxAlertOnHit.Size = new Size(87, 19); + _checkBoxAlertOnHit.TabIndex = 6; + _checkBoxAlertOnHit.Text = "Alert on Hit"; + _checkBoxAlertOnHit.UseVisualStyleBackColor = true; + _checkBoxAlertOnHit.CheckedChanged += OnAlertOnHitChanged; + // + // _labelSoundFile + // + _labelSoundFile.AutoSize = true; + _labelSoundFile.Location = new Point(30, 180); + _labelSoundFile.Name = "_labelSoundFile"; + _labelSoundFile.Size = new Size(0, 15); + _labelSoundFile.TabIndex = 7; + // + // _textBoxSoundFile + // + _textBoxSoundFile.Location = new Point(110, 176); + _textBoxSoundFile.Name = "_textBoxSoundFile"; + _textBoxSoundFile.Size = new Size(210, 23); + _textBoxSoundFile.TabIndex = 8; + // + // _btnBrowseSoundFile + // + _btnBrowseSoundFile.Location = new Point(326, 174); + _btnBrowseSoundFile.Name = "_btnBrowseSoundFile"; + _btnBrowseSoundFile.Size = new Size(90, 28); + _btnBrowseSoundFile.TabIndex = 9; + _btnBrowseSoundFile.Text = "Select Sound File"; + _btnBrowseSoundFile.UseVisualStyleBackColor = true; + _btnBrowseSoundFile.Click += OnBrowseSoundFileClick; + // + // _labelCooldown + // + _labelCooldown.AutoSize = true; + _labelCooldown.Location = new Point(30, 215); + _labelCooldown.Name = "_labelCooldown"; + _labelCooldown.Size = new Size(0, 15); + _labelCooldown.TabIndex = 10; + // + // _numericCooldownSeconds + // + _numericCooldownSeconds.Location = new Point(110, 211); + _numericCooldownSeconds.Maximum = new decimal(new int[] { 3600, 0, 0, 0 }); + _numericCooldownSeconds.Name = "_numericCooldownSeconds"; + _numericCooldownSeconds.Size = new Size(70, 23); + _numericCooldownSeconds.TabIndex = 11; + _numericCooldownSeconds.Value = new decimal(new int[] { 2, 0, 0, 0 }); + // + // _labelCooldownSeconds + // + _labelCooldownSeconds.AutoSize = true; + _labelCooldownSeconds.Location = new Point(190, 215); + _labelCooldownSeconds.Name = "_labelCooldownSeconds"; + _labelCooldownSeconds.Size = new Size(0, 15); + _labelCooldownSeconds.TabIndex = 12; + // + // _btnOk + // + _btnOk.Anchor = AnchorStyles.Bottom | AnchorStyles.Right; + _btnOk.Location = new Point(378, 385); + _btnOk.Name = "_btnOk"; + _btnOk.Size = new Size(90, 30); + _btnOk.TabIndex = 2; + _btnOk.Text = "Ok"; + _btnOk.UseVisualStyleBackColor = true; + _btnOk.Click += OnOkClick; + // + // _btnCancel + // + _btnCancel.Anchor = AnchorStyles.Bottom | AnchorStyles.Right; + _btnCancel.DialogResult = DialogResult.Cancel; + _btnCancel.Location = new Point(478, 385); + _btnCancel.Name = "_btnCancel"; + _btnCancel.Size = new Size(90, 30); + _btnCancel.TabIndex = 3; + _btnCancel.Text = "Cancel"; + _btnCancel.UseVisualStyleBackColor = true; + // + // HighlightEntryDialog + // + AcceptButton = _btnOk; + AutoScaleDimensions = new SizeF(96F, 96F); + AutoScaleMode = AutoScaleMode.Dpi; + CancelButton = _btnCancel; + ClientSize = new Size(584, 427); + Controls.Add(_previewLabel); + Controls.Add(_tabControl); + Controls.Add(_btnOk); + Controls.Add(_btnCancel); + MaximizeBox = false; + MinimizeBox = false; + Name = "HighlightEntryDialog"; + ShowInTaskbar = false; + StartPosition = FormStartPosition.CenterParent; + Text = "HighlightEntryDialog"; + _tabControl.ResumeLayout(false); + _tabLineMatch.ResumeLayout(false); + _tabLineMatch.PerformLayout(); + _tabColoring.ResumeLayout(false); + _tabColoring.PerformLayout(); + _tabActions.ResumeLayout(false); + _tabActions.PerformLayout(); + ((System.ComponentModel.ISupportInitialize)_numericCooldownSeconds).EndInit(); + ResumeLayout(false); + } + + #endregion + + private System.Windows.Forms.Label _previewLabel; + private System.Windows.Forms.TabControl _tabControl; + private System.Windows.Forms.TabPage _tabLineMatch; + private System.Windows.Forms.TabPage _tabColoring; + private System.Windows.Forms.TabPage _tabActions; + private System.Windows.Forms.Label _labelSearchString; + private System.Windows.Forms.TextBox _textBoxSearchString; + private System.Windows.Forms.CheckBox _checkBoxCaseSensitive; + private System.Windows.Forms.CheckBox _checkBoxRegex; + private System.Windows.Forms.Label _labelForeColor; + private LogExpert.UI.Controls.ColorComboBox _colorBoxForeground; + private System.Windows.Forms.Button _btnCustomForeColor; + private System.Windows.Forms.Label _labelBackColor; + private LogExpert.UI.Controls.ColorComboBox _colorBoxBackground; + private System.Windows.Forms.Button _btnCustomBackColor; + private System.Windows.Forms.CheckBox _checkBoxBold; + private System.Windows.Forms.CheckBox _checkBoxWordMatch; + private System.Windows.Forms.CheckBox _checkBoxNoBackground; + private System.Windows.Forms.CheckBox _checkBoxBookmark; + private System.Windows.Forms.Button _btnBookmarkComment; + private System.Windows.Forms.CheckBox _checkBoxStopTail; + private System.Windows.Forms.CheckBox _checkBoxDontDirtyLed; + private System.Windows.Forms.CheckBox _checkBoxPlugin; + private System.Windows.Forms.Button _btnSelectPlugin; + private System.Windows.Forms.CheckBox _checkBoxAlertOnHit; + private System.Windows.Forms.Label _labelSoundFile; + private System.Windows.Forms.TextBox _textBoxSoundFile; + private System.Windows.Forms.Button _btnBrowseSoundFile; + private System.Windows.Forms.Label _labelCooldown; + private System.Windows.Forms.NumericUpDown _numericCooldownSeconds; + private System.Windows.Forms.Label _labelCooldownSeconds; + private System.Windows.Forms.Button _btnOk; + private System.Windows.Forms.Button _btnCancel; + private System.Windows.Forms.ToolTip _toolTip; +} diff --git a/src/LogExpert.UI/Dialogs/Highlight/HighlightEntryDialog.cs b/src/LogExpert.UI/Dialogs/Highlight/HighlightEntryDialog.cs new file mode 100644 index 00000000..ad5ecd30 --- /dev/null +++ b/src/LogExpert.UI/Dialogs/Highlight/HighlightEntryDialog.cs @@ -0,0 +1,452 @@ +using System.Data; +using System.Globalization; +using System.Text.RegularExpressions; + +using ColumnizerLib; + +using LogExpert.Core.Classes.Highlight; +using LogExpert.Core.Helpers; +using LogExpert.Dialogs; +using LogExpert.UI.Controls; + +namespace LogExpert.UI.Dialogs.Highlight; + +public partial class HighlightEntryDialog : Form +{ + private readonly HighlightEntry _entry; + private readonly IList _keywordActionList; + private readonly bool _isNew; + private ActionEntry _currentActionEntry; + private string _bookmarkComment; + + public HighlightEntryDialog (HighlightEntry entry, IList keywordActions, bool isNew) + { + AutoScaleDimensions = new SizeF(96F, 96F); + AutoScaleMode = AutoScaleMode.Dpi; + + InitializeComponent(); + ArgumentNullException.ThrowIfNull(entry); + + _entry = entry; + _keywordActionList = keywordActions; + _isNew = isNew; + _currentActionEntry = entry.ActionEntry != null + ? (ActionEntry)entry.ActionEntry.Clone() + : new ActionEntry(); + _bookmarkComment = entry.BookmarkComment ?? string.Empty; + + ApplyResources(); + LoadFromEntry(); + UpdateTitle(); + UpdateOkEnabled(); + UpdateAlertEnabled(); + UpdateBookmarkCommentEnabled(); + UpdatePluginEnabled(); + UpdateNoBackgroundEnabled(); + UpdateBackgroundColorEnabled(); + UpdatePreview(); + } + + private void ApplyResources () + { + _tabLineMatch.Text = Resources.HighlightEntryEditDialog_UI_Tab_LineMatchCriteria; + _tabColoring.Text = Resources.HighlightEntryEditDialog_UI_Tab_Coloring; + _tabActions.Text = Resources.HighlightEntryEditDialog_UI_Tab_Actions; + + _labelSearchString.Text = Resources.HighlightDialog_UI_Label_SearchString; + _checkBoxRegex.Text = Resources.HighlightDialog_UI_CheckBox_RegEx; + _checkBoxCaseSensitive.Text = Resources.HighlightDialog_UI_CheckBox_CaseSensitive; + + _labelForeColor.Text = Resources.HighlightDialog_UI_Label_ForegroundColor; + _labelBackColor.Text = Resources.HighlightDialog_UI_Label_BackgroundColor; + _btnCustomForeColor.Text = Resources.HighlightDialog_UI_Button_CustomForeColor; + _btnCustomBackColor.Text = Resources.HighlightDialog_UI_Button_CustomBackColor; + _checkBoxBold.Text = Resources.HighlightDialog_UI_CheckBox_Bold; + _checkBoxWordMatch.Text = Resources.HighlightDialog_UI_CheckBox_WordMatch; + _checkBoxNoBackground.Text = Resources.HighlightDialog_UI_CheckBox_NoBackground; + + _checkBoxBookmark.Text = Resources.HighlightDialog_UI_CheckBox_Bookmark; + _btnBookmarkComment.Text = Resources.HighlightDialog_UI_Button_BookmarkComment; + _checkBoxStopTail.Text = Resources.HighlightDialog_UI_CheckBox_StopTail; + _checkBoxDontDirtyLed.Text = Resources.HighlightDialog_UI_CheckBox_DontDirtyLed; + _checkBoxPlugin.Text = Resources.HighlightDialog_UI_CheckBox_Plugin; + _btnSelectPlugin.Text = Resources.HighlightDialog_UI_Button_SelectPlugin; + _checkBoxAlertOnHit.Text = Resources.HighlightDialog_UI_CheckBox_AlertOnHit; + _labelSoundFile.Text = Resources.HighlightDialog_UI_Label_SoundFile; + _btnBrowseSoundFile.Text = Resources.HighlightDialog_UI_Button_BrowseSoundFile; + _labelCooldown.Text = Resources.HighlightDialog_UI_Label_Cooldown; + _labelCooldownSeconds.Text = Resources.HighlightDialog_UI_Label_Seconds; + + _btnOk.Text = Resources.LogExpert_Common_UI_Button_OK; + _btnCancel.Text = Resources.LogExpert_Common_UI_Button_Cancel; + } + + private void LoadFromEntry () + { + _textBoxSearchString.Text = _entry.SearchText ?? string.Empty; + _checkBoxRegex.Checked = _entry.IsRegex; + _checkBoxCaseSensitive.Checked = _entry.IsCaseSensitive; + + SelectComboColor(_colorBoxForeground, _entry.ForegroundColor.IsEmpty ? Color.White : _entry.ForegroundColor); + SelectComboColor(_colorBoxBackground, _entry.BackgroundColor.IsEmpty ? Color.Gray : _entry.BackgroundColor); + + _checkBoxBold.Checked = _entry.IsBold; + _checkBoxWordMatch.Checked = _entry.IsWordMatch; + _checkBoxNoBackground.Checked = _entry.NoBackground; + + _checkBoxBookmark.Checked = _entry.IsSetBookmark; + _checkBoxStopTail.Checked = _entry.IsStopTail; + _checkBoxDontDirtyLed.Checked = _entry.IsLedSwitch; + _checkBoxPlugin.Checked = _entry.IsActionEntry; + + _checkBoxAlertOnHit.Checked = _entry.AlertOnHit; + _textBoxSoundFile.Text = _entry.SoundFilePath ?? string.Empty; + var cooldown = _entry.CooldownSeconds; + + if (cooldown < _numericCooldownSeconds.Minimum) + { + cooldown = (int)_numericCooldownSeconds.Minimum; + } + else if (cooldown > _numericCooldownSeconds.Maximum) + { + cooldown = (int)_numericCooldownSeconds.Maximum; + } + + _numericCooldownSeconds.Value = cooldown; + } + + private static void SelectComboColor (ColorComboBox combo, Color color) + { + combo.CustomColor = color; + + if (combo.Items.Contains(color)) + { + combo.SelectedIndex = combo.Items.Cast().ToList().LastIndexOf(color); + } + else + { + combo.SelectedItem = color; + } + } + + private void SaveToEntry () + { + _entry.SearchText = _textBoxSearchString.Text; + _entry.IsRegex = _checkBoxRegex.Checked; + _entry.IsCaseSensitive = _checkBoxCaseSensitive.Checked; + + _entry.ForegroundColor = _colorBoxForeground.SelectedItem is Color fg ? fg : _colorBoxForeground.SelectedColor; + _entry.BackgroundColor = _colorBoxBackground.SelectedItem is Color bg ? bg : _colorBoxBackground.SelectedColor; + _entry.IsBold = _checkBoxBold.Checked; + _entry.IsWordMatch = _checkBoxWordMatch.Checked; + _entry.NoBackground = _checkBoxNoBackground.Checked; + + _entry.IsSetBookmark = _checkBoxBookmark.Checked; + _entry.BookmarkComment = _bookmarkComment; + _entry.IsStopTail = _checkBoxStopTail.Checked; + _entry.IsLedSwitch = _checkBoxDontDirtyLed.Checked; + _entry.IsActionEntry = _checkBoxPlugin.Checked; + _entry.ActionEntry = (ActionEntry)_currentActionEntry.Clone(); + + _entry.AlertOnHit = _checkBoxAlertOnHit.Checked; + _entry.SoundFilePath = _textBoxSoundFile.Text?.Trim() ?? string.Empty; + _entry.CooldownSeconds = (int)_numericCooldownSeconds.Value; + } + + private void OnOkClick (object sender, EventArgs e) + { + // Validate Regex pattern (mirrors legacy CheckRegex) + if (_checkBoxRegex.Checked) + { + if (string.IsNullOrWhiteSpace(_textBoxSearchString.Text)) + { + ShowError(Resources.HighlightDialog_RegexError); + _tabControl.SelectedTab = _tabLineMatch; + _ = _textBoxSearchString.Focus(); + return; + } + + var (isValid, error) = RegexHelper.IsValidPattern(_textBoxSearchString.Text); + if (!isValid) + { + ShowError(error ?? Resources.HighlightDialog_RegexError); + _tabControl.SelectedTab = _tabLineMatch; + _ = _textBoxSearchString.Focus(); + return; + } + } + + try + { + SaveToEntry(); + } + catch (Exception ex) when (ex is ArgumentException + or RegexMatchTimeoutException + or ArgumentNullException + or InvalidOperationException + or SystemException) + { + ShowError(string.Format(CultureInfo.InvariantCulture, + _isNew + ? Resources.HighlightDialog_UI_ErrorDuringAddOfHighLightEntry + : Resources.HighlightDialog_UI_ErrorDuringSavingOfHighlightEntry, + ex.Message)); + return; + } + + DialogResult = DialogResult.OK; + Close(); + } + + private void ShowError (string message) + { + _ = MessageBox.Show(this, message, + Resources.LogExpert_Common_UI_Title_Error, + MessageBoxButtons.OK, + MessageBoxIcon.Error); + } + + private void OnSearchStringChanged (object sender, EventArgs e) + { + UpdateOkEnabled(); + UpdateTitle(); + UpdatePreview(); + } + + private void OnSearchStringMouseUp (object sender, MouseEventArgs e) + { + // Legacy parity: right-click on search box (when Regex is on) used to be + // bound to the regex test helper via the checkbox; we keep that gesture + // available here when the user right-clicks the search string itself. + if (e.Button == MouseButtons.Right && _checkBoxRegex.Checked) + { + OpenRegexHelper(); + } + } + + private void OnRegexMouseUp (object sender, MouseEventArgs e) + { + if (e.Button == MouseButtons.Right) + { + OpenRegexHelper(); + } + } + + private void OpenRegexHelper () + { + using RegexHelperDialog dlg = new() + { + Owner = this, + CaseSensitive = _checkBoxCaseSensitive.Checked, + Pattern = _textBoxSearchString.Text, + }; + + if (dlg.ShowDialog() == DialogResult.OK) + { + _checkBoxCaseSensitive.Checked = dlg.CaseSensitive; + _textBoxSearchString.Text = dlg.Pattern; + } + } + + private void OnBookmarkChanged (object sender, EventArgs e) + { + UpdateBookmarkCommentEnabled(); + } + + private void OnBookmarkCommentClick (object sender, EventArgs e) + { + using BookmarkCommentDlg dlg = new() + { + Comment = _bookmarkComment, + }; + + if (dlg.ShowDialog(this) == DialogResult.OK) + { + _bookmarkComment = dlg.Comment; + } + } + + private void OnPluginChanged (object sender, EventArgs e) + { + UpdatePluginEnabled(); + } + + private void OnSelectPluginClick (object sender, EventArgs e) + { + using KeywordActionDlg dlg = new(_currentActionEntry, _keywordActionList); + if (dlg.ShowDialog(this) == DialogResult.OK) + { + _currentActionEntry = dlg.ActionEntry; + } + } + + private void OnAlertOnHitChanged (object sender, EventArgs e) + { + UpdateAlertEnabled(); + } + + private void OnBrowseSoundFileClick (object sender, EventArgs e) + { + using OpenFileDialog dlg = new() + { + Title = Resources.HighlightDialog_UI_Label_SoundFile, + Filter = Resources.HighlightDialog_UI_OpenFileFilter_Audio, + CheckFileExists = true, + Multiselect = false, + }; + + if (!string.IsNullOrWhiteSpace(_textBoxSoundFile.Text)) + { + try + { + var existingDir = Path.GetDirectoryName(_textBoxSoundFile.Text); + if (!string.IsNullOrEmpty(existingDir) && Directory.Exists(existingDir)) + { + dlg.InitialDirectory = existingDir; + } + } + catch (Exception ex) when (ex is ArgumentException or PathTooLongException) + { + // Ignore invalid existing path; the dialog will use its default. + } + } + + if (dlg.ShowDialog(this) == DialogResult.OK) + { + _textBoxSoundFile.Text = dlg.FileName; + } + } + + private void OnWordMatchChanged (object sender, EventArgs e) + { + UpdateNoBackgroundEnabled(); + } + + private void OnNoBackgroundChanged (object sender, EventArgs e) + { + UpdateBackgroundColorEnabled(); + UpdatePreview(); + } + + private void OnColorOrStyleChanged (object sender, EventArgs e) + { + UpdatePreview(); + } + + private void UpdateTitle () + { + if (_isNew) + { + Text = Resources.HighlightEntryEditDialog_UI_Title_Add; + return; + } + + var search = _textBoxSearchString.Text ?? string.Empty; + Text = string.Format(CultureInfo.CurrentCulture, Resources.HighlightEntryEditDialog_UI_Title_EditFormat, search); + } + + private void UpdateOkEnabled () + { + _btnOk.Enabled = !string.IsNullOrEmpty(_textBoxSearchString.Text); + } + + private void UpdateAlertEnabled () + { + var on = _checkBoxAlertOnHit.Checked; + _textBoxSoundFile.Enabled = on; + _btnBrowseSoundFile.Enabled = on; + _numericCooldownSeconds.Enabled = on; + } + + private void UpdateBookmarkCommentEnabled () + { + _btnBookmarkComment.Enabled = _checkBoxBookmark.Checked; + } + + private void UpdatePluginEnabled () + { + _btnSelectPlugin.Enabled = _checkBoxPlugin.Checked; + } + + private void UpdateNoBackgroundEnabled () + { + _checkBoxNoBackground.Enabled = _checkBoxWordMatch.Checked; + } + + private void UpdateBackgroundColorEnabled () + { + var enabled = !_checkBoxNoBackground.Checked; + _colorBoxBackground.Enabled = enabled; + _btnCustomBackColor.Enabled = enabled; + } + + private void UpdatePreview () + { + if (_previewLabel == null) + { + return; + } + + var text = _textBoxSearchString?.Text ?? string.Empty; + _previewLabel.Text = string.IsNullOrEmpty(text) + ? Resources.HighlightEntryEditDialog_UI_Preview_Placeholder + : text; + + _previewLabel.ForeColor = GetSelectedColor(_colorBoxForeground, Color.Black); + + _previewLabel.BackColor = _checkBoxNoBackground != null && _checkBoxNoBackground.Checked + ? SystemColors.Window + : GetSelectedColor(_colorBoxBackground, SystemColors.Window); + + var bold = _checkBoxBold != null && _checkBoxBold.Checked; + var baseFont = Font; + var desiredStyle = bold ? FontStyle.Bold : FontStyle.Regular; + if (_previewLabel.Font.Style != desiredStyle || _previewLabel.Font.FontFamily.Name != baseFont.FontFamily.Name) + { + var previousFont = _previewLabel.Font; + _previewLabel.Font = new Font(baseFont, desiredStyle); + if (!ReferenceEquals(previousFont, baseFont)) + { + previousFont.Dispose(); + } + } + } + + private static Color GetSelectedColor (ColorComboBox combo, Color fallback) + { + return combo == null + ? fallback + : combo.SelectedItem is Color selected + ? selected + : combo.CustomColor.IsEmpty + ? fallback + : combo.CustomColor; + } + + private void ChooseColor (ColorComboBox comboBox) + { + using ColorDialog colorDialog = new() + { + AllowFullOpen = true, + ShowHelp = false, + Color = comboBox.CustomColor, + }; + + if (colorDialog.ShowDialog() == DialogResult.OK) + { + comboBox.CustomColor = colorDialog.Color; + comboBox.SelectedIndex = 0; + UpdatePreview(); + } + } + + private void OnBtnCustomForeColorClicked (object sender, EventArgs e) + { + ChooseColor(_colorBoxForeground); + } + + private void OnBtnCustomBackColorClicked (object sender, EventArgs e) + { + ChooseColor(_colorBoxBackground); + } +} diff --git a/src/LogExpert.UI/Dialogs/Highlight/HighlightEntryDialog.resx b/src/LogExpert.UI/Dialogs/Highlight/HighlightEntryDialog.resx new file mode 100644 index 00000000..1af7de15 --- /dev/null +++ b/src/LogExpert.UI/Dialogs/Highlight/HighlightEntryDialog.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/src/LogExpert.UI/Dialogs/HighlightDialog.Designer.cs b/src/LogExpert.UI/Dialogs/HighlightDialog.Designer.cs deleted file mode 100644 index af7d8866..00000000 --- a/src/LogExpert.UI/Dialogs/HighlightDialog.Designer.cs +++ /dev/null @@ -1,728 +0,0 @@ -using LogExpert.UI.Controls; - -using System.Drawing; - -namespace LogExpert.Dialogs; - -partial class HighlightDialog -{ - /// - /// Required designer variable. - /// - private System.ComponentModel.IContainer components = null; - - /// - /// Clean up any resources being used. - /// - /// true if managed resources should be disposed; otherwise, false. - protected override void Dispose(bool disposing) - { - if (disposing && (components != null)) - { - components.Dispose(); - } - base.Dispose(disposing); - } - - #region Windows Form Designer generated code - - /// - /// Required method for Designer support - do not modify - /// the contents of this method with the code editor. - /// - private void InitializeComponent () - { - components = new System.ComponentModel.Container(); - var resources = new System.ComponentModel.ComponentResourceManager(typeof(HighlightDialog)); - listBoxHighlight = new ListBox(); - btnAdd = new Button(); - btnDelete = new Button(); - btnMoveUp = new Button(); - btnMoveDown = new Button(); - labelForgroundColor = new Label(); - labelBackgroundColor = new Label(); - btnOk = new Button(); - btnCancel = new Button(); - textBoxSearchString = new TextBox(); - labelSearchString = new Label(); - btnApply = new Button(); - btnCustomForeColor = new Button(); - btnCustomBackColor = new Button(); - checkBoxRegex = new CheckBox(); - checkBoxCaseSensitive = new CheckBox(); - checkBoxDontDirtyLed = new CheckBox(); - groupBoxLineMatchCriteria = new GroupBox(); - groupBoxColoring = new GroupBox(); - checkBoxNoBackground = new CheckBox(); - checkBoxBold = new CheckBox(); - checkBoxWordMatch = new CheckBox(); - colorBoxForeground = new ColorComboBox(); - colorBoxBackground = new ColorComboBox(); - groupBoxActions = new GroupBox(); - btnBookmarkComment = new Button(); - btnSelectPlugin = new Button(); - checkBoxPlugin = new CheckBox(); - checkBoxStopTail = new CheckBox(); - checkBoxBookmark = new CheckBox(); - helpProvider = new HelpProvider(); - groupBoxGroups = new GroupBox(); - btnImportGroup = new Button(); - btnExportGroup = new Button(); - btnMoveGroupDown = new Button(); - btnMoveGroupUp = new Button(); - labelAssignNamesToGroups = new Label(); - btnCopyGroup = new Button(); - btnDeleteGroup = new Button(); - btnNewGroup = new Button(); - comboBoxGroups = new ComboBox(); - toolTip = new ToolTip(components); - pnlBackground = new Panel(); - groupBoxLineMatchCriteria.SuspendLayout(); - groupBoxColoring.SuspendLayout(); - groupBoxActions.SuspendLayout(); - groupBoxGroups.SuspendLayout(); - pnlBackground.SuspendLayout(); - SuspendLayout(); - // - // listBoxHighlight - // - listBoxHighlight.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right; - listBoxHighlight.DrawMode = DrawMode.OwnerDrawFixed; - listBoxHighlight.FormattingEnabled = true; - listBoxHighlight.Location = new Point(32, 129); - listBoxHighlight.Margin = new Padding(4, 5, 4, 5); - listBoxHighlight.Name = "listBoxHighlight"; - listBoxHighlight.Size = new Size(413, 180); - listBoxHighlight.TabIndex = 0; - listBoxHighlight.SelectedIndexChanged += OnListBoxHighlightSelectedIndexChanged; - // - // btnAdd - // - btnAdd.Anchor = AnchorStyles.Top | AnchorStyles.Right; - btnAdd.Location = new Point(453, 187); - btnAdd.Margin = new Padding(4, 5, 4, 5); - btnAdd.Name = "btnAdd"; - btnAdd.Size = new Size(158, 35); - btnAdd.TabIndex = 1; - btnAdd.Text = "&Add"; - toolTip.SetToolTip(btnAdd, "Create a new hilight item from information below"); - btnAdd.UseVisualStyleBackColor = true; - btnAdd.Click += OnAddButtonClick; - // - // btnDelete - // - btnDelete.Anchor = AnchorStyles.Top | AnchorStyles.Right; - btnDelete.Location = new Point(453, 232); - btnDelete.Margin = new Padding(4, 5, 4, 5); - btnDelete.Name = "btnDelete"; - btnDelete.Size = new Size(158, 35); - btnDelete.TabIndex = 2; - btnDelete.Text = "D&elete"; - toolTip.SetToolTip(btnDelete, "Delete the current hilight"); - btnDelete.UseVisualStyleBackColor = true; - btnDelete.Click += OnDeleteButtonClick; - // - // btnMoveUp - // - btnMoveUp.Anchor = AnchorStyles.Top | AnchorStyles.Right; - btnMoveUp.Location = new Point(453, 129); - btnMoveUp.Margin = new Padding(4, 5, 4, 5); - btnMoveUp.Name = "btnMoveUp"; - btnMoveUp.Size = new Size(75, 35); - btnMoveUp.TabIndex = 3; - btnMoveUp.Text = "&Up"; - toolTip.SetToolTip(btnMoveUp, "Move the current hilight one position up"); - btnMoveUp.UseVisualStyleBackColor = true; - btnMoveUp.Click += OnBtnMoveUpClick; - // - // btnMoveDown - // - btnMoveDown.Anchor = AnchorStyles.Top | AnchorStyles.Right; - btnMoveDown.Location = new Point(536, 129); - btnMoveDown.Margin = new Padding(4, 5, 4, 5); - btnMoveDown.Name = "btnMoveDown"; - btnMoveDown.Size = new Size(75, 35); - btnMoveDown.TabIndex = 4; - btnMoveDown.Text = "&Down"; - toolTip.SetToolTip(btnMoveDown, "Move the current hilight one position down"); - btnMoveDown.UseVisualStyleBackColor = true; - btnMoveDown.Click += OnBtnMoveDownClick; - // - // labelForgroundColor - // - labelForgroundColor.AutoSize = true; - labelForgroundColor.Location = new Point(9, 38); - labelForgroundColor.Margin = new Padding(4, 0, 4, 0); - labelForgroundColor.Name = "labelForgroundColor"; - labelForgroundColor.Size = new Size(99, 15); - labelForgroundColor.TabIndex = 6; - labelForgroundColor.Text = "Foreground color"; - // - // labelBackgroundColor - // - labelBackgroundColor.AutoSize = true; - labelBackgroundColor.Location = new Point(9, 115); - labelBackgroundColor.Margin = new Padding(4, 0, 4, 0); - labelBackgroundColor.Name = "labelBackgroundColor"; - labelBackgroundColor.Size = new Size(101, 15); - labelBackgroundColor.TabIndex = 8; - labelBackgroundColor.Text = "Background color"; - // - // btnOk - // - btnOk.Anchor = AnchorStyles.Bottom | AnchorStyles.Right; - btnOk.DialogResult = DialogResult.OK; - btnOk.Location = new Point(372, 718); - btnOk.Margin = new Padding(4, 5, 4, 5); - btnOk.Name = "btnOk"; - btnOk.Size = new Size(112, 35); - btnOk.TabIndex = 9; - btnOk.Text = "OK"; - btnOk.UseVisualStyleBackColor = true; - btnOk.Click += OnBtnOkClick; - // - // btnCancel - // - btnCancel.Anchor = AnchorStyles.Bottom | AnchorStyles.Right; - btnCancel.DialogResult = DialogResult.Cancel; - btnCancel.Location = new Point(499, 718); - btnCancel.Margin = new Padding(4, 5, 4, 5); - btnCancel.Name = "btnCancel"; - btnCancel.Size = new Size(112, 35); - btnCancel.TabIndex = 10; - btnCancel.Text = "Cancel"; - btnCancel.UseVisualStyleBackColor = true; - // - // textBoxSearchString - // - textBoxSearchString.Anchor = AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right; - textBoxSearchString.Location = new Point(9, 55); - textBoxSearchString.Margin = new Padding(4, 5, 4, 5); - textBoxSearchString.Name = "textBoxSearchString"; - textBoxSearchString.Size = new Size(575, 23); - textBoxSearchString.TabIndex = 11; - textBoxSearchString.TextChanged += ChangeToDirty; - // - // labelSearchString - // - labelSearchString.AutoSize = true; - labelSearchString.Location = new Point(9, 31); - labelSearchString.Margin = new Padding(4, 0, 4, 0); - labelSearchString.Name = "labelSearchString"; - labelSearchString.Size = new Size(78, 15); - labelSearchString.TabIndex = 12; - labelSearchString.Text = "Search string:"; - // - // btnApply - // - btnApply.Anchor = AnchorStyles.Top | AnchorStyles.Right; - btnApply.Enabled = false; - btnApply.Image = (Image)resources.GetObject("btnApply.Image"); - btnApply.ImageAlign = ContentAlignment.MiddleRight; - btnApply.Location = new Point(453, 277); - btnApply.Margin = new Padding(4, 5, 4, 5); - btnApply.Name = "btnApply"; - btnApply.Size = new Size(158, 35); - btnApply.TabIndex = 13; - btnApply.Text = "A&pply"; - toolTip.SetToolTip(btnApply, "Apply changes below to current hiligth"); - btnApply.UseVisualStyleBackColor = true; - btnApply.Click += OnBtnApplyClick; - // - // btnCustomForeColor - // - btnCustomForeColor.Anchor = AnchorStyles.Top | AnchorStyles.Right; - btnCustomForeColor.Location = new Point(183, 60); - btnCustomForeColor.Margin = new Padding(4, 5, 4, 5); - btnCustomForeColor.Name = "btnCustomForeColor"; - btnCustomForeColor.Size = new Size(78, 35); - btnCustomForeColor.TabIndex = 14; - btnCustomForeColor.Text = "Custom"; - toolTip.SetToolTip(btnCustomForeColor, "Pick a custom foreground color"); - btnCustomForeColor.UseVisualStyleBackColor = true; - btnCustomForeColor.Click += OnBtnCustomForeColorClick; - // - // btnCustomBackColor - // - btnCustomBackColor.Anchor = AnchorStyles.Top | AnchorStyles.Right; - btnCustomBackColor.Location = new Point(183, 137); - btnCustomBackColor.Margin = new Padding(4, 5, 4, 5); - btnCustomBackColor.Name = "btnCustomBackColor"; - btnCustomBackColor.Size = new Size(78, 35); - btnCustomBackColor.TabIndex = 15; - btnCustomBackColor.Text = "Custom"; - toolTip.SetToolTip(btnCustomBackColor, "Pick a custom background color"); - btnCustomBackColor.UseVisualStyleBackColor = true; - btnCustomBackColor.Click += OnBtnCustomBackColorClick; - // - // checkBoxRegex - // - checkBoxRegex.AutoSize = true; - checkBoxRegex.Location = new Point(180, 95); - checkBoxRegex.Margin = new Padding(4, 5, 4, 5); - checkBoxRegex.Name = "checkBoxRegex"; - checkBoxRegex.Size = new Size(58, 19); - checkBoxRegex.TabIndex = 16; - checkBoxRegex.Text = "RegEx"; - toolTip.SetToolTip(checkBoxRegex, "Whether the string is a regular expresion"); - checkBoxRegex.UseVisualStyleBackColor = true; - checkBoxRegex.CheckedChanged += ChangeToDirty; - checkBoxRegex.MouseUp += OnChkBoxRegexMouseUp; - // - // checkBoxCaseSensitive - // - checkBoxCaseSensitive.AutoSize = true; - checkBoxCaseSensitive.Location = new Point(14, 95); - checkBoxCaseSensitive.Margin = new Padding(4, 5, 4, 5); - checkBoxCaseSensitive.Name = "checkBoxCaseSensitive"; - checkBoxCaseSensitive.Size = new Size(99, 19); - checkBoxCaseSensitive.TabIndex = 17; - checkBoxCaseSensitive.Text = "Case sensitive"; - toolTip.SetToolTip(checkBoxCaseSensitive, "Whether the string will match uppercases and lowercases"); - checkBoxCaseSensitive.UseVisualStyleBackColor = true; - checkBoxCaseSensitive.CheckedChanged += ChangeToDirty; - // - // checkBoxDontDirtyLed - // - checkBoxDontDirtyLed.AutoSize = true; - checkBoxDontDirtyLed.Location = new Point(15, 38); - checkBoxDontDirtyLed.Margin = new Padding(4, 5, 4, 5); - checkBoxDontDirtyLed.Name = "checkBoxDontDirtyLed"; - checkBoxDontDirtyLed.Size = new Size(118, 19); - checkBoxDontDirtyLed.TabIndex = 18; - checkBoxDontDirtyLed.Text = "Don't lit dirty LED"; - toolTip.SetToolTip(checkBoxDontDirtyLed, "When matching a line, don't mark the page as \"dirty\""); - checkBoxDontDirtyLed.UseVisualStyleBackColor = true; - checkBoxDontDirtyLed.CheckedChanged += ChangeToDirty; - // - // groupBoxLineMatchCriteria - // - groupBoxLineMatchCriteria.Anchor = AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right; - groupBoxLineMatchCriteria.Controls.Add(textBoxSearchString); - groupBoxLineMatchCriteria.Controls.Add(labelSearchString); - groupBoxLineMatchCriteria.Controls.Add(checkBoxRegex); - groupBoxLineMatchCriteria.Controls.Add(checkBoxCaseSensitive); - groupBoxLineMatchCriteria.Location = new Point(18, 322); - groupBoxLineMatchCriteria.Margin = new Padding(4, 5, 4, 5); - groupBoxLineMatchCriteria.Name = "groupBoxLineMatchCriteria"; - groupBoxLineMatchCriteria.Padding = new Padding(4, 5, 4, 5); - groupBoxLineMatchCriteria.Size = new Size(607, 135); - groupBoxLineMatchCriteria.TabIndex = 19; - groupBoxLineMatchCriteria.TabStop = false; - groupBoxLineMatchCriteria.Text = "Line match criteria"; - // - // groupBoxColoring - // - groupBoxColoring.Anchor = AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right; - groupBoxColoring.Controls.Add(checkBoxNoBackground); - groupBoxColoring.Controls.Add(checkBoxBold); - groupBoxColoring.Controls.Add(checkBoxWordMatch); - groupBoxColoring.Controls.Add(labelForgroundColor); - groupBoxColoring.Controls.Add(colorBoxForeground); - groupBoxColoring.Controls.Add(btnCustomForeColor); - groupBoxColoring.Controls.Add(btnCustomBackColor); - groupBoxColoring.Controls.Add(labelBackgroundColor); - groupBoxColoring.Controls.Add(colorBoxBackground); - groupBoxColoring.Location = new Point(18, 467); - groupBoxColoring.Margin = new Padding(4, 5, 4, 5); - groupBoxColoring.Name = "groupBoxColoring"; - groupBoxColoring.Padding = new Padding(4, 5, 4, 5); - groupBoxColoring.Size = new Size(285, 286); - groupBoxColoring.TabIndex = 20; - groupBoxColoring.TabStop = false; - groupBoxColoring.Text = "Coloring"; - // - // checkBoxNoBackground - // - checkBoxNoBackground.AutoSize = true; - checkBoxNoBackground.Enabled = false; - checkBoxNoBackground.Location = new Point(141, 240); - checkBoxNoBackground.Margin = new Padding(4, 5, 4, 5); - checkBoxNoBackground.Name = "checkBoxNoBackground"; - checkBoxNoBackground.Size = new Size(109, 19); - checkBoxNoBackground.TabIndex = 18; - checkBoxNoBackground.Text = "No Background"; - toolTip.SetToolTip(checkBoxNoBackground, "Don't set the background color"); - checkBoxNoBackground.UseVisualStyleBackColor = true; - checkBoxNoBackground.CheckedChanged += OnChkBoxNoBackgroundCheckedChanged; - // - // checkBoxBold - // - checkBoxBold.AutoSize = true; - checkBoxBold.Location = new Point(9, 205); - checkBoxBold.Margin = new Padding(4, 5, 4, 5); - checkBoxBold.Name = "checkBoxBold"; - checkBoxBold.Size = new Size(50, 19); - checkBoxBold.TabIndex = 17; - checkBoxBold.Text = "Bold"; - toolTip.SetToolTip(checkBoxBold, "Display the line in bold characters"); - checkBoxBold.UseVisualStyleBackColor = true; - checkBoxBold.CheckedChanged += OnChkBoxBoldCheckedChanged; - // - // checkBoxWordMatch - // - checkBoxWordMatch.AutoSize = true; - checkBoxWordMatch.Location = new Point(9, 240); - checkBoxWordMatch.Margin = new Padding(4, 5, 4, 5); - checkBoxWordMatch.Name = "checkBoxWordMatch"; - checkBoxWordMatch.Size = new Size(89, 19); - checkBoxWordMatch.TabIndex = 16; - checkBoxWordMatch.Text = "Word mode"; - toolTip.SetToolTip(checkBoxWordMatch, "Don't highlight the whole line but only the matching keywords"); - checkBoxWordMatch.UseVisualStyleBackColor = true; - checkBoxWordMatch.CheckedChanged += OnChkBoxWordMatchCheckedChanged; - // - // colorBoxForeground - // - colorBoxForeground.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right; - colorBoxForeground.CustomColor = Color.Black; - colorBoxForeground.DrawMode = DrawMode.OwnerDrawFixed; - colorBoxForeground.DropDownStyle = ComboBoxStyle.DropDownList; - colorBoxForeground.FormattingEnabled = true; - colorBoxForeground.Items.AddRange(new object[] { Color.Black, Color.White, Color.Gray, Color.DarkGray, Color.Blue, Color.LightBlue, Color.DarkBlue, Color.Green, Color.LightGreen, Color.DarkGreen, Color.Olive, Color.Red, Color.Pink, Color.Purple, Color.IndianRed, Color.DarkCyan, Color.Yellow}); - colorBoxForeground.Location = new Point(8, 63); - colorBoxForeground.Margin = new Padding(4, 5, 4, 5); - colorBoxForeground.Name = "colorBoxForeground"; - colorBoxForeground.Size = new Size(165, 24); - colorBoxForeground.TabIndex = 5; - colorBoxForeground.SelectedIndexChanged += ChangeToDirty; - // - // colorBoxBackground - // - colorBoxBackground.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right; - colorBoxBackground.CustomColor = Color.Black; - colorBoxBackground.DrawMode = DrawMode.OwnerDrawFixed; - colorBoxBackground.DropDownStyle = ComboBoxStyle.DropDownList; - colorBoxBackground.FormattingEnabled = true; - colorBoxBackground.Items.AddRange(new object[] { Color.Black, Color.White, Color.Gray, Color.DarkGray, Color.Blue, Color.LightBlue, Color.DarkBlue, Color.Green, Color.LightGreen, Color.DarkGreen, Color.Olive, Color.Red, Color.Pink, Color.Purple, Color.IndianRed, Color.DarkCyan, Color.Yellow }); - colorBoxBackground.Location = new Point(9, 140); - colorBoxBackground.Margin = new Padding(4, 5, 4, 5); - colorBoxBackground.Name = "colorBoxBackground"; - colorBoxBackground.Size = new Size(165, 24); - colorBoxBackground.TabIndex = 7; - colorBoxBackground.SelectedIndexChanged += ChangeToDirty; - // - // groupBoxActions - // - groupBoxActions.Anchor = AnchorStyles.Bottom | AnchorStyles.Right; - groupBoxActions.Controls.Add(btnBookmarkComment); - groupBoxActions.Controls.Add(btnSelectPlugin); - groupBoxActions.Controls.Add(checkBoxPlugin); - groupBoxActions.Controls.Add(checkBoxStopTail); - groupBoxActions.Controls.Add(checkBoxBookmark); - groupBoxActions.Controls.Add(checkBoxDontDirtyLed); - groupBoxActions.Location = new Point(313, 467); - groupBoxActions.Margin = new Padding(4, 5, 4, 5); - groupBoxActions.Name = "groupBoxActions"; - groupBoxActions.Padding = new Padding(4, 5, 4, 5); - groupBoxActions.Size = new Size(312, 195); - groupBoxActions.TabIndex = 21; - groupBoxActions.TabStop = false; - groupBoxActions.Text = "Actions"; - // - // btnBookmarkComment - // - btnBookmarkComment.Anchor = AnchorStyles.Top | AnchorStyles.Right; - btnBookmarkComment.Location = new Point(210, 69); - btnBookmarkComment.Margin = new Padding(4, 5, 4, 5); - btnBookmarkComment.Name = "btnBookmarkComment"; - btnBookmarkComment.Size = new Size(81, 31); - btnBookmarkComment.TabIndex = 23; - btnBookmarkComment.Text = "Text..."; - btnBookmarkComment.UseVisualStyleBackColor = true; - btnBookmarkComment.Click += OnBtnBookmarkCommentClick; - // - // btnSelectPlugin - // - btnSelectPlugin.Anchor = AnchorStyles.Top | AnchorStyles.Right; - btnSelectPlugin.Location = new Point(210, 143); - btnSelectPlugin.Margin = new Padding(4, 5, 4, 5); - btnSelectPlugin.Name = "btnSelectPlugin"; - btnSelectPlugin.Size = new Size(81, 31); - btnSelectPlugin.TabIndex = 22; - btnSelectPlugin.Text = "Select..."; - btnSelectPlugin.UseVisualStyleBackColor = true; - btnSelectPlugin.Click += OnPluginButtonClick; - // - // checkBoxPlugin - // - checkBoxPlugin.AutoSize = true; - checkBoxPlugin.Location = new Point(15, 148); - checkBoxPlugin.Margin = new Padding(4, 5, 4, 5); - checkBoxPlugin.Name = "checkBoxPlugin"; - checkBoxPlugin.Size = new Size(60, 19); - checkBoxPlugin.TabIndex = 21; - checkBoxPlugin.Text = "Plugin"; - toolTip.SetToolTip(checkBoxPlugin, "When matching a line, call a keyword action plugin"); - checkBoxPlugin.UseVisualStyleBackColor = true; - checkBoxPlugin.CheckedChanged += OnChkBoxPluginCheckedChanged; - // - // checkBoxStopTail - // - checkBoxStopTail.AutoSize = true; - checkBoxStopTail.Location = new Point(15, 111); - checkBoxStopTail.Margin = new Padding(4, 5, 4, 5); - checkBoxStopTail.Name = "checkBoxStopTail"; - checkBoxStopTail.Size = new Size(108, 19); - checkBoxStopTail.TabIndex = 20; - checkBoxStopTail.Text = "Stop Follow Tail"; - toolTip.SetToolTip(checkBoxStopTail, "When matching a line, stop automatic scrolling"); - checkBoxStopTail.UseVisualStyleBackColor = true; - checkBoxStopTail.CheckedChanged += ChangeToDirty; - // - // checkBoxBookmark - // - checkBoxBookmark.AutoSize = true; - checkBoxBookmark.Location = new Point(15, 74); - checkBoxBookmark.Margin = new Padding(4, 5, 4, 5); - checkBoxBookmark.Name = "checkBoxBookmark"; - checkBoxBookmark.Size = new Size(99, 19); - checkBoxBookmark.TabIndex = 19; - checkBoxBookmark.Text = "Set bookmark"; - toolTip.SetToolTip(checkBoxBookmark, "When matching a line, create a new bookmark for it"); - checkBoxBookmark.UseVisualStyleBackColor = true; - checkBoxBookmark.CheckedChanged += ChangeToDirty; - // - // helpProvider - // - helpProvider.HelpNamespace = "LogExpert.chm"; - helpProvider.Tag = ""; - // - // groupBox4 - // - groupBoxGroups.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right; - groupBoxGroups.Controls.Add(btnImportGroup); - groupBoxGroups.Controls.Add(btnExportGroup); - groupBoxGroups.Controls.Add(btnMoveGroupDown); - groupBoxGroups.Controls.Add(btnMoveGroupUp); - groupBoxGroups.Controls.Add(labelAssignNamesToGroups); - groupBoxGroups.Controls.Add(btnCopyGroup); - groupBoxGroups.Controls.Add(btnDeleteGroup); - groupBoxGroups.Controls.Add(btnNewGroup); - groupBoxGroups.Controls.Add(comboBoxGroups); - groupBoxGroups.Location = new Point(18, 5); - groupBoxGroups.Margin = new Padding(4, 5, 4, 5); - groupBoxGroups.Name = "groupBox4"; - groupBoxGroups.Padding = new Padding(4, 5, 4, 5); - groupBoxGroups.Size = new Size(607, 114); - groupBoxGroups.TabIndex = 22; - groupBoxGroups.TabStop = false; - groupBoxGroups.Text = "Groups"; - // - // btnImportGroup - // - btnImportGroup.Anchor = AnchorStyles.Bottom | AnchorStyles.Right; - btnImportGroup.Location = new Point(269, 11); - btnImportGroup.Margin = new Padding(4, 5, 4, 5); - btnImportGroup.Name = "btnImportGroup"; - btnImportGroup.Size = new Size(75, 35); - btnImportGroup.TabIndex = 7; - btnImportGroup.Text = "Import"; - toolTip.SetToolTip(btnImportGroup, "Import highlight groups"); - btnImportGroup.UseVisualStyleBackColor = true; - btnImportGroup.Click += OnBtnImportGroupClick; - // - // btnExportGroup - // - btnExportGroup.Anchor = AnchorStyles.Bottom | AnchorStyles.Right; - btnExportGroup.Location = new Point(269, 53); - btnExportGroup.Margin = new Padding(4, 5, 4, 5); - btnExportGroup.Name = "btnExportGroup"; - btnExportGroup.Size = new Size(75, 35); - btnExportGroup.TabIndex = 8; - btnExportGroup.Text = "Export"; - toolTip.SetToolTip(btnExportGroup, "Export highlight groups"); - btnExportGroup.UseVisualStyleBackColor = true; - btnExportGroup.Click += OnBtnExportGroupClick; - // - // btnMoveGroupDown - // - btnMoveGroupDown.Anchor = AnchorStyles.Bottom | AnchorStyles.Right; - btnMoveGroupDown.Location = new Point(518, 56); - btnMoveGroupDown.Margin = new Padding(4, 5, 4, 5); - btnMoveGroupDown.Name = "btnMoveGroupDown"; - btnMoveGroupDown.Size = new Size(75, 35); - btnMoveGroupDown.TabIndex = 6; - btnMoveGroupDown.Text = "Down"; - toolTip.SetToolTip(btnMoveGroupDown, "Move the current hilight group one position down"); - btnMoveGroupDown.UseVisualStyleBackColor = true; - btnMoveGroupDown.Click += OnBtnGroupDownClick; - // - // btnMoveGroupUp - // - btnMoveGroupUp.Anchor = AnchorStyles.Bottom | AnchorStyles.Right; - btnMoveGroupUp.Location = new Point(435, 53); - btnMoveGroupUp.Margin = new Padding(4, 5, 4, 5); - btnMoveGroupUp.Name = "btnMoveGroupUp"; - btnMoveGroupUp.Size = new Size(75, 35); - btnMoveGroupUp.TabIndex = 5; - btnMoveGroupUp.Text = "Up"; - toolTip.SetToolTip(btnMoveGroupUp, "Move the current hilight group one position up"); - btnMoveGroupUp.UseVisualStyleBackColor = true; - btnMoveGroupUp.Click += OnBtnGroupUpClick; - // - // labelAssignNamesToGroups - // - labelAssignNamesToGroups.Anchor = AnchorStyles.Left | AnchorStyles.Right; - labelAssignNamesToGroups.AutoSize = true; - labelAssignNamesToGroups.Location = new Point(8, 93); - labelAssignNamesToGroups.Margin = new Padding(4, 0, 4, 0); - labelAssignNamesToGroups.Name = "labelAssignNamesToGroups"; - labelAssignNamesToGroups.Size = new Size(276, 15); - labelAssignNamesToGroups.TabIndex = 4; - labelAssignNamesToGroups.Text = "You can assign groups to file names in the settings."; - // - // btnCopyGroup - // - btnCopyGroup.Anchor = AnchorStyles.Bottom | AnchorStyles.Right; - btnCopyGroup.Location = new Point(518, 11); - btnCopyGroup.Margin = new Padding(4, 5, 4, 5); - btnCopyGroup.Name = "btnCopyGroup"; - btnCopyGroup.Size = new Size(75, 35); - btnCopyGroup.TabIndex = 3; - btnCopyGroup.Text = "Copy"; - toolTip.SetToolTip(btnCopyGroup, "Copy the current hilight group into a new one"); - btnCopyGroup.UseVisualStyleBackColor = true; - btnCopyGroup.Click += OnBtnCopyGroupClick; - // - // btnDeleteGroup - // - btnDeleteGroup.Anchor = AnchorStyles.Bottom | AnchorStyles.Right; - btnDeleteGroup.Location = new Point(435, 11); - btnDeleteGroup.Margin = new Padding(4, 5, 4, 5); - btnDeleteGroup.Name = "btnDeleteGroup"; - btnDeleteGroup.Size = new Size(75, 35); - btnDeleteGroup.TabIndex = 2; - btnDeleteGroup.Text = "Del"; - toolTip.SetToolTip(btnDeleteGroup, "Delete the current hilight group"); - btnDeleteGroup.UseVisualStyleBackColor = true; - btnDeleteGroup.Click += OnBtnDelGroupClick; - // - // btnNewGroup - // - btnNewGroup.Anchor = AnchorStyles.Bottom | AnchorStyles.Right; - btnNewGroup.Location = new Point(352, 11); - btnNewGroup.Margin = new Padding(4, 5, 4, 5); - btnNewGroup.Name = "btnNewGroup"; - btnNewGroup.Size = new Size(75, 35); - btnNewGroup.TabIndex = 1; - btnNewGroup.Text = "New group"; - btnNewGroup.TextAlign = ContentAlignment.MiddleLeft; - toolTip.SetToolTip(btnNewGroup, "Create a new empty hilight group"); - btnNewGroup.UseVisualStyleBackColor = true; - btnNewGroup.Click += OnBtnNewGroupClick; - // - // comboBoxGroups - // - comboBoxGroups.Anchor = AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right; - comboBoxGroups.DisplayMember = "GroupName"; - comboBoxGroups.DrawMode = DrawMode.OwnerDrawFixed; - comboBoxGroups.Location = new Point(14, 17); - comboBoxGroups.Margin = new Padding(4, 5, 4, 5); - comboBoxGroups.Name = "comboBoxGroups"; - comboBoxGroups.Size = new Size(247, 24); - comboBoxGroups.TabIndex = 0; - toolTip.SetToolTip(comboBoxGroups, "Choose a group to create different highlight settings. Type in a name to change in the name of a group."); - comboBoxGroups.DrawItem += OnCmbBoxGroupDrawItem; - comboBoxGroups.SelectionChangeCommitted += OnCmbBoxGroupSelectionChangeCommitted; - comboBoxGroups.TextUpdate += OnCmbBoxGroupTextUpdate; - // - // pnlBackground - // - pnlBackground.AutoScroll = true; - pnlBackground.Controls.Add(listBoxHighlight); - pnlBackground.Controls.Add(btnAdd); - pnlBackground.Controls.Add(btnDelete); - pnlBackground.Controls.Add(btnMoveUp); - pnlBackground.Controls.Add(btnMoveDown); - pnlBackground.Controls.Add(btnOk); - pnlBackground.Controls.Add(btnCancel); - pnlBackground.Controls.Add(btnApply); - pnlBackground.Controls.Add(groupBoxLineMatchCriteria); - pnlBackground.Controls.Add(groupBoxColoring); - pnlBackground.Controls.Add(groupBoxActions); - pnlBackground.Controls.Add(groupBoxGroups); - pnlBackground.Dock = DockStyle.Fill; - pnlBackground.Location = new Point(0, 0); - pnlBackground.Name = "pnlBackground"; - pnlBackground.Size = new Size(644, 761); - pnlBackground.TabIndex = 23; - // - // HighlightDialog - // - AcceptButton = btnOk; - CancelButton = btnCancel; - ClientSize = new Size(644, 761); - Controls.Add(pnlBackground); - DoubleBuffered = true; - helpProvider.SetHelpKeyword(this, "Highlighting.htm"); - helpProvider.SetHelpNavigator(this, HelpNavigator.Topic); - helpProvider.SetHelpString(this, ""); - Icon = (Icon)resources.GetObject("$this.Icon"); - Margin = new Padding(4, 5, 4, 5); - MaximizeBox = false; - MinimizeBox = false; - MinimumSize = new Size(660, 800); - Name = "HighlightDialog"; - helpProvider.SetShowHelp(this, true); - StartPosition = FormStartPosition.CenterParent; - Text = "Highlighting and action triggers"; - Shown += OnHighlightDialogShown; - groupBoxLineMatchCriteria.ResumeLayout(false); - groupBoxLineMatchCriteria.PerformLayout(); - groupBoxColoring.ResumeLayout(false); - groupBoxColoring.PerformLayout(); - groupBoxActions.ResumeLayout(false); - groupBoxActions.PerformLayout(); - groupBoxGroups.ResumeLayout(false); - groupBoxGroups.PerformLayout(); - pnlBackground.ResumeLayout(false); - ResumeLayout(false); - } - - #endregion - - private System.Windows.Forms.ListBox listBoxHighlight; - private System.Windows.Forms.Button btnAdd; - private System.Windows.Forms.Button btnDelete; - private System.Windows.Forms.Button btnMoveUp; - private System.Windows.Forms.Button btnMoveDown; - private ColorComboBox colorBoxForeground; - private System.Windows.Forms.Label labelForgroundColor; - private ColorComboBox colorBoxBackground; - private System.Windows.Forms.Label labelBackgroundColor; - private System.Windows.Forms.Button btnOk; - private System.Windows.Forms.Button btnCancel; - private System.Windows.Forms.TextBox textBoxSearchString; - private System.Windows.Forms.Label labelSearchString; - private System.Windows.Forms.Button btnApply; - private System.Windows.Forms.Button btnCustomForeColor; - private System.Windows.Forms.Button btnCustomBackColor; - private System.Windows.Forms.CheckBox checkBoxRegex; - private System.Windows.Forms.CheckBox checkBoxCaseSensitive; - private System.Windows.Forms.CheckBox checkBoxDontDirtyLed; - private System.Windows.Forms.GroupBox groupBoxLineMatchCriteria; - private System.Windows.Forms.GroupBox groupBoxColoring; - private System.Windows.Forms.GroupBox groupBoxActions; - private System.Windows.Forms.CheckBox checkBoxBookmark; - private System.Windows.Forms.CheckBox checkBoxStopTail; - private System.Windows.Forms.HelpProvider helpProvider; - private System.Windows.Forms.CheckBox checkBoxPlugin; - private System.Windows.Forms.Button btnSelectPlugin; - private System.Windows.Forms.Button btnBookmarkComment; - private System.Windows.Forms.GroupBox groupBoxGroups; - private System.Windows.Forms.ComboBox comboBoxGroups; - private System.Windows.Forms.Button btnDeleteGroup; - private System.Windows.Forms.Button btnNewGroup; - private System.Windows.Forms.Button btnCopyGroup; - private System.Windows.Forms.ToolTip toolTip; - private System.Windows.Forms.Label labelAssignNamesToGroups; - private System.Windows.Forms.Button btnMoveGroupUp; - private System.Windows.Forms.Button btnMoveGroupDown; - private System.Windows.Forms.CheckBox checkBoxWordMatch; - private System.Windows.Forms.CheckBox checkBoxBold; - private System.Windows.Forms.CheckBox checkBoxNoBackground; - private System.Windows.Forms.Button btnImportGroup; - private System.Windows.Forms.Button btnExportGroup; - private System.Windows.Forms.Panel pnlBackground; -} \ No newline at end of file diff --git a/src/LogExpert.UI/LogExpert.UI.csproj b/src/LogExpert.UI/LogExpert.UI.csproj index e3cff129..ba379d5a 100644 --- a/src/LogExpert.UI/LogExpert.UI.csproj +++ b/src/LogExpert.UI/LogExpert.UI.csproj @@ -11,6 +11,7 @@ + diff --git a/src/LogExpert.sln b/src/LogExpert.sln index ee967ce8..62df124f 100644 --- a/src/LogExpert.sln +++ b/src/LogExpert.sln @@ -71,6 +71,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LogExpert.Resources", "LogE EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LogExpert.UI", "LogExpert.UI\LogExpert.UI.csproj", "{5DB0B0F8-3C3E-4805-93A3-7E69AC45CD40}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LogExpert.Audio", "LogExpert.Audio\LogExpert.Audio.csproj", "{A8F4D2E1-7B5C-4F3A-9C2D-1E8B6A4F0D52}" +EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LogExpert.PluginRegistry", "PluginRegistry\LogExpert.PluginRegistry.csproj", "{E2D8E653-B7DF-4ACE-8314-8059B1E20751}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Columnizers", "Columnizers", "{02EA681E-C7D8-13C7-8484-4AC65E1B71E8}" @@ -191,6 +193,10 @@ Global {5DB0B0F8-3C3E-4805-93A3-7E69AC45CD40}.Debug|Any CPU.Build.0 = Debug|Any CPU {5DB0B0F8-3C3E-4805-93A3-7E69AC45CD40}.Release|Any CPU.ActiveCfg = Release|Any CPU {5DB0B0F8-3C3E-4805-93A3-7E69AC45CD40}.Release|Any CPU.Build.0 = Release|Any CPU + {A8F4D2E1-7B5C-4F3A-9C2D-1E8B6A4F0D52}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A8F4D2E1-7B5C-4F3A-9C2D-1E8B6A4F0D52}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A8F4D2E1-7B5C-4F3A-9C2D-1E8B6A4F0D52}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A8F4D2E1-7B5C-4F3A-9C2D-1E8B6A4F0D52}.Release|Any CPU.Build.0 = Release|Any CPU {E2D8E653-B7DF-4ACE-8314-8059B1E20751}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {E2D8E653-B7DF-4ACE-8314-8059B1E20751}.Debug|Any CPU.Build.0 = Debug|Any CPU {E2D8E653-B7DF-4ACE-8314-8059B1E20751}.Release|Any CPU.ActiveCfg = Release|Any CPU diff --git a/src/PluginRegistry/PluginHashGenerator.Generated.cs b/src/PluginRegistry/PluginHashGenerator.Generated.cs index 42a817ce..cf08c2af 100644 --- a/src/PluginRegistry/PluginHashGenerator.Generated.cs +++ b/src/PluginRegistry/PluginHashGenerator.Generated.cs @@ -10,7 +10,7 @@ public static partial class PluginValidator { /// /// Gets pre-calculated SHA256 hashes for built-in plugins. - /// Generated: 2026-05-18 14:44:47 UTC + /// Generated: 2026-05-19 20:13:54 UTC /// Configuration: Release /// Plugin count: 22 /// @@ -18,28 +18,28 @@ public static Dictionary GetBuiltInPluginHashes() { return new Dictionary(StringComparer.OrdinalIgnoreCase) { - ["AutoColumnizer.dll"] = "634CB25EEA09ED577924B42ED442F154A67BB0CF7CE3A94386536E19BB0ABDF2", + ["AutoColumnizer.dll"] = "87E50EA915140C9F594471EF06C862AB668EB93619E32E43656A16C18E2FC0C6", ["BouncyCastle.Cryptography.dll"] = "E5EEAF6D263C493619982FD3638E6135077311D08C961E1FE128F9107D29EBC6", ["BouncyCastle.Cryptography.dll (x86)"] = "E5EEAF6D263C493619982FD3638E6135077311D08C961E1FE128F9107D29EBC6", - ["CsvColumnizer.dll"] = "52D3C61DF91C9EA546AC5DBE5B95492DC9BAFDBCCFBE0531BCAB6E5003FC5EBC", - ["CsvColumnizer.dll (x86)"] = "52D3C61DF91C9EA546AC5DBE5B95492DC9BAFDBCCFBE0531BCAB6E5003FC5EBC", - ["DefaultPlugins.dll"] = "870098D44238FBA24B1DB5D3B288A733F58F02A6827CD2F88A10A47E7F41DB4E", - ["FlashIconHighlighter.dll"] = "23D1DA294C45C964E2A215CD3E9B411BA1527E35512954F97D4972B57F108565", - ["GlassfishColumnizer.dll"] = "DF7A10A0B01FA051CC5D74ED67A3B814F571A068EE26E42B63EB93D0037D6826", - ["JsonColumnizer.dll"] = "8076C312EBDB2CB182CB14186ACCE4F134DBDC5CBDC5AFAF3AB96AB9E1536665", - ["JsonCompactColumnizer.dll"] = "72582949383131764C5D490EFACE50AB5271812339A613A6E9DA4790A5BD7028", - ["Log4jXmlColumnizer.dll"] = "0BCAB71BA2457F6C99EF1CEC23B3C37D98733C4323037B3E8BC6B392499273D1", - ["LogExpert.Core.dll"] = "71D798E476B4BEEAF9DFB75DBE57BDC0E6676F3085EFEACBFC73159E59243109", - ["LogExpert.Resources.dll"] = "EDF8F824CAD03F8B0F25E9119D5E64284465BCA9118B69BFBC901B9EDE5A5845", + ["CsvColumnizer.dll"] = "8FF0321593BB8A3A2FB3E32CF8586547204AA27809FDCF43748740AF26A556C7", + ["CsvColumnizer.dll (x86)"] = "8FF0321593BB8A3A2FB3E32CF8586547204AA27809FDCF43748740AF26A556C7", + ["DefaultPlugins.dll"] = "B88C87586A6C12B877CF798A88F8B47DE7C032B6D0CEF9F7BD53EC9FC24E9A47", + ["FlashIconHighlighter.dll"] = "78F12169D88F4E3CACA57CD0398FA05DC468035066C3FA258D33B6CCF98B6EB5", + ["GlassfishColumnizer.dll"] = "3D1EBB4E913F4053FBF3DA33DD9238A5EBCA3336FDD8A3AC9F6111FA78745B56", + ["JsonColumnizer.dll"] = "4EEE0FA7995C6B5F269582BC8A7860707E7F1901972236D1807CF20814033583", + ["JsonCompactColumnizer.dll"] = "1A54DA4D05BCDF46353E42E5730EACFAD733790A65BAF85EB0A821406354D70D", + ["Log4jXmlColumnizer.dll"] = "A226AAD5959EEB8F93DFFAF1D2E09355363C02AA97BACF7F3F2107E3BB2BB1ED", + ["LogExpert.Core.dll"] = "F7B7126F9E1D6B1A39FD05E32E8750C72517F87F25A4867D756C72FFFC7F11DA", + ["LogExpert.Resources.dll"] = "841E7FA856C59364F8CD03C6E1DF51CE960AF38733E1AB133A9C166EB9031BC4", ["Microsoft.Extensions.DependencyInjection.Abstractions.dll"] = "67FA4325000DB017DC0C35829B416F024F042D24EFB868BCF17A895EE6500A93", ["Microsoft.Extensions.DependencyInjection.Abstractions.dll (x86)"] = "67FA4325000DB017DC0C35829B416F024F042D24EFB868BCF17A895EE6500A93", ["Microsoft.Extensions.Logging.Abstractions.dll"] = "BB853130F5AFAF335BE7858D661F8212EC653835100F5A4E3AA2C66A4D4F685D", ["Microsoft.Extensions.Logging.Abstractions.dll (x86)"] = "BB853130F5AFAF335BE7858D661F8212EC653835100F5A4E3AA2C66A4D4F685D", - ["RegexColumnizer.dll"] = "C7AE8F4872EE00EFC7995558FE00934C2DC666A6BF0700E61BD0D0795AF96E25", - ["SftpFileSystem.dll"] = "E2CEBB24CFAF9CC0282CBDA14FF5AA47DA649198BE52C490E5427D1849ACCA1B", - ["SftpFileSystem.dll (x86)"] = "2CF325C8CB52629A8925005D530FEEC8C67F3933124FC9008AD886F029C3E9C2", - ["SftpFileSystem.Resources.dll"] = "E4B004CAF83C91CFB0B2192E5EAB7269EBAB9910EF1E8FFE9305E26186F28895", - ["SftpFileSystem.Resources.dll (x86)"] = "E4B004CAF83C91CFB0B2192E5EAB7269EBAB9910EF1E8FFE9305E26186F28895", + ["RegexColumnizer.dll"] = "0406128BB1F418CBEA376270987399B8E75FC2F2399932728A8B12B5B128D697", + ["SftpFileSystem.dll"] = "49A6F6EDE8A88DA908DF19571E0DD92928C7404A833B6B24A7F8045B026E93AB", + ["SftpFileSystem.dll (x86)"] = "99E68F1896239F9CCF8BCD2037F44FBAA33DB5CC92DD6913C6651EA5A54015EB", + ["SftpFileSystem.Resources.dll"] = "E7B3910AB0D312027174DC071114995B6694A2980582DCF90F71949B27B47177", + ["SftpFileSystem.Resources.dll (x86)"] = "E7B3910AB0D312027174DC071114995B6694A2980582DCF90F71949B27B47177", }; }