[Phase L2-3] 클립보드 이미지 미리보기 창 구현
신규 파일: - ClipboardImagePreviewWindow.xaml (신규, 140줄): WindowStyle=None, 커스텀 타이틀바, 이미지 ScaleTransform 줌, 하단 툴바(축소/줌레이블/확대 / 1:1 / 창맞춤 / 저장 / 복사) - ClipboardImagePreviewWindow.xaml.cs (신규, 173줄): 원본 해상도 이미지 로드(OriginalImagePath → 썸네일 폴백), FitToWindow() 초기 자동 맞춤, ApplyZoom(ScaleTransform), Ctrl+휠 줌, 키보드 단축키(+/-/0/F/Esc/Ctrl+C/Ctrl+S), PNG·JPEG·BMP 저장(SaveFileDialog), NotificationCenterService 피드백 변경 파일: - LauncherWindow.Keyboard.cs: Shift+Enter 시 ClipboardEntry 이미지 항목 → 미리보기 창 열기(기존 폴더열기 분기 전에 추가) - LauncherWindow.ShortcutHelp.cs: "Shift+Enter — 대형 텍스트 / 이미지 미리보기 (#)" 안내 갱신 빌드: 경고 0, 오류 0 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
225
src/AxCopilot/Views/ClipboardImagePreviewWindow.xaml
Normal file
225
src/AxCopilot/Views/ClipboardImagePreviewWindow.xaml
Normal file
@@ -0,0 +1,225 @@
|
||||
<Window x:Class="AxCopilot.Views.ClipboardImagePreviewWindow"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
Title="AX Copilot — 이미지 미리보기"
|
||||
Width="820" Height="640"
|
||||
WindowStyle="None" AllowsTransparency="True"
|
||||
Background="Transparent"
|
||||
WindowStartupLocation="CenterScreen"
|
||||
ResizeMode="CanResizeWithGrip"
|
||||
MinWidth="320" MinHeight="260">
|
||||
|
||||
<!-- Phase L2-3: 클립보드 이미지 미리보기 창 -->
|
||||
|
||||
<Border Background="{DynamicResource LauncherBackground}" CornerRadius="12"
|
||||
BorderBrush="{DynamicResource BorderColor}" BorderThickness="1"
|
||||
Margin="6">
|
||||
<Border.Effect>
|
||||
<DropShadowEffect BlurRadius="20" ShadowDepth="4" Opacity="0.3" Color="Black" Direction="270"/>
|
||||
</Border.Effect>
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="44"/> <!-- 타이틀바 -->
|
||||
<RowDefinition Height="*"/> <!-- 이미지 영역 -->
|
||||
<RowDefinition Height="46"/> <!-- 하단 툴바 -->
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<!-- ─── 타이틀바 ─────────────────────────────────────────────── -->
|
||||
<Border Grid.Row="0" CornerRadius="12,12,0,0"
|
||||
Background="{DynamicResource ItemBackground}"
|
||||
MouseLeftButtonDown="TitleBar_MouseDown">
|
||||
<Grid Margin="16,0,8,0">
|
||||
<StackPanel Orientation="Horizontal" VerticalAlignment="Center">
|
||||
<!-- 이미지 아이콘 -->
|
||||
<TextBlock Text="" FontFamily="Segoe MDL2 Assets" FontSize="15"
|
||||
Foreground="{DynamicResource AccentColor}"
|
||||
VerticalAlignment="Center" Margin="0,1,10,0"/>
|
||||
<TextBlock Text="이미지 미리보기"
|
||||
FontSize="13" FontWeight="SemiBold"
|
||||
Foreground="{DynamicResource PrimaryText}"
|
||||
VerticalAlignment="Center"/>
|
||||
<TextBlock x:Name="SizeLabel" Text=""
|
||||
FontSize="11" Foreground="{DynamicResource SecondaryText}"
|
||||
VerticalAlignment="Center" Margin="12,0,0,0"/>
|
||||
</StackPanel>
|
||||
|
||||
<!-- 닫기 버튼 -->
|
||||
<Border x:Name="BtnClose" HorizontalAlignment="Right" VerticalAlignment="Center"
|
||||
CornerRadius="4" Padding="8,4" Cursor="Hand"
|
||||
MouseLeftButtonUp="BtnClose_Click">
|
||||
<Border.Style>
|
||||
<Style TargetType="Border">
|
||||
<Setter Property="Background" Value="Transparent"/>
|
||||
<Style.Triggers>
|
||||
<Trigger Property="IsMouseOver" Value="True">
|
||||
<Setter Property="Background" Value="#40C05050"/>
|
||||
</Trigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</Border.Style>
|
||||
<TextBlock Text="" FontFamily="Segoe MDL2 Assets" FontSize="13"
|
||||
Foreground="{DynamicResource SecondaryText}"/>
|
||||
</Border>
|
||||
</Grid>
|
||||
</Border>
|
||||
|
||||
<!-- ─── 이미지 영역 ────────────────────────────────────────────── -->
|
||||
<ScrollViewer Grid.Row="1" x:Name="ImageScroll"
|
||||
HorizontalScrollBarVisibility="Auto"
|
||||
VerticalScrollBarVisibility="Auto"
|
||||
Background="{DynamicResource LauncherBackground}"
|
||||
PreviewMouseWheel="ImageScroll_PreviewMouseWheel">
|
||||
<Grid HorizontalAlignment="Center" VerticalAlignment="Center" Margin="8">
|
||||
<Image x:Name="PreviewImage"
|
||||
RenderOptions.BitmapScalingMode="HighQuality"
|
||||
Stretch="None"
|
||||
HorizontalAlignment="Center" VerticalAlignment="Center">
|
||||
<Image.LayoutTransform>
|
||||
<ScaleTransform x:Name="ZoomTransform" ScaleX="1" ScaleY="1"/>
|
||||
</Image.LayoutTransform>
|
||||
</Image>
|
||||
</Grid>
|
||||
</ScrollViewer>
|
||||
|
||||
<!-- ─── 하단 툴바 ─────────────────────────────────────────────── -->
|
||||
<Border Grid.Row="2" CornerRadius="0,0,12,12"
|
||||
Background="{DynamicResource ItemBackground}"
|
||||
BorderBrush="{DynamicResource BorderColor}" BorderThickness="0,1,0,0">
|
||||
<Grid Margin="12,0">
|
||||
|
||||
<!-- 좌측: 줌 컨트롤 -->
|
||||
<StackPanel Orientation="Horizontal" VerticalAlignment="Center">
|
||||
|
||||
<!-- 축소 버튼 -->
|
||||
<Border CornerRadius="6" Padding="8,5" Cursor="Hand" Margin="0,0,2,0"
|
||||
ToolTip="축소 (−)" MouseLeftButtonUp="BtnZoomOut_Click">
|
||||
<Border.Style>
|
||||
<Style TargetType="Border">
|
||||
<Setter Property="Background" Value="Transparent"/>
|
||||
<Style.Triggers>
|
||||
<Trigger Property="IsMouseOver" Value="True">
|
||||
<Setter Property="Background" Value="{DynamicResource ItemHoverBackground}"/>
|
||||
</Trigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</Border.Style>
|
||||
<TextBlock Text="" FontFamily="Segoe MDL2 Assets" FontSize="13"
|
||||
Foreground="{DynamicResource PrimaryText}"/>
|
||||
</Border>
|
||||
|
||||
<!-- 줌 퍼센트 라벨 -->
|
||||
<Border CornerRadius="4" Padding="6,4" Margin="2,0"
|
||||
Background="{DynamicResource HintBackground}">
|
||||
<TextBlock x:Name="ZoomLabel" Text="100%"
|
||||
FontSize="11" FontWeight="Medium"
|
||||
Foreground="{DynamicResource PrimaryText}"
|
||||
MinWidth="44" TextAlignment="Center"/>
|
||||
</Border>
|
||||
|
||||
<!-- 확대 버튼 -->
|
||||
<Border CornerRadius="6" Padding="8,5" Cursor="Hand" Margin="2,0,6,0"
|
||||
ToolTip="확대 (+)" MouseLeftButtonUp="BtnZoomIn_Click">
|
||||
<Border.Style>
|
||||
<Style TargetType="Border">
|
||||
<Setter Property="Background" Value="Transparent"/>
|
||||
<Style.Triggers>
|
||||
<Trigger Property="IsMouseOver" Value="True">
|
||||
<Setter Property="Background" Value="{DynamicResource ItemHoverBackground}"/>
|
||||
</Trigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</Border.Style>
|
||||
<TextBlock Text="" FontFamily="Segoe MDL2 Assets" FontSize="13"
|
||||
Foreground="{DynamicResource PrimaryText}"/>
|
||||
</Border>
|
||||
|
||||
<!-- 구분선 -->
|
||||
<Border Width="1" Height="20" Margin="2,0,8,0"
|
||||
Background="{DynamicResource BorderColor}"/>
|
||||
|
||||
<!-- 실제 크기 -->
|
||||
<Border CornerRadius="6" Padding="8,5" Cursor="Hand" Margin="0,0,2,0"
|
||||
ToolTip="실제 크기 (0)" MouseLeftButtonUp="BtnActualSize_Click">
|
||||
<Border.Style>
|
||||
<Style TargetType="Border">
|
||||
<Setter Property="Background" Value="Transparent"/>
|
||||
<Style.Triggers>
|
||||
<Trigger Property="IsMouseOver" Value="True">
|
||||
<Setter Property="Background" Value="{DynamicResource ItemHoverBackground}"/>
|
||||
</Trigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</Border.Style>
|
||||
<TextBlock Text="1:1" FontSize="11" FontWeight="Bold"
|
||||
Foreground="{DynamicResource SecondaryText}"/>
|
||||
</Border>
|
||||
|
||||
<!-- 창에 맞추기 -->
|
||||
<Border CornerRadius="6" Padding="8,5" Cursor="Hand"
|
||||
ToolTip="창에 맞추기 (F)" MouseLeftButtonUp="BtnFitToWindow_Click">
|
||||
<Border.Style>
|
||||
<Style TargetType="Border">
|
||||
<Setter Property="Background" Value="Transparent"/>
|
||||
<Style.Triggers>
|
||||
<Trigger Property="IsMouseOver" Value="True">
|
||||
<Setter Property="Background" Value="{DynamicResource ItemHoverBackground}"/>
|
||||
</Trigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</Border.Style>
|
||||
<TextBlock Text="" FontFamily="Segoe MDL2 Assets" FontSize="13"
|
||||
Foreground="{DynamicResource SecondaryText}"/>
|
||||
</Border>
|
||||
</StackPanel>
|
||||
|
||||
<!-- 우측: 복사 / 저장 버튼 -->
|
||||
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right" VerticalAlignment="Center">
|
||||
|
||||
<!-- 파일로 저장 -->
|
||||
<Border CornerRadius="8" Padding="12,6" Cursor="Hand" Margin="0,0,8,0"
|
||||
ToolTip="파일로 저장 (Ctrl+S)"
|
||||
MouseLeftButtonUp="BtnSave_Click">
|
||||
<Border.Style>
|
||||
<Style TargetType="Border">
|
||||
<Setter Property="Background" Value="{DynamicResource ItemBackground}"/>
|
||||
<Style.Triggers>
|
||||
<Trigger Property="IsMouseOver" Value="True">
|
||||
<Setter Property="Background" Value="{DynamicResource ItemHoverBackground}"/>
|
||||
</Trigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</Border.Style>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<TextBlock Text="" FontFamily="Segoe MDL2 Assets" FontSize="12"
|
||||
Foreground="{DynamicResource SecondaryText}" VerticalAlignment="Center"/>
|
||||
<TextBlock Text=" 저장" FontSize="12"
|
||||
Foreground="{DynamicResource SecondaryText}" Margin="4,0,0,0"/>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
|
||||
<!-- 클립보드 복사 -->
|
||||
<Border CornerRadius="8" Padding="12,6" Cursor="Hand"
|
||||
ToolTip="클립보드에 복사 (Ctrl+C)"
|
||||
MouseLeftButtonUp="BtnCopy_Click">
|
||||
<Border.Style>
|
||||
<Style TargetType="Border">
|
||||
<Setter Property="Background" Value="{DynamicResource AccentColor}"/>
|
||||
<Style.Triggers>
|
||||
<Trigger Property="IsMouseOver" Value="True">
|
||||
<Setter Property="Opacity" Value="0.85"/>
|
||||
</Trigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</Border.Style>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<TextBlock Text="" FontFamily="Segoe MDL2 Assets" FontSize="12"
|
||||
Foreground="White" VerticalAlignment="Center"/>
|
||||
<TextBlock Text=" 복사" FontSize="12" Foreground="White" Margin="4,0,0,0"/>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</Border>
|
||||
</Grid>
|
||||
</Border>
|
||||
</Window>
|
||||
231
src/AxCopilot/Views/ClipboardImagePreviewWindow.xaml.cs
Normal file
231
src/AxCopilot/Views/ClipboardImagePreviewWindow.xaml.cs
Normal file
@@ -0,0 +1,231 @@
|
||||
using System.IO;
|
||||
using System.Windows;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media.Imaging;
|
||||
using AxCopilot.Services;
|
||||
using Microsoft.Win32;
|
||||
|
||||
namespace AxCopilot.Views;
|
||||
|
||||
/// <summary>
|
||||
/// Phase L2-3: 클립보드 이미지 미리보기 창.
|
||||
/// 원본 해상도 이미지 표시 + 확대/축소 + 클립보드 복사 + 파일 저장.
|
||||
/// Shift+Enter (이미지 항목 선택 시) 또는 런처 내 미리보기 액션으로 열립니다.
|
||||
/// </summary>
|
||||
public partial class ClipboardImagePreviewWindow : Window
|
||||
{
|
||||
private readonly ClipboardEntry _entry;
|
||||
private BitmapSource? _fullImage;
|
||||
private double _zoomFactor = 1.0;
|
||||
|
||||
private const double ZoomStep = 0.25;
|
||||
private const double MinZoom = 0.05;
|
||||
private const double MaxZoom = 8.0;
|
||||
|
||||
public ClipboardImagePreviewWindow(ClipboardEntry entry)
|
||||
{
|
||||
InitializeComponent();
|
||||
_entry = entry;
|
||||
KeyDown += OnKeyDown;
|
||||
Loaded += OnLoaded;
|
||||
}
|
||||
|
||||
// ─── 초기화 ──────────────────────────────────────────────────────────
|
||||
|
||||
private void OnLoaded(object sender, RoutedEventArgs e)
|
||||
{
|
||||
LoadImage();
|
||||
}
|
||||
|
||||
private void LoadImage()
|
||||
{
|
||||
// 원본 해상도 이미지 우선, 없으면 썸네일 폴백
|
||||
_fullImage = ClipboardHistoryService.LoadOriginalImage(_entry.OriginalImagePath)
|
||||
?? _entry.Image;
|
||||
|
||||
if (_fullImage == null)
|
||||
{
|
||||
SizeLabel.Text = "(이미지 없음)";
|
||||
return;
|
||||
}
|
||||
|
||||
PreviewImage.Source = _fullImage;
|
||||
SizeLabel.Text = $"{_fullImage.PixelWidth} × {_fullImage.PixelHeight} px";
|
||||
|
||||
// 창 레이아웃이 확정된 후 Fit 적용
|
||||
Dispatcher.InvokeAsync(FitToWindow, System.Windows.Threading.DispatcherPriority.Loaded);
|
||||
}
|
||||
|
||||
// ─── 줌 제어 ─────────────────────────────────────────────────────────
|
||||
|
||||
private void FitToWindow()
|
||||
{
|
||||
if (_fullImage == null) return;
|
||||
var availW = ImageScroll.ActualWidth - 24;
|
||||
var availH = ImageScroll.ActualHeight - 24;
|
||||
if (availW <= 0 || availH <= 0) return;
|
||||
|
||||
var scaleX = availW / _fullImage.PixelWidth;
|
||||
var scaleY = availH / _fullImage.PixelHeight;
|
||||
_zoomFactor = Math.Min(1.0, Math.Min(scaleX, scaleY));
|
||||
ApplyZoom();
|
||||
}
|
||||
|
||||
private void ApplyZoom()
|
||||
{
|
||||
ZoomTransform.ScaleX = _zoomFactor;
|
||||
ZoomTransform.ScaleY = _zoomFactor;
|
||||
ZoomLabel.Text = $"{_zoomFactor * 100:F0}%";
|
||||
}
|
||||
|
||||
// ─── 타이틀바 ────────────────────────────────────────────────────────
|
||||
|
||||
private void TitleBar_MouseDown(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
if (e.LeftButton == MouseButtonState.Pressed)
|
||||
DragMove();
|
||||
}
|
||||
|
||||
// ─── 버튼 핸들러 ─────────────────────────────────────────────────────
|
||||
|
||||
private void BtnClose_Click(object sender, MouseButtonEventArgs e) => Close();
|
||||
|
||||
private void BtnZoomIn_Click(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
_zoomFactor = Math.Min(MaxZoom, Math.Round(_zoomFactor + ZoomStep, 2));
|
||||
ApplyZoom();
|
||||
}
|
||||
|
||||
private void BtnZoomOut_Click(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
_zoomFactor = Math.Max(MinZoom, Math.Round(_zoomFactor - ZoomStep, 2));
|
||||
ApplyZoom();
|
||||
}
|
||||
|
||||
private void BtnActualSize_Click(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
_zoomFactor = 1.0;
|
||||
ApplyZoom();
|
||||
}
|
||||
|
||||
private void BtnFitToWindow_Click(object sender, MouseButtonEventArgs e)
|
||||
=> FitToWindow();
|
||||
|
||||
private void BtnCopy_Click(object sender, MouseButtonEventArgs e)
|
||||
=> CopyToClipboard();
|
||||
|
||||
private void BtnSave_Click(object sender, MouseButtonEventArgs e)
|
||||
=> SaveToFile();
|
||||
|
||||
// ─── 스크롤 휠 줌 ────────────────────────────────────────────────────
|
||||
|
||||
private void ImageScroll_PreviewMouseWheel(object sender, MouseWheelEventArgs e)
|
||||
{
|
||||
if ((Keyboard.Modifiers & ModifierKeys.Control) == 0) return;
|
||||
e.Handled = true;
|
||||
|
||||
var delta = e.Delta > 0 ? ZoomStep : -ZoomStep;
|
||||
_zoomFactor = Math.Clamp(Math.Round(_zoomFactor + delta, 2), MinZoom, MaxZoom);
|
||||
ApplyZoom();
|
||||
}
|
||||
|
||||
// ─── 키보드 단축키 ───────────────────────────────────────────────────
|
||||
|
||||
private void OnKeyDown(object sender, KeyEventArgs e)
|
||||
{
|
||||
switch (e.Key)
|
||||
{
|
||||
case Key.Escape:
|
||||
Close();
|
||||
e.Handled = true;
|
||||
break;
|
||||
|
||||
case Key.Add:
|
||||
case Key.OemPlus:
|
||||
_zoomFactor = Math.Min(MaxZoom, Math.Round(_zoomFactor + ZoomStep, 2));
|
||||
ApplyZoom();
|
||||
e.Handled = true;
|
||||
break;
|
||||
|
||||
case Key.Subtract:
|
||||
case Key.OemMinus:
|
||||
_zoomFactor = Math.Max(MinZoom, Math.Round(_zoomFactor - ZoomStep, 2));
|
||||
ApplyZoom();
|
||||
e.Handled = true;
|
||||
break;
|
||||
|
||||
case Key.D0:
|
||||
case Key.NumPad0:
|
||||
_zoomFactor = 1.0;
|
||||
ApplyZoom();
|
||||
e.Handled = true;
|
||||
break;
|
||||
|
||||
case Key.F:
|
||||
FitToWindow();
|
||||
e.Handled = true;
|
||||
break;
|
||||
|
||||
case Key.C when (Keyboard.Modifiers & ModifierKeys.Control) != 0:
|
||||
CopyToClipboard();
|
||||
e.Handled = true;
|
||||
break;
|
||||
|
||||
case Key.S when (Keyboard.Modifiers & ModifierKeys.Control) != 0:
|
||||
SaveToFile();
|
||||
e.Handled = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// ─── 내부 동작 ───────────────────────────────────────────────────────
|
||||
|
||||
private void CopyToClipboard()
|
||||
{
|
||||
if (_fullImage == null) return;
|
||||
try
|
||||
{
|
||||
Clipboard.SetImage(_fullImage);
|
||||
NotificationCenterService.Show("클립보드", "이미지를 클립보드에 복사했습니다.",
|
||||
NotificationType.Success);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
NotificationCenterService.Show("복사 실패", ex.Message, NotificationType.Error);
|
||||
}
|
||||
}
|
||||
|
||||
private void SaveToFile()
|
||||
{
|
||||
if (_fullImage == null) return;
|
||||
|
||||
var dlg = new SaveFileDialog
|
||||
{
|
||||
Title = "이미지 저장",
|
||||
Filter = "PNG 이미지 (*.png)|*.png|JPEG 이미지 (*.jpg)|*.jpg|BMP 이미지 (*.bmp)|*.bmp",
|
||||
FileName = $"clipboard_{DateTime.Now:yyyyMMdd_HHmmss}",
|
||||
DefaultExt = "png",
|
||||
};
|
||||
if (dlg.ShowDialog(this) != true) return;
|
||||
|
||||
try
|
||||
{
|
||||
BitmapEncoder encoder = Path.GetExtension(dlg.FileName).ToLowerInvariant() switch
|
||||
{
|
||||
".jpg" or ".jpeg" => new JpegBitmapEncoder { QualityLevel = 95 },
|
||||
".bmp" => new BmpBitmapEncoder(),
|
||||
_ => new PngBitmapEncoder(),
|
||||
};
|
||||
encoder.Frames.Add(BitmapFrame.Create(_fullImage));
|
||||
using var fs = File.OpenWrite(dlg.FileName);
|
||||
encoder.Save(fs);
|
||||
|
||||
NotificationCenterService.Show("저장 완료", Path.GetFileName(dlg.FileName),
|
||||
NotificationType.Success);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
NotificationCenterService.Show("저장 실패", ex.Message, NotificationType.Error);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -50,6 +50,16 @@ public partial class LauncherWindow
|
||||
|
||||
if (shift)
|
||||
{
|
||||
// Phase L2-3: 클립보드 이미지 항목 → 이미지 미리보기 창 열기
|
||||
if (_vm.SelectedItem?.Data is AxCopilot.Services.ClipboardEntry imgEntry && !imgEntry.IsText)
|
||||
{
|
||||
e.Handled = true;
|
||||
Hide();
|
||||
var previewWin = new ClipboardImagePreviewWindow(imgEntry);
|
||||
previewWin.Show();
|
||||
break;
|
||||
}
|
||||
|
||||
// 퍼지 파일 검색 결과: Shift+Enter → 파일이 있는 폴더 열기
|
||||
if (_vm.SelectedItem?.Data is AxCopilot.Services.IndexEntry shiftEntry)
|
||||
{
|
||||
|
||||
@@ -41,7 +41,7 @@ public partial class LauncherWindow
|
||||
"Ctrl+Shift+E 탐색기에서 열기",
|
||||
"Ctrl+Enter 관리자 실행",
|
||||
"Alt+Enter 속성 보기",
|
||||
"Shift+Enter 대형 텍스트",
|
||||
"Shift+Enter 대형 텍스트 / 이미지 미리보기 (#)",
|
||||
};
|
||||
|
||||
CustomMessageBox.Show(
|
||||
|
||||
Reference in New Issue
Block a user