477 lines
19 KiB
C#
477 lines
19 KiB
C#
using Microsoft.VisualBasic.FileIO;
|
|
using ModVersionChecker.data.model;
|
|
using ModVersionChecker.managers.interfaces;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Windows.Forms;
|
|
using static System.Windows.Forms.VisualStyles.VisualStyleElement.Window;
|
|
|
|
namespace ModVersionChecker.forms
|
|
{
|
|
public class AppDetailsForm : Form
|
|
{
|
|
private readonly IConfigManager _configManager;
|
|
private readonly IAppsManager _appsManager;
|
|
private readonly ISourcesDefManager _sourcesDefManager;
|
|
private readonly ICheckerTypesDefManager _checkerTypesDefManager;
|
|
private readonly IFlightSimsManager _flightSimsManager;
|
|
private readonly GlobalConfig _globalConfig;
|
|
private int _currentRow;
|
|
//private string? _appId;
|
|
private bool _isEditable;
|
|
//private List<AppConfig> _apps;
|
|
private List<SourceDef> _sourcesDef;
|
|
private List<CheckerTypeDef> _checkerTypesDef;
|
|
|
|
private TextBox _nameField, _downloadUrlField;
|
|
private Label _nameLabel, _msfsVersionsLabel, _sourceLabel, _paramsSubtitle, _downloadUrlLabel;
|
|
private ComboBox _sourceField;
|
|
private Button _saveButton, _closeButton;
|
|
private TableLayoutPanel _mainLayout, _paramsPanel, _fsFieldsPanel;
|
|
private FlowLayoutPanel _buttonsPanel, _fsPanel;
|
|
private readonly Dictionary<string, TextBox> _paramFields = new Dictionary<string, TextBox>();
|
|
private readonly Dictionary<string, Dictionary<string, TextBox>> _fsFields = new Dictionary<string, Dictionary<string, TextBox>>();
|
|
private List<string> _selectedFs = new List<string>();
|
|
private List<CheckBox> _fsCheckBoxes = new List<CheckBox>();
|
|
private AppConfig? _currentApp;
|
|
|
|
private List<FsModPathConfig> _flightSims;
|
|
|
|
public event EventHandler<string> OnAppChanged;
|
|
|
|
public AppDetailsForm(
|
|
IConfigManager configManager,
|
|
IAppsManager appsManager,
|
|
ISourcesDefManager sourcesDefManager,
|
|
ICheckerTypesDefManager checkerTypesDefManager,
|
|
IFlightSimsManager flightSimsManager
|
|
)
|
|
{
|
|
|
|
_configManager = configManager ?? throw new ArgumentNullException(nameof(configManager));
|
|
_appsManager = appsManager ?? throw new ArgumentNullException(nameof(appsManager));
|
|
_sourcesDefManager = sourcesDefManager ?? throw new ArgumentNullException(nameof(sourcesDefManager));
|
|
_checkerTypesDefManager = checkerTypesDefManager ?? throw new ArgumentNullException(nameof(checkerTypesDefManager));
|
|
_flightSimsManager = flightSimsManager ?? throw new ArgumentNullException(nameof(flightSimsManager));
|
|
|
|
_flightSims = _flightSimsManager.Load() ?? new List<FsModPathConfig>();
|
|
|
|
_globalConfig = _configManager.Load() ?? new GlobalConfig();
|
|
|
|
_sourcesDef = _sourcesDefManager.List() ?? new List<SourceDef>();
|
|
_checkerTypesDef = _checkerTypesDefManager.Load() ?? new List<CheckerTypeDef>();
|
|
|
|
|
|
_selectedFs = _flightSims.Select(sim => sim.ShortName).ToList();
|
|
|
|
_mainLayout = new TableLayoutPanel
|
|
{
|
|
Dock = DockStyle.Fill,
|
|
ColumnCount = 2,
|
|
RowCount = 14,
|
|
ColumnStyles = { new ColumnStyle(SizeType.Absolute, 150), new ColumnStyle(SizeType.Percent, 100) }
|
|
};
|
|
|
|
// App Name
|
|
_nameLabel = new Label { Text = "Name:" };
|
|
_nameField = new TextBox { Text = "", Enabled = _isEditable, Width = 300 };
|
|
// FS Versions
|
|
_msfsVersionsLabel = new Label { Text = "FS:" };
|
|
_fsPanel = new FlowLayoutPanel
|
|
{
|
|
FlowDirection = FlowDirection.LeftToRight,
|
|
AutoSize = true,
|
|
Dock = DockStyle.Fill
|
|
};
|
|
//_msfs2020CheckBox = new CheckBox { Text = "MSFS 2020", Enabled = _isEditable };
|
|
//_msfs2024CheckBox = new CheckBox { Text = "MSFS 2024", Enabled = _isEditable };
|
|
// Source
|
|
_sourceLabel = new Label { Text = "Source:" };
|
|
_sourceField = new ComboBox { Enabled = _isEditable, Width = 300, DropDownStyle = ComboBoxStyle.DropDownList };
|
|
_sourceField.Items.AddRange(_sourcesDef.Select(sd => sd.Id).ToArray());
|
|
_sourceField.SelectedIndexChanged += OnSourceFieldIndexChanged;
|
|
// Parameters
|
|
_paramsSubtitle = new Label { Text = "SourceParameters:", Font = new System.Drawing.Font(Font, System.Drawing.FontStyle.Bold) };
|
|
_paramsPanel = new TableLayoutPanel
|
|
{
|
|
AutoSize = true,
|
|
BackColor = Color.White,
|
|
Dock = DockStyle.Fill,
|
|
ColumnCount = 2,
|
|
RowCount = 2,
|
|
ColumnStyles = { new ColumnStyle(SizeType.Absolute, 150), new ColumnStyle(SizeType.Percent, 100) }
|
|
};
|
|
// Fs Fields Panel
|
|
_fsFieldsPanel = new TableLayoutPanel
|
|
{
|
|
AutoSize = true,
|
|
BackColor = Color.White,
|
|
Dock = DockStyle.Fill,
|
|
ColumnCount = 2,
|
|
RowCount = 2,
|
|
ColumnStyles = { new ColumnStyle(SizeType.Absolute, 150), new ColumnStyle(SizeType.Percent, 100) }
|
|
};
|
|
|
|
|
|
// App Name
|
|
_downloadUrlLabel = new Label { Text = "Download Url:" };
|
|
_downloadUrlField = new TextBox { Text = "", Enabled = _isEditable, Width = 300 };
|
|
|
|
_buttonsPanel = new FlowLayoutPanel { FlowDirection = FlowDirection.RightToLeft, AutoSize = true, Dock = DockStyle.Fill };
|
|
_saveButton = new Button { Text = "Save", Width = 100 };
|
|
_closeButton = new Button { Text = "Close", Width = 100 };
|
|
_saveButton.Click += OnSaveButtonClicked;
|
|
_closeButton.Click += (s, e) => Close();
|
|
Controls.Add(_mainLayout);
|
|
|
|
Size = new System.Drawing.Size(500, 500);
|
|
StartPosition = FormStartPosition.CenterParent;
|
|
|
|
InitializeForm();
|
|
|
|
}
|
|
|
|
public void SetApp(AppConfig? app, bool update = true)
|
|
{
|
|
_currentApp = app;
|
|
_selectedFs = _currentApp?.MsfsVersions ?? new List<string>();
|
|
|
|
if (update)
|
|
{
|
|
UpdateForm();
|
|
}
|
|
}
|
|
|
|
public void SetEditable(bool isEditable, bool update = true)
|
|
{
|
|
_isEditable = isEditable;
|
|
if (update)
|
|
{
|
|
UpdateForm();
|
|
}
|
|
}
|
|
|
|
public void UpdateForm()
|
|
{
|
|
|
|
Text = _currentApp == null ? "Add App" : (_isEditable ? "Edit App" : "App Details");
|
|
|
|
_nameField.Text = _currentApp != null ? _currentApp.Name : "";
|
|
_downloadUrlField.Enabled = _nameField.Enabled = _sourceField.Enabled = _isEditable;
|
|
_downloadUrlField.Text = _currentApp != null ? _currentApp.DownloadUrl : "";
|
|
|
|
_flightSims.ForEach(fs =>
|
|
{
|
|
if (_currentApp != null && _currentApp.MsfsVersions.Contains(fs.ShortName))
|
|
{
|
|
if (!_selectedFs.Contains(fs.ShortName))
|
|
{
|
|
_selectedFs.Add(fs.ShortName);
|
|
}
|
|
}
|
|
});
|
|
|
|
for (int i = 0; i < _fsCheckBoxes.Count; i++)
|
|
{
|
|
var fsKey = _flightSims.FirstOrDefault(f => f.ShortName == _fsCheckBoxes[i].Text)?.ShortName;
|
|
if (fsKey != null)
|
|
{
|
|
_fsCheckBoxes[i].Checked = _currentApp != null && _currentApp.MsfsVersions.Contains(fsKey);
|
|
}
|
|
}
|
|
|
|
_sourceField.SelectedIndex = _sourceField.Items.IndexOf(_currentApp != null ? _currentApp.Source : "");
|
|
|
|
UpdateFsFields();
|
|
|
|
UpdateParamFields();
|
|
}
|
|
|
|
private bool isFsSelected(FsModPathConfig fs)
|
|
{
|
|
return _selectedFs.Contains(fs.ShortName);
|
|
}
|
|
private void UpdateFsFields()
|
|
{
|
|
_fsFields.Clear();
|
|
_fsFieldsPanel.Controls.Clear();
|
|
|
|
foreach (var fs in _flightSims)
|
|
{
|
|
|
|
if (fs == null || !isFsSelected(fs))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
var fsKey = fs.ShortName;
|
|
var fieldsDict = new Dictionary<string, TextBox>();
|
|
_fsFields[fsKey] = fieldsDict;
|
|
int currentRow = 0;
|
|
|
|
Label horizontalSeparator = new Label
|
|
{
|
|
Height = 50,
|
|
Padding = new Padding(10, 0, 0, 0),
|
|
BackColor = Color.GhostWhite, // Line-like separator
|
|
Dock = DockStyle.Fill,
|
|
TextAlign = ContentAlignment.MiddleLeft,
|
|
Text = fsKey, // Optional: Add text to the separator
|
|
ForeColor = Color.FromArgb(50, 50, 50) // Text color contrasts with background
|
|
};
|
|
|
|
_fsFieldsPanel.Controls.Add(horizontalSeparator, 0, currentRow);
|
|
_fsFieldsPanel.SetColumnSpan(horizontalSeparator, 2);
|
|
currentRow++;
|
|
|
|
|
|
foreach (var field in fs.Fields)
|
|
{
|
|
Control control;
|
|
var value = GetFsFieldValue(fsKey, field.Name);
|
|
var label = new Label { Text = $"{field.Label} ({(field.Required ? "Required" : "Optional")}):", Width = 100, AutoSize = true };
|
|
var textBox = new TextBox
|
|
{
|
|
Width = 300,
|
|
Enabled = _isEditable,
|
|
Text = value
|
|
};
|
|
|
|
switch (field.Control.ToLower())
|
|
{
|
|
case "directory":
|
|
textBox.ReadOnly = true;
|
|
control = new TableLayoutPanel
|
|
{
|
|
AutoSize = true,
|
|
Dock = DockStyle.Fill,
|
|
ColumnCount = 2,
|
|
RowCount = 1,
|
|
ColumnStyles = { new ColumnStyle(SizeType.Percent, 80), new ColumnStyle(SizeType.Percent, 20) }
|
|
};
|
|
(control as TableLayoutPanel).Controls.Add(textBox, 0, 0);
|
|
var browseButton = new Button { Text = "Browse", Width = 80, Enabled = _isEditable };
|
|
browseButton.Click += (s, e) =>
|
|
{
|
|
using (var folderDialog = new FolderBrowserDialog())
|
|
{
|
|
folderDialog.Description = $"Select directory for {field.Label}";
|
|
folderDialog.SelectedPath = textBox.Text == "" ? Path.Combine(fs.Path) : textBox.Text;
|
|
|
|
if (folderDialog.ShowDialog() == DialogResult.OK)
|
|
{
|
|
string selectedDirectory = folderDialog.SelectedPath;
|
|
string folderName = Path.GetFileName(selectedDirectory);
|
|
textBox.Text = folderName;
|
|
}
|
|
}
|
|
};
|
|
(control as TableLayoutPanel).Controls.Add(browseButton, 1, 0);
|
|
break;
|
|
default:
|
|
control = textBox;
|
|
break;
|
|
}
|
|
|
|
fieldsDict[field.Name] = textBox;
|
|
|
|
_fsFieldsPanel.Controls.Add(label, 0, currentRow);
|
|
_fsFieldsPanel.Controls.Add(control, 1, currentRow);
|
|
currentRow++;
|
|
}
|
|
}
|
|
}
|
|
|
|
private string GetFsFieldValue(string fsKey, string fieldName)
|
|
{
|
|
if (_currentApp == null) return "";
|
|
|
|
var fsFields = _currentApp.FsFields.ContainsKey(fsKey) ? _currentApp.FsFields[fsKey] : new Dictionary<string, string>();
|
|
if (fsFields.ContainsKey(fieldName))
|
|
{
|
|
return fsFields[fieldName];
|
|
}
|
|
return "";
|
|
}
|
|
|
|
private void UpdateParamFields()
|
|
{
|
|
if (_sourceField?.SelectedItem == null) return;
|
|
|
|
var selectedSource = _sourcesDef.FirstOrDefault(sd => sd.Id == _sourceField.SelectedItem.ToString());
|
|
if (selectedSource == null) return;
|
|
|
|
var checkerType = _checkerTypesDef.FirstOrDefault(ct => ct.Name == selectedSource.Type);
|
|
if (checkerType == null) return;
|
|
|
|
_paramFields.Clear();
|
|
_paramsPanel.Controls.Clear();
|
|
|
|
int currentRow = 0;
|
|
foreach (var paramDef in checkerType.Params)
|
|
{
|
|
var label = new Label { Text = $"{paramDef.Label} ({(paramDef.Required ? "Required" : "Optional")}):", Width = 100, AutoSize = true };
|
|
var textBox = new TextBox
|
|
{
|
|
Width = 300,
|
|
Enabled = _isEditable,
|
|
Text = GetParamValue(paramDef.Name, selectedSource)
|
|
};
|
|
_paramFields[paramDef.Name] = textBox;
|
|
|
|
_paramsPanel.Controls.Add(label, 0, currentRow);
|
|
_paramsPanel.Controls.Add(textBox, 1, currentRow);
|
|
currentRow++;
|
|
}
|
|
}
|
|
|
|
private string GetParamValue(string paramName, SourceDef source)
|
|
{
|
|
var valueFromSource = source.Defaults != null && source.Defaults.ContainsKey(paramName) ? source.Defaults[paramName] : "";
|
|
|
|
|
|
if (_currentApp == null || _currentApp.Params == null || !_currentApp.Params.ContainsKey(paramName))
|
|
return valueFromSource;
|
|
return _currentApp.Params[paramName];
|
|
}
|
|
|
|
|
|
private void InitializeForm()
|
|
{
|
|
|
|
|
|
_currentRow = 0;
|
|
_mainLayout.Controls.Add(_nameLabel, 0, _currentRow);
|
|
_mainLayout.Controls.Add(_nameField, 1, _currentRow++);
|
|
_mainLayout.Controls.Add(_msfsVersionsLabel, 0, _currentRow++);
|
|
_mainLayout.Controls.Add(_fsPanel, 1, _currentRow);
|
|
_mainLayout.SetColumnSpan(_fsPanel, 2);
|
|
_currentRow++;
|
|
_mainLayout.Controls.Add(_fsFieldsPanel, 0, _currentRow);
|
|
_mainLayout.SetColumnSpan(_fsFieldsPanel, 2);
|
|
_currentRow++;
|
|
|
|
_mainLayout.Controls.Add(_sourceLabel, 0, _currentRow);
|
|
_mainLayout.Controls.Add(_sourceField, 1, _currentRow++);
|
|
_mainLayout.Controls.Add(_paramsSubtitle, 0, _currentRow);
|
|
_mainLayout.SetColumnSpan(_paramsSubtitle, 2);
|
|
_currentRow++;
|
|
_mainLayout.Controls.Add(_paramsPanel, 0, _currentRow);
|
|
_mainLayout.SetColumnSpan(_paramsPanel, 2);
|
|
_currentRow++;
|
|
_mainLayout.Controls.Add(_downloadUrlLabel, 0, _currentRow);
|
|
_mainLayout.Controls.Add(_downloadUrlField, 1, _currentRow++);
|
|
_currentRow++;
|
|
|
|
|
|
_mainLayout.Controls.Add(_buttonsPanel, 0, _currentRow++);
|
|
|
|
AddFsCheckboxes();
|
|
AddButtons();
|
|
|
|
// UpdateForm();
|
|
}
|
|
|
|
private void AddFsCheckboxes()
|
|
{
|
|
foreach (var fs in _flightSims)
|
|
{
|
|
var checkBox = new CheckBox
|
|
{
|
|
Text = fs.ShortName,
|
|
Checked = _currentApp != null && _currentApp.MsfsVersions.Contains(fs.ShortName),
|
|
};
|
|
checkBox.CheckedChanged += (s, e) =>
|
|
{
|
|
if (checkBox.Checked)
|
|
{
|
|
if (!_selectedFs.Contains(fs.ShortName))
|
|
{
|
|
_selectedFs.Add(fs.ShortName);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
_selectedFs.Remove(fs.ShortName);
|
|
}
|
|
UpdateFsFields();
|
|
};
|
|
_fsPanel.Controls.Add(checkBox);
|
|
_fsCheckBoxes.Add(checkBox);
|
|
}
|
|
}
|
|
|
|
|
|
private void OnSourceFieldIndexChanged(object? sender, EventArgs e)
|
|
{
|
|
if (_isEditable && _sourceField.SelectedItem != null)
|
|
{
|
|
UpdateParamFields();
|
|
}
|
|
}
|
|
|
|
private void AddButtons()
|
|
{
|
|
_buttonsPanel.Controls.Clear();
|
|
_buttonsPanel.Controls.Add(_saveButton);
|
|
_buttonsPanel.Controls.Add(_closeButton);
|
|
}
|
|
|
|
private void OnSaveButtonClicked(object? sender, EventArgs e)
|
|
{
|
|
try {
|
|
var paramsDict = _paramFields.ToDictionary(kvp => kvp.Key, kvp => kvp.Value.Text.Trim());
|
|
var fsFieldsDict = _fsFields.ToDictionary(
|
|
kvp => kvp.Key,
|
|
kvp => kvp.Value.ToDictionary(fkvp => fkvp.Key, fkvp => fkvp.Value.Text.Trim())
|
|
);
|
|
var requiredParams = _checkerTypesDef
|
|
.First(ct => ct.Name == _sourcesDef.FirstOrDefault(sd => sd.Id == _sourceField.SelectedItem?.ToString())?.Type)
|
|
.Params.Where(p => p.Required)
|
|
.Select(p => p.Name);
|
|
if (requiredParams.Any(rp => string.IsNullOrWhiteSpace(paramsDict[rp])))
|
|
{
|
|
throw new Exception("All required parameters must be filled.");
|
|
}
|
|
var msfsVersions = _selectedFs;
|
|
var isNewApp = (_currentApp == null || string.IsNullOrEmpty(_currentApp.Id));
|
|
var app = new AppConfig
|
|
{
|
|
Id = isNewApp ? GetUuid() : _currentApp.Id,
|
|
Name = _nameField.Text.Trim(),
|
|
MsfsVersions = msfsVersions,
|
|
Source = _sourceField.SelectedItem?.ToString() ?? "",
|
|
Params = paramsDict,
|
|
FsFields = fsFieldsDict,
|
|
DownloadUrl = _downloadUrlField.Text.Trim(),
|
|
CurrentVersion = _currentApp?.CurrentVersion ?? "",
|
|
LatestVersion = _currentApp?.LatestVersion ?? "",
|
|
Status = _currentApp?.Status ?? AppStatus.None
|
|
};
|
|
|
|
if (isNewApp)
|
|
{
|
|
_appsManager.Insert(app);
|
|
} else
|
|
{
|
|
_appsManager.Update(app);
|
|
}
|
|
|
|
_currentApp = app;
|
|
OnAppChanged?.Invoke(this, "App saved");
|
|
Close();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
MessageBox.Show($"Error: {ex.Message}", "Invalid Input", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
|
}
|
|
}
|
|
|
|
private string GetUuid()
|
|
{
|
|
Guid uuid = Guid.NewGuid();
|
|
return uuid.ToString();
|
|
}
|
|
}
|
|
} |