Files
TeslaSuite/Console/TeslaConsole/dlgAddProduct.cs
T
CydandClaude Opus 4.8 a91d31913e Remove redundant "Push to selected pods now" checkbox from Add Product
Deployment intent is now implied by the install package field: if a package is
supplied the product is installed to the selected pods after being added; if not,
it is only added to the catalog. Removes the checkbox (dlgAddProduct) and the
push-decision branch (AddProduct_Click). The register-only-without-package path is
retired with it, so the now-dead RegisterProductOnSelectedPods is removed too.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-30 20:36:30 -05:00

250 lines
6.3 KiB
C#

using System;
using System.Drawing;
using System.IO;
using System.Windows.Forms;
namespace TeslaConsole;
/// <summary>
/// Defines a new catalog product (a single launch entry) and, optionally, an install
/// package to deploy. The validated result is exposed as <see cref="Product"/>; the
/// caller persists it to the catalog and (optionally) pushes it to selected pods.
/// </summary>
internal class dlgAddProduct : Form
{
private TextBox txtName;
private TextBox txtInstallDir;
private TextBox txtExe;
private TextBox txtArgs;
private TextBox txtPackage;
private CheckBox chkAutoRestart;
private Button cmdOK;
private Button cmdCancel;
/// <summary>The product the operator defined. Valid only after the dialog returns <see cref="DialogResult.OK"/>.</summary>
public ProductDefinition Product { get; private set; }
/// <summary>Optional install package (zip). If set, the product is deployed to the
/// selected pods after it is added; if null/empty, it is only added to the catalog.</summary>
public string PackagePath => string.IsNullOrWhiteSpace(txtPackage.Text) ? null : txtPackage.Text.Trim();
public dlgAddProduct()
{
InitializeComponent();
}
private void InitializeComponent()
{
this.txtName = new TextBox();
this.txtInstallDir = new TextBox();
this.txtExe = new TextBox();
this.txtArgs = new TextBox();
this.txtPackage = new TextBox();
this.chkAutoRestart = new CheckBox();
this.cmdOK = new Button();
this.cmdCancel = new Button();
base.SuspendLayout();
int labelX = 12;
int fieldX = 130;
int fieldW = 300;
int browseX = fieldX + fieldW + 6;
int y = 15;
int rowH = 28;
AddLabel("Product name:", labelX, y);
this.txtName.SetBounds(fieldX, y - 3, fieldW, 20);
y += rowH;
AddLabel("Install directory:", labelX, y);
this.txtInstallDir.SetBounds(fieldX, y - 3, fieldW, 20);
AddBrowseButton(browseX, y - 4, BrowseInstallDir);
y += rowH;
AddLabel("Executable:", labelX, y);
this.txtExe.SetBounds(fieldX, y - 3, fieldW, 20);
AddBrowseButton(browseX, y - 4, BrowseExe);
y += rowH;
AddLabel("Arguments:", labelX, y);
this.txtArgs.SetBounds(fieldX, y - 3, fieldW, 20);
y += rowH;
AddLabel("Install package (optional):", labelX, y);
this.txtPackage.SetBounds(fieldX, y - 3, fieldW, 20);
AddBrowseButton(browseX, y - 4, BrowsePackage);
y += rowH;
this.chkAutoRestart.SetBounds(fieldX, y, 200, 20);
this.chkAutoRestart.Text = "Auto-restart if it exits";
this.chkAutoRestart.Checked = true;
y += 36;
this.cmdOK.SetBounds(browseX - 169, y, 80, 24);
this.cmdOK.Text = "OK";
this.cmdOK.Click += cmdOK_Click;
this.cmdCancel.SetBounds(browseX - 83, y, 80, 24);
this.cmdCancel.Text = "Cancel";
this.cmdCancel.DialogResult = DialogResult.Cancel;
base.AcceptButton = this.cmdOK;
base.CancelButton = this.cmdCancel;
base.FormBorderStyle = FormBorderStyle.FixedDialog;
base.MaximizeBox = false;
base.MinimizeBox = false;
base.StartPosition = FormStartPosition.CenterParent;
base.ClientSize = new Size(browseX + 40, y + 36);
base.Controls.Add(this.txtName);
base.Controls.Add(this.txtInstallDir);
base.Controls.Add(this.txtExe);
base.Controls.Add(this.txtArgs);
base.Controls.Add(this.txtPackage);
base.Controls.Add(this.chkAutoRestart);
base.Controls.Add(this.cmdOK);
base.Controls.Add(this.cmdCancel);
base.Name = "dlgAddProduct";
this.Text = "Add Product";
base.ResumeLayout(false);
base.PerformLayout();
}
private void AddLabel(string text, int x, int y)
{
Label label = new Label
{
Text = text,
AutoSize = true
};
label.SetBounds(x, y, 110, 16);
base.Controls.Add(label);
}
private void AddBrowseButton(int x, int y, EventHandler onClick)
{
Button button = new Button
{
Text = "..."
};
button.SetBounds(x, y, 30, 22);
button.Click += onClick;
base.Controls.Add(button);
}
private void BrowseInstallDir(object sender, EventArgs e)
{
using FolderBrowserDialog dialog = new FolderBrowserDialog();
if (!string.IsNullOrWhiteSpace(txtInstallDir.Text))
{
dialog.SelectedPath = txtInstallDir.Text;
}
if (dialog.ShowDialog(this) == DialogResult.OK)
{
txtInstallDir.Text = dialog.SelectedPath;
}
}
private void BrowseExe(object sender, EventArgs e)
{
using OpenFileDialog dialog = new OpenFileDialog
{
Filter = "Executables (*.exe)|*.exe|All Files (*.*)|*.*",
Title = "Select Executable"
};
if (dialog.ShowDialog(this) == DialogResult.OK)
{
txtExe.Text = dialog.FileName;
}
}
private void BrowsePackage(object sender, EventArgs e)
{
using OpenFileDialog dialog = new OpenFileDialog
{
Filter = "VWE Install Archive (*.zip)|*.zip|All Files (*.*)|*.*",
Title = "Select Install Package"
};
if (dialog.ShowDialog(this) == DialogResult.OK)
{
txtPackage.Text = dialog.FileName;
}
}
private void cmdOK_Click(object sender, EventArgs e)
{
string name = txtName.Text.Trim();
string installDir = txtInstallDir.Text.Trim();
string exe = txtExe.Text.Trim();
if (name.Length == 0)
{
Warn("Please enter a product name.");
return;
}
if (exe.Length == 0)
{
Warn("Please specify the executable path.");
return;
}
if (installDir.Length == 0)
{
Warn("Please specify the install directory.");
return;
}
string fullExe, fullDir;
try
{
fullExe = Path.GetFullPath(exe);
fullDir = Path.GetFullPath(installDir);
}
catch (Exception)
{
Warn("The executable or install directory path is not valid.");
return;
}
// Invariant: the exe must live under the install directory the package extracts to.
string dirWithSep = fullDir.TrimEnd('\\', '/') + "\\";
if (!fullExe.StartsWith(dirWithSep, StringComparison.OrdinalIgnoreCase))
{
Warn("The executable must be located inside the install directory:\n" + fullDir);
return;
}
Guid id = Guid.NewGuid();
Product = new ProductDefinition
{
Id = id,
Name = name,
MenuText = name + "...",
HostTypeDialog = false
};
Product.Entries.Add(new LaunchEntryDefinition
{
LaunchKey = id,
DisplayName = name,
Exe = fullExe,
Args = txtArgs.Text.Trim(),
WorkingDirectory = fullDir,
AutoRestart = chkAutoRestart.Checked,
HostType = AppHostType.None
});
base.DialogResult = DialogResult.OK;
Close();
}
private void Warn(string message)
{
MessageBox.Show(this, message, "Add Product", MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
}