using System.Globalization; using System.Windows; using System.Windows.Controls; using SheetMe.Core.Catalog; namespace SheetMe.Designer.Views; /// /// DataTableField 전용 편집기 — 문법 골격을 코드가 조립하고, 저장 전에 검사한다. /// /// 레거시 편집기와 다르게 기존 값을 되읽어 채운다. 레거시는 열 때마다 백지에서 시작해 /// 한 조각만 고치려 해도 전부 다시 골라야 했다(fmMDataTableField.InitializeSelectedData). /// 형태(Select/Rows)도 연 값 그대로 유지한다 — 운영 다수는 Rows 형이고(1,624건, 76%), /// 형태를 바꾸면 그 형태만 이해하는 보조 로더에서 동작이 달라질 수 있다. /// public partial class DataTableFieldDialogView : Window { #region Member Fields private readonly IReadOnlyList tables; private bool loading = true; #endregion #region Properties /// 적용 결과 — 취소면 null, '배선 지우기'면 빈 문자열 public string? Result { get; private set; } #endregion #region Constructors public DataTableFieldDialogView(string? current, IReadOnlyList dataTables) { InitializeComponent(); tables = dataTables; foreach (var name in tables) { TableList.Items.Add(name); } NoTableHint.Visibility = tables.Count == 0 ? Visibility.Visible : Visibility.Collapsed; var spec = DataTableFieldSpec.Parse(current); if (spec is not null) { FormBox.SelectedIndex = spec.Form == DataTableFieldForm.Rows ? 1 : 0; TableList.SelectedItem = tables.FirstOrDefault(t => string.Equals(t, spec.TableName, StringComparison.Ordinal)); FilterBox.Text = spec.Filter; RowBox.Text = spec.RowIndex.ToString(CultureInfo.InvariantCulture); FieldBox.Text = spec.Field; } else { // 새 배선 — 레거시 편집기와 같은 Select 형으로 시작한다 FormBox.SelectedIndex = 0; RowBox.Text = "0"; if (tables.Count == 1) { TableList.SelectedIndex = 0; } } loading = false; Refresh(); } #endregion #region Methods /// /// 현재 입력을 명세로 옮긴다 — 행 번호는 숫자가 아니면 0 으로 본다 /// (레거시도 빈 값을 0 으로 강제한다: fmMDataTableField.vb:135). /// private DataTableFieldSpec CurrentSpec() { var row = int.TryParse(RowBox.Text.Trim(), NumberStyles.Integer, CultureInfo.InvariantCulture, out var parsed) ? parsed : 0; return new DataTableFieldSpec { Form = FormBox.SelectedIndex == 1 ? DataTableFieldForm.Rows : DataTableFieldForm.Select, TableName = TableList.SelectedItem as string ?? string.Empty, Filter = FilterBox.Text, RowIndex = row, Field = FieldBox.Text.Trim(), }; } private void Refresh() { var spec = CurrentSpec(); var rowsForm = spec.Form == DataTableFieldForm.Rows; // Rows 형은 필터를 아예 쓰지 않는다 — 켜 두면 입력해도 무시되는 칸이 된다 FilterBox.IsEnabled = !rowsForm; FilterLabel.Opacity = rowsForm ? 0.45 : 1; FilterBox.Opacity = rowsForm ? 0.45 : 1; PreviewText.Text = spec.Compose(); var problem = spec.Validate(tables); ProblemText.Text = problem ?? string.Empty; ProblemText.Visibility = problem is null ? Visibility.Collapsed : Visibility.Visible; // 레거시는 아무것도 안 고르고 확인하면 ")(" 같은 찌꺼기를 저장한다 — 그 경로를 막는다 OkButton.IsEnabled = problem is null; } private void OnFormChanged(object sender, RoutedEventArgs e) { if (!loading) { Refresh(); } } private void OnApply(object sender, RoutedEventArgs e) { var spec = CurrentSpec(); if (spec.Validate(tables) is not null) { return; } Result = spec.Compose(); DialogResult = true; } private void OnClear(object sender, RoutedEventArgs e) { Result = string.Empty; DialogResult = true; } #endregion }