using System.Windows; using System.Windows.Controls; using System.Windows.Input; using System.Windows.Media; using AxCopilot.Services; using AxCopilot.ViewModels; namespace AxCopilot.Views; public partial class SettingsWindow { // ─── AI 기능 활성화 토글 + 네트워크 모드 ──────────────────────────────────── /// AI 기능 토글 상태를 UI와 설정에 반영합니다. private void ApplyAiEnabledState(bool enabled, bool init = false) { // 토글 스위치 체크 상태 동기화 (init 시에는 이벤트 억제) if (AiEnabledToggle != null && AiEnabledToggle.IsChecked != enabled) { AiEnabledToggle.IsChecked = enabled; } // AgentTabItem은 항상 숨김 — 설정은 ChatWindow 내 AgentSettingsPanel에서 if (AgentTabItem != null) AgentTabItem.Visibility = Visibility.Collapsed; // 고급 에이전트 탭: AI 활성화 여부에 따라 표시 if (AdvancedAgentTabItem != null) AdvancedAgentTabItem.Visibility = enabled ? Visibility.Visible : Visibility.Collapsed; } private void AiEnabled_Changed(object sender, RoutedEventArgs e) { if (!IsLoaded) return; var tryEnable = AiEnabledToggle?.IsChecked == true; // 비활성화는 즉시 적용 (비밀번호 불필요) if (!tryEnable) { var app2 = CurrentApp; if (app2?.SettingsService?.Settings != null) { app2.SettingsService.Settings.AiEnabled = false; app2.SettingsService.Save(); } ApplyAiEnabledState(false); return; } // 이미 활성화된 상태에서 설정 창이 열릴 때 토글 복원으로 인한 이벤트 → 비밀번호 불필요 var currentApp = CurrentApp; if (currentApp?.SettingsService?.Settings.AiEnabled == true) return; // 새로 활성화하는 경우에만 비밀번호 확인 var bgBrush = TryFindResource("LauncherBackground") as Brush ?? new SolidColorBrush(Color.FromRgb(0x1E, 0x1E, 0x2E)); var fgBrush = TryFindResource("PrimaryText") as Brush ?? Brushes.White; var subFgBrush = TryFindResource("SecondaryText") as Brush ?? Brushes.Gray; var borderBrush = TryFindResource("BorderColor") as Brush ?? new SolidColorBrush(Color.FromRgb(0x40, 0x40, 0x60)); var itemBg = TryFindResource("ItemBackground") as Brush ?? new SolidColorBrush(Color.FromRgb(0x2A, 0x2A, 0x40)); var dlg = new Window { Title = "AI 기능 활성화 — 비밀번호 확인", Width = 340, SizeToContent = SizeToContent.Height, WindowStartupLocation = WindowStartupLocation.CenterOwner, Owner = this, ResizeMode = ResizeMode.NoResize, WindowStyle = WindowStyle.None, AllowsTransparency = true, Background = Brushes.Transparent, }; var border = new Border { Background = bgBrush, CornerRadius = new CornerRadius(12), BorderBrush = borderBrush, BorderThickness = new Thickness(1), Padding = new Thickness(20), }; var stack = new StackPanel(); stack.Children.Add(new TextBlock { Text = "\U0001f512 AI 기능 활성화", FontSize = 15, FontWeight = FontWeights.SemiBold, Foreground = fgBrush, Margin = new Thickness(0, 0, 0, 12), }); stack.Children.Add(new TextBlock { Text = "비밀번호를 입력하세요:", FontSize = 12, Foreground = subFgBrush, Margin = new Thickness(0, 0, 0, 6), }); var pwBox = new PasswordBox { FontSize = 14, Padding = new Thickness(8, 6, 8, 6), Background = itemBg, Foreground = fgBrush, BorderBrush = borderBrush, PasswordChar = '*', }; stack.Children.Add(pwBox); var btnRow = new StackPanel { Orientation = Orientation.Horizontal, HorizontalAlignment = HorizontalAlignment.Right, Margin = new Thickness(0, 16, 0, 0) }; var cancelBtn = new Button { Content = "취소", Padding = new Thickness(16, 6, 16, 6), Margin = new Thickness(0, 0, 8, 0) }; cancelBtn.Click += (_, _) => { dlg.DialogResult = false; }; btnRow.Children.Add(cancelBtn); var okBtn = new Button { Content = "확인", Padding = new Thickness(16, 6, 16, 6), IsDefault = true }; okBtn.Click += (_, _) => { if (pwBox.Password == SettingsPassword) dlg.DialogResult = true; else { pwBox.Clear(); pwBox.Focus(); } }; btnRow.Children.Add(okBtn); stack.Children.Add(btnRow); border.Child = stack; dlg.Content = border; dlg.Loaded += (_, _) => pwBox.Focus(); if (dlg.ShowDialog() == true) { var app = CurrentApp; if (app?.SettingsService?.Settings != null) { app.SettingsService.Settings.AiEnabled = true; app.SettingsService.Save(); } ApplyAiEnabledState(true); } else { // 취소/실패 — 토글 원상복구 if (AiEnabledToggle != null) AiEnabledToggle.IsChecked = false; } } // ─── 사내/사외 모드 토글 ───────────────────────────────────────────────────── private const string SettingsPassword = "axgo123!"; private void NetworkMode_Changed(object sender, RoutedEventArgs e) { if (!IsLoaded) return; var tryInternalMode = InternalModeToggle?.IsChecked == true; // true = 사내(차단), false = 사외(허용) // 사내 모드로 전환(차단 강화)은 비밀번호 불필요 if (tryInternalMode) { var app2 = CurrentApp; if (app2?.SettingsService?.Settings != null) { app2.SettingsService.Settings.InternalModeEnabled = true; app2.SettingsService.Save(); } return; } // 이미 사외 모드인 경우 토글 복원으로 인한 이벤트 → 비밀번호 불필요 var currentApp = CurrentApp; if (currentApp?.SettingsService?.Settings.InternalModeEnabled == false) return; // 사외 모드 활성화(외부 허용)는 비밀번호 확인 필요 var bgBrush = TryFindResource("LauncherBackground") as Brush ?? new SolidColorBrush(Color.FromRgb(0x1E, 0x1E, 0x2E)); var fgBrush = TryFindResource("PrimaryText") as Brush ?? Brushes.White; var subFgBrush = TryFindResource("SecondaryText") as Brush ?? Brushes.Gray; var borderBrush = TryFindResource("BorderColor") as Brush ?? new SolidColorBrush(Color.FromRgb(0x40, 0x40, 0x60)); var itemBg = TryFindResource("ItemBackground") as Brush ?? new SolidColorBrush(Color.FromRgb(0x2A, 0x2A, 0x40)); var dlg = new Window { Title = "사외 모드 활성화 — 비밀번호 확인", Width = 340, SizeToContent = SizeToContent.Height, WindowStartupLocation = WindowStartupLocation.CenterOwner, Owner = this, ResizeMode = ResizeMode.NoResize, WindowStyle = WindowStyle.None, AllowsTransparency = true, Background = Brushes.Transparent, }; var border = new Border { Background = bgBrush, CornerRadius = new CornerRadius(12), BorderBrush = borderBrush, BorderThickness = new Thickness(1), Padding = new Thickness(20), }; var stack = new StackPanel(); stack.Children.Add(new TextBlock { Text = "🌐 사외 모드 활성화", FontSize = 15, FontWeight = FontWeights.SemiBold, Foreground = fgBrush, Margin = new Thickness(0, 0, 0, 8), }); stack.Children.Add(new TextBlock { Text = "사외 모드에서는 인터넷 검색과 외부 HTTP 접속이 허용됩니다.\n비밀번호를 입력하세요:", FontSize = 12, Foreground = subFgBrush, Margin = new Thickness(0, 0, 0, 10), TextWrapping = TextWrapping.Wrap, }); var pwBox = new PasswordBox { FontSize = 14, Padding = new Thickness(8, 6, 8, 6), Background = itemBg, Foreground = fgBrush, BorderBrush = borderBrush, PasswordChar = '*', }; stack.Children.Add(pwBox); var btnRow = new StackPanel { Orientation = Orientation.Horizontal, HorizontalAlignment = HorizontalAlignment.Right, Margin = new Thickness(0, 16, 0, 0) }; var cancelBtn = new Button { Content = "취소", Padding = new Thickness(16, 6, 16, 6), Margin = new Thickness(0, 0, 8, 0) }; cancelBtn.Click += (_, _) => { dlg.DialogResult = false; }; btnRow.Children.Add(cancelBtn); var okBtn = new Button { Content = "확인", Padding = new Thickness(16, 6, 16, 6), IsDefault = true }; okBtn.Click += (_, _) => { if (pwBox.Password == SettingsPassword) dlg.DialogResult = true; else { pwBox.Clear(); pwBox.Focus(); } }; btnRow.Children.Add(okBtn); stack.Children.Add(btnRow); border.Child = stack; dlg.Content = border; dlg.Loaded += (_, _) => pwBox.Focus(); if (dlg.ShowDialog() == true) { var app = CurrentApp; if (app?.SettingsService?.Settings != null) { app.SettingsService.Settings.InternalModeEnabled = false; app.SettingsService.Save(); } } else { // 취소/실패 — 토글 원상복구 (사내 모드 유지) if (InternalModeToggle != null) InternalModeToggle.IsChecked = true; } } private void StepApprovalCheckBox_Checked(object sender, RoutedEventArgs e) { if (sender is not CheckBox cb || !cb.IsChecked.GetValueOrDefault()) return; // 설정 창 로드 중 바인딩에 의한 자동 Checked 이벤트 무시 (이미 활성화된 상태 복원) if (!IsLoaded) return; // 테마 리소스 조회 var bgBrush = TryFindResource("LauncherBackground") as Brush ?? new SolidColorBrush(Color.FromRgb(0x1E, 0x1E, 0x2E)); var fgBrush = TryFindResource("PrimaryText") as Brush ?? Brushes.White; var subFgBrush = TryFindResource("SecondaryText") as Brush ?? Brushes.Gray; var borderBrush = TryFindResource("BorderColor") as Brush ?? new SolidColorBrush(Color.FromRgb(0x40, 0x40, 0x60)); var itemBg = TryFindResource("ItemBackground") as Brush ?? new SolidColorBrush(Color.FromRgb(0x2A, 0x2A, 0x40)); var dlg = new Window { Title = "스텝 바이 스텝 승인 — 비밀번호 확인", Width = 340, SizeToContent = SizeToContent.Height, WindowStartupLocation = WindowStartupLocation.CenterOwner, Owner = this, ResizeMode = ResizeMode.NoResize, WindowStyle = WindowStyle.None, AllowsTransparency = true, Background = Brushes.Transparent, }; var border = new Border { Background = bgBrush, CornerRadius = new CornerRadius(12), BorderBrush = borderBrush, BorderThickness = new Thickness(1), Padding = new Thickness(20), }; var stack = new StackPanel(); stack.Children.Add(new TextBlock { Text = "\U0001f50d 스텝 바이 스텝 승인 활성화", FontSize = 15, FontWeight = FontWeights.SemiBold, Foreground = fgBrush, Margin = new Thickness(0, 0, 0, 12), }); stack.Children.Add(new TextBlock { Text = "개발자 비밀번호를 입력하세요:", FontSize = 12, Foreground = subFgBrush, Margin = new Thickness(0, 0, 0, 6), }); var pwBox = new PasswordBox { FontSize = 14, Padding = new Thickness(8, 6, 8, 6), Background = itemBg, Foreground = fgBrush, BorderBrush = borderBrush, PasswordChar = '*', }; stack.Children.Add(pwBox); var btnRow = new StackPanel { Orientation = Orientation.Horizontal, HorizontalAlignment = HorizontalAlignment.Right, Margin = new Thickness(0, 16, 0, 0) }; var cancelBtn = new Button { Content = "취소", Padding = new Thickness(16, 6, 16, 6), Margin = new Thickness(0, 0, 8, 0) }; cancelBtn.Click += (_, _) => { dlg.DialogResult = false; }; btnRow.Children.Add(cancelBtn); var okBtn = new Button { Content = "확인", Padding = new Thickness(16, 6, 16, 6), IsDefault = true }; okBtn.Click += (_, _) => { if (pwBox.Password == "mouse12#") dlg.DialogResult = true; else { pwBox.Clear(); pwBox.Focus(); } }; btnRow.Children.Add(okBtn); stack.Children.Add(btnRow); border.Child = stack; dlg.Content = border; dlg.Loaded += (_, _) => pwBox.Focus(); if (dlg.ShowDialog() != true) { cb.IsChecked = false; } } private void BtnClearMemory_Click(object sender, RoutedEventArgs e) { var result = CustomMessageBox.Show( "에이전트 메모리를 초기화하면 학습된 모든 규칙과 선호도가 삭제됩니다.\n계속하시겠습니까?", "에이전트 메모리 초기화", MessageBoxButton.YesNo, MessageBoxImage.Warning); if (result != MessageBoxResult.Yes) return; var app = CurrentApp; app?.MemoryService?.Clear(); CustomMessageBox.Show("에이전트 메모리가 초기화되었습니다.", "완료", MessageBoxButton.OK, MessageBoxImage.Information); } }