D-6: 비교 결과 텍스트 내보내기
결과를 남에게 보내거나 결재에 붙일 때 화면을 캡처하는 것 말고는 방법이 없었다. 캡처는 검색도 안 되고 줄 번호를 짚어 말하기도 어렵다. Services/CompareReport.cs 신설. 파일 비교와 폴더 비교 양쪽에서 쓴다. 글을 만드는 일만 여기서 하고, 어디에 저장할지 묻는 것은 화면 쪽 일이다. 그래야 화면 없이 검사한다. 파일 쪽은 요약과 다른 줄 목록을 적는다. 줄 번호는 양쪽을 다 적는다. 한쪽에만 있는 줄이 있어 번호가 어긋나므로 하나만 적으면 파일에서 그 줄을 찾을 수 없다. 폴더 쪽은 상태와 상대 경로를 줄마다 적는다. 폴더 자체는 적지 않는다. 그 안의 파일이 이미 다 적혀 있다. 곁들여 요약에 주석만 다른 수를 덧붙였다. "다름 3(주석만 1)". D-1 로 새로 생긴 갈래가 요약에는 안 보였다. 확인: 두 화면에서 각각 뽑아 메모장으로 열었다. ReportTest 23건 신설. 전체 451건 통과. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
32c0146b48
commit
ee5d34c2a6
41
doc/진행상황.md
41
doc/진행상황.md
@ -131,7 +131,7 @@ CommunityToolkit 커맨드는 CommandManager 를 구독하지 않는데 이 둘
|
|||||||
| 대기 | D-3 폴더 안 전체 검색 |
|
| 대기 | D-3 폴더 안 전체 검색 |
|
||||||
| ~~취소~~ | ~~D-4 비교 창 여러 개~~ (2026-09-09 사용자 판단으로 뺌) |
|
| ~~취소~~ | ~~D-4 비교 창 여러 개~~ (2026-09-09 사용자 판단으로 뺌) |
|
||||||
| **완료** | D-5 덩어리 단위 반영 (3-Way 에서 BASE 를 가져오던 것을 REMOTE 로) |
|
| **완료** | D-5 덩어리 단위 반영 (3-Way 에서 BASE 를 가져오던 것을 REMOTE 로) |
|
||||||
| 대기 | D-6 비교 결과 텍스트 내보내기 |
|
| **완료** | D-6 비교 결과 텍스트 내보내기 |
|
||||||
| 대기 | D-7 드래그 앤 드롭으로 열기 |
|
| 대기 | D-7 드래그 앤 드롭으로 열기 |
|
||||||
|
|
||||||
### E. 추가 요청 (2026-09-09 오후)
|
### E. 추가 요청 (2026-09-09 오후)
|
||||||
@ -160,6 +160,45 @@ BASE 머리글에 그렇게 적었다 - `BASE (merge base) · 이 파일 없음
|
|||||||
조상에 파일이 있는 경우는 지금까지처럼 파일 이름이 그대로 나온다.
|
조상에 파일이 있는 경우는 지금까지처럼 파일 이름이 그대로 나온다.
|
||||||
---
|
---
|
||||||
|
|
||||||
|
### D-6. 비교 결과 텍스트 내보내기 — **완료** (2026-09-09)
|
||||||
|
|
||||||
|
**왜 필요했나** - 결과를 남에게 보내거나 결재에 붙일 때 <b>화면을 캡처하는 것 말고는 방법이 없었다.</b>
|
||||||
|
캡처는 검색도 안 되고 줄 번호를 짚어 말하기도 어렵다.
|
||||||
|
|
||||||
|
`Services/CompareReport.cs` 신설. 파일 비교와 폴더 비교 양쪽에서 쓴다.
|
||||||
|
<b>글을 만드는 일만</b> 여기서 하고, 어디에 저장할지 묻는 것은 화면 쪽 일이다 - 그래야 화면 없이 검사한다.
|
||||||
|
|
||||||
|
파일 비교 결과는 이렇게 나온다.
|
||||||
|
|
||||||
|
```
|
||||||
|
MergeHub 파일 비교 결과
|
||||||
|
만든 때: 2026-09-09 14:46:23
|
||||||
|
왼쪽 : ...\WeldController_기준.cs
|
||||||
|
오른쪽: ...\WeldController_내작업.cs
|
||||||
|
----------------------------------------------------------------
|
||||||
|
요약: 총 43 줄 · 다름 5 · 오른쪽에만 5 · 왼쪽에만 0
|
||||||
|
|
||||||
|
다른 줄
|
||||||
|
----------------------------------------------------------------
|
||||||
|
[8/8] 다름
|
||||||
|
- private const int PowerWatt = 1800;
|
||||||
|
+ private const int PowerWatt = 2000;
|
||||||
|
[-/28] 오른쪽에만
|
||||||
|
+ {
|
||||||
|
```
|
||||||
|
|
||||||
|
**줄 번호를 양쪽 다 적는다.** 한쪽에만 있는 줄이 있어 번호가 어긋나므로, 하나만 적으면
|
||||||
|
파일에서 그 줄을 찾을 수 없다. 없는 쪽은 `-` 로 둔다.
|
||||||
|
|
||||||
|
폴더 비교 결과는 상태와 경로를 줄마다 적는다. 하위 폴더 파일도 상대 경로로 들어가고,
|
||||||
|
폴더 자체는 줄로 적지 않는다 - 그 안의 파일이 이미 다 적혀 있다.
|
||||||
|
|
||||||
|
**곁들여** 요약에 주석만 다른 수를 덧붙였다 - `다름 3(주석만 1)`.
|
||||||
|
D-1 로 새로 생긴 갈래가 요약에는 안 보였다.
|
||||||
|
|
||||||
|
**확인**: 두 화면에서 각각 뽑아 메모장으로 열었다. `ReportTest` 23건 신설. 전체 **451건**.
|
||||||
|
---
|
||||||
|
|
||||||
### D-1. 주석만 다른 파일을 다른 색으로 — **완료** (2026-09-09)
|
### D-1. 주석만 다른 파일을 다른 색으로 — **완료** (2026-09-09)
|
||||||
|
|
||||||
폴더 비교 결과에 `주석만 다름` 상태를 새로 두었다. 코드는 같고 주석·공백만 다른 파일이다.
|
폴더 비교 결과에 `주석만 다름` 상태를 새로 두었다. 코드는 같고 주석·공백만 다른 파일이다.
|
||||||
|
|||||||
147
src/MergeHub/Services/CompareReport.cs
Normal file
147
src/MergeHub/Services/CompareReport.cs
Normal file
@ -0,0 +1,147 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
using MergeHub.Models;
|
||||||
|
|
||||||
|
namespace MergeHub.Services
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 비교 결과를 <b>메모장으로 열어 읽을 수 있는 글</b>로 만든다.
|
||||||
|
///
|
||||||
|
/// 왜 글로 뽑나 - 결과를 남에게 보내거나 결재에 붙일 때 화면을 캡처하는 것 말고는 방법이 없었다.
|
||||||
|
/// 캡처는 검색도 안 되고 줄 번호를 짚어 말하기도 어렵다.
|
||||||
|
///
|
||||||
|
/// 화면 없이 검사할 수 있어야 하므로 <b>글을 만드는 일만</b> 여기서 한다.
|
||||||
|
/// 어디에 저장할지 묻는 것은 화면 쪽 일이다.
|
||||||
|
/// </summary>
|
||||||
|
public static class CompareReport
|
||||||
|
{
|
||||||
|
private const string Rule = "----------------------------------------------------------------";
|
||||||
|
|
||||||
|
/// <summary>파일 비교 결과.</summary>
|
||||||
|
public static string ForFile(string leftLabel, string rightLabel,
|
||||||
|
IReadOnlyList<MergeLine> lines, DateTime when)
|
||||||
|
{
|
||||||
|
var text = new StringBuilder();
|
||||||
|
|
||||||
|
Head(text, "파일 비교 결과", leftLabel, rightLabel, when);
|
||||||
|
|
||||||
|
var changed = 0;
|
||||||
|
var added = 0;
|
||||||
|
var removed = 0;
|
||||||
|
|
||||||
|
foreach (var line in lines)
|
||||||
|
{
|
||||||
|
if (line.IsMergeNote || line.IsIgnored) continue;
|
||||||
|
|
||||||
|
switch (line.State)
|
||||||
|
{
|
||||||
|
case MergeLineState.Changed: changed++; break;
|
||||||
|
case MergeLineState.LocalOnly: added++; break;
|
||||||
|
case MergeLineState.BaseOnly: removed++; break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
text.AppendLine($"요약: 총 {lines.Count} 줄 · 다름 {changed} · 오른쪽에만 {added} · 왼쪽에만 {removed}");
|
||||||
|
text.AppendLine();
|
||||||
|
|
||||||
|
if (changed + added + removed == 0)
|
||||||
|
{
|
||||||
|
text.AppendLine("다른 줄이 없습니다.");
|
||||||
|
return text.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
text.AppendLine("다른 줄");
|
||||||
|
text.AppendLine(Rule);
|
||||||
|
|
||||||
|
foreach (var line in lines)
|
||||||
|
{
|
||||||
|
if (line.IsMergeNote || line.IsIgnored) continue;
|
||||||
|
if (line.State == MergeLineState.Same) continue;
|
||||||
|
|
||||||
|
// 줄 번호는 <b>양쪽을 다 적는다.</b> 한쪽에만 있는 줄이 있어 번호가 어긋나므로,
|
||||||
|
// 하나만 적으면 파일에서 그 줄을 찾을 수 없다.
|
||||||
|
var number = $"{Number(line.BaseNumber)}/{Number(line.LocalNumber)}";
|
||||||
|
|
||||||
|
text.AppendLine($"[{number}] {StateName(line.State)}");
|
||||||
|
if (line.HasBase) text.AppendLine(" - " + line.BaseText);
|
||||||
|
if (line.HasLocal) text.AppendLine(" + " + line.LocalText);
|
||||||
|
}
|
||||||
|
|
||||||
|
return text.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>폴더 비교 결과.</summary>
|
||||||
|
public static string ForFolder(string leftFolder, string rightFolder,
|
||||||
|
FolderCompareResult result, DateTime when)
|
||||||
|
{
|
||||||
|
var text = new StringBuilder();
|
||||||
|
|
||||||
|
Head(text, "폴더 비교 결과", leftFolder, rightFolder, when);
|
||||||
|
text.AppendLine("요약: " + result.Summary);
|
||||||
|
if (result.Truncated) text.AppendLine("(항목이 너무 많아 도중에 멈춘 결과입니다)");
|
||||||
|
text.AppendLine();
|
||||||
|
|
||||||
|
var rows = new List<(string Status, string Path)>();
|
||||||
|
Collect(result.Items, rows);
|
||||||
|
|
||||||
|
if (rows.Count == 0)
|
||||||
|
{
|
||||||
|
text.AppendLine("다른 항목이 없습니다.");
|
||||||
|
return text.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
text.AppendLine("다른 항목");
|
||||||
|
text.AppendLine(Rule);
|
||||||
|
|
||||||
|
foreach (var row in rows) text.AppendLine($"{row.Status,-12}{row.Path}");
|
||||||
|
|
||||||
|
return text.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>폴더 트리를 훑어 "같음"이 아닌 <b>파일만</b> 모은다.</summary>
|
||||||
|
private static void Collect(IEnumerable<FolderCompareItem> items, List<(string, string)> rows)
|
||||||
|
{
|
||||||
|
foreach (var item in items)
|
||||||
|
{
|
||||||
|
if (item.IsDirectory)
|
||||||
|
{
|
||||||
|
Collect(item.Children, rows);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (item.Status == FolderEntryStatus.Same) continue;
|
||||||
|
rows.Add((StatusName(item.Status), item.RelativePath));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void Head(StringBuilder text, string title, string left, string right, DateTime when)
|
||||||
|
{
|
||||||
|
text.AppendLine($"MergeHub {title}");
|
||||||
|
text.AppendLine($"만든 때: {when:yyyy-MM-dd HH:mm:ss}");
|
||||||
|
text.AppendLine($"왼쪽 : {left}");
|
||||||
|
text.AppendLine($"오른쪽: {right}");
|
||||||
|
text.AppendLine(Rule);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string Number(int? value) => value is int n ? n.ToString() : "-";
|
||||||
|
|
||||||
|
private static string StateName(MergeLineState state) => state switch
|
||||||
|
{
|
||||||
|
MergeLineState.Changed => "다름",
|
||||||
|
MergeLineState.LocalOnly => "오른쪽에만",
|
||||||
|
MergeLineState.BaseOnly => "왼쪽에만",
|
||||||
|
_ => "같음"
|
||||||
|
};
|
||||||
|
|
||||||
|
private static string StatusName(FolderEntryStatus status) => status switch
|
||||||
|
{
|
||||||
|
FolderEntryStatus.Different => "다름",
|
||||||
|
FolderEntryStatus.CommentOnly => "주석만 다름",
|
||||||
|
FolderEntryStatus.Binary => "다름(이진)",
|
||||||
|
FolderEntryStatus.LeftOnly => "왼쪽에만",
|
||||||
|
FolderEntryStatus.RightOnly => "오른쪽에만",
|
||||||
|
_ => "같음"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -101,11 +101,16 @@ namespace MergeHub.Services
|
|||||||
public int LeftOnlyCount { get; set; }
|
public int LeftOnlyCount { get; set; }
|
||||||
public int RightOnlyCount { get; set; }
|
public int RightOnlyCount { get; set; }
|
||||||
|
|
||||||
|
/// <summary>그중 코드는 같고 주석만 다른 것. "다름" 안에 든 수다.</summary>
|
||||||
|
public int CommentOnlyCount { get; set; }
|
||||||
|
|
||||||
/// <summary>항목 상한에 걸려 도중에 멈췄는지.</summary>
|
/// <summary>항목 상한에 걸려 도중에 멈췄는지.</summary>
|
||||||
public bool Truncated { get; set; }
|
public bool Truncated { get; set; }
|
||||||
|
|
||||||
public string Summary =>
|
public string Summary =>
|
||||||
$"전체 {TotalFiles}개 · 다름 {DifferentCount} · 왼쪽만 {LeftOnlyCount} · 오른쪽만 {RightOnlyCount} · 같음 {SameCount}"
|
$"전체 {TotalFiles}개 · 다름 {DifferentCount}"
|
||||||
|
+ (CommentOnlyCount > 0 ? $"(주석만 {CommentOnlyCount})" : string.Empty)
|
||||||
|
+ $" · 왼쪽만 {LeftOnlyCount} · 오른쪽만 {RightOnlyCount} · 같음 {SameCount}"
|
||||||
+ (Truncated ? " (너무 많아 일부만 봄)" : string.Empty);
|
+ (Truncated ? " (너무 많아 일부만 봄)" : string.Empty);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -198,6 +203,11 @@ namespace MergeHub.Services
|
|||||||
switch (item.Status)
|
switch (item.Status)
|
||||||
{
|
{
|
||||||
case FolderEntryStatus.Same: result.SameCount++; break;
|
case FolderEntryStatus.Same: result.SameCount++; break;
|
||||||
|
// "주석만 다름"도 다름의 한 갈래다. 둘 다 센다 - 요약이 "다름 3(주석만 1)" 로 읽힌다.
|
||||||
|
case FolderEntryStatus.CommentOnly:
|
||||||
|
result.DifferentCount++;
|
||||||
|
result.CommentOnlyCount++;
|
||||||
|
break;
|
||||||
case FolderEntryStatus.LeftOnly: result.LeftOnlyCount++; break;
|
case FolderEntryStatus.LeftOnly: result.LeftOnlyCount++; break;
|
||||||
case FolderEntryStatus.RightOnly: result.RightOnlyCount++; break;
|
case FolderEntryStatus.RightOnly: result.RightOnlyCount++; break;
|
||||||
default: result.DifferentCount++; break;
|
default: result.DifferentCount++; break;
|
||||||
|
|||||||
@ -208,6 +208,7 @@ namespace MergeHub.ViewModels
|
|||||||
CopyToLeftCommand.NotifyCanExecuteChanged();
|
CopyToLeftCommand.NotifyCanExecuteChanged();
|
||||||
DeleteLeftCommand.NotifyCanExecuteChanged();
|
DeleteLeftCommand.NotifyCanExecuteChanged();
|
||||||
DeleteRightCommand.NotifyCanExecuteChanged();
|
DeleteRightCommand.NotifyCanExecuteChanged();
|
||||||
|
ExportReportCommand.NotifyCanExecuteChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
[RelayCommand]
|
[RelayCommand]
|
||||||
@ -222,6 +223,57 @@ namespace MergeHub.ViewModels
|
|||||||
if (AskForFolder("오른쪽(비교 대상) 폴더 고르기", RightFolder) is { } picked) RightFolder = picked;
|
if (AskForFolder("오른쪽(비교 대상) 폴더 고르기", RightFolder) is { } picked) RightFolder = picked;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ================= 결과 내보내기 =================
|
||||||
|
|
||||||
|
private bool CanExportReport() => _lastResult != null;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 비교 결과를 글로 뽑아 파일에 쓴다.
|
||||||
|
///
|
||||||
|
/// 화면을 캡처하는 것 말고는 결과를 남에게 보낼 방법이 없었다. 캡처는 검색도 안 되고
|
||||||
|
/// 줄 번호를 짚어 말하기도 어렵다. 글이면 메일에 붙이든 결재에 넣든 그대로 쓴다.
|
||||||
|
/// </summary>
|
||||||
|
[RelayCommand(CanExecute = nameof(CanExportReport))]
|
||||||
|
private void ExportReport()
|
||||||
|
{
|
||||||
|
if (_lastResult is not { } result) return;
|
||||||
|
|
||||||
|
var dialog = new Microsoft.Win32.SaveFileDialog
|
||||||
|
{
|
||||||
|
Title = "폴더 비교 결과 저장",
|
||||||
|
Filter = "텍스트 파일 (*.txt)|*.txt|모든 파일 (*.*)|*.*",
|
||||||
|
DefaultExt = ".txt",
|
||||||
|
FileName = $"폴더비교_{DateTime.Now:yyyyMMdd_HHmm}.txt"
|
||||||
|
};
|
||||||
|
|
||||||
|
var start = PathUtil.FullFolderPath(LeftFolder);
|
||||||
|
if (start.Length > 0) dialog.InitialDirectory = start;
|
||||||
|
|
||||||
|
bool ok;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
ok = dialog.ShowDialog() == true;
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
dialog.InitialDirectory = string.Empty;
|
||||||
|
ok = dialog.ShowDialog() == true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ok) return;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var report = CompareReport.ForFolder(LeftFolder, RightFolder, result, DateTime.Now);
|
||||||
|
TextFile.Write(dialog.FileName, report);
|
||||||
|
MessageUtil.ShowSuccessToast($"저장했습니다 · {Path.GetFileName(dialog.FileName)}");
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
MessageUtil.ShowErrorToast($"저장하지 못했습니다: {ex.Message}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static string? AskForFolder(string title, string current)
|
private static string? AskForFolder(string title, string current)
|
||||||
=> FolderPicker.Pick(title, current);
|
=> FolderPicker.Pick(title, current);
|
||||||
private bool CanCompare() => !IsBusy;
|
private bool CanCompare() => !IsBusy;
|
||||||
|
|||||||
@ -471,6 +471,7 @@ namespace MergeHub.ViewModels
|
|||||||
ReloadCommand.NotifyCanExecuteChanged();
|
ReloadCommand.NotifyCanExecuteChanged();
|
||||||
SaveAndCommitCommand.NotifyCanExecuteChanged();
|
SaveAndCommitCommand.NotifyCanExecuteChanged();
|
||||||
SavePlainCommand.NotifyCanExecuteChanged();
|
SavePlainCommand.NotifyCanExecuteChanged();
|
||||||
|
ExportReportCommand.NotifyCanExecuteChanged();
|
||||||
|
|
||||||
AutoMergeCommand.NotifyCanExecuteChanged();
|
AutoMergeCommand.NotifyCanExecuteChanged();
|
||||||
AcceptBlockCommand.NotifyCanExecuteChanged();
|
AcceptBlockCommand.NotifyCanExecuteChanged();
|
||||||
@ -1443,6 +1444,64 @@ namespace MergeHub.ViewModels
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ================= 결과 내보내기 =================
|
||||||
|
|
||||||
|
private bool CanExportReport() => Lines.Count > 0;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 비교 결과를 글로 뽑아 파일에 쓴다.
|
||||||
|
///
|
||||||
|
/// 화면을 캡처하는 것 말고는 결과를 남에게 보낼 방법이 없었다. 캡처는 검색도 안 되고
|
||||||
|
/// 줄 번호를 짚어 말하기도 어렵다.
|
||||||
|
/// </summary>
|
||||||
|
[RelayCommand(CanExecute = nameof(CanExportReport))]
|
||||||
|
private void ExportReport()
|
||||||
|
{
|
||||||
|
var dialog = new Microsoft.Win32.SaveFileDialog
|
||||||
|
{
|
||||||
|
Title = "파일 비교 결과 저장",
|
||||||
|
Filter = "텍스트 파일 (*.txt)|*.txt|모든 파일 (*.*)|*.*",
|
||||||
|
DefaultExt = ".txt",
|
||||||
|
FileName = $"파일비교_{DateTime.Now:yyyyMMdd_HHmm}.txt"
|
||||||
|
};
|
||||||
|
|
||||||
|
var start = PathUtil.FolderOfFile(RightFile.Length > 0 ? RightFile : LeftFile);
|
||||||
|
if (start.Length > 0) dialog.InitialDirectory = start;
|
||||||
|
|
||||||
|
bool ok;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
ok = dialog.ShowDialog() == true;
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
dialog.InitialDirectory = string.Empty;
|
||||||
|
ok = dialog.ShowDialog() == true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ok) return;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var report = CompareReport.ForFile(ReportLabel(BaseHeader, LeftFile),
|
||||||
|
ReportLabel(LocalHeader, RightFile),
|
||||||
|
Lines, DateTime.Now);
|
||||||
|
TextFile.Write(dialog.FileName, report);
|
||||||
|
MessageUtil.ShowSuccessToast($"저장했습니다 · {Path.GetFileName(dialog.FileName)}");
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
MessageUtil.ShowErrorToast($"저장하지 못했습니다: {ex.Message}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 보고서에 적을 쪽 이름. Git 모드면 머리글(브랜치·커밋)이 더 쓸모 있고,
|
||||||
|
/// 파일 비교 모드면 경로가 있어야 어느 파일인지 알 수 있다.
|
||||||
|
/// </summary>
|
||||||
|
private string ReportLabel(string header, string path) =>
|
||||||
|
IsGitMode || path.Length == 0 ? header : path;
|
||||||
|
|
||||||
private static string? AskForFile(string title, string current)
|
private static string? AskForFile(string title, string current)
|
||||||
{
|
{
|
||||||
var dialog = new Microsoft.Win32.OpenFileDialog
|
var dialog = new Microsoft.Win32.OpenFileDialog
|
||||||
|
|||||||
@ -255,6 +255,9 @@
|
|||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
|
||||||
<WrapPanel Grid.Column="1" Orientation="Horizontal">
|
<WrapPanel Grid.Column="1" Orientation="Horizontal">
|
||||||
|
<Button Content="결과 내보내기" Command="{Binding ExportReportCommand}"
|
||||||
|
Height="28" Padding="10,2" FontSize="11" Margin="0,0,14,0"
|
||||||
|
ToolTip="비교 결과를 글로 뽑아 파일에 저장합니다. 메일이나 결재에 그대로 붙일 수 있습니다"/>
|
||||||
<Button Content="줄 단위 비교" Command="{Binding OpenInDiffCommand}"
|
<Button Content="줄 단위 비교" Command="{Binding OpenInDiffCommand}"
|
||||||
Height="28" Padding="10,2" FontSize="11" Margin="0,0,6,0"/>
|
Height="28" Padding="10,2" FontSize="11" Margin="0,0,6,0"/>
|
||||||
<Button Content="→ 오른쪽으로 복사" Command="{Binding CopyToRightCommand}"
|
<Button Content="→ 오른쪽으로 복사" Command="{Binding CopyToRightCommand}"
|
||||||
|
|||||||
@ -354,6 +354,11 @@
|
|||||||
Height="26" MinHeight="26" Padding="10,2" FontSize="11" Margin="10,0,0,0"
|
Height="26" MinHeight="26" Padding="10,2" FontSize="11" Margin="10,0,0,0"
|
||||||
VerticalAlignment="Top"
|
VerticalAlignment="Top"
|
||||||
ToolTip="단축키 목록을 봅니다 (F1)"/>
|
ToolTip="단축키 목록을 봅니다 (F1)"/>
|
||||||
|
<Button DockPanel.Dock="Right" Content="결과 내보내기" Command="{Binding ExportReportCommand}"
|
||||||
|
Height="26" MinHeight="26" Padding="10,2" FontSize="11" Margin="10,0,0,0"
|
||||||
|
VerticalAlignment="Top"
|
||||||
|
ToolTip="비교 결과를 글로 뽑아 파일에 저장합니다. 메일이나 결재에 그대로 붙일 수 있습니다"/>
|
||||||
|
|
||||||
|
|
||||||
<WrapPanel Orientation="Horizontal">
|
<WrapPanel Orientation="Horizontal">
|
||||||
<!-- 지금 어느 모드인지 늘 보이게 한다 - 커밋 이력이 없는 이유를 알 수 있어야 한다. -->
|
<!-- 지금 어느 모드인지 늘 보이게 한다 - 커밋 이력이 없는 이유를 알 수 있어야 한다. -->
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user