Files
AX-Copilot/src/AxCopilot/Models/AppSettings.cs
lacvet c12e863e3a [Phase L5-1] 항목별 전용 핫키 기능 구현
HotkeyAssignment 모델 추가 (AppSettings.Models.cs):
- Hotkey, Target, Label, Type 필드 (app/url/folder/command)
- AppSettings.CustomHotkeys (List<HotkeyAssignment>) 추가

InputListener.cs 확장 (Core/):
- _customHotkeys 목록 (스레드 안전 lock)
- UpdateCustomHotkeys() 메서드 — 설정 저장 후 즉시 갱신
- CustomHotkeyTriggered 이벤트 (CustomHotkeyEventArgs: Target, Type)
- WH_KEYBOARD_LL 콜백에 전용 핫키 감지 분기 추가

HotkeyHandler.cs 신규 생성 (Handlers/, 140줄):
- prefix="hotkey" — 등록 목록 표시 / 설정 열기
- ExecuteHotkeyTarget() — app/url/folder/command 타입별 실행

App.xaml.cs + App.Settings.cs:
- HotkeyHandler 등록 (Phase L5 주석)
- OnCustomHotkeyTriggered 이벤트 핸들러 연결
- 설정 저장 시 UpdateCustomHotkeys() 호출

SettingsViewModel 3파일 업데이트:
- HotkeyRowModel (Properties.cs): Hotkey/Target/Label/Type + TypeSymbol
- CustomHotkeys ObservableCollection + New* 필드 (Properties.cs)
- AddCustomHotkey() / RemoveCustomHotkey() 메서드 (Methods.cs)
  - HotkeyParser 형식 검증, 중복 핫키 방지
- Load/Save에 CustomHotkeys 매핑 (SettingsViewModel.cs, Methods.cs)

SettingsWindow.xaml + .xaml.cs:
- "전용 핫키" 탭 신규 추가 (배치 명령 탭 다음)
  - 안내 배너, 입력 폼 (핫키 레코더 + 표시이름 + 타입 + 대상)
  - 핫키 목록 (배지 + 타입아이콘 + 이름/경로 + 삭제 버튼)
- HotkeyRecord_Click: 클릭 후 키 입력 → 자동 핫키 감지 (PreviewKeyDown)
- AddHotkey_Click, RemoveHotkey_Click, BrowseHotkeyTarget_Click 핸들러

docs/LAUNCHER_ROADMAP.md:
- L5-1  완료 표시, 구현 내용 업데이트

빌드: 경고 0, 오류 0

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-04 12:12:32 +09:00

323 lines
14 KiB
C#

using System.Text.Json.Serialization;
namespace AxCopilot.Models;
public class AppSettings
{
[JsonPropertyName("version")]
public string Version { get; set; } = "1.0";
/// <summary>
/// AI 기능 활성화 여부. false이면 ! 명령어 차단 + 설정의 AX Agent 탭 숨김.
/// 클로드 버전(AI 미포함 배포)은 false로 설정합니다.
/// </summary>
[JsonPropertyName("ai_enabled")]
public bool AiEnabled { get; set; } = false;
/// <summary>
/// 사내 모드 활성화 여부. true(기본)이면 외부 인터넷 접속 차단.
/// false(사외 모드)이면 웹 검색, 외부 HTTP 요청 허용.
/// 사외 모드 전환은 비밀번호(axgo123!) 인증 필요.
/// </summary>
[JsonPropertyName("internal_mode_enabled")]
public bool InternalModeEnabled { get; set; } = true;
[JsonPropertyName("hotkey")]
public string Hotkey { get; set; } = "Alt+Space";
[JsonPropertyName("launcher")]
public LauncherSettings Launcher { get; set; } = new();
[JsonPropertyName("indexPaths")]
public List<string> IndexPaths { get; set; } = new()
{
"%USERPROFILE%\\Desktop",
"%APPDATA%\\Microsoft\\Windows\\Start Menu"
};
/// <summary>
/// 인덱싱할 파일 확장자 목록 (점 포함). 빈 리스트 = 모든 파일.
/// 기본값: 실행 파일 + 문서 + 이미지 + 텍스트 파일.
/// </summary>
[JsonPropertyName("indexExtensions")]
public List<string> IndexExtensions { get; set; } = new()
{
// 실행 파일
".exe", ".lnk", ".bat", ".ps1", ".url", ".cmd", ".msi",
// 문서
".pdf", ".doc", ".docx", ".xls", ".xlsx", ".ppt", ".pptx",
".hwp", ".hwpx",
// 텍스트
".txt", ".md", ".csv", ".json", ".xml", ".yaml", ".yml",
".log", ".ini", ".cfg", ".conf",
// 이미지
".png", ".jpg", ".jpeg", ".gif", ".bmp", ".svg", ".webp", ".ico", ".tiff",
// 기타
".zip", ".7z", ".rar"
};
/// <summary>인덱싱 속도. slow | normal | fast. 기본 normal.</summary>
[JsonPropertyName("indexSpeed")]
public string IndexSpeed { get; set; } = "normal"; // slow | normal | fast
[JsonPropertyName("monitorMismatch")]
public string MonitorMismatch { get; set; } = "warn"; // fit | skip | warn
[JsonPropertyName("profiles")]
public List<WorkspaceProfile> Profiles { get; set; } = new();
[JsonPropertyName("aliases")]
public List<AliasEntry> Aliases { get; set; } = new();
[JsonPropertyName("clipboardTransformers")]
public List<ClipboardTransformer> ClipboardTransformers { get; set; } = new();
[JsonPropertyName("apiAdapters")]
public List<ApiAdapter> ApiAdapters { get; set; } = new();
[JsonPropertyName("plugins")]
public List<PluginEntry> Plugins { get; set; } = new();
[JsonPropertyName("snippets")]
public List<SnippetEntry> Snippets { get; set; } = new();
[JsonPropertyName("quickLinks")]
public List<QuickLinkEntry> QuickLinks { get; set; } = new();
[JsonPropertyName("aiSnippetTemplates")]
public List<AiSnippetTemplate> AiSnippetTemplates { get; set; } = new()
{
new() { Keyword = "email", Name = "업무 이메일", Prompt = "다음 상황에 맞는 업무용 이메일을 작성해주세요: {0}" },
new() { Keyword = "summary", Name = "요약", Prompt = "다음 내용을 간결하게 요약해주세요: {0}" },
new() { Keyword = "translate",Name = "번역", Prompt = "다음 텍스트를 자연스럽게 한국어로 번역해주세요: {0}" },
new() { Keyword = "review", Name = "코드 리뷰", Prompt = "다음 코드를 검토하고 개선점을 제안해주세요:\n{0}" },
new() { Keyword = "commit", Name = "커밋 메시지", Prompt = "다음 변경사항에 대한 git 커밋 메시지를 작성해주세요: {0}" },
};
[JsonPropertyName("clipboardHistory")]
public ClipboardHistorySettings ClipboardHistory { get; set; } = new();
[JsonPropertyName("systemCommands")]
public SystemCommandSettings SystemCommands { get; set; } = new();
[JsonPropertyName("screenCapture")]
public ScreenCaptureSettings ScreenCapture { get; set; } = new();
[JsonPropertyName("reminder")]
public ReminderSettings Reminder { get; set; } = new();
/// <summary>
/// 항목별 글로벌 전용 핫키 목록. 어떤 앱이 포커스를 가져도 해당 핫키로 즉시 실행됩니다.
/// </summary>
[JsonPropertyName("customHotkeys")]
public List<HotkeyAssignment> CustomHotkeys { get; set; } = new();
[JsonPropertyName("llm")]
public LlmSettings Llm { get; set; } = new();
}
public class LauncherSettings
{
[JsonPropertyName("opacity")]
public double Opacity { get; set; } = 0.96;
[JsonPropertyName("maxResults")]
public int MaxResults { get; set; } = 7;
[JsonPropertyName("theme")]
// 지원 값: system | dark | light | oled | nord | monokai | catppuccin | sepia | custom
public string Theme { get; set; } = "system";
[JsonPropertyName("position")]
public string Position { get; set; } = "center-top"; // center-top | center | bottom
[JsonPropertyName("width")]
public double Width { get; set; } = 680;
[JsonPropertyName("webSearchEngine")]
public string WebSearchEngine { get; set; } = "g"; // g | n | d | y | w
[JsonPropertyName("snippetAutoExpand")]
public bool SnippetAutoExpand { get; set; } = true;
[JsonPropertyName("language")]
public string Language { get; set; } = "ko"; // ko | en | ja | zh | vi
[JsonPropertyName("customTheme")]
public CustomThemeColors? CustomTheme { get; set; }
// ─── 기능 토글 ─────────────────────────────────────────────────────────
/// <summary>번호 배지(1~9) 표시 여부. Ctrl+숫자로 바로 실행. 기본 true.</summary>
[JsonPropertyName("showNumberBadges")]
public bool ShowNumberBadges { get; set; } = true;
/// <summary>즐겨찾기 기능 활성화. fav 접두어, Ctrl+B. 기본 true.</summary>
[JsonPropertyName("enableFavorites")]
public bool EnableFavorites { get; set; } = true;
/// <summary>최근 실행 기록 저장 여부. recent 접두어, Ctrl+R. 기본 true.</summary>
[JsonPropertyName("enableRecent")]
public bool EnableRecent { get; set; } = true;
/// <summary>액션 모드 진입 허용 여부. Ctrl+Enter / Alt+Enter / → 키. 기본 true.</summary>
[JsonPropertyName("enableActionMode")]
public bool EnableActionMode { get; set; } = true;
/// <summary>포커스 잃을 때 런처 자동 닫기. 기본 true.</summary>
[JsonPropertyName("closeOnFocusLost")]
public bool CloseOnFocusLost { get; set; } = true;
/// <summary>입력창 좌측 프리픽스 배지 표시. 기본 true.</summary>
[JsonPropertyName("showPrefixBadge")]
public bool ShowPrefixBadge { get; set; } = true;
/// <summary>런처 아이콘 애니메이션 효과 활성화. 기본 true.</summary>
[JsonPropertyName("enableIconAnimation")]
public bool EnableIconAnimation { get; set; } = true;
/// <summary>런처 안내 문구 랜덤 출력 활성화. false이면 고정 문구. 기본 true.</summary>
[JsonPropertyName("enableRandomPlaceholder")]
public bool EnableRandomPlaceholder { get; set; } = true;
/// <summary>런처 무지개 글로우 효과 활성화. 기본 false (성능 고려).</summary>
[JsonPropertyName("enableRainbowGlow")]
public bool EnableRainbowGlow { get; set; } = false;
/// <summary>선택된 아이템 상시 글로우 효과. 기본 false.</summary>
[JsonPropertyName("enableSelectionGlow")]
public bool EnableSelectionGlow { get; set; } = false;
/// <summary>런처 창 테두리 표시 여부. 기본 true(표시).</summary>
[JsonPropertyName("showLauncherBorder")]
public bool ShowLauncherBorder { get; set; } = true;
/// <summary>단축키 헬프 창에서 아이콘 색상을 테마 AccentColor 기준으로 표시. 기본 true(테마색).</summary>
[JsonPropertyName("shortcutHelpUseThemeColor")]
public bool ShortcutHelpUseThemeColor { get; set; } = true;
// ─── 독 바 설정 ──────────────────────────────────────────────────────────
// ─── 선택 텍스트 AI 명령 설정 ───────────────────────────────────────────
/// <summary>선택 텍스트 AI 명령 활성화. 기본 true.</summary>
[JsonPropertyName("enableTextAction")]
public bool EnableTextAction { get; set; } = true;
/// <summary>활성화된 텍스트 AI 명령 목록. 가능한 값: translate, summarize, grammar, explain, rewrite</summary>
[JsonPropertyName("textActionCommands")]
public List<string> TextActionCommands { get; set; } = new() { "translate", "summarize", "grammar", "explain", "rewrite" };
/// <summary>번역 기본 언어. 기본 "한국어↔영어 자동".</summary>
[JsonPropertyName("textActionTranslateLanguage")]
public string TextActionTranslateLanguage { get; set; } = "auto";
// ─── 파일 대화상자 통합 설정 ─────────────────────────────────────────────
/// <summary>열기/저장 대화상자 감지 시 런처 자동 열기. 기본 false.</summary>
[JsonPropertyName("enableFileDialogIntegration")]
public bool EnableFileDialogIntegration { get; set; } = false;
// ─── 클립보드 핀/카테고리 설정 ───────────────────────────────────────────
/// <summary>클립보드 자동 카테고리 분류 활성화. 기본 true.</summary>
[JsonPropertyName("enableClipboardAutoCategory")]
public bool EnableClipboardAutoCategory { get; set; } = true;
/// <summary>최대 핀 고정 개수. 기본 20.</summary>
[JsonPropertyName("maxPinnedClipboardItems")]
public int MaxPinnedClipboardItems { get; set; } = 20;
// ─── 독 바 설정 ──────────────────────────────────────────────────────────
/// <summary>독 바 표시 항목. 가능한 값: launcher, clipboard, capture, agent, clock, cpu, ram, quickinput</summary>
[JsonPropertyName("dockBarItems")]
public List<string> DockBarItems { get; set; } = new() { "launcher", "clipboard", "capture", "agent", "clock", "cpu" };
/// <summary>독 바 앱 시작 시 자동 표시. 기본 false.</summary>
[JsonPropertyName("dockBarAutoShow")]
public bool DockBarAutoShow { get; set; } = false;
/// <summary>독 바 투명도 (0.3~1.0). 기본 0.92.</summary>
[JsonPropertyName("dockBarOpacity")]
public double DockBarOpacity { get; set; } = 0.92;
/// <summary>독 바 무지개 글로우 효과. 기본 false.</summary>
[JsonPropertyName("dockBarRainbowGlow")]
public bool DockBarRainbowGlow { get; set; } = false;
/// <summary>독 바 마지막 위치 X. -1이면 중앙.</summary>
[JsonPropertyName("dockBarLeft")]
public double DockBarLeft { get; set; } = -1;
/// <summary>독 바 마지막 위치 Y. -1이면 하단.</summary>
[JsonPropertyName("dockBarTop")]
public double DockBarTop { get; set; } = -1;
/// <summary>
/// Phase L3-7: 모니터별 독 바 위치.
/// key = 모니터 디바이스 이름 (예: \\.\DISPLAY1), value = [WPF Left, WPF Top].
/// 모니터가 재연결되면 해당 모니터의 저장 위치로 자동 복원됩니다.
/// </summary>
[JsonPropertyName("monitorDockPositions")]
public Dictionary<string, double[]> MonitorDockPositions { get; set; } = new();
}
/// <summary>
/// "theme": "custom" 설정 시 사용할 사용자 정의 색상.
/// settings.json에서 직접 헥스 코드(#RRGGBB)로 지정합니다.
/// </summary>
public class CustomThemeColors
{
[JsonPropertyName("launcherBackground")]
public string LauncherBackground { get; set; } = "#1A1B2E";
[JsonPropertyName("itemBackground")]
public string ItemBackground { get; set; } = "#252637";
[JsonPropertyName("itemSelectedBackground")]
public string ItemSelectedBackground { get; set; } = "#3B4BDB";
[JsonPropertyName("itemHoverBackground")]
public string ItemHoverBackground { get; set; } = "#22233A";
[JsonPropertyName("primaryText")]
public string PrimaryText { get; set; } = "#F0F0FF";
[JsonPropertyName("secondaryText")]
public string SecondaryText { get; set; } = "#7A7D9C";
[JsonPropertyName("placeholderText")]
public string PlaceholderText { get; set; } = "#464868";
[JsonPropertyName("accentColor")]
public string AccentColor { get; set; } = "#4B5EFC";
[JsonPropertyName("separatorColor")]
public string SeparatorColor { get; set; } = "#252637";
[JsonPropertyName("hintBackground")]
public string HintBackground { get; set; } = "#252637";
[JsonPropertyName("hintText")]
public string HintText { get; set; } = "#4B5070";
[JsonPropertyName("borderColor")]
public string BorderColor { get; set; } = "#2E2F4A";
[JsonPropertyName("scrollbarThumb")]
public string ScrollbarThumb { get; set; } = "#3A3B5A";
[JsonPropertyName("shadowColor")]
public string ShadowColor { get; set; } = "#000000";
/// <summary>창 전체 모서리 라운딩 (0~30). 기본값 20.</summary>
[JsonPropertyName("windowCornerRadius")]
public int WindowCornerRadius { get; set; } = 20;
/// <summary>결과 항목 모서리 라운딩 (0~20). 기본값 10.</summary>
[JsonPropertyName("itemCornerRadius")]
public int ItemCornerRadius { get; set; } = 10;
}