- tabPage2: DataGridView (Name/Wallet/Demo/Aktiv) + Toolstrip (Neuer Account/ Loeschen) + PropertyGrid. Da AccountState jetzt general-only ist, zeigt das PropertyGrid automatisch nur die allgemeinen Felder (Wallet, API-Keys, Payouts). - SettingsView.cs: Accounts laden, Auswahl -> PropertyGrid, Bearbeiten -> speichern (IAccountRepository + TradingState), Neu/Loeschen. - Program.cs: Settings-View bekommt IAccountRepository + TradingState injiziert. - Copytrading-Detail-Limits folgen im Modul-Account-View. - Build 0 Fehler. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
134 lines
4.6 KiB
C#
134 lines
4.6 KiB
C#
using System;
|
|
using System.ComponentModel;
|
|
using System.Linq;
|
|
using System.Windows.Forms;
|
|
using PolyTrader.Core.Persistence;
|
|
using PolyTraderSharp.Models;
|
|
using PolyTraderSharp.Services;
|
|
|
|
namespace PolyTraderSharp.Ui.Views
|
|
{
|
|
/// <summary>
|
|
/// Core-Settings-Fenster: allgemeine Server-Einstellungen (PropertyGrid) und die
|
|
/// allgemeine Verwaltung der Polymarket-Accounts (Wallets, API-Keys …).
|
|
/// Die copytrading-spezifischen Detail-Limits werden NICHT hier, sondern im
|
|
/// Copytrading-Modul-View bearbeitet (AccountState ist bewusst general-only).
|
|
/// </summary>
|
|
public partial class SettingsView : Form
|
|
{
|
|
private const string SettingsPath = "server_settings.xml";
|
|
|
|
private ServerSettings _settings = new();
|
|
private ThreemaService? _threema;
|
|
private MullvadVpnService? _vpn;
|
|
private TerminalLogger? _logger;
|
|
|
|
private IAccountRepository? _accountRepo;
|
|
private TradingState? _state;
|
|
private BindingList<AccountState> _accounts = new();
|
|
|
|
public SettingsView()
|
|
{
|
|
InitializeComponent();
|
|
|
|
btn_save.Click += (_, _) => Save();
|
|
btn_loadsettings.Click += (_, _) => Reload();
|
|
|
|
btnAccNew.Click += (_, _) => AddAccount();
|
|
btnAccDelete.Click += (_, _) => DeleteAccount();
|
|
dgvAccounts.SelectionChanged += (_, _) =>
|
|
{
|
|
pgAccount.SelectedObject = dgvAccounts.CurrentRow?.DataBoundItem as AccountState;
|
|
};
|
|
pgAccount.PropertyValueChanged += (_, _) =>
|
|
{
|
|
if (pgAccount.SelectedObject is AccountState acc) SaveAccount(acc);
|
|
};
|
|
}
|
|
|
|
public void Initialize(ThreemaService threema, MullvadVpnService vpn, TerminalLogger logger,
|
|
IAccountRepository accountRepo, TradingState state)
|
|
{
|
|
_threema = threema;
|
|
_vpn = vpn;
|
|
_logger = logger;
|
|
_accountRepo = accountRepo;
|
|
_state = state;
|
|
|
|
Reload();
|
|
LoadAccounts();
|
|
}
|
|
|
|
// ===== Server-Settings =====
|
|
|
|
private void Reload()
|
|
{
|
|
_settings = ServerSettings.Load(SettingsPath);
|
|
propertyGrid.SelectedObject = _settings;
|
|
}
|
|
|
|
private void Save()
|
|
{
|
|
try
|
|
{
|
|
_settings.Save(SettingsPath);
|
|
_threema?.ReloadSettings();
|
|
_vpn?.ReloadSettings();
|
|
_logger?.Info("Server-Einstellungen gespeichert und Services neu geladen.");
|
|
MessageBox.Show("Server-Einstellungen gespeichert.", "Erfolg",
|
|
MessageBoxButtons.OK, MessageBoxIcon.Information);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
MessageBox.Show($"Fehler beim Speichern: {ex.Message}", "Fehler",
|
|
MessageBoxButtons.OK, MessageBoxIcon.Error);
|
|
}
|
|
}
|
|
|
|
// ===== Polymarket Accounts (allgemeine Einstellungen) =====
|
|
|
|
private void LoadAccounts()
|
|
{
|
|
if (_state == null) return;
|
|
_accounts = new BindingList<AccountState>(_state.Accounts.Values.OrderBy(a => a.AccountId).ToList());
|
|
dgvAccounts.DataSource = _accounts;
|
|
pgAccount.SelectedObject = dgvAccounts.CurrentRow?.DataBoundItem as AccountState;
|
|
}
|
|
|
|
private void AddAccount()
|
|
{
|
|
if (_state == null || _accountRepo == null) return;
|
|
|
|
int newId = _state.Accounts.Count > 0 ? _state.Accounts.Keys.Max() + 1 : 1;
|
|
var acc = new AccountState { AccountId = newId, Name = "Neuer Account" };
|
|
|
|
_state.Accounts[acc.AccountId] = acc;
|
|
_accountRepo.Upsert(acc);
|
|
|
|
_accounts.Add(acc);
|
|
dgvAccounts.CurrentCell = dgvAccounts.Rows[dgvAccounts.Rows.Count - 1].Cells[0];
|
|
}
|
|
|
|
private void DeleteAccount()
|
|
{
|
|
if (_state == null || _accountRepo == null) return;
|
|
if (dgvAccounts.CurrentRow?.DataBoundItem is not AccountState acc) return;
|
|
|
|
if (MessageBox.Show($"Account '{acc.Name}' (ID {acc.AccountId}) wirklich löschen?",
|
|
"Löschen bestätigen", MessageBoxButtons.YesNo, MessageBoxIcon.Warning) != DialogResult.Yes)
|
|
return;
|
|
|
|
_state.Accounts.TryRemove(acc.AccountId, out _);
|
|
_accountRepo.Delete(acc.AccountId);
|
|
_accounts.Remove(acc);
|
|
}
|
|
|
|
private void SaveAccount(AccountState acc)
|
|
{
|
|
_accountRepo?.Upsert(acc);
|
|
_state?.Accounts.AddOrUpdate(acc.AccountId, acc, (_, _) => acc);
|
|
dgvAccounts.Refresh();
|
|
}
|
|
}
|
|
}
|