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>
441 lines
18 KiB
C#
441 lines
18 KiB
C#
using System.Collections.ObjectModel;
|
|
using AxCopilot.Models;
|
|
|
|
namespace AxCopilot.ViewModels;
|
|
|
|
public partial class SettingsViewModel
|
|
{
|
|
// ─── 기능 토글 속성 ───────────────────────────────────────────────────
|
|
|
|
public bool ShowNumberBadges
|
|
{
|
|
get => _showNumberBadges;
|
|
set { _showNumberBadges = value; OnPropertyChanged(); }
|
|
}
|
|
|
|
public bool EnableFavorites
|
|
{
|
|
get => _enableFavorites;
|
|
set { _enableFavorites = value; OnPropertyChanged(); }
|
|
}
|
|
|
|
public bool EnableRecent
|
|
{
|
|
get => _enableRecent;
|
|
set { _enableRecent = value; OnPropertyChanged(); }
|
|
}
|
|
|
|
public bool EnableActionMode
|
|
{
|
|
get => _enableActionMode;
|
|
set { _enableActionMode = value; OnPropertyChanged(); }
|
|
}
|
|
|
|
public bool CloseOnFocusLost
|
|
{
|
|
get => _closeOnFocusLost;
|
|
set { _closeOnFocusLost = value; OnPropertyChanged(); }
|
|
}
|
|
|
|
public bool ShowPrefixBadge
|
|
{
|
|
get => _showPrefixBadge;
|
|
set { _showPrefixBadge = value; OnPropertyChanged(); }
|
|
}
|
|
|
|
public bool EnableIconAnimation
|
|
{
|
|
get => _enableIconAnimation;
|
|
set { _enableIconAnimation = value; OnPropertyChanged(); }
|
|
}
|
|
|
|
public bool EnableRainbowGlow
|
|
{
|
|
get => _enableRainbowGlow;
|
|
set { _enableRainbowGlow = value; OnPropertyChanged(); }
|
|
}
|
|
|
|
public bool EnableSelectionGlow
|
|
{
|
|
get => _enableSelectionGlow;
|
|
set { _enableSelectionGlow = value; OnPropertyChanged(); }
|
|
}
|
|
|
|
public bool EnableRandomPlaceholder
|
|
{
|
|
get => _enableRandomPlaceholder;
|
|
set { _enableRandomPlaceholder = value; OnPropertyChanged(); }
|
|
}
|
|
|
|
public bool ShowLauncherBorder
|
|
{
|
|
get => _showLauncherBorder;
|
|
set { _showLauncherBorder = value; OnPropertyChanged(); }
|
|
}
|
|
|
|
// ─── v1.4.0 신기능 설정 ──────────────────────────────────────────────────
|
|
|
|
private bool _enableTextAction = true;
|
|
public bool EnableTextAction
|
|
{
|
|
get => _enableTextAction;
|
|
set { _enableTextAction = value; OnPropertyChanged(); }
|
|
}
|
|
|
|
private bool _enableFileDialogIntegration = false;
|
|
public bool EnableFileDialogIntegration
|
|
{
|
|
get => _enableFileDialogIntegration;
|
|
set { _enableFileDialogIntegration = value; OnPropertyChanged(); }
|
|
}
|
|
|
|
private bool _enableClipboardAutoCategory = true;
|
|
public bool EnableClipboardAutoCategory
|
|
{
|
|
get => _enableClipboardAutoCategory;
|
|
set { _enableClipboardAutoCategory = value; OnPropertyChanged(); }
|
|
}
|
|
|
|
private int _maxPinnedClipboardItems = 20;
|
|
public int MaxPinnedClipboardItems
|
|
{
|
|
get => _maxPinnedClipboardItems;
|
|
set { _maxPinnedClipboardItems = value; OnPropertyChanged(); }
|
|
}
|
|
|
|
private string _textActionTranslateLanguage = "auto";
|
|
public string TextActionTranslateLanguage
|
|
{
|
|
get => _textActionTranslateLanguage;
|
|
set { _textActionTranslateLanguage = value; OnPropertyChanged(); }
|
|
}
|
|
|
|
private int _maxSubAgents = 3;
|
|
public int MaxSubAgents
|
|
{
|
|
get => _maxSubAgents;
|
|
set { _maxSubAgents = value; OnPropertyChanged(); }
|
|
}
|
|
|
|
private string _pdfExportPath = "";
|
|
public string PdfExportPath
|
|
{
|
|
get => _pdfExportPath;
|
|
set { _pdfExportPath = value; OnPropertyChanged(); }
|
|
}
|
|
|
|
private int _tipDurationSeconds = 5;
|
|
public int TipDurationSeconds
|
|
{
|
|
get => _tipDurationSeconds;
|
|
set { _tipDurationSeconds = value; OnPropertyChanged(); }
|
|
}
|
|
|
|
public bool ShortcutHelpUseThemeColor
|
|
{
|
|
get => _shortcutHelpUseThemeColor;
|
|
set { _shortcutHelpUseThemeColor = value; OnPropertyChanged(); }
|
|
}
|
|
|
|
// ─── 테마 카드 목록 ───────────────────────────────────────────────────
|
|
public List<ThemeCardModel> ThemeCards { get; } = new()
|
|
{
|
|
new()
|
|
{
|
|
Key = "system", Name = "시스템",
|
|
PreviewBackground = "#1E1E1E", PreviewText = "#FFFFFF",
|
|
PreviewSubText = "#888888", PreviewAccent = "#0078D4",
|
|
PreviewItem = "#2D2D2D", PreviewBorder = "#3D3D3D"
|
|
},
|
|
new()
|
|
{
|
|
Key = "dark", Name = "Dark",
|
|
PreviewBackground = "#1A1B2E", PreviewText = "#F0F0FF",
|
|
PreviewSubText = "#7A7D9C", PreviewAccent = "#4B5EFC",
|
|
PreviewItem = "#252637", PreviewBorder = "#2E2F4A"
|
|
},
|
|
new()
|
|
{
|
|
Key = "light", Name = "Light",
|
|
PreviewBackground = "#FAFAFA", PreviewText = "#1A1B2E",
|
|
PreviewSubText = "#666680", PreviewAccent = "#4B5EFC",
|
|
PreviewItem = "#F0F0F8", PreviewBorder = "#E0E0F0"
|
|
},
|
|
new()
|
|
{
|
|
Key = "oled", Name = "OLED",
|
|
PreviewBackground = "#000000", PreviewText = "#FFFFFF",
|
|
PreviewSubText = "#888899", PreviewAccent = "#5C6EFF",
|
|
PreviewItem = "#0A0A14", PreviewBorder = "#1A1A2E"
|
|
},
|
|
new()
|
|
{
|
|
Key = "nord", Name = "Nord",
|
|
PreviewBackground = "#2E3440", PreviewText = "#ECEFF4",
|
|
PreviewSubText = "#D8DEE9", PreviewAccent = "#88C0D0",
|
|
PreviewItem = "#3B4252", PreviewBorder = "#434C5E"
|
|
},
|
|
new()
|
|
{
|
|
Key = "monokai", Name = "Monokai",
|
|
PreviewBackground = "#272822", PreviewText = "#F8F8F2",
|
|
PreviewSubText = "#75715E", PreviewAccent = "#A6E22E",
|
|
PreviewItem = "#3E3D32", PreviewBorder = "#49483E"
|
|
},
|
|
new()
|
|
{
|
|
Key = "catppuccin", Name = "Catppuccin",
|
|
PreviewBackground = "#1E1E2E", PreviewText = "#CDD6F4",
|
|
PreviewSubText = "#A6ADC8", PreviewAccent = "#CBA6F7",
|
|
PreviewItem = "#313244", PreviewBorder = "#45475A"
|
|
},
|
|
new()
|
|
{
|
|
Key = "sepia", Name = "Sepia",
|
|
PreviewBackground = "#F5EFE0", PreviewText = "#3C2F1A",
|
|
PreviewSubText = "#7A6040", PreviewAccent = "#C0822A",
|
|
PreviewItem = "#EDE6D6", PreviewBorder = "#D8CCBA"
|
|
},
|
|
new()
|
|
{
|
|
Key = "alfred", Name = "Indigo",
|
|
PreviewBackground = "#26273B", PreviewText = "#EEEEFF",
|
|
PreviewSubText = "#8888BB", PreviewAccent = "#8877EE",
|
|
PreviewItem = "#3B3D60", PreviewBorder = "#40416A"
|
|
},
|
|
new()
|
|
{
|
|
Key = "alfredlight", Name = "Frost",
|
|
PreviewBackground = "#FFFFFF", PreviewText = "#1A1A2E",
|
|
PreviewSubText = "#9090AA", PreviewAccent = "#5555EE",
|
|
PreviewItem = "#E8E9FF", PreviewBorder = "#DCDCEE"
|
|
},
|
|
new()
|
|
{
|
|
Key = "codex", Name = "Codex",
|
|
PreviewBackground = "#FFFFFF", PreviewText = "#111111",
|
|
PreviewSubText = "#6B7280", PreviewAccent = "#7C3AED",
|
|
PreviewItem = "#F5F5F7", PreviewBorder = "#E5E7EB"
|
|
},
|
|
new()
|
|
{
|
|
Key = "custom", Name = "커스텀",
|
|
PreviewBackground = "#1A1B2E", PreviewText = "#F0F0FF",
|
|
PreviewSubText = "#7A7D9C", PreviewAccent = "#4B5EFC",
|
|
PreviewItem = "#252637", PreviewBorder = "#2E2F4A"
|
|
},
|
|
};
|
|
|
|
// ─── 커스텀 색상 행 목록 ──────────────────────────────────────────────
|
|
public List<ColorRowModel> ColorRows { get; }
|
|
|
|
// ─── 프롬프트 템플릿 ──────────────────────────────────────────────────
|
|
public ObservableCollection<PromptTemplateRow> PromptTemplates { get; } = new();
|
|
|
|
// ─── 배치 명령 ────────────────────────────────────────────────────────
|
|
public ObservableCollection<BatchCommandModel> BatchCommands { get; } = new();
|
|
|
|
private string _newBatchKey = "";
|
|
private string _newBatchCommand = "";
|
|
private bool _newBatchShowWindow;
|
|
|
|
public string NewBatchKey
|
|
{
|
|
get => _newBatchKey;
|
|
set { _newBatchKey = value; OnPropertyChanged(); }
|
|
}
|
|
public string NewBatchCommand
|
|
{
|
|
get => _newBatchCommand;
|
|
set { _newBatchCommand = value; OnPropertyChanged(); }
|
|
}
|
|
public bool NewBatchShowWindow
|
|
{
|
|
get => _newBatchShowWindow;
|
|
set { _newBatchShowWindow = value; OnPropertyChanged(); }
|
|
}
|
|
|
|
// ─── 빠른 실행 단축키 ─────────────────────────────────────────────────
|
|
public ObservableCollection<AppShortcutModel> AppShortcuts { get; } = new();
|
|
|
|
private string _newKey = "";
|
|
private string _newDescription = "";
|
|
private string _newTarget = "";
|
|
private string _newType = "app";
|
|
|
|
public string NewKey { get => _newKey; set { _newKey = value; OnPropertyChanged(); } }
|
|
public string NewDescription { get => _newDescription; set { _newDescription = value; OnPropertyChanged(); } }
|
|
public string NewTarget { get => _newTarget; set { _newTarget = value; OnPropertyChanged(); } }
|
|
public string NewType { get => _newType; set { _newType = value; OnPropertyChanged(); } }
|
|
|
|
// ─── 커스텀 테마 모서리 라운딩 ───────────────────────────────────────────
|
|
private int _customWindowCornerRadius = 20;
|
|
private int _customItemCornerRadius = 10;
|
|
|
|
public int CustomWindowCornerRadius
|
|
{
|
|
get => _customWindowCornerRadius;
|
|
set { _customWindowCornerRadius = Math.Clamp(value, 0, 30); OnPropertyChanged(); }
|
|
}
|
|
|
|
public int CustomItemCornerRadius
|
|
{
|
|
get => _customItemCornerRadius;
|
|
set { _customItemCornerRadius = Math.Clamp(value, 0, 20); OnPropertyChanged(); }
|
|
}
|
|
|
|
// ─── 인덱스 경로 ──────────────────────────────────────────────────────
|
|
public ObservableCollection<string> IndexPaths { get; } = new();
|
|
|
|
// ─── 인덱스 확장자 ──────────────────────────────────────────────────
|
|
public ObservableCollection<string> IndexExtensions { get; } = new();
|
|
|
|
// ─── 전용 핫키 설정 ─────────────────────────────────────────────────────────
|
|
public ObservableCollection<HotkeyRowModel> CustomHotkeys { get; } = new();
|
|
|
|
private string _newHotkeyStr = "";
|
|
private string _newHotkeyTarget = "";
|
|
private string _newHotkeyLabel = "";
|
|
private string _newHotkeyType = "app";
|
|
|
|
public string NewHotkeyStr { get => _newHotkeyStr; set { _newHotkeyStr = value; OnPropertyChanged(); } }
|
|
public string NewHotkeyTarget { get => _newHotkeyTarget; set { _newHotkeyTarget = value; OnPropertyChanged(); } }
|
|
public string NewHotkeyLabel { get => _newHotkeyLabel; set { _newHotkeyLabel = value; OnPropertyChanged(); } }
|
|
public string NewHotkeyType { get => _newHotkeyType; set { _newHotkeyType = value; OnPropertyChanged(); } }
|
|
|
|
// ─── 스니펫 설정 ──────────────────────────────────────────────────────────
|
|
public ObservableCollection<SnippetRowModel> Snippets { get; } = new();
|
|
|
|
private string _newSnippetKey = "";
|
|
private string _newSnippetName = "";
|
|
private string _newSnippetContent = "";
|
|
|
|
public string NewSnippetKey { get => _newSnippetKey; set { _newSnippetKey = value; OnPropertyChanged(); } }
|
|
public string NewSnippetName { get => _newSnippetName; set { _newSnippetName = value; OnPropertyChanged(); } }
|
|
public string NewSnippetContent { get => _newSnippetContent; set { _newSnippetContent = value; OnPropertyChanged(); } }
|
|
|
|
// ─── 클립보드 히스토리 설정 ────────────────────────────────────────────────
|
|
private bool _clipboardEnabled;
|
|
private int _clipboardMaxItems;
|
|
|
|
public bool ClipboardEnabled
|
|
{
|
|
get => _clipboardEnabled;
|
|
set { _clipboardEnabled = value; OnPropertyChanged(); }
|
|
}
|
|
|
|
public int ClipboardMaxItems
|
|
{
|
|
get => _clipboardMaxItems;
|
|
set { _clipboardMaxItems = value; OnPropertyChanged(); }
|
|
}
|
|
|
|
// ─── 스크린 캡처 설정 ──────────────────────────────────────────────────────
|
|
private string _capPrefix = "cap";
|
|
private bool _capGlobalHotkeyEnabled;
|
|
private string _capGlobalHotkey = "PrintScreen";
|
|
private string _capGlobalMode = "screen";
|
|
private int _capScrollDelayMs = 120;
|
|
|
|
public string CapPrefix
|
|
{
|
|
get => _capPrefix;
|
|
set { _capPrefix = value; OnPropertyChanged(); }
|
|
}
|
|
|
|
public bool CapGlobalHotkeyEnabled
|
|
{
|
|
get => _capGlobalHotkeyEnabled;
|
|
set { _capGlobalHotkeyEnabled = value; OnPropertyChanged(); }
|
|
}
|
|
|
|
public string CapGlobalHotkey
|
|
{
|
|
get => _capGlobalHotkey;
|
|
set { _capGlobalHotkey = value; OnPropertyChanged(); }
|
|
}
|
|
|
|
public string CapGlobalMode
|
|
{
|
|
get => _capGlobalMode;
|
|
set { _capGlobalMode = value; OnPropertyChanged(); }
|
|
}
|
|
|
|
public int CapScrollDelayMs
|
|
{
|
|
get => _capScrollDelayMs;
|
|
set { _capScrollDelayMs = value; OnPropertyChanged(); OnPropertyChanged(nameof(CapScrollDelayMsStr)); }
|
|
}
|
|
|
|
/// <summary>ComboBox SelectedValue와 string 바인딩 용도</summary>
|
|
public string CapScrollDelayMsStr
|
|
{
|
|
get => _capScrollDelayMs.ToString();
|
|
set { if (int.TryParse(value, out int v)) CapScrollDelayMs = v; }
|
|
}
|
|
|
|
// ─── 잠금 해제 알림 설정 ──────────────────────────────────────────────────
|
|
private bool _reminderEnabled;
|
|
private string _reminderCorner = "bottom-right";
|
|
private int _reminderIntervalMinutes = 60;
|
|
private int _reminderDisplaySeconds = 15;
|
|
|
|
public bool ReminderEnabled
|
|
{
|
|
get => _reminderEnabled;
|
|
set { _reminderEnabled = value; OnPropertyChanged(); }
|
|
}
|
|
|
|
public string ReminderCorner
|
|
{
|
|
get => _reminderCorner;
|
|
set { _reminderCorner = value; OnPropertyChanged(); }
|
|
}
|
|
|
|
public int ReminderIntervalMinutes
|
|
{
|
|
get => _reminderIntervalMinutes;
|
|
set { _reminderIntervalMinutes = value; OnPropertyChanged(); }
|
|
}
|
|
|
|
public int ReminderDisplaySeconds
|
|
{
|
|
get => _reminderDisplaySeconds;
|
|
set { _reminderDisplaySeconds = value; OnPropertyChanged(); }
|
|
}
|
|
|
|
// ─── 시스템 명령 설정 ──────────────────────────────────────────────────────
|
|
private bool _sysShowLock;
|
|
private bool _sysShowSleep;
|
|
private bool _sysShowRestart;
|
|
private bool _sysShowShutdown;
|
|
private bool _sysShowHibernate;
|
|
private bool _sysShowLogout;
|
|
private bool _sysShowRecycleBin;
|
|
|
|
public bool SysShowLock { get => _sysShowLock; set { _sysShowLock = value; OnPropertyChanged(); } }
|
|
public bool SysShowSleep { get => _sysShowSleep; set { _sysShowSleep = value; OnPropertyChanged(); } }
|
|
public bool SysShowRestart { get => _sysShowRestart; set { _sysShowRestart = value; OnPropertyChanged(); } }
|
|
public bool SysShowShutdown { get => _sysShowShutdown; set { _sysShowShutdown = value; OnPropertyChanged(); } }
|
|
public bool SysShowHibernate { get => _sysShowHibernate; set { _sysShowHibernate = value; OnPropertyChanged(); } }
|
|
public bool SysShowLogout { get => _sysShowLogout; set { _sysShowLogout = value; OnPropertyChanged(); } }
|
|
public bool SysShowRecycleBin { get => _sysShowRecycleBin; set { _sysShowRecycleBin = value; OnPropertyChanged(); } }
|
|
|
|
// ─── 시스템 명령 별칭 (쉼표 구분 문자열) ───────────────────────────────────
|
|
private string _aliasLock = "";
|
|
private string _aliasSleep = "";
|
|
private string _aliasRestart = "";
|
|
private string _aliasShutdown = "";
|
|
private string _aliasHibernate = "";
|
|
private string _aliasLogout = "";
|
|
private string _aliasRecycle = "";
|
|
|
|
public string AliasLock { get => _aliasLock; set { _aliasLock = value; OnPropertyChanged(); } }
|
|
public string AliasSleep { get => _aliasSleep; set { _aliasSleep = value; OnPropertyChanged(); } }
|
|
public string AliasRestart { get => _aliasRestart; set { _aliasRestart = value; OnPropertyChanged(); } }
|
|
public string AliasShutdown { get => _aliasShutdown; set { _aliasShutdown = value; OnPropertyChanged(); } }
|
|
public string AliasHibernate { get => _aliasHibernate; set { _aliasHibernate = value; OnPropertyChanged(); } }
|
|
public string AliasLogout { get => _aliasLogout; set { _aliasLogout = value; OnPropertyChanged(); } }
|
|
public string AliasRecycle { get => _aliasRecycle; set { _aliasRecycle = value; OnPropertyChanged(); } }
|
|
}
|