diff --git a/Hawkeye.VisionBuilder.UI.RecipeYoloPatcher/Hawkeye.VisionBuilder.UI.RecipeYoloPatcher.csproj b/Hawkeye.VisionBuilder.UI.RecipeYoloPatcher/Hawkeye.VisionBuilder.UI.RecipeYoloPatcher.csproj
new file mode 100644
index 0000000..bdc20d7
--- /dev/null
+++ b/Hawkeye.VisionBuilder.UI.RecipeYoloPatcher/Hawkeye.VisionBuilder.UI.RecipeYoloPatcher.csproj
@@ -0,0 +1,29 @@
+
+
+
+ WinExe
+ net8.0-windows
+ true
+ enable
+ enable
+ Hawkeye.VisionBuilder.UI.RecipeYoloPatcher
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Hawkeye.VisionBuilder.UI.RecipeYoloPatcher/MainForm.Designer.cs b/Hawkeye.VisionBuilder.UI.RecipeYoloPatcher/MainForm.Designer.cs
new file mode 100644
index 0000000..2360a70
--- /dev/null
+++ b/Hawkeye.VisionBuilder.UI.RecipeYoloPatcher/MainForm.Designer.cs
@@ -0,0 +1,399 @@
+#nullable disable
+
+namespace Hawkeye.VisionBuilder.UI.RecipeYoloPatcher
+{
+ partial class MainForm
+ {
+ ///
+ /// 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()
+ {
+ this.lblModel = new System.Windows.Forms.Label();
+ this.txtModelPath = new System.Windows.Forms.TextBox();
+ this.btnBrowseModel = new System.Windows.Forms.Button();
+ this.btnLoadClasses = new System.Windows.Forms.Button();
+ this.lblClasses = new System.Windows.Forms.Label();
+ this.lstClasses = new System.Windows.Forms.CheckedListBox();
+ this.lblFiles = new System.Windows.Forms.Label();
+ this.lstFiles = new System.Windows.Forms.ListBox();
+ this.btnAddFiles = new System.Windows.Forms.Button();
+ this.btnRemoveFiles = new System.Windows.Forms.Button();
+ this.btnClearFiles = new System.Windows.Forms.Button();
+ this.grpBounds = new System.Windows.Forms.GroupBox();
+ this.lblMinArea = new System.Windows.Forms.Label();
+ this.numMinArea = new System.Windows.Forms.NumericUpDown();
+ this.lblMaxArea = new System.Windows.Forms.Label();
+ this.numMaxArea = new System.Windows.Forms.NumericUpDown();
+ this.lblMinWidth = new System.Windows.Forms.Label();
+ this.numMinWidth = new System.Windows.Forms.NumericUpDown();
+ this.lblMaxWidth = new System.Windows.Forms.Label();
+ this.numMaxWidth = new System.Windows.Forms.NumericUpDown();
+ this.lblMinHeight = new System.Windows.Forms.Label();
+ this.numMinHeight = new System.Windows.Forms.NumericUpDown();
+ this.lblMaxHeight = new System.Windows.Forms.Label();
+ this.numMaxHeight = new System.Windows.Forms.NumericUpDown();
+ this.btnApply = new System.Windows.Forms.Button();
+ this.btnStandardize = new System.Windows.Forms.Button();
+ this.txtLog = new System.Windows.Forms.TextBox();
+ this.grpBounds.SuspendLayout();
+ ((System.ComponentModel.ISupportInitialize)(this.numMinArea)).BeginInit();
+ ((System.ComponentModel.ISupportInitialize)(this.numMaxArea)).BeginInit();
+ ((System.ComponentModel.ISupportInitialize)(this.numMinWidth)).BeginInit();
+ ((System.ComponentModel.ISupportInitialize)(this.numMaxWidth)).BeginInit();
+ ((System.ComponentModel.ISupportInitialize)(this.numMinHeight)).BeginInit();
+ ((System.ComponentModel.ISupportInitialize)(this.numMaxHeight)).BeginInit();
+ this.SuspendLayout();
+ //
+ // lblModel
+ //
+ this.lblModel.AutoSize = true;
+ this.lblModel.Location = new System.Drawing.Point(10, 15);
+ this.lblModel.Name = "lblModel";
+ this.lblModel.Size = new System.Drawing.Size(46, 15);
+ this.lblModel.TabIndex = 0;
+ this.lblModel.Text = "Model:";
+ //
+ // txtModelPath
+ //
+ this.txtModelPath.Location = new System.Drawing.Point(70, 12);
+ this.txtModelPath.Name = "txtModelPath";
+ this.txtModelPath.ReadOnly = true;
+ this.txtModelPath.Size = new System.Drawing.Size(580, 23);
+ this.txtModelPath.TabIndex = 1;
+ //
+ // btnBrowseModel
+ //
+ this.btnBrowseModel.Location = new System.Drawing.Point(660, 10);
+ this.btnBrowseModel.Name = "btnBrowseModel";
+ this.btnBrowseModel.Size = new System.Drawing.Size(110, 25);
+ this.btnBrowseModel.TabIndex = 2;
+ this.btnBrowseModel.Text = "Browse...";
+ this.btnBrowseModel.UseVisualStyleBackColor = true;
+ this.btnBrowseModel.Click += new System.EventHandler(this.BtnBrowseModel_Click);
+ //
+ // btnLoadClasses
+ //
+ this.btnLoadClasses.Enabled = false;
+ this.btnLoadClasses.Location = new System.Drawing.Point(10, 45);
+ this.btnLoadClasses.Name = "btnLoadClasses";
+ this.btnLoadClasses.Size = new System.Drawing.Size(130, 25);
+ this.btnLoadClasses.TabIndex = 3;
+ this.btnLoadClasses.Text = "Load classes";
+ this.btnLoadClasses.UseVisualStyleBackColor = true;
+ this.btnLoadClasses.Click += new System.EventHandler(this.BtnLoadClasses_Click);
+ //
+ // lblClasses
+ //
+ this.lblClasses.AutoSize = true;
+ this.lblClasses.Location = new System.Drawing.Point(10, 85);
+ this.lblClasses.Name = "lblClasses";
+ this.lblClasses.Size = new System.Drawing.Size(228, 15);
+ this.lblClasses.TabIndex = 4;
+ this.lblClasses.Text = "Classes (check the ones to add/update):";
+ //
+ // lstClasses
+ //
+ this.lstClasses.CheckOnClick = true;
+ this.lstClasses.FormattingEnabled = true;
+ this.lstClasses.IntegralHeight = false;
+ this.lstClasses.Location = new System.Drawing.Point(10, 105);
+ this.lstClasses.Name = "lstClasses";
+ this.lstClasses.Size = new System.Drawing.Size(760, 180);
+ this.lstClasses.TabIndex = 5;
+ //
+ // lblFiles
+ //
+ this.lblFiles.AutoSize = true;
+ this.lblFiles.Location = new System.Drawing.Point(10, 295);
+ this.lblFiles.Name = "lblFiles";
+ this.lblFiles.Size = new System.Drawing.Size(173, 15);
+ this.lblFiles.TabIndex = 6;
+ this.lblFiles.Text = "Recipe files (*.hrcp, *.jhrcp):";
+ //
+ // lstFiles
+ //
+ this.lstFiles.FormattingEnabled = true;
+ this.lstFiles.HorizontalScrollbar = true;
+ this.lstFiles.IntegralHeight = false;
+ this.lstFiles.ItemHeight = 15;
+ this.lstFiles.Location = new System.Drawing.Point(10, 315);
+ this.lstFiles.Name = "lstFiles";
+ this.lstFiles.SelectionMode = System.Windows.Forms.SelectionMode.MultiExtended;
+ this.lstFiles.Size = new System.Drawing.Size(660, 130);
+ this.lstFiles.TabIndex = 7;
+ //
+ // btnAddFiles
+ //
+ this.btnAddFiles.Location = new System.Drawing.Point(680, 315);
+ this.btnAddFiles.Name = "btnAddFiles";
+ this.btnAddFiles.Size = new System.Drawing.Size(90, 25);
+ this.btnAddFiles.TabIndex = 8;
+ this.btnAddFiles.Text = "Add files...";
+ this.btnAddFiles.UseVisualStyleBackColor = true;
+ this.btnAddFiles.Click += new System.EventHandler(this.BtnAddFiles_Click);
+ //
+ // btnRemoveFiles
+ //
+ this.btnRemoveFiles.Location = new System.Drawing.Point(680, 345);
+ this.btnRemoveFiles.Name = "btnRemoveFiles";
+ this.btnRemoveFiles.Size = new System.Drawing.Size(90, 25);
+ this.btnRemoveFiles.TabIndex = 9;
+ this.btnRemoveFiles.Text = "Remove";
+ this.btnRemoveFiles.UseVisualStyleBackColor = true;
+ this.btnRemoveFiles.Click += new System.EventHandler(this.BtnRemoveFiles_Click);
+ //
+ // btnClearFiles
+ //
+ this.btnClearFiles.Location = new System.Drawing.Point(680, 375);
+ this.btnClearFiles.Name = "btnClearFiles";
+ this.btnClearFiles.Size = new System.Drawing.Size(90, 25);
+ this.btnClearFiles.TabIndex = 10;
+ this.btnClearFiles.Text = "Clear";
+ this.btnClearFiles.UseVisualStyleBackColor = true;
+ this.btnClearFiles.Click += new System.EventHandler(this.BtnClearFiles_Click);
+ //
+ // grpBounds
+ //
+ this.grpBounds.Controls.Add(this.lblMinArea);
+ this.grpBounds.Controls.Add(this.numMinArea);
+ this.grpBounds.Controls.Add(this.lblMaxArea);
+ this.grpBounds.Controls.Add(this.numMaxArea);
+ this.grpBounds.Controls.Add(this.lblMinWidth);
+ this.grpBounds.Controls.Add(this.numMinWidth);
+ this.grpBounds.Controls.Add(this.lblMaxWidth);
+ this.grpBounds.Controls.Add(this.numMaxWidth);
+ this.grpBounds.Controls.Add(this.lblMinHeight);
+ this.grpBounds.Controls.Add(this.numMinHeight);
+ this.grpBounds.Controls.Add(this.lblMaxHeight);
+ this.grpBounds.Controls.Add(this.numMaxHeight);
+ this.grpBounds.Location = new System.Drawing.Point(10, 455);
+ this.grpBounds.Name = "grpBounds";
+ this.grpBounds.Size = new System.Drawing.Size(760, 90);
+ this.grpBounds.TabIndex = 11;
+ this.grpBounds.TabStop = false;
+ this.grpBounds.Text = "Bounds (applied to selected classes)";
+ //
+ // lblMinArea
+ //
+ this.lblMinArea.AutoSize = true;
+ this.lblMinArea.Location = new System.Drawing.Point(10, 20);
+ this.lblMinArea.Name = "lblMinArea";
+ this.lblMinArea.Size = new System.Drawing.Size(56, 15);
+ this.lblMinArea.TabIndex = 0;
+ this.lblMinArea.Text = "Min Area";
+ //
+ // numMinArea
+ //
+ this.numMinArea.Location = new System.Drawing.Point(10, 40);
+ this.numMinArea.Maximum = new decimal(new int[] { 9999999, 0, 0, 0 });
+ this.numMinArea.Name = "numMinArea";
+ this.numMinArea.Size = new System.Drawing.Size(110, 23);
+ this.numMinArea.TabIndex = 1;
+ //
+ // lblMaxArea
+ //
+ this.lblMaxArea.AutoSize = true;
+ this.lblMaxArea.Location = new System.Drawing.Point(130, 20);
+ this.lblMaxArea.Name = "lblMaxArea";
+ this.lblMaxArea.Size = new System.Drawing.Size(59, 15);
+ this.lblMaxArea.TabIndex = 2;
+ this.lblMaxArea.Text = "Max Area";
+ //
+ // numMaxArea
+ //
+ this.numMaxArea.Location = new System.Drawing.Point(130, 40);
+ this.numMaxArea.Maximum = new decimal(new int[] { 9999999, 0, 0, 0 });
+ this.numMaxArea.Name = "numMaxArea";
+ this.numMaxArea.Size = new System.Drawing.Size(110, 23);
+ this.numMaxArea.TabIndex = 3;
+ this.numMaxArea.Value = new decimal(new int[] { 99999, 0, 0, 0 });
+ //
+ // lblMinWidth
+ //
+ this.lblMinWidth.AutoSize = true;
+ this.lblMinWidth.Location = new System.Drawing.Point(260, 20);
+ this.lblMinWidth.Name = "lblMinWidth";
+ this.lblMinWidth.Size = new System.Drawing.Size(64, 15);
+ this.lblMinWidth.TabIndex = 4;
+ this.lblMinWidth.Text = "Min Width";
+ //
+ // numMinWidth
+ //
+ this.numMinWidth.Location = new System.Drawing.Point(260, 40);
+ this.numMinWidth.Maximum = new decimal(new int[] { 9999999, 0, 0, 0 });
+ this.numMinWidth.Name = "numMinWidth";
+ this.numMinWidth.Size = new System.Drawing.Size(110, 23);
+ this.numMinWidth.TabIndex = 5;
+ //
+ // lblMaxWidth
+ //
+ this.lblMaxWidth.AutoSize = true;
+ this.lblMaxWidth.Location = new System.Drawing.Point(390, 20);
+ this.lblMaxWidth.Name = "lblMaxWidth";
+ this.lblMaxWidth.Size = new System.Drawing.Size(67, 15);
+ this.lblMaxWidth.TabIndex = 6;
+ this.lblMaxWidth.Text = "Max Width";
+ //
+ // numMaxWidth
+ //
+ this.numMaxWidth.Location = new System.Drawing.Point(390, 40);
+ this.numMaxWidth.Maximum = new decimal(new int[] { 9999999, 0, 0, 0 });
+ this.numMaxWidth.Name = "numMaxWidth";
+ this.numMaxWidth.Size = new System.Drawing.Size(110, 23);
+ this.numMaxWidth.TabIndex = 7;
+ this.numMaxWidth.Value = new decimal(new int[] { 99999, 0, 0, 0 });
+ //
+ // lblMinHeight
+ //
+ this.lblMinHeight.AutoSize = true;
+ this.lblMinHeight.Location = new System.Drawing.Point(520, 20);
+ this.lblMinHeight.Name = "lblMinHeight";
+ this.lblMinHeight.Size = new System.Drawing.Size(67, 15);
+ this.lblMinHeight.TabIndex = 8;
+ this.lblMinHeight.Text = "Min Height";
+ //
+ // numMinHeight
+ //
+ this.numMinHeight.Location = new System.Drawing.Point(520, 40);
+ this.numMinHeight.Maximum = new decimal(new int[] { 9999999, 0, 0, 0 });
+ this.numMinHeight.Name = "numMinHeight";
+ this.numMinHeight.Size = new System.Drawing.Size(110, 23);
+ this.numMinHeight.TabIndex = 9;
+ //
+ // lblMaxHeight
+ //
+ this.lblMaxHeight.AutoSize = true;
+ this.lblMaxHeight.Location = new System.Drawing.Point(640, 20);
+ this.lblMaxHeight.Name = "lblMaxHeight";
+ this.lblMaxHeight.Size = new System.Drawing.Size(70, 15);
+ this.lblMaxHeight.TabIndex = 10;
+ this.lblMaxHeight.Text = "Max Height";
+ //
+ // numMaxHeight
+ //
+ this.numMaxHeight.Location = new System.Drawing.Point(640, 40);
+ this.numMaxHeight.Maximum = new decimal(new int[] { 9999999, 0, 0, 0 });
+ this.numMaxHeight.Name = "numMaxHeight";
+ this.numMaxHeight.Size = new System.Drawing.Size(110, 23);
+ this.numMaxHeight.TabIndex = 11;
+ this.numMaxHeight.Value = new decimal(new int[] { 99999, 0, 0, 0 });
+ //
+ // btnApply
+ //
+ this.btnApply.Location = new System.Drawing.Point(10, 555);
+ this.btnApply.Name = "btnApply";
+ this.btnApply.Size = new System.Drawing.Size(375, 32);
+ this.btnApply.TabIndex = 12;
+ this.btnApply.Text = "Apply";
+ this.btnApply.UseVisualStyleBackColor = true;
+ this.btnApply.Click += new System.EventHandler(this.BtnApply_Click);
+ //
+ // btnStandardize
+ //
+ this.btnStandardize.Location = new System.Drawing.Point(395, 555);
+ this.btnStandardize.Name = "btnStandardize";
+ this.btnStandardize.Size = new System.Drawing.Size(375, 32);
+ this.btnStandardize.TabIndex = 13;
+ this.btnStandardize.Text = "Standardize names";
+ this.btnStandardize.UseVisualStyleBackColor = true;
+ this.btnStandardize.Click += new System.EventHandler(this.BtnStandardize_Click);
+ //
+ // txtLog
+ //
+ this.txtLog.Location = new System.Drawing.Point(10, 595);
+ this.txtLog.Multiline = true;
+ this.txtLog.Name = "txtLog";
+ this.txtLog.ReadOnly = true;
+ this.txtLog.ScrollBars = System.Windows.Forms.ScrollBars.Vertical;
+ this.txtLog.Size = new System.Drawing.Size(760, 80);
+ this.txtLog.TabIndex = 14;
+ this.txtLog.WordWrap = false;
+ //
+ // MainForm
+ //
+ this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F);
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.ClientSize = new System.Drawing.Size(784, 690);
+ this.Controls.Add(this.txtLog);
+ this.Controls.Add(this.btnStandardize);
+ this.Controls.Add(this.btnApply);
+ this.Controls.Add(this.grpBounds);
+ this.Controls.Add(this.btnClearFiles);
+ this.Controls.Add(this.btnRemoveFiles);
+ this.Controls.Add(this.btnAddFiles);
+ this.Controls.Add(this.lstFiles);
+ this.Controls.Add(this.lblFiles);
+ this.Controls.Add(this.lstClasses);
+ this.Controls.Add(this.lblClasses);
+ this.Controls.Add(this.btnLoadClasses);
+ this.Controls.Add(this.btnBrowseModel);
+ this.Controls.Add(this.txtModelPath);
+ this.Controls.Add(this.lblModel);
+ this.Name = "MainForm";
+ this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
+ this.Text = "Recipe Yolo Patcher";
+ this.grpBounds.ResumeLayout(false);
+ this.grpBounds.PerformLayout();
+ ((System.ComponentModel.ISupportInitialize)(this.numMinArea)).EndInit();
+ ((System.ComponentModel.ISupportInitialize)(this.numMaxArea)).EndInit();
+ ((System.ComponentModel.ISupportInitialize)(this.numMinWidth)).EndInit();
+ ((System.ComponentModel.ISupportInitialize)(this.numMaxWidth)).EndInit();
+ ((System.ComponentModel.ISupportInitialize)(this.numMinHeight)).EndInit();
+ ((System.ComponentModel.ISupportInitialize)(this.numMaxHeight)).EndInit();
+ this.ResumeLayout(false);
+ this.PerformLayout();
+ }
+
+ #endregion
+
+ private System.Windows.Forms.Label lblModel;
+ private System.Windows.Forms.TextBox txtModelPath;
+ private System.Windows.Forms.Button btnBrowseModel;
+ private System.Windows.Forms.Button btnLoadClasses;
+ private System.Windows.Forms.Label lblClasses;
+ private System.Windows.Forms.CheckedListBox lstClasses;
+ private System.Windows.Forms.Label lblFiles;
+ private System.Windows.Forms.ListBox lstFiles;
+ private System.Windows.Forms.Button btnAddFiles;
+ private System.Windows.Forms.Button btnRemoveFiles;
+ private System.Windows.Forms.Button btnClearFiles;
+ private System.Windows.Forms.GroupBox grpBounds;
+ private System.Windows.Forms.Label lblMinArea;
+ private System.Windows.Forms.NumericUpDown numMinArea;
+ private System.Windows.Forms.Label lblMaxArea;
+ private System.Windows.Forms.NumericUpDown numMaxArea;
+ private System.Windows.Forms.Label lblMinWidth;
+ private System.Windows.Forms.NumericUpDown numMinWidth;
+ private System.Windows.Forms.Label lblMaxWidth;
+ private System.Windows.Forms.NumericUpDown numMaxWidth;
+ private System.Windows.Forms.Label lblMinHeight;
+ private System.Windows.Forms.NumericUpDown numMinHeight;
+ private System.Windows.Forms.Label lblMaxHeight;
+ private System.Windows.Forms.NumericUpDown numMaxHeight;
+ private System.Windows.Forms.Button btnApply;
+ private System.Windows.Forms.Button btnStandardize;
+ private System.Windows.Forms.TextBox txtLog;
+ }
+}
diff --git a/Hawkeye.VisionBuilder.UI.RecipeYoloPatcher/MainForm.cs b/Hawkeye.VisionBuilder.UI.RecipeYoloPatcher/MainForm.cs
new file mode 100644
index 0000000..c0d46d6
--- /dev/null
+++ b/Hawkeye.VisionBuilder.UI.RecipeYoloPatcher/MainForm.cs
@@ -0,0 +1,312 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Windows.Forms;
+using Compunet.YoloV8;
+using Hawkeye.VisionBuilder.Workflow;
+using Hawkeye.VisionBuilder.Workflow.Operations.AI;
+
+namespace Hawkeye.VisionBuilder.UI.RecipeYoloPatcher;
+
+public partial class MainForm : Form
+{
+ private sealed class ClassEntry
+ {
+ public int Id { get; init; }
+ public string Name { get; init; } = "";
+ public override string ToString() => $"{Id}: {Name}";
+ }
+
+ public MainForm()
+ {
+ InitializeComponent();
+ }
+
+ private void BtnBrowseModel_Click(object? sender, EventArgs e)
+ {
+ using var dialog = new OpenFileDialog
+ {
+ Filter = "ONNX models (*.onnx)|*.onnx",
+ Title = "Select Yolo model"
+ };
+ var defaultDir = Path.GetFullPath(@"..\Data\Models");
+ if (Directory.Exists(defaultDir)) dialog.InitialDirectory = defaultDir;
+ if (dialog.ShowDialog(this) == DialogResult.OK)
+ {
+ txtModelPath.Text = dialog.FileName;
+ btnLoadClasses.Enabled = true;
+ lstClasses.Items.Clear();
+ }
+ }
+
+ private void BtnLoadClasses_Click(object? sender, EventArgs e)
+ {
+ if (string.IsNullOrWhiteSpace(txtModelPath.Text) || !File.Exists(txtModelPath.Text))
+ {
+ MessageBox.Show(this, "Pick a valid .onnx model first.", "Recipe Yolo Patcher",
+ MessageBoxButtons.OK, MessageBoxIcon.Warning);
+ return;
+ }
+ lstClasses.Items.Clear();
+ Cursor = Cursors.WaitCursor;
+ try
+ {
+ using var predictor = YoloV8Predictor.Create(txtModelPath.Text);
+ foreach (var cls in predictor.Metadata.Names)
+ {
+ lstClasses.Items.Add(new ClassEntry { Id = cls.Id, Name = cls.Name });
+ }
+ Log($"Loaded {lstClasses.Items.Count} class(es) from {Path.GetFileName(txtModelPath.Text)}.");
+ }
+ catch (Exception ex)
+ {
+ MessageBox.Show(this, $"Failed to load model:\r\n{ex.Message}", "Recipe Yolo Patcher",
+ MessageBoxButtons.OK, MessageBoxIcon.Error);
+ }
+ finally
+ {
+ Cursor = Cursors.Default;
+ }
+ }
+
+ private void BtnAddFiles_Click(object? sender, EventArgs e)
+ {
+ using var dialog = new OpenFileDialog
+ {
+ Filter = "Recipes (*.hrcp;*.jhrcp)|*.hrcp;*.jhrcp",
+ Multiselect = true,
+ Title = "Select recipe files"
+ };
+ var defaultDir = Path.GetFullPath(@"..\Data\Recipes");
+ if (Directory.Exists(defaultDir)) dialog.InitialDirectory = defaultDir;
+ if (dialog.ShowDialog(this) == DialogResult.OK)
+ {
+ foreach (var f in dialog.FileNames)
+ {
+ if (!lstFiles.Items.Contains(f)) lstFiles.Items.Add(f);
+ }
+ }
+ }
+
+ private void BtnRemoveFiles_Click(object? sender, EventArgs e)
+ {
+ var selected = lstFiles.SelectedItems.Cast