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 { /// /// 프로그램 정보 창(12차 B-2). [단축키] 옆 단추로 연다. /// /// 관리 목적이다 - "지금 이 PC 에 깔린 것이 무엇인가"를 묻고 답하는 자리. /// 그래서 버전 · 빌드 날짜는 실행 파일에서 읽고(), /// 사람이 바뀌는 것(만든 사람 · 문의처)만 설정에서 받는다. /// 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(); /// 창에 보이는 것을 그대로 옮긴다. 결함을 알릴 때 이 네 줄이 첫 질문이다. 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) { // 다른 프로그램이 클립보드를 잡고 있으면 실패한다 - 창을 닫을 일은 아니다. } } /// 복사했다는 표시를 잠깐 보인다. 토스트는 셸 것이라 이 창 뒤로 가려 안 보인다. 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(); } /// 이미 떠 있으면 앞으로 가져온다 - 단축키 창과 같은 규칙. 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()?.Description ?? "사내 Git Merge/Diff 도구"; open = new AboutWindow(info, description); if (owner is not null) open.Owner = owner; open.Closed += (_, _) => open = null; open.Show(); } } }