From a67b6ee4b80ad5f49d2df8afba0dc2e4ed509f52 Mon Sep 17 00:00:00 2001 From: Msystech Date: Tue, 18 Aug 2026 09:54:00 +0900 Subject: [PATCH] =?UTF-8?q?=EB=AF=B8=EB=A6=AC=EB=B3=B4=EA=B8=B0=EC=97=90?= =?UTF-8?q?=20=EB=B3=B4=EA=B8=B0=20=EC=A0=84=ED=99=98=EC=9D=84=20=EB=91=94?= =?UTF-8?q?=EB=8B=A4=20=E2=80=94=20=EC=9D=B8=EC=87=84=EB=90=A0=20=EA=B2=83?= =?UTF-8?q?=EB=A7=8C=20/=20=ED=99=94=EB=A9=B4=20=EA=B7=B8=EB=8C=80?= =?UTF-8?q?=EB=A1=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 미리보기 레거시 호환 계획의 P0-3. P0 세 항목이 이걸로 끝난다. 레거시 미리보기와 레거시 인쇄가 서로 다르다 — 미리보기는 PrintOutPut=False 컨트롤을 그대로 보여 주고(그 속성은 PrintMe 안에만 있다, Label.vb:454-457) 인쇄만 뺀다. SheetMe 는 인쇄 쪽을 골라 테스트로 못 박아 뒀었다. 둘 다 확인해야 하므로 미리보기 창이 보기를 가른다. 기본은 인쇄 기준 — 저장 전에 확인하려는 것이 대개 종이 결과다. Hidden(디자이너 임시 숨김)과 MDataTable(런타임 비가시)은 보기와 무관하게 항상 뺀다. 레거시 미리보기에서도 안 보이는 것들이다 — 보기가 가르는 것은 Visible/PrintOutPut 뿐이다. 인쇄 경로는 언제나 필터를 건다. 인쇄는 인쇄다. 단정은 "돌아오는가"를 본다. 필터를 켜서 뺀 것이 끄면 다시 나와야 한다 — 안 나오면 전환이 배선만 된 것이다. 컨테이너 안까지 세므로 P0-1 의 투영도 함께 검증된다. XAML 파싱 중에 이벤트가 발생했다. 토글의 IsChecked="True" 가 파스 시점에 Checked 를 쏘는데, 토글이 트리에서 앞에 있어 그때 PagesHost 는 아직 null 이다 → InitializeComponent 안에서 NullReferenceException. 가드를 넣고 이유를 적었다. --edit-smoke 가 잡았다. 없었으면 미리보기를 여는 순간 앱이 죽었을 것이다. 게이트: 테스트 298/298, --edit-smoke 0실패(미리보기 7건), --dialog-shots 글자 2,653개 FAIL 0 대조군 4/4, --modal-check 0실패, --cleartype 11/11, --maxrect 0실패, --scale-budget 5/5, 빌드 경고 0, --db-smoke 1271건 diff 0, --db-render P062 md5 8d683835f5d81e7bb41c79071d6bf954 동일. Co-Authored-By: Claude Opus 5 --- src/SheetMe.Designer/Diagnostics/EditSmoke.cs | 14 +++++++++++ src/SheetMe.Designer/Services/PrintService.cs | 24 +++++++++++++------ src/SheetMe.Designer/Views/PreviewWindow.xaml | 10 ++++++++ .../Views/PreviewWindow.xaml.cs | 12 +++++++++- 4 files changed, 52 insertions(+), 8 deletions(-) diff --git a/src/SheetMe.Designer/Diagnostics/EditSmoke.cs b/src/SheetMe.Designer/Diagnostics/EditSmoke.cs index 3306400..cadc0f2 100644 --- a/src/SheetMe.Designer/Diagnostics/EditSmoke.cs +++ b/src/SheetMe.Designer/Diagnostics/EditSmoke.cs @@ -337,6 +337,20 @@ public static class EditSmoke Check("미리보기: 컨테이너 안의 PrintOutPut=False 도 빠진다", afterHide < baseline, $"요소 {baseline} → {afterHide} (안 줄면 최상위만 거르고 있다)"); + // 보기 전환 — 레거시 미리보기는 PrintOutPut=False 를 그대로 보여 준다. + // 필터를 끄면 방금 뺀 것이 돌아와야 한다. 안 돌아오면 전환이 배선만 된 것이다. + int RenderedRaw() + { + var visual = (System.Windows.FrameworkElement) + Services.PrintService.BuildPageVisual(boxedVm.Pages[0], printFilter: false); + visual.Measure(new System.Windows.Size(720, 856)); + visual.Arrange(new Rect(0, 0, 720, 856)); + visual.UpdateLayout(); + return CountVisuals(visual); + } + Check("미리보기: '화면 그대로' 로 바꾸면 숨긴 것이 돌아온다", RenderedRaw() > afterHide, + $"인쇄기준 {afterHide} → 화면기준 {RenderedRaw()}"); + // 인쇄 필터가 캔버스로 새면 안 된다 — 편집 중인 것을 못 보면 고칠 수 없다 Check("미리보기: 캔버스는 자식을 그대로 다 보여 준다", boxedPanel.Children.Count == 3, $"{boxedPanel.Children.Count} (기대 3)"); diff --git a/src/SheetMe.Designer/Services/PrintService.cs b/src/SheetMe.Designer/Services/PrintService.cs index 30ae448..33f8460 100644 --- a/src/SheetMe.Designer/Services/PrintService.cs +++ b/src/SheetMe.Designer/Services/PrintService.cs @@ -49,8 +49,16 @@ public static class PrintService return document; } - /// 페이지 컨트롤층 비주얼 — 크롬 없는 Canvas(그리기 순서 = 컬렉션 순서, 미리보기/인쇄 공용) - public static UIElement BuildPageVisual(PageViewModel page) + /// + /// 페이지 컨트롤층 비주얼 — 크롬 없는 Canvas(그리기 순서 = 컬렉션 순서, 미리보기/인쇄 공용). + /// + /// 가 false 면 화면에 보이는 것을 그대로 그린다. + /// 레거시가 그렇게 동작한다 — 레거시 미리보기는 PrintOutPut=False 컨트롤을 + /// 그대로 보여 주고(그 속성은 PrintMe 안에만 있다) 레거시 인쇄만 뺀다. + /// 두 눈이 필요해서 미리보기 창이 보기를 전환할 수 있게 열어 둔다. + /// 인쇄는 언제나 true 다 — 인쇄는 인쇄다. + /// + public static UIElement BuildPageVisual(PageViewModel page, bool printFilter = true) { var canvas = new Canvas { @@ -73,14 +81,16 @@ public static class PrintService // ③ 을 오래 빠뜨려서 '인쇄 출력'을 꺼도 미리보기에 그대로 나왔다 — // 저장 전 검증 수단이 거짓말을 하고 있었다. // 캔버스는 계속 다 보여 준다(편집 중인 것을 못 보면 고칠 수 없다) — 여기만 거른다. + // Hidden(디자이너 임시 숨김)과 MDataTable(런타임 비가시)은 보기와 무관하게 항상 뺀다 — + // 레거시 미리보기에서도 안 보이는 것들이다. 보기가 가르는 것은 ③ 뿐이다. if (control.Model.Hidden || control is DataTableViewModel - || !SheetMe.Core.Catalog.PrintFilter.IsPrinted(control.Model)) + || (printFilter && !SheetMe.Core.Catalog.PrintFilter.IsPrinted(control.Model))) { continue; } var presenter = new ContentPresenter { - Content = PrintProjection(control), + Content = PrintProjection(control, printFilter), Width = Math.Max(1, control.Width), Height = Math.Max(1, control.Height), }; @@ -109,7 +119,7 @@ public static class PrintService /// 자식 VM 은 새로 만들지 않고 원본을 그대로 담는다 — 해석된 글꼴·색이 유지된다. /// 캔버스가 쓰는 VM 은 한 글자도 건드리지 않는다. /// - private static object PrintProjection(ControlViewModel control) + private static object PrintProjection(ControlViewModel control, bool printFilter) { if (control is not ContainerViewModel container) { @@ -129,11 +139,11 @@ public static class PrintService foreach (var child in container.Children) { if (child.Model.Hidden || child is DataTableViewModel - || !SheetMe.Core.Catalog.PrintFilter.IsPrinted(child.Model)) + || (printFilter && !SheetMe.Core.Catalog.PrintFilter.IsPrinted(child.Model))) { continue; } - if (PrintProjection(child) is ControlViewModel projected) + if (PrintProjection(child, printFilter) is ControlViewModel projected) { copy.Children.Add(projected); } diff --git a/src/SheetMe.Designer/Views/PreviewWindow.xaml b/src/SheetMe.Designer/Views/PreviewWindow.xaml index d17d2c2..0a0d2c4 100644 --- a/src/SheetMe.Designer/Views/PreviewWindow.xaml +++ b/src/SheetMe.Designer/Views/PreviewWindow.xaml @@ -11,6 +11,16 @@