새 플랫폼(UbisamBase.Launcher) 위로 옮기면서 12차 A~E 를 한 번에 담는다.
항목별 값과 판정은 doc/history/2026-09-23-12차.md, 요약은 doc/history/changelog.md.
A. 폴더 비교를 읽기 쉽게
- A-1 폴더 줄의 크기가 늘 0B 이던 것 - 안에 든 파일 크기 합계를 아래에서 위로 더해 적는다
(걸러 낸 파일은 합계에서도 빠진다)
- A-2 좌우로 나눠 보이기 - 왼쪽 · 오른쪽 목록을 나란히 두고 같은 줄에 맞춘다.
한쪽에만 있는 항목은 반대편을 비운다
B. 파일 비교 화면
- B-1 2-Way 에서 양쪽으로 머지 - 칸마다 반영 · 저장. 왼쪽 기준점을 따로 세고,
되돌리기 · 저장 백업도 양쪽 모두
- B-2 프로그램 정보 창 - 버전 · 빌드 날짜 · 만든 사람 · 사내 문의처 · 플랫폼 버전 · 로그 폴더
- B-3 칸 아래에 무엇이 달라졌는지 - 칸마다 줄 수 · 추가 · 삭제 · 수정, 가운데에 진행
C. 플랫폼 (플랫폼 저장소에서 함께 나감)
- C-2 하단 탭 줄을 한 단계 작게 - 74 -> 61 DIP. 실측 133 -> 109px 이고
그만큼 코드 칸이 늘어 파일 비교가 47 -> 48줄
E. 저장하지 않아도 남는 편집
- E-2 여러 짝을 동시에(문서 탭). 지금까지는 한 짝만 들어서 짝을 바꾸면
저장하지 않은 편집을 묻고 버리면 사라졌다(재현: 16줄 -> 15줄).
이제 떠 있던 탭이 그 글을 맡아 두므로 묻지 않는다.
- 탭마다 HomeViewModel 을 따로 만들지 않았다 - 이 화면은 GitWorkspace 의 여러 사건과
한 자리짜리 약속(ConfirmDiscardEdits · ConfirmLeaveCommit)에 물려 있다.
화면은 하나로 두고 탭이 파일에 없는 것만 맡는다(고친 글 · 왼쪽 글 · 되돌리기 이력 ·
두 기준점 · 캐럿 · 스크롤 · 저장 형식)
- 탭 이름은 파일 이름, 다르면 왼 <-> 오. 양쪽이 같은 부분은 한 번만 적는다
(WeldController_기준 <-> 내작업.cs, 421 -> 288px). 같은 이름이 겹치면
갈릴 때까지 위 폴더를 한 겹씩 덧붙인다
- 저장하지 않은 탭에 가운뎃점. 사람이 손댄 것만 센다 - 중괄호 맞춤으로만 바뀐 것은
묻는 자리와 같은 기준으로 뺀다(안 그러면 .cs 를 여는 것만으로 늘 점이 붙는다)
- 탭이 사라져도 고친 글은 보관함에 남아 다시 열면 되살아난다(짝 50개).
E-1(껐다 켜도 남는 편집)은 이 보관함을 파일로 옮겨 적으면 된다
- 이전 · 다음 파일은 지금 탭의 짝만 바꾸고, 폴더 비교에서 두 번 누르면 새 탭(사용자 결정)
- Ctrl+Tab · Ctrl+Shift+Tab · Ctrl+W · 가운데 단추 닫기. 닫을 때도 묻지 않는다
- Git 탭 · 병합 중 네 칸은 탭이 맡지 않는다 - 그쪽은 예전처럼 묻는다
하네스 27벌 1,787건 통과 · 실패 0(DocTabTest 106건 새로 만듦).
빌드 경고 0 · 오류 0. 화면으로 E-2 34건 · 회귀 19건 확인.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
108 lines
3.9 KiB
C#
108 lines
3.9 KiB
C#
using System;
|
|
using System.Reflection;
|
|
using System.Text;
|
|
using System.Windows;
|
|
using System.Windows.Input;
|
|
using System.Windows.Threading;
|
|
using MergeHub.Services;
|
|
|
|
namespace MergeHub.Views
|
|
{
|
|
/// <summary>
|
|
/// 프로그램 정보 창(12차 B-2). [단축키] 옆 단추로 연다.
|
|
///
|
|
/// 관리 목적이다 - "지금 이 PC 에 깔린 것이 무엇인가"를 묻고 답하는 자리.
|
|
/// 그래서 버전 · 빌드 날짜는 <b>실행 파일에서 읽고</b>(<see cref="ProgramInfoReader"/>),
|
|
/// 사람이 바뀌는 것(만든 사람 · 문의처)만 설정에서 받는다.
|
|
/// </summary>
|
|
public partial class AboutWindow : Window
|
|
{
|
|
private readonly ProgramInfo info;
|
|
|
|
public AboutWindow(ProgramInfo info, string description)
|
|
{
|
|
InitializeComponent();
|
|
|
|
this.info = info;
|
|
|
|
NameText.Text = info.Name;
|
|
DescriptionText.Text = description;
|
|
VersionText.Text = info.Version;
|
|
BuildDateText.Text = info.BuildDate;
|
|
AuthorText.Text = info.Author;
|
|
ContactText.Text = info.Contact;
|
|
|
|
if (Application.Current?.MainWindow is { IsLoaded: true } main && !ReferenceEquals(main, this))
|
|
{
|
|
Owner = main;
|
|
WindowStartupLocation = WindowStartupLocation.CenterOwner;
|
|
}
|
|
else
|
|
{
|
|
WindowStartupLocation = WindowStartupLocation.CenterScreen;
|
|
}
|
|
}
|
|
|
|
private void TitleBar_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) => DragMove();
|
|
|
|
private void Close_Click(object sender, RoutedEventArgs e) => Close();
|
|
|
|
/// <summary>창에 보이는 것을 그대로 옮긴다. 결함을 알릴 때 이 네 줄이 첫 질문이다.</summary>
|
|
private void Copy_Click(object sender, RoutedEventArgs e)
|
|
{
|
|
var text = new StringBuilder()
|
|
.AppendLine(info.Name)
|
|
.AppendLine($"버전: {info.Version}")
|
|
.AppendLine($"빌드 날짜: {info.BuildDate}")
|
|
.AppendLine($"만든 사람: {info.Author}")
|
|
.AppendLine($"사내 문의처: {info.Contact}")
|
|
.ToString();
|
|
|
|
try
|
|
{
|
|
Clipboard.SetText(text);
|
|
ShowCopied();
|
|
}
|
|
catch (Exception ex) when (ex is System.Runtime.InteropServices.COMException)
|
|
{
|
|
// 다른 프로그램이 클립보드를 잡고 있으면 실패한다 - 창을 닫을 일은 아니다.
|
|
}
|
|
}
|
|
|
|
/// <summary>복사했다는 표시를 잠깐 보인다. 토스트는 셸 것이라 이 창 뒤로 가려 안 보인다.</summary>
|
|
private void ShowCopied()
|
|
{
|
|
CopiedText.Visibility = Visibility.Visible;
|
|
var timer = new DispatcherTimer { Interval = TimeSpan.FromSeconds(2) };
|
|
timer.Tick += (_, _) =>
|
|
{
|
|
timer.Stop();
|
|
CopiedText.Visibility = Visibility.Collapsed;
|
|
};
|
|
timer.Start();
|
|
}
|
|
|
|
/// <summary>이미 떠 있으면 앞으로 가져온다 - 단축키 창과 같은 규칙.</summary>
|
|
private static AboutWindow? open;
|
|
|
|
public static void ShowOrActivate(Window? owner, string? author, string? contact)
|
|
{
|
|
if (open is { IsLoaded: true })
|
|
{
|
|
open.Activate();
|
|
return;
|
|
}
|
|
|
|
var assembly = Assembly.GetExecutingAssembly();
|
|
var info = ProgramInfoReader.For(assembly, author, contact);
|
|
var description = assembly.GetCustomAttribute<AssemblyDescriptionAttribute>()?.Description
|
|
?? "사내 Git Merge/Diff 도구";
|
|
|
|
open = new AboutWindow(info, description);
|
|
if (owner is not null) open.Owner = owner;
|
|
open.Closed += (_, _) => open = null;
|
|
open.Show();
|
|
}
|
|
}
|
|
}
|