Initial commit to new repository
This commit is contained in:
943
.decompiledproj/AxCopilot/App.cs
Normal file
943
.decompiledproj/AxCopilot/App.cs
Normal file
@@ -0,0 +1,943 @@
|
||||
using System;
|
||||
using System.CodeDom.Compiler;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Drawing;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Forms;
|
||||
using System.Windows.Threading;
|
||||
using AxCopilot.Core;
|
||||
using AxCopilot.Handlers;
|
||||
using AxCopilot.Models;
|
||||
using AxCopilot.Security;
|
||||
using AxCopilot.Services;
|
||||
using AxCopilot.ViewModels;
|
||||
using AxCopilot.Views;
|
||||
using Microsoft.Win32;
|
||||
|
||||
namespace AxCopilot;
|
||||
|
||||
public class App : System.Windows.Application
|
||||
{
|
||||
private static class NativeMethods
|
||||
{
|
||||
public struct INPUT
|
||||
{
|
||||
public uint type;
|
||||
|
||||
public InputUnion u;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Explicit)]
|
||||
public struct InputUnion
|
||||
{
|
||||
[FieldOffset(0)]
|
||||
public KEYBDINPUT ki;
|
||||
}
|
||||
|
||||
public struct KEYBDINPUT
|
||||
{
|
||||
public ushort wVk;
|
||||
|
||||
public ushort wScan;
|
||||
|
||||
public uint dwFlags;
|
||||
|
||||
public uint time;
|
||||
|
||||
public nint dwExtraInfo;
|
||||
}
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
public static extern uint SendInput(uint nInputs, INPUT[] pInputs, int cbSize);
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
[CompilerGenerated]
|
||||
private sealed class _003C_003Ec
|
||||
{
|
||||
public static readonly _003C_003Ec _003C_003E9 = new _003C_003Ec();
|
||||
|
||||
public static DispatcherUnhandledExceptionEventHandler _003C_003E9__24_0;
|
||||
|
||||
public static Action _003C_003E9__31_10;
|
||||
|
||||
public static Action _003C_003E9__31_17;
|
||||
|
||||
public static Action _003C_003E9__31_18;
|
||||
|
||||
public static Action<bool> _003C_003E9__31_13;
|
||||
|
||||
public static Action _003C_003E9__31_19;
|
||||
|
||||
internal void _003COnStartup_003Eb__24_0(object _, DispatcherUnhandledExceptionEventArgs ex)
|
||||
{
|
||||
LogService.Error($"미처리 예외: {ex.Exception}");
|
||||
CustomMessageBox.Show("오류가 발생했습니다:\n" + ex.Exception.Message + "\n\n로그 폴더를 확인하세요.", "AX Copilot 오류", MessageBoxButton.OK, MessageBoxImage.Hand);
|
||||
ex.Handled = true;
|
||||
}
|
||||
|
||||
internal void _003CSetupTrayIcon_003Eb__31_10()
|
||||
{
|
||||
string arguments = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "AxCopilot", "logs");
|
||||
Process.Start(new ProcessStartInfo("explorer.exe", arguments)
|
||||
{
|
||||
UseShellExecute = true
|
||||
});
|
||||
}
|
||||
|
||||
internal void _003CSetupTrayIcon_003Eb__31_17()
|
||||
{
|
||||
new StatisticsWindow().Show();
|
||||
}
|
||||
|
||||
internal void _003CSetupTrayIcon_003Eb__31_18()
|
||||
{
|
||||
new GuideViewerWindow().Show();
|
||||
}
|
||||
|
||||
internal void _003CSetupTrayIcon_003Eb__31_13(bool isChecked)
|
||||
{
|
||||
SetAutoStart(isChecked);
|
||||
}
|
||||
|
||||
internal void _003CSetupTrayIcon_003Eb__31_19()
|
||||
{
|
||||
new AboutWindow().Show();
|
||||
}
|
||||
}
|
||||
|
||||
private Mutex? _singleInstanceMutex;
|
||||
|
||||
private InputListener? _inputListener;
|
||||
|
||||
private LauncherWindow? _launcher;
|
||||
|
||||
private NotifyIcon? _trayIcon;
|
||||
|
||||
private TrayMenuWindow? _trayMenu;
|
||||
|
||||
private SettingsService? _settings;
|
||||
|
||||
private SettingsWindow? _settingsWindow;
|
||||
|
||||
private PluginHost? _pluginHost;
|
||||
|
||||
private ClipboardHistoryService? _clipboardHistory;
|
||||
|
||||
private DockBarWindow? _dockBar;
|
||||
|
||||
private FileDialogWatcher? _fileDialogWatcher;
|
||||
|
||||
private volatile IndexService? _indexService;
|
||||
|
||||
private SessionTrackingService? _sessionTracking;
|
||||
|
||||
private WorktimeReminderService? _worktimeReminder;
|
||||
|
||||
private ScreenCaptureHandler? _captureHandler;
|
||||
|
||||
private AgentMemoryService? _memoryService;
|
||||
|
||||
private ChatWindow? _chatWindow;
|
||||
|
||||
private const string AutoRunKey = "Software\\Microsoft\\Windows\\CurrentVersion\\Run";
|
||||
|
||||
private const string AutoRunName = "AxCopilot";
|
||||
|
||||
private bool _contentLoaded;
|
||||
|
||||
public IndexService? IndexService => _indexService;
|
||||
|
||||
public SettingsService? SettingsService => _settings;
|
||||
|
||||
public ClipboardHistoryService? ClipboardHistoryService => _clipboardHistory;
|
||||
|
||||
public AgentMemoryService? MemoryService => _memoryService;
|
||||
|
||||
protected override void OnStartup(StartupEventArgs e)
|
||||
{
|
||||
//IL_0031: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_0036: Unknown result type (might be due to invalid IL or missing references)
|
||||
//IL_003c: Expected O, but got Unknown
|
||||
base.OnStartup(e);
|
||||
AntiTamper.Check();
|
||||
object obj = _003C_003Ec._003C_003E9__24_0;
|
||||
if (obj == null)
|
||||
{
|
||||
DispatcherUnhandledExceptionEventHandler val = delegate(object _, DispatcherUnhandledExceptionEventArgs ex)
|
||||
{
|
||||
LogService.Error($"미처리 예외: {ex.Exception}");
|
||||
CustomMessageBox.Show("오류가 발생했습니다:\n" + ex.Exception.Message + "\n\n로그 폴더를 확인하세요.", "AX Copilot 오류", MessageBoxButton.OK, MessageBoxImage.Hand);
|
||||
ex.Handled = true;
|
||||
};
|
||||
_003C_003Ec._003C_003E9__24_0 = val;
|
||||
obj = (object)val;
|
||||
}
|
||||
base.DispatcherUnhandledException += (DispatcherUnhandledExceptionEventHandler)obj;
|
||||
_singleInstanceMutex = new Mutex(initiallyOwned: true, "Global\\AXCopilot_SingleInstance", out var createdNew);
|
||||
if (!createdNew)
|
||||
{
|
||||
_singleInstanceMutex.Dispose();
|
||||
_singleInstanceMutex = null;
|
||||
CustomMessageBox.Show("AX Copilot가 이미 실행 중입니다.\n트레이 아이콘을 확인하세요.", "AX Copilot", MessageBoxButton.OK, MessageBoxImage.Asterisk);
|
||||
Shutdown();
|
||||
return;
|
||||
}
|
||||
LogService.Info("=== AX Copilot 시작 ===");
|
||||
_settings = new SettingsService();
|
||||
SettingsService settings = _settings;
|
||||
settings.Load();
|
||||
if (settings.MigrationSummary != null)
|
||||
{
|
||||
((DispatcherObject)this).Dispatcher.BeginInvoke((Delegate)(Action)delegate
|
||||
{
|
||||
CustomMessageBox.Show(settings.MigrationSummary, "AX Copilot — 설정 업데이트", MessageBoxButton.OK, MessageBoxImage.Asterisk);
|
||||
}, (DispatcherPriority)6, Array.Empty<object>());
|
||||
}
|
||||
L10n.SetLanguage(settings.Settings.Launcher.Language);
|
||||
if (!IsAutoStartEnabled())
|
||||
{
|
||||
SetAutoStart(enable: true);
|
||||
}
|
||||
_memoryService = new AgentMemoryService();
|
||||
_memoryService.Load(settings.Settings.Llm.WorkFolder);
|
||||
_indexService = new IndexService(settings);
|
||||
IndexService indexService = _indexService;
|
||||
FuzzyEngine fuzzy = new FuzzyEngine(indexService);
|
||||
CommandResolver commandResolver = new CommandResolver(fuzzy, settings);
|
||||
ContextManager context = new ContextManager(settings);
|
||||
_sessionTracking = new SessionTrackingService();
|
||||
_worktimeReminder = new WorktimeReminderService(settings, ((DispatcherObject)this).Dispatcher);
|
||||
_clipboardHistory = new ClipboardHistoryService(settings);
|
||||
commandResolver.RegisterHandler(new CalculatorHandler());
|
||||
commandResolver.RegisterHandler(new SystemCommandHandler(settings));
|
||||
commandResolver.RegisterHandler(new SnippetHandler(settings));
|
||||
commandResolver.RegisterHandler(new ClipboardHistoryHandler(_clipboardHistory));
|
||||
commandResolver.RegisterHandler(new WorkspaceHandler(context, settings));
|
||||
commandResolver.RegisterHandler(new UrlAliasHandler(settings));
|
||||
commandResolver.RegisterHandler(new FolderAliasHandler(settings));
|
||||
commandResolver.RegisterHandler(new BatchHandler(settings));
|
||||
commandResolver.RegisterHandler(new ClipboardHandler(settings));
|
||||
commandResolver.RegisterHandler(new BookmarkHandler());
|
||||
commandResolver.RegisterHandler(new WebSearchHandler(settings));
|
||||
commandResolver.RegisterHandler(new ProcessHandler());
|
||||
commandResolver.RegisterHandler(new MediaHandler());
|
||||
commandResolver.RegisterHandler(new SystemInfoHandler());
|
||||
commandResolver.RegisterHandler(new StarInfoHandler());
|
||||
commandResolver.RegisterHandler(new EmojiHandler());
|
||||
commandResolver.RegisterHandler(new ColorHandler());
|
||||
commandResolver.RegisterHandler(new RecentFilesHandler());
|
||||
commandResolver.RegisterHandler(new NoteHandler());
|
||||
commandResolver.RegisterHandler(new UninstallHandler());
|
||||
commandResolver.RegisterHandler(new PortHandler());
|
||||
commandResolver.RegisterHandler(new EnvHandler());
|
||||
commandResolver.RegisterHandler(new JsonHandler());
|
||||
commandResolver.RegisterHandler(new EncodeHandler());
|
||||
commandResolver.RegisterHandler(new SnapHandler());
|
||||
_captureHandler = new ScreenCaptureHandler(settings);
|
||||
commandResolver.RegisterHandler(_captureHandler);
|
||||
commandResolver.RegisterHandler(new ColorPickHandler());
|
||||
commandResolver.RegisterHandler(new DateCalcHandler());
|
||||
commandResolver.RegisterHandler(new ServiceHandler(_clipboardHistory));
|
||||
commandResolver.RegisterHandler(new ClipboardPipeHandler());
|
||||
commandResolver.RegisterHandler(new JournalHandler());
|
||||
commandResolver.RegisterHandler(new RoutineHandler());
|
||||
commandResolver.RegisterHandler(new BatchTextHandler());
|
||||
commandResolver.RegisterHandler(new DiffHandler(_clipboardHistory));
|
||||
commandResolver.RegisterHandler(new WindowSwitchHandler());
|
||||
commandResolver.RegisterHandler(new RunHandler());
|
||||
commandResolver.RegisterHandler(new TextStatsHandler());
|
||||
commandResolver.RegisterHandler(new FavoriteHandler());
|
||||
commandResolver.RegisterHandler(new RenameHandler());
|
||||
commandResolver.RegisterHandler(new MonitorHandler());
|
||||
commandResolver.RegisterHandler(new ScaffoldHandler());
|
||||
commandResolver.RegisterHandler(new EverythingHandler());
|
||||
commandResolver.RegisterHandler(new HelpHandler(settings));
|
||||
commandResolver.RegisterHandler(new ChatHandler(settings));
|
||||
PluginHost pluginHost = new PluginHost(settings, commandResolver);
|
||||
pluginHost.LoadAll();
|
||||
_pluginHost = pluginHost;
|
||||
LauncherViewModel vm = new LauncherViewModel(commandResolver, settings);
|
||||
_launcher = new LauncherWindow(vm)
|
||||
{
|
||||
OpenSettingsAction = OpenSettings
|
||||
};
|
||||
((DispatcherObject)this).Dispatcher.BeginInvoke((Delegate)(Action)delegate
|
||||
{
|
||||
_clipboardHistory?.Initialize();
|
||||
}, (DispatcherPriority)2, Array.Empty<object>());
|
||||
((DispatcherObject)this).Dispatcher.BeginInvoke((Delegate)(Action)delegate
|
||||
{
|
||||
PrewarmChatWindow();
|
||||
}, (DispatcherPriority)1, Array.Empty<object>());
|
||||
indexService.BuildAsync().ContinueWith(delegate
|
||||
{
|
||||
indexService.StartWatchers();
|
||||
});
|
||||
_inputListener = new InputListener();
|
||||
_inputListener.HotkeyTriggered += OnHotkeyTriggered;
|
||||
_inputListener.CaptureHotkeyTriggered += OnCaptureHotkeyTriggered;
|
||||
_inputListener.HookFailed += OnHookFailed;
|
||||
_inputListener.UpdateHotkey(settings.Settings.Hotkey);
|
||||
_inputListener.UpdateCaptureHotkey(settings.Settings.ScreenCapture.GlobalHotkey, settings.Settings.ScreenCapture.GlobalHotkeyEnabled);
|
||||
SnippetExpander snippetExpander = new SnippetExpander(settings);
|
||||
_inputListener.KeyFilter = snippetExpander.HandleKey;
|
||||
_inputListener.Start();
|
||||
SetupTrayIcon(pluginHost, settings);
|
||||
_fileDialogWatcher = new FileDialogWatcher();
|
||||
_fileDialogWatcher.FileDialogOpened += delegate
|
||||
{
|
||||
((DispatcherObject)this).Dispatcher.Invoke((Action)delegate
|
||||
{
|
||||
if (_launcher != null && !_launcher.IsVisible)
|
||||
{
|
||||
SettingsService? settings2 = _settings;
|
||||
if (settings2 != null && settings2.Settings.Launcher.EnableFileDialogIntegration)
|
||||
{
|
||||
WindowTracker.Capture();
|
||||
_launcher.Show();
|
||||
((DispatcherObject)this).Dispatcher.BeginInvoke((DispatcherPriority)5, (Delegate)(Action)delegate
|
||||
{
|
||||
_launcher.SetInputText("cd ");
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
_fileDialogWatcher.Start();
|
||||
if (settings.Settings.Launcher.DockBarAutoShow)
|
||||
{
|
||||
((DispatcherObject)this).Dispatcher.BeginInvoke((DispatcherPriority)6, (Delegate)(Action)delegate
|
||||
{
|
||||
ToggleDockBar();
|
||||
});
|
||||
}
|
||||
LogService.Info("초기화 완료. " + settings.Settings.Hotkey + "로 실행하세요.");
|
||||
}
|
||||
|
||||
private void OnHotkeyTriggered(object? sender, EventArgs e)
|
||||
{
|
||||
WindowTracker.Capture();
|
||||
LauncherSettings launcherSettings = _settings?.Settings.Launcher;
|
||||
bool flag = launcherSettings?.EnableTextAction ?? false;
|
||||
bool isVisible = false;
|
||||
((DispatcherObject)this).Dispatcher.Invoke((Action)delegate
|
||||
{
|
||||
isVisible = _launcher?.IsVisible ?? false;
|
||||
});
|
||||
if (isVisible)
|
||||
{
|
||||
((DispatcherObject)this).Dispatcher.Invoke((Action)delegate
|
||||
{
|
||||
_launcher?.Hide();
|
||||
});
|
||||
return;
|
||||
}
|
||||
if (!flag)
|
||||
{
|
||||
((DispatcherObject)this).Dispatcher.Invoke((Action)delegate
|
||||
{
|
||||
if (_launcher != null)
|
||||
{
|
||||
UsageStatisticsService.RecordLauncherOpen();
|
||||
_launcher.Show();
|
||||
}
|
||||
});
|
||||
return;
|
||||
}
|
||||
string selectedText = TryGetSelectedText();
|
||||
((DispatcherObject)this).Dispatcher.Invoke((Action)delegate
|
||||
{
|
||||
if (_launcher != null)
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(selectedText))
|
||||
{
|
||||
List<string> enabledCmds = launcherSettings?.TextActionCommands ?? new List<string>();
|
||||
if (enabledCmds.Count == 1 && !string.IsNullOrEmpty(TextActionPopup.AvailableCommands.FirstOrDefault<(string, string)>(((string Key, string Label) c) => c.Key == enabledCmds[0]).Item1))
|
||||
{
|
||||
string text = enabledCmds[0];
|
||||
if (1 == 0)
|
||||
{
|
||||
}
|
||||
TextActionPopup.ActionResult actionResult = text switch
|
||||
{
|
||||
"translate" => TextActionPopup.ActionResult.Translate,
|
||||
"summarize" => TextActionPopup.ActionResult.Summarize,
|
||||
"grammar" => TextActionPopup.ActionResult.GrammarFix,
|
||||
"explain" => TextActionPopup.ActionResult.Explain,
|
||||
"rewrite" => TextActionPopup.ActionResult.Rewrite,
|
||||
_ => TextActionPopup.ActionResult.None,
|
||||
};
|
||||
if (1 == 0)
|
||||
{
|
||||
}
|
||||
TextActionPopup.ActionResult actionResult2 = actionResult;
|
||||
if (actionResult2 != TextActionPopup.ActionResult.None)
|
||||
{
|
||||
ExecuteTextAction(actionResult2, selectedText);
|
||||
return;
|
||||
}
|
||||
}
|
||||
TextActionPopup popup = new TextActionPopup(selectedText, enabledCmds);
|
||||
popup.Closed += delegate
|
||||
{
|
||||
switch (popup.SelectedAction)
|
||||
{
|
||||
case TextActionPopup.ActionResult.OpenLauncher:
|
||||
UsageStatisticsService.RecordLauncherOpen();
|
||||
_launcher.Show();
|
||||
break;
|
||||
case TextActionPopup.ActionResult.None:
|
||||
break;
|
||||
default:
|
||||
ExecuteTextAction(popup.SelectedAction, popup.SelectedText);
|
||||
break;
|
||||
}
|
||||
};
|
||||
popup.Show();
|
||||
}
|
||||
else
|
||||
{
|
||||
UsageStatisticsService.RecordLauncherOpen();
|
||||
_launcher.Show();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private string? TryGetSelectedText()
|
||||
{
|
||||
try
|
||||
{
|
||||
string prevText = null;
|
||||
bool hadText = false;
|
||||
((DispatcherObject)this).Dispatcher.Invoke((Action)delegate
|
||||
{
|
||||
hadText = System.Windows.Clipboard.ContainsText();
|
||||
prevText = (hadText ? System.Windows.Clipboard.GetText() : null);
|
||||
System.Windows.Clipboard.Clear();
|
||||
});
|
||||
Thread.Sleep(30);
|
||||
NativeMethods.INPUT[] array = new NativeMethods.INPUT[4]
|
||||
{
|
||||
new NativeMethods.INPUT
|
||||
{
|
||||
type = 1u,
|
||||
u = new NativeMethods.InputUnion
|
||||
{
|
||||
ki = new NativeMethods.KEYBDINPUT
|
||||
{
|
||||
wVk = 17
|
||||
}
|
||||
}
|
||||
},
|
||||
new NativeMethods.INPUT
|
||||
{
|
||||
type = 1u,
|
||||
u = new NativeMethods.InputUnion
|
||||
{
|
||||
ki = new NativeMethods.KEYBDINPUT
|
||||
{
|
||||
wVk = 67
|
||||
}
|
||||
}
|
||||
},
|
||||
new NativeMethods.INPUT
|
||||
{
|
||||
type = 1u,
|
||||
u = new NativeMethods.InputUnion
|
||||
{
|
||||
ki = new NativeMethods.KEYBDINPUT
|
||||
{
|
||||
wVk = 67,
|
||||
dwFlags = 2u
|
||||
}
|
||||
}
|
||||
},
|
||||
new NativeMethods.INPUT
|
||||
{
|
||||
type = 1u,
|
||||
u = new NativeMethods.InputUnion
|
||||
{
|
||||
ki = new NativeMethods.KEYBDINPUT
|
||||
{
|
||||
wVk = 17,
|
||||
dwFlags = 2u
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
NativeMethods.SendInput((uint)array.Length, array, Marshal.SizeOf<NativeMethods.INPUT>());
|
||||
Thread.Sleep(80);
|
||||
string selected = null;
|
||||
((DispatcherObject)this).Dispatcher.Invoke((Action)delegate
|
||||
{
|
||||
if (System.Windows.Clipboard.ContainsText())
|
||||
{
|
||||
string text = System.Windows.Clipboard.GetText();
|
||||
if (text != prevText && !string.IsNullOrWhiteSpace(text))
|
||||
{
|
||||
selected = text;
|
||||
}
|
||||
}
|
||||
if (selected != null && prevText != null)
|
||||
{
|
||||
System.Windows.Clipboard.SetText(prevText);
|
||||
}
|
||||
else if (selected != null && !hadText)
|
||||
{
|
||||
System.Windows.Clipboard.Clear();
|
||||
}
|
||||
});
|
||||
return selected;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private void ExecuteTextAction(TextActionPopup.ActionResult action, string text)
|
||||
{
|
||||
if (1 == 0)
|
||||
{
|
||||
}
|
||||
string text2 = action switch
|
||||
{
|
||||
TextActionPopup.ActionResult.Translate => "다음 텍스트를 번역해줘:\n\n" + text,
|
||||
TextActionPopup.ActionResult.Summarize => "다음 텍스트를 요약해줘:\n\n" + text,
|
||||
TextActionPopup.ActionResult.GrammarFix => "다음 텍스트의 문법을 교정해줘:\n\n" + text,
|
||||
TextActionPopup.ActionResult.Explain => "다음 텍스트를 쉽게 설명해줘:\n\n" + text,
|
||||
TextActionPopup.ActionResult.Rewrite => "다음 텍스트를 다시 작성해줘:\n\n" + text,
|
||||
_ => text,
|
||||
};
|
||||
if (1 == 0)
|
||||
{
|
||||
}
|
||||
string text3 = text2;
|
||||
_launcher?.Show();
|
||||
_launcher?.SetInputText("! " + text3);
|
||||
}
|
||||
|
||||
private void OnCaptureHotkeyTriggered(object? sender, EventArgs e)
|
||||
{
|
||||
WindowTracker.Capture();
|
||||
string mode = _settings?.Settings.ScreenCapture.GlobalHotkeyMode ?? "screen";
|
||||
((DispatcherObject)this).Dispatcher.Invoke<Task>((Func<Task>)async delegate
|
||||
{
|
||||
if (_captureHandler == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
try
|
||||
{
|
||||
await _captureHandler.CaptureDirectAsync(mode);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogService.Error("글로벌 캡처 실패: " + ex.Message);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void OnHookFailed(object? sender, EventArgs e)
|
||||
{
|
||||
((DispatcherObject)this).Dispatcher.Invoke((Action)delegate
|
||||
{
|
||||
_trayIcon?.ShowBalloonTip(3000, "AX Copilot", "글로벌 단축키 등록에 실패했습니다.\n다른 앱과 " + (_settings?.Settings.Hotkey ?? "단축키") + "가 충돌하고 있을 수 있습니다.", ToolTipIcon.Warning);
|
||||
});
|
||||
}
|
||||
|
||||
private void SetupTrayIcon(PluginHost pluginHost, SettingsService settings)
|
||||
{
|
||||
_trayIcon = new NotifyIcon
|
||||
{
|
||||
Text = "AX Copilot",
|
||||
Visible = true,
|
||||
Icon = LoadAppIcon()
|
||||
};
|
||||
_trayMenu = new TrayMenuWindow();
|
||||
_trayMenu.AddItem("\ue7c5", "AX Commander 호출하기", delegate
|
||||
{
|
||||
((DispatcherObject)this).Dispatcher.Invoke((Action)delegate
|
||||
{
|
||||
_launcher?.Show();
|
||||
});
|
||||
}).AddItem("\ue8bd", "AX Agent 대화하기", delegate
|
||||
{
|
||||
((DispatcherObject)this).Dispatcher.Invoke((Action)delegate
|
||||
{
|
||||
OpenAiChat();
|
||||
});
|
||||
}, out Border aiTrayItem).AddItem("\ue8a7", "독 바 표시", delegate
|
||||
{
|
||||
((DispatcherObject)this).Dispatcher.Invoke((Action)delegate
|
||||
{
|
||||
ToggleDockBar();
|
||||
});
|
||||
})
|
||||
.AddSeparator()
|
||||
.AddItem("\ue72c", "플러그인 재로드", delegate
|
||||
{
|
||||
pluginHost.Reload();
|
||||
_trayIcon.ShowBalloonTip(2000, "AX Copilot", "플러그인이 재로드되었습니다.", ToolTipIcon.None);
|
||||
})
|
||||
.AddItem("\ue838", "로그 폴더 열기", delegate
|
||||
{
|
||||
string arguments = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "AxCopilot", "logs");
|
||||
Process.Start(new ProcessStartInfo("explorer.exe", arguments)
|
||||
{
|
||||
UseShellExecute = true
|
||||
});
|
||||
})
|
||||
.AddItem("\ue9d9", "사용 통계", delegate
|
||||
{
|
||||
((DispatcherObject)this).Dispatcher.Invoke((Action)delegate
|
||||
{
|
||||
new StatisticsWindow().Show();
|
||||
});
|
||||
})
|
||||
.AddItem("\ue736", "사용 가이드 문서보기", delegate
|
||||
{
|
||||
try
|
||||
{
|
||||
((DispatcherObject)this).Dispatcher.Invoke((Action)delegate
|
||||
{
|
||||
new GuideViewerWindow().Show();
|
||||
});
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogService.Error("사용 가이드 열기 실패: " + ex.Message);
|
||||
}
|
||||
})
|
||||
.AddSeparator()
|
||||
.AddToggleItem("\ue82f", "Windows 시작 시 자동 실행", IsAutoStartEnabled(), delegate(bool isChecked)
|
||||
{
|
||||
SetAutoStart(isChecked);
|
||||
}, out Func<bool> _, out Action<string> _)
|
||||
.AddSeparator()
|
||||
.AddItem("\ue713", "설정", delegate
|
||||
{
|
||||
((DispatcherObject)this).Dispatcher.Invoke((Action)OpenSettings);
|
||||
})
|
||||
.AddItem("\ue946", "개발 정보", delegate
|
||||
{
|
||||
((DispatcherObject)this).Dispatcher.Invoke((Action)delegate
|
||||
{
|
||||
new AboutWindow().Show();
|
||||
});
|
||||
})
|
||||
.AddItem("\ue711", "종료", delegate
|
||||
{
|
||||
_inputListener?.Dispose();
|
||||
_trayIcon?.Dispose();
|
||||
Shutdown();
|
||||
});
|
||||
_trayMenu.Opening += delegate
|
||||
{
|
||||
aiTrayItem.Visibility = ((!settings.Settings.AiEnabled) ? Visibility.Collapsed : Visibility.Visible);
|
||||
};
|
||||
_trayIcon.MouseClick += delegate(object? _, MouseEventArgs e)
|
||||
{
|
||||
if (e.Button == MouseButtons.Left)
|
||||
{
|
||||
((DispatcherObject)this).Dispatcher.Invoke((Action)delegate
|
||||
{
|
||||
_launcher?.Show();
|
||||
});
|
||||
}
|
||||
else if (e.Button == MouseButtons.Right)
|
||||
{
|
||||
((DispatcherObject)this).Dispatcher.Invoke((Action)delegate
|
||||
{
|
||||
_trayMenu?.ShowWithUpdate();
|
||||
});
|
||||
}
|
||||
};
|
||||
NotificationService.Initialize(delegate(string title, string msg)
|
||||
{
|
||||
((DispatcherObject)this).Dispatcher.Invoke((Action)delegate
|
||||
{
|
||||
_trayIcon?.ShowBalloonTip(4000, title, msg, ToolTipIcon.None);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
public void OpenSettingsFromChat()
|
||||
{
|
||||
((DispatcherObject)this).Dispatcher.Invoke((Action)OpenSettings);
|
||||
}
|
||||
|
||||
internal void PrewarmChatWindow()
|
||||
{
|
||||
if (_chatWindow == null && _settings != null)
|
||||
{
|
||||
_chatWindow = new ChatWindow(_settings);
|
||||
}
|
||||
}
|
||||
|
||||
private void OpenAiChat()
|
||||
{
|
||||
if (_settings != null)
|
||||
{
|
||||
if (_chatWindow == null)
|
||||
{
|
||||
_chatWindow = new ChatWindow(_settings);
|
||||
}
|
||||
_chatWindow.Show();
|
||||
_chatWindow.Activate();
|
||||
}
|
||||
}
|
||||
|
||||
public void ToggleDockBar()
|
||||
{
|
||||
if (_dockBar != null && _dockBar.IsVisible)
|
||||
{
|
||||
_dockBar.Hide();
|
||||
return;
|
||||
}
|
||||
if (_dockBar == null)
|
||||
{
|
||||
_dockBar = new DockBarWindow();
|
||||
_dockBar.OnQuickSearch = delegate(string query)
|
||||
{
|
||||
if (_launcher != null)
|
||||
{
|
||||
_launcher.Show();
|
||||
_launcher.Activate();
|
||||
if (!string.IsNullOrEmpty(query))
|
||||
{
|
||||
((DispatcherObject)this).Dispatcher.BeginInvoke((DispatcherPriority)5, (Delegate)(Action)delegate
|
||||
{
|
||||
_launcher.SetInputText(query);
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
_dockBar.OnCapture = async delegate
|
||||
{
|
||||
WindowTracker.Capture();
|
||||
if (_captureHandler != null)
|
||||
{
|
||||
await _captureHandler.CaptureDirectAsync("region");
|
||||
}
|
||||
};
|
||||
_dockBar.OnOpenAgent = delegate
|
||||
{
|
||||
if (_launcher != null)
|
||||
{
|
||||
_launcher.Show();
|
||||
((DispatcherObject)this).Dispatcher.BeginInvoke((DispatcherPriority)5, (Delegate)(Action)delegate
|
||||
{
|
||||
_launcher.SetInputText("!");
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
LauncherSettings launcherSettings = _settings?.Settings.Launcher;
|
||||
List<string> itemKeys = launcherSettings?.DockBarItems ?? new List<string> { "launcher", "clipboard", "capture", "agent", "clock", "cpu" };
|
||||
_dockBar.BuildFromSettings(itemKeys);
|
||||
_dockBar.OnPositionChanged = delegate(double left, double top)
|
||||
{
|
||||
if (_settings != null)
|
||||
{
|
||||
_settings.Settings.Launcher.DockBarLeft = left;
|
||||
_settings.Settings.Launcher.DockBarTop = top;
|
||||
_settings.Save();
|
||||
}
|
||||
};
|
||||
_dockBar.Show();
|
||||
_dockBar.ApplySettings(launcherSettings?.DockBarOpacity ?? 0.92, launcherSettings?.DockBarLeft ?? (-1.0), launcherSettings?.DockBarTop ?? (-1.0), launcherSettings?.DockBarRainbowGlow ?? false);
|
||||
}
|
||||
|
||||
public void RefreshDockBar()
|
||||
{
|
||||
if (_dockBar != null && _dockBar.IsVisible)
|
||||
{
|
||||
LauncherSettings launcherSettings = _settings?.Settings.Launcher;
|
||||
List<string> itemKeys = launcherSettings?.DockBarItems ?? new List<string> { "launcher", "clipboard", "capture", "agent", "clock", "cpu" };
|
||||
_dockBar.BuildFromSettings(itemKeys);
|
||||
_dockBar.ApplySettings(launcherSettings?.DockBarOpacity ?? 0.92, launcherSettings?.DockBarLeft ?? (-1.0), launcherSettings?.DockBarTop ?? (-1.0), launcherSettings?.DockBarRainbowGlow ?? false);
|
||||
}
|
||||
}
|
||||
|
||||
private void OpenSettings()
|
||||
{
|
||||
SettingsViewModel vm;
|
||||
if (_settingsWindow != null && _settingsWindow.IsVisible)
|
||||
{
|
||||
_settingsWindow.Activate();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_settings == null || _launcher == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
vm = new SettingsViewModel(_settings);
|
||||
_settingsWindow = new SettingsWindow(vm, PreviewCallback, RevertCallback)
|
||||
{
|
||||
SuspendHotkeyCallback = delegate(bool suspend)
|
||||
{
|
||||
if (_inputListener != null)
|
||||
{
|
||||
_inputListener.SuspendHotkey = suspend;
|
||||
}
|
||||
}
|
||||
};
|
||||
vm.SaveCompleted += delegate
|
||||
{
|
||||
if (_inputListener != null && _settings != null)
|
||||
{
|
||||
_inputListener.UpdateHotkey(_settings.Settings.Hotkey);
|
||||
_inputListener.UpdateCaptureHotkey(_settings.Settings.ScreenCapture.GlobalHotkey, _settings.Settings.ScreenCapture.GlobalHotkeyEnabled);
|
||||
}
|
||||
_worktimeReminder?.RestartTimer();
|
||||
};
|
||||
_settingsWindow.Show();
|
||||
}
|
||||
void PreviewCallback(string themeKey)
|
||||
{
|
||||
if (themeKey == "custom")
|
||||
{
|
||||
CustomThemeColors customThemeColors = new CustomThemeColors();
|
||||
foreach (ColorRowModel colorRow in vm.ColorRows)
|
||||
{
|
||||
typeof(CustomThemeColors).GetProperty(colorRow.Property)?.SetValue(customThemeColors, colorRow.Hex);
|
||||
}
|
||||
_launcher.ApplyTheme(themeKey, customThemeColors);
|
||||
}
|
||||
else
|
||||
{
|
||||
_launcher.ApplyTheme(themeKey, _settings.Settings.Launcher.CustomTheme);
|
||||
}
|
||||
}
|
||||
void RevertCallback()
|
||||
{
|
||||
_launcher.ApplyTheme(_settings.Settings.Launcher.Theme ?? "system", _settings.Settings.Launcher.CustomTheme);
|
||||
}
|
||||
}
|
||||
|
||||
private static Icon LoadAppIcon()
|
||||
{
|
||||
Size smallIconSize = SystemInformation.SmallIconSize;
|
||||
try
|
||||
{
|
||||
string path = Path.GetDirectoryName(Environment.ProcessPath) ?? AppContext.BaseDirectory;
|
||||
string text = Path.Combine(path, "Assets", "icon.ico");
|
||||
if (File.Exists(text))
|
||||
{
|
||||
return new Icon(text, smallIconSize);
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
try
|
||||
{
|
||||
Uri uriResource = new Uri("pack://application:,,,/Assets/icon.ico");
|
||||
Stream stream = System.Windows.Application.GetResourceStream(uriResource)?.Stream;
|
||||
if (stream != null)
|
||||
{
|
||||
return new Icon(stream, smallIconSize);
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
return SystemIcons.Application;
|
||||
}
|
||||
|
||||
private static bool IsAutoStartEnabled()
|
||||
{
|
||||
try
|
||||
{
|
||||
using RegistryKey registryKey = Registry.CurrentUser.OpenSubKey("Software\\Microsoft\\Windows\\CurrentVersion\\Run", writable: false);
|
||||
return registryKey?.GetValue("AxCopilot") != null;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private static void SetAutoStart(bool enable)
|
||||
{
|
||||
try
|
||||
{
|
||||
using RegistryKey registryKey = Registry.CurrentUser.OpenSubKey("Software\\Microsoft\\Windows\\CurrentVersion\\Run", writable: true);
|
||||
if (registryKey == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (enable)
|
||||
{
|
||||
string text = Environment.ProcessPath ?? Process.GetCurrentProcess().MainModule?.FileName ?? string.Empty;
|
||||
if (!string.IsNullOrEmpty(text))
|
||||
{
|
||||
registryKey.SetValue("AxCopilot", "\"" + text + "\"");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
registryKey.DeleteValue("AxCopilot", throwOnMissingValue: false);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogService.Warn("자동 시작 레지스트리 설정 실패: " + ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnExit(ExitEventArgs e)
|
||||
{
|
||||
_chatWindow?.ForceClose();
|
||||
_inputListener?.Dispose();
|
||||
_clipboardHistory?.Dispose();
|
||||
_indexService?.Dispose();
|
||||
_sessionTracking?.Dispose();
|
||||
_worktimeReminder?.Dispose();
|
||||
_trayIcon?.Dispose();
|
||||
try
|
||||
{
|
||||
_singleInstanceMutex?.ReleaseMutex();
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
_singleInstanceMutex?.Dispose();
|
||||
LogService.Info("=== AX Copilot 종료 ===");
|
||||
base.OnExit(e);
|
||||
}
|
||||
|
||||
[DebuggerNonUserCode]
|
||||
[GeneratedCode("PresentationBuildTasks", "10.0.5.0")]
|
||||
public void InitializeComponent()
|
||||
{
|
||||
if (!_contentLoaded)
|
||||
{
|
||||
_contentLoaded = true;
|
||||
Uri resourceLocator = new Uri("/AxCopilot;component/app.xaml", UriKind.Relative);
|
||||
System.Windows.Application.LoadComponent(this, resourceLocator);
|
||||
}
|
||||
}
|
||||
|
||||
[STAThread]
|
||||
[DebuggerNonUserCode]
|
||||
[GeneratedCode("PresentationBuildTasks", "10.0.5.0")]
|
||||
public static void Main()
|
||||
{
|
||||
App app = new App();
|
||||
app.InitializeComponent();
|
||||
app.Run();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user