Add project files.
This commit is contained in:
477
ModVersionChecker/forms/AppDetailsForm.cs
Normal file
477
ModVersionChecker/forms/AppDetailsForm.cs
Normal file
@@ -0,0 +1,477 @@
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user