초기 커밋: SheetMe 서식생성기 (P0~P5 완료 상태)

레거시 서식생성기(VB.NET WinForms) 대체용 C#/.NET 10 WPF 디자이너.
기준선: 실DB 활성 디자인 1,271건 왕복 의미론 diff 0 / 예외 0, 단위 테스트 49/49.

이 커밋에 함께 포함된 자격증명 분리:
- appsettings.json 을 __HOST__/__PASSWORD__ 플레이스홀더로 전환
- 실접속 정보는 appsettings.Development.json 으로 분리(.gitignore 제외,
  csproj Debug 조건부 복사라 Release 산출물에 실리지 않음)
- ConfigLoader 를 환경변수 > Development > appsettings 순 레이어링으로 변경,
  미치환 플레이스홀더는 '미설정'으로 간주

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Msystech
2026-08-11 17:20:22 +09:00
co-authored by Claude Fable 5
commit 16c07f48dc
102 changed files with 14210 additions and 0 deletions
@@ -0,0 +1,79 @@
using System.Globalization;
using System.Windows;
using System.Windows.Media;
using SheetMe.Core.Serialization;
using SheetMe.Designer.ViewModels;
namespace SheetMe.Designer.Views;
/// <summary>
/// 폰트 일괄 변경 대화상자 — 레거시 frmFontManager 이식.
/// 문서 전체 (타입·글꼴·크기·스타일) 집계 → 선택 조합 또는 전체에 새 글꼴 일괄 적용(Undo 1스텝).
/// </summary>
public partial class FontManagerDialogView : Window
{
#region Member Fields
private readonly DesignerViewModel designer;
#endregion
#region Constructors
public FontManagerDialogView(DesignerViewModel designer)
{
this.designer = designer;
InitializeComponent();
FamilyBox.ItemsSource = Fonts.SystemFontFamilies
.Select(f => f.FamilyNames.Values.FirstOrDefault() ?? f.Source)
.Distinct()
.OrderBy(name => name, StringComparer.CurrentCulture)
.ToList();
FamilyBox.Text = "굴림";
Reload();
}
#endregion
#region Methods
private void Reload()
{
GroupList.ItemsSource = designer.CollectFontUsage();
}
private void OnApplySelected(object sender, RoutedEventArgs e)
=> Apply(GroupList.SelectedItems.Cast<FontUsageGroup>().ToList());
private void OnApplyAll(object sender, RoutedEventArgs e)
=> Apply(GroupList.Items.Cast<FontUsageGroup>().ToList());
private void Apply(List<FontUsageGroup> targets)
{
if (targets.Count == 0)
{
MessageBox.Show("변경할 조합을 선택하세요.", "폰트 일괄 변경");
return;
}
var family = FamilyBox.Text.Trim();
if (family.Length == 0)
{
MessageBox.Show("글꼴명을 입력하세요.", "폰트 일괄 변경");
return;
}
if (!double.TryParse(SizeBox.Text.Trim(), NumberStyles.Number, CultureInfo.InvariantCulture, out var sizePt)
|| sizePt <= 0 || sizePt > 200)
{
MessageBox.Show("크기(pt)를 올바르게 입력하세요.", "폰트 일괄 변경");
return;
}
var newFont = new LegacyFont
{
Family = family,
SizePt = sizePt,
Bold = BoldBox.IsChecked == true,
Italic = ItalicBox.IsChecked == true,
Underline = UnderlineBox.IsChecked == true,
};
var changed = designer.ApplyFontBulk(targets, newFont);
ResultText.Text = $"{changed}개 컨트롤 변경됨";
Reload();
}
#endregion
}