diff --git a/Ui/Views/SettingsView.Designer.cs b/Ui/Views/SettingsView.Designer.cs
index 3d30b1c..a901e54 100644
--- a/Ui/Views/SettingsView.Designer.cs
+++ b/Ui/Views/SettingsView.Designer.cs
@@ -18,13 +18,13 @@ namespace PolyTraderSharp.Ui.Views
private void InitializeComponent()
{
propertyGrid = new PropertyGrid();
- toolStrip1 = new ToolStrip();
tabControl1 = new TabControl();
tabPage1 = new TabPage();
toolStrip2 = new ToolStrip();
btn_save = new ToolStripButton();
btn_loadsettings = new ToolStripButton();
btnGenMasterKey = new ToolStripButton();
+ btnSetOpenRouterKey = new ToolStripButton();
tabPage2 = new TabPage();
pgAccount = new PropertyGrid();
dgvAccounts = new DataGridView();
@@ -41,37 +41,25 @@ namespace PolyTraderSharp.Ui.Views
//
// propertyGrid
//
- propertyGrid.Dock = DockStyle.Bottom;
- propertyGrid.Location = new Point(3, 610);
- propertyGrid.Margin = new Padding(4, 25, 4, 5);
+ propertyGrid.Dock = DockStyle.Fill;
propertyGrid.Name = "propertyGrid";
- propertyGrid.Size = new Size(1171, 274);
propertyGrid.TabIndex = 1;
- //
- // toolStrip1
- //
- toolStrip1.ImageScalingSize = new Size(24, 24);
- toolStrip1.Location = new Point(0, 0);
- toolStrip1.Name = "toolStrip1";
- toolStrip1.Size = new Size(1185, 25);
- toolStrip1.TabIndex = 2;
- toolStrip1.Text = "toolStrip1";
- //
+ //
// tabControl1
- //
- tabControl1.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right;
+ //
tabControl1.Controls.Add(tabPage1);
tabControl1.Controls.Add(tabPage2);
- tabControl1.Location = new Point(0, 24);
+ tabControl1.Dock = DockStyle.Fill;
+ tabControl1.Location = new Point(0, 0);
tabControl1.Name = "tabControl1";
tabControl1.SelectedIndex = 0;
- tabControl1.Size = new Size(1185, 925);
+ tabControl1.Size = new Size(1185, 800);
tabControl1.TabIndex = 3;
- //
+ //
// tabPage1
- //
- tabPage1.Controls.Add(toolStrip2);
+ //
tabPage1.Controls.Add(propertyGrid);
+ tabPage1.Controls.Add(toolStrip2);
tabPage1.Location = new Point(4, 34);
tabPage1.Name = "tabPage1";
tabPage1.Padding = new Padding(3);
@@ -82,8 +70,9 @@ namespace PolyTraderSharp.Ui.Views
//
// toolStrip2
//
+ toolStrip2.Dock = DockStyle.Top;
toolStrip2.ImageScalingSize = new Size(24, 24);
- toolStrip2.Items.AddRange(new ToolStripItem[] { btn_save, btn_loadsettings, btnGenMasterKey });
+ toolStrip2.Items.AddRange(new ToolStripItem[] { btn_save, btn_loadsettings, btnGenMasterKey, btnSetOpenRouterKey });
toolStrip2.Location = new Point(3, 3);
toolStrip2.Name = "toolStrip2";
toolStrip2.Size = new Size(1171, 34);
@@ -114,6 +103,14 @@ namespace PolyTraderSharp.Ui.Views
btnGenMasterKey.Text = "Master-Key erzeugen";
btnGenMasterKey.ToolTipText = "Erzeugt einen zufälligen AES-Master-Key (nur wenn noch keiner existiert).";
//
+ // btnSetOpenRouterKey
+ //
+ btnSetOpenRouterKey.DisplayStyle = ToolStripItemDisplayStyle.Text;
+ btnSetOpenRouterKey.Name = "btnSetOpenRouterKey";
+ btnSetOpenRouterKey.Size = new Size(200, 29);
+ btnSetOpenRouterKey.Text = "OpenRouter-Key setzen …";
+ btnSetOpenRouterKey.ToolTipText = "Speichert den OpenRouter-API-Key für den Supervisor (gitignorierte Datei openrouter.key).";
+ //
// tabPage2
//
tabPage2.Controls.Add(pgAccount);
@@ -153,6 +150,7 @@ namespace PolyTraderSharp.Ui.Views
//
// toolStripAccounts
//
+ toolStripAccounts.Dock = DockStyle.Top;
toolStripAccounts.ImageScalingSize = new Size(24, 24);
toolStripAccounts.Items.AddRange(new ToolStripItem[] { btnAccNew, btnAccDelete });
toolStripAccounts.Location = new Point(3, 3);
@@ -178,9 +176,8 @@ namespace PolyTraderSharp.Ui.Views
//
AutoScaleDimensions = new SizeF(10F, 25F);
AutoScaleMode = AutoScaleMode.Font;
- ClientSize = new Size(1185, 1523);
+ ClientSize = new Size(1185, 820);
Controls.Add(tabControl1);
- Controls.Add(toolStrip1);
Margin = new Padding(4, 5, 4, 5);
Name = "SettingsView";
Text = "Server Settings";
@@ -201,7 +198,6 @@ namespace PolyTraderSharp.Ui.Views
#endregion
private System.Windows.Forms.PropertyGrid propertyGrid;
- private ToolStrip toolStrip1;
private TabControl tabControl1;
private TabPage tabPage1;
private ToolStrip toolStrip2;
@@ -209,6 +205,7 @@ namespace PolyTraderSharp.Ui.Views
private ToolStripButton btn_save;
private ToolStripButton btn_loadsettings;
private ToolStripButton btnGenMasterKey;
+ private ToolStripButton btnSetOpenRouterKey;
private ToolStrip toolStripAccounts;
private ToolStripButton btnAccNew;
private ToolStripButton btnAccDelete;
diff --git a/Ui/Views/SettingsView.cs b/Ui/Views/SettingsView.cs
index b48c112..0424ec9 100644
--- a/Ui/Views/SettingsView.cs
+++ b/Ui/Views/SettingsView.cs
@@ -36,6 +36,7 @@ namespace PolyTraderSharp.Ui.Views
btn_save.Click += (_, _) => Save();
btn_loadsettings.Click += (_, _) => Reload();
btnGenMasterKey.Click += (_, _) => GenerateMasterKey();
+ btnSetOpenRouterKey.Click += (_, _) => SetOpenRouterKey();
UpdateMasterKeyButtonState();
btnAccNew.Click += (_, _) => AddAccount();
@@ -182,5 +183,71 @@ namespace PolyTraderSharp.Ui.Views
UpdateMasterKeyButtonState(); // nach Erzeugung deaktivieren
}
+
+ // ===== OpenRouter-API-Key (Supervisor) =====
+
+ ///
+ /// Setzt/entfernt den OpenRouter-API-Key des Supervisors. Ablage in der gitignorierten Datei
+ /// openrouter.key (genau das liest der OpenRouterClient) – kein Secret im Klartext in
+ /// server_settings.xml. Der Nutzer gibt den Key selbst maskiert ein.
+ ///
+ private void SetOpenRouterKey()
+ {
+ string keyFile = Path.Combine(AppContext.BaseDirectory, "openrouter.key");
+ bool exists = File.Exists(keyFile) ||
+ !string.IsNullOrWhiteSpace(Environment.GetEnvironmentVariable("POLYTRADER_OPENROUTER_KEY"));
+ string? key = PromptForSecret("OpenRouter-API-Key",
+ "OpenRouter-API-Key für den Supervisor eingeben.\n" +
+ "Wird in der gitignorierten Datei 'openrouter.key' gespeichert (leer = entfernen).\n" +
+ (exists ? "Aktuell ist bereits ein Key hinterlegt." : "Aktuell ist KEIN Key gesetzt."));
+ if (key == null) return; // Abbruch
+
+ try
+ {
+ if (string.IsNullOrWhiteSpace(key))
+ {
+ if (File.Exists(keyFile)) File.Delete(keyFile);
+ _logger?.Info("OpenRouter-Key aus openrouter.key entfernt.");
+ MessageBox.Show("OpenRouter-Key entfernt.", "OpenRouter",
+ MessageBoxButtons.OK, MessageBoxIcon.Information);
+ }
+ else
+ {
+ File.WriteAllText(keyFile, key.Trim());
+ _logger?.Info("OpenRouter-Key gespeichert (openrouter.key).");
+ MessageBox.Show("OpenRouter-Key gespeichert. Wirkt beim nächsten Programmstart bzw. der nächsten Supervisor-Anfrage.\n\n" +
+ "Tipp: bei OpenRouter ein Spend-Limit für diesen Key setzen (separater Key für den Supervisor empfohlen).",
+ "OpenRouter", MessageBoxButtons.OK, MessageBoxIcon.Information);
+ }
+ }
+ catch (Exception ex)
+ {
+ MessageBox.Show($"Fehler beim Speichern des OpenRouter-Keys: {ex.Message}",
+ "Fehler", MessageBoxButtons.OK, MessageBoxIcon.Error);
+ }
+ }
+
+ /// Modaler Mini-Dialog mit maskierter Eingabe. Rückgabe null = Abbruch.
+ private string? PromptForSecret(string title, string prompt)
+ {
+ using var form = new Form
+ {
+ Text = title,
+ Width = 480,
+ Height = 210,
+ FormBorderStyle = FormBorderStyle.FixedDialog,
+ StartPosition = FormStartPosition.CenterParent,
+ MinimizeBox = false,
+ MaximizeBox = false
+ };
+ var lbl = new Label { Text = prompt, Left = 12, Top = 12, Width = 445, Height = 70, AutoSize = false };
+ var tb = new TextBox { Left = 12, Top = 92, Width = 445, UseSystemPasswordChar = true };
+ var ok = new Button { Text = "OK", DialogResult = DialogResult.OK, Left = 296, Top = 128, Width = 75 };
+ var cancel = new Button { Text = "Abbrechen", DialogResult = DialogResult.Cancel, Left = 380, Top = 128, Width = 77 };
+ form.Controls.AddRange(new Control[] { lbl, tb, ok, cancel });
+ form.AcceptButton = ok;
+ form.CancelButton = cancel;
+ return form.ShowDialog(this) == DialogResult.OK ? tb.Text : null;
+ }
}
}