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; + } } }