diff --git a/src/modules/keyboardmanager/KeyboardManagerEditorUI/App.xaml b/src/modules/keyboardmanager/KeyboardManagerEditorUI/App.xaml index 6f7eb35101..1e1537351b 100644 --- a/src/modules/keyboardmanager/KeyboardManagerEditorUI/App.xaml +++ b/src/modules/keyboardmanager/KeyboardManagerEditorUI/App.xaml @@ -17,10 +17,10 @@ 960 - - + + M12.001 2C17.5238 2 22.001 6.47715 22.001 12C22.001 17.5228 17.5238 22 12.001 22C6.47813 22 2.00098 17.5228 2.00098 12C2.00098 6.47715 6.47813 2 12.001 2ZM12.7813 7.46897L12.6972 7.39635C12.4362 7.2027 12.078 7.20031 11.8146 7.38918L11.7206 7.46897L11.648 7.55308C11.4544 7.81407 11.452 8.17229 11.6409 8.43568L11.7206 8.52963L14.4403 11.2493H7.75027L7.6485 11.2561C7.31571 11.3013 7.05227 11.5647 7.00712 11.8975L7.00027 11.9993L7.00712 12.1011C7.05227 12.4339 7.31571 12.6973 7.6485 12.7424L7.75027 12.7493H14.4403L11.72 15.4697L11.6474 15.5538C11.4295 15.8474 11.4536 16.264 11.7198 16.5303C11.9861 16.7967 12.4027 16.8209 12.6964 16.6032L12.7805 16.5306L16.782 12.5306L16.8547 12.4464C17.0484 12.1854 17.0508 11.8272 16.8619 11.5638L16.7821 11.4698L12.7813 7.46897L12.6972 7.39635L12.7813 7.46897Z - + diff --git a/src/modules/keyboardmanager/KeyboardManagerEditorUI/Controls/AppPageInputControl.xaml b/src/modules/keyboardmanager/KeyboardManagerEditorUI/Controls/AppPageInputControl.xaml deleted file mode 100644 index 28f58e454a..0000000000 --- a/src/modules/keyboardmanager/KeyboardManagerEditorUI/Controls/AppPageInputControl.xaml +++ /dev/null @@ -1,119 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/modules/keyboardmanager/KeyboardManagerEditorUI/Pages/Programs.xaml.cs b/src/modules/keyboardmanager/KeyboardManagerEditorUI/Pages/Programs.xaml.cs deleted file mode 100644 index f512e322d5..0000000000 --- a/src/modules/keyboardmanager/KeyboardManagerEditorUI/Pages/Programs.xaml.cs +++ /dev/null @@ -1,336 +0,0 @@ -// Copyright (c) Microsoft Corporation -// The Microsoft Corporation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.Globalization; -using System.Linq; -using KeyboardManagerEditorUI.Helpers; -using KeyboardManagerEditorUI.Interop; -using KeyboardManagerEditorUI.Settings; -using ManagedCommon; -using Microsoft.UI.Xaml; -using Microsoft.UI.Xaml.Controls; -using static KeyboardManagerEditorUI.Interop.ShortcutKeyMapping; - -namespace KeyboardManagerEditorUI.Pages -{ - public sealed partial class Programs : Page, IDisposable - { - private KeyboardMappingService? _mappingService; - - // Flag to indicate if the user is editing an existing mapping - private bool _isEditMode; - private ProgramShortcut? _editingMapping; - - private bool _disposed; - - // The list of text mappings - public ObservableCollection Shortcuts { get; set; } = new ObservableCollection { }; - - public Programs() - { - this.InitializeComponent(); - - try - { - _mappingService = new KeyboardMappingService(); - LoadProgramShortcuts(); - } - catch (Exception ex) - { - Logger.LogError("Failed to initialize KeyboardMappingService: " + ex.Message); - } - - this.Unloaded += Text_Unloaded; - } - - private void Text_Unloaded(object sender, RoutedEventArgs e) - { - Dispose(); - } - - private void LoadProgramShortcuts() - { - if (_mappingService == null) - { - return; - } - - Shortcuts.Clear(); - - foreach (var shortcutSettings in SettingsManager.GetShortcutSettingsByOperationType(ShortcutOperationType.RunProgram)) - { - ShortcutKeyMapping mapping = shortcutSettings.Shortcut; - string[] originalKeyCodes = mapping.OriginalKeys.Split(';'); - var originalKeyNames = new List(); - foreach (var keyCode in originalKeyCodes) - { - if (int.TryParse(keyCode, out int code)) - { - originalKeyNames.Add(_mappingService.GetKeyDisplayName(code)); - } - } - - Shortcuts.Add(new ProgramShortcut - { - Shortcut = originalKeyNames, - AppToRun = mapping.ProgramPath, - Args = mapping.ProgramArgs, - IsActive = shortcutSettings.IsActive, - Id = shortcutSettings.Id, - }); - } - } - - private async void NewShortcutBtn_Click(object sender, RoutedEventArgs e) - { - _isEditMode = false; - _editingMapping = null; - - AppShortcutControl.ClearKeys(); - AppShortcutControl.SetProgramPathContent(string.Empty); - AppShortcutControl.SetProgramArgsContent(string.Empty); - - await KeyDialog.ShowAsync(); - } - - private async void ListView_ItemClick(object sender, ItemClickEventArgs e) - { - if (e.ClickedItem is ProgramShortcut selectedMapping) - { - _isEditMode = true; - _editingMapping = selectedMapping; - - AppShortcutControl.SetShortcutKeys(selectedMapping.Shortcut); - AppShortcutControl.SetProgramPathContent(selectedMapping.AppToRun); - AppShortcutControl.SetProgramArgsContent(selectedMapping.Args); - - await KeyDialog.ShowAsync(); - } - } - - private void KeyDialog_PrimaryButtonClick(ContentDialog sender, ContentDialogButtonClickEventArgs args) - { - if (_mappingService == null) - { - return; - } - - List keys = AppShortcutControl.GetShortcutKeys(); - string programPath = AppShortcutControl.GetProgramPathContent(); - string programArgs = AppShortcutControl.GetProgramArgsContent(); - ElevationLevel elevationLevel = AppShortcutControl.GetElevationLevel(); - StartWindowType startWindowType = AppShortcutControl.GetVisibility(); - ProgramAlreadyRunningAction programAlreadyRunningAction = AppShortcutControl.GetIfRunningAction(); - - // Validate inputs - ValidationErrorType errorType = ValidationHelper.ValidateProgramOrUrlMapping(keys, false, string.Empty, _mappingService); - - if (errorType != ValidationErrorType.NoError) - { - ShowValidationError(errorType, args); - return; - } - - bool saved = false; - - try - { - // Delete existing mapping if in edit mode - if (_isEditMode && _editingMapping != null) - { - if (_editingMapping.Shortcut.Count == 1) - { - int originalKey = _mappingService.GetKeyCodeFromName(_editingMapping.Shortcut[0]); - if (originalKey != 0) - { - _mappingService.DeleteSingleKeyMapping(originalKey); - } - } - else - { - string originalKeys = string.Join(";", _editingMapping.Shortcut.Select(k => _mappingService.GetKeyCodeFromName(k).ToString(CultureInfo.InvariantCulture))); - _mappingService.DeleteShortcutMapping(originalKeys); - } - - SettingsManager.RemoveShortcutKeyMappingFromSettings(_editingMapping.Id); - } - - // Shortcut to text mapping - string originalKeysString = string.Join(";", keys.Select(k => _mappingService.GetKeyCodeFromName(k).ToString(CultureInfo.InvariantCulture))); - - // if (isAppSpecific && !string.IsNullOrEmpty(appName)) - // { - // saved = _mappingService.AddShortcutMapping(originalKeysString, programPath, appName, ShortcutOperationType.RemapText); - // } - // else - // { - ShortcutKeyMapping shortcutKeyMapping = new ShortcutKeyMapping() - { - OperationType = ShortcutOperationType.RunProgram, - OriginalKeys = originalKeysString, - TargetKeys = originalKeysString, - ProgramPath = programPath, - ProgramArgs = programArgs, - IfRunningAction = programAlreadyRunningAction, - Visibility = startWindowType, - Elevation = elevationLevel, - }; - - saved = _mappingService.AddShorcutMapping(shortcutKeyMapping); - - if (saved) - { - _mappingService.SaveSettings(); - SettingsManager.AddShortcutKeyMappingToSettings(shortcutKeyMapping); - LoadProgramShortcuts(); // Refresh the list - } - } - catch (Exception ex) - { - Logger.LogError("Error saving text mapping: " + ex.Message); - args.Cancel = true; - } - } - - private void DeleteButton_Click(object sender, RoutedEventArgs e) - { - if (_mappingService == null || !(sender is Button button) || !(button.DataContext is ProgramShortcut shortcut)) - { - return; - } - - try - { - bool deleted = false; - if (shortcut.Shortcut.Count == 1) - { - // Single key mapping - int originalKey = _mappingService.GetKeyCodeFromName(shortcut.Shortcut[0]); - if (originalKey != 0) - { - deleted = _mappingService.DeleteSingleKeyToTextMapping(originalKey); - } - } - else - { - // Shortcut mapping - string originalKeys = string.Join(";", shortcut.Shortcut.Select(k => _mappingService.GetKeyCodeFromName(k))); - deleted = _mappingService.DeleteShortcutMapping(originalKeys); - } - - Shortcuts.Remove(shortcut); - SettingsManager.RemoveShortcutKeyMappingFromSettings(shortcut.Id); - - if (deleted) - { - _mappingService.SaveSettings(); - } - - LoadProgramShortcuts(); - } - catch (Exception ex) - { - Logger.LogError("Error deleting text mapping: " + ex.Message); - } - } - - private void ShowValidationError(ValidationErrorType errorType, ContentDialogButtonClickEventArgs args) - { - // if (ValidationHelper.ValidationMessages.TryGetValue(errorType, out (string Title, string Message) error)) - // { - // ValidationTip.Title = error.Title; - // ValidationTip.Subtitle = error.Message; - // ValidationTip.IsOpen = true; - // args.Cancel = true; - // } - } - - public void Dispose() - { - Dispose(true); - GC.SuppressFinalize(this); - } - - private void Dispose(bool disposing) - { - if (!_disposed) - { - if (disposing) - { - _mappingService?.Dispose(); - _mappingService = null; - } - - _disposed = true; - } - } - - private void ToggleSwitch_Toggled(object sender, RoutedEventArgs e) - { - if (sender is ToggleSwitch toggleSwitch && toggleSwitch.DataContext is ProgramShortcut shortcut && _mappingService != null) - { - try - { - if (toggleSwitch.IsOn) - { - bool saved = false; - ShortcutKeyMapping shortcutKeyMapping = SettingsManager.EditorSettings.ShortcutSettingsDictionary[shortcut.Id].Shortcut; - - saved = _mappingService.AddShorcutMapping(shortcutKeyMapping); - - if (saved) - { - shortcut.IsActive = true; - _mappingService.SaveSettings(); - SettingsManager.ToggleShortcutKeyMappingActiveState(shortcut.Id); - } - else - { - toggleSwitch.IsOn = false; - } - } - else - { - bool deleted = false; - if (shortcut.Shortcut.Count == 1) - { - // Single key mapping - int originalKey = _mappingService.GetKeyCodeFromName(shortcut.Shortcut[0]); - if (originalKey != 0) - { - deleted = _mappingService.DeleteSingleKeyToTextMapping(originalKey); - } - } - else - { - // Shortcut mapping - string originalKeys = string.Join(";", shortcut.Shortcut.Select(k => _mappingService.GetKeyCodeFromName(k))); - deleted = _mappingService.DeleteShortcutMapping(originalKeys); - } - - if (deleted) - { - shortcut.IsActive = false; - SettingsManager.ToggleShortcutKeyMappingActiveState(shortcut.Id); - _mappingService.SaveSettings(); - } - else - { - toggleSwitch.IsOn = true; - } - - LoadProgramShortcuts(); - } - } - catch (Exception ex) - { - Logger.LogError("Error toggling shortcut active state: " + ex.Message); - } - } - } - } -} diff --git a/src/modules/keyboardmanager/KeyboardManagerEditorUI/Pages/Remappings.xaml b/src/modules/keyboardmanager/KeyboardManagerEditorUI/Pages/Remappings.xaml deleted file mode 100644 index 75e2868ad0..0000000000 --- a/src/modules/keyboardmanager/KeyboardManagerEditorUI/Pages/Remappings.xaml +++ /dev/null @@ -1,218 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/modules/keyboardmanager/KeyboardManagerEditorUI/Pages/Remappings.xaml.cs b/src/modules/keyboardmanager/KeyboardManagerEditorUI/Pages/Remappings.xaml.cs deleted file mode 100644 index fc440db46a..0000000000 --- a/src/modules/keyboardmanager/KeyboardManagerEditorUI/Pages/Remappings.xaml.cs +++ /dev/null @@ -1,370 +0,0 @@ -// Copyright (c) Microsoft Corporation -// The Microsoft Corporation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.Diagnostics; -using System.Globalization; -using System.IO; -using System.Linq; -using System.Runtime.InteropServices; -using System.Runtime.InteropServices.WindowsRuntime; -using System.Text; -using System.Threading.Tasks; -using KeyboardManagerEditorUI.Helpers; -using KeyboardManagerEditorUI.Interop; -using ManagedCommon; -using Microsoft.UI.Xaml; -using Microsoft.UI.Xaml.Controls; -using Microsoft.UI.Xaml.Controls.Primitives; -using Microsoft.UI.Xaml.Data; -using Microsoft.UI.Xaml.Input; -using Microsoft.UI.Xaml.Media; -using Microsoft.UI.Xaml.Navigation; -using Microsoft.Windows.ApplicationModel.Resources; -using Windows.ApplicationModel; -using Windows.Foundation; -using Windows.Foundation.Collections; -using static KeyboardManagerEditorUI.Helpers.ValidationHelper; - -namespace KeyboardManagerEditorUI.Pages -{ - /// - /// The Remapping page that allow users to configure a single key or shortcut to a new key or shortcut - /// - public sealed partial class Remappings : Page, IDisposable - { - private KeyboardMappingService? _mappingService; - - // Flag to indicate if the user is editing an existing remapping - private bool _isEditMode; - private Remapping? _editingRemapping; - - private bool _disposed; - - // The list of single key mappings - public ObservableCollection SingleKeyMappings { get; } = new ObservableCollection(); - - // The list of shortcut key mappings - public ObservableCollection ShortcutKeyMappings { get; } = new ObservableCollection(); - - // The full list of remappings - public ObservableCollection RemappingList { get; set; } - - public Remappings() - { - this.InitializeComponent(); - - RemappingList = new ObservableCollection(); - _mappingService = new KeyboardMappingService(); - - // Load all existing remappings - LoadMappings(); - - this.Unloaded += Remappings_Unloaded; - } - - private void Remappings_Unloaded(object sender, RoutedEventArgs e) - { - // Make sure we unregister the handler when the page is unloaded - UnregisterWindowActivationHandler(); - KeyboardHookHelper.Instance.CleanupHook(); - } - - private void RegisterWindowActivationHandler() - { - // Get the current window that contains this page - if (App.MainWindow is Window window) - { - // Register for window activation events - window.Activated += Dialog_WindowActivated; - } - } - - private void UnregisterWindowActivationHandler() - { - // Unregister to prevent memory leaks - if (App.MainWindow is Window window) - { - window.Activated -= Dialog_WindowActivated; - } - } - - private void Dialog_WindowActivated(object sender, WindowActivatedEventArgs args) - { - // When window is deactivated (user switched to another app) - if (args.WindowActivationState == WindowActivationState.Deactivated) - { - // Make sure to cleanup the keyboard hook when the window loses focus - KeyboardHookHelper.Instance.CleanupHook(); - - RemappingControl.ResetToggleButtons(); - RemappingControl.UpdateAllAppsCheckBoxState(); - } - } - - private async void NewRemappingBtn_Click(object sender, RoutedEventArgs e) - { - _isEditMode = false; - _editingRemapping = null; - - RemappingControl.SetOriginalKeys(new List()); - RemappingControl.SetRemappedKeys(new List()); - RemappingControl.SetApp(false, string.Empty); - RemappingControl.SetUpToggleButtonInitialStatus(); - - RegisterWindowActivationHandler(); - - // Show the dialog to add a new remapping - KeyDialog.PrimaryButtonClick += KeyDialog_PrimaryButtonClick; - await KeyDialog.ShowAsync(); - KeyDialog.PrimaryButtonClick -= KeyDialog_PrimaryButtonClick; - - UnregisterWindowActivationHandler(); - - KeyboardHookHelper.Instance.CleanupHook(); - } - - private async void ListView_ItemClick(object sender, ItemClickEventArgs e) - { - if (e.ClickedItem is Remapping selectedRemapping && selectedRemapping.IsEnabled) - { - // Set to edit mode - _isEditMode = true; - _editingRemapping = selectedRemapping; - - RemappingControl.SetOriginalKeys(selectedRemapping.Shortcut); - RemappingControl.SetRemappedKeys(selectedRemapping.RemappedKeys); - RemappingControl.SetApp(!selectedRemapping.IsAllApps, selectedRemapping.AppName); - RemappingControl.SetUpToggleButtonInitialStatus(); - - RegisterWindowActivationHandler(); - - KeyDialog.PrimaryButtonClick += KeyDialog_PrimaryButtonClick; - await KeyDialog.ShowAsync(); - KeyDialog.PrimaryButtonClick -= KeyDialog_PrimaryButtonClick; - - UnregisterWindowActivationHandler(); - - KeyboardHookHelper.Instance.CleanupHook(); - - // Reset the edit status - _isEditMode = false; - _editingRemapping = null; - } - } - - private void KeyDialog_PrimaryButtonClick(ContentDialog sender, ContentDialogButtonClickEventArgs args) - { - List originalKeys = RemappingControl.GetOriginalKeys(); - List remappedKeys = RemappingControl.GetRemappedKeys(); - bool isAppSpecific = RemappingControl.GetIsAppSpecific(); - string appName = RemappingControl.GetAppName(); - - // Make sure _mappingService is not null before validating and saving - if (_mappingService == null) - { - Logger.LogError("Mapping service is null, cannot validate mapping"); - return; - } - - // Validate the remapping - ValidationErrorType errorType = ValidationHelper.ValidateKeyMapping( - originalKeys, remappedKeys, isAppSpecific, appName, _mappingService, _isEditMode, _editingRemapping); - - if (errorType != ValidationErrorType.NoError) - { - ShowValidationError(errorType, args); - return; - } - - // Check for orphaned keys - if (originalKeys.Count == 1 && _mappingService != null) - { - int originalKeyCode = _mappingService.GetKeyCodeFromName(originalKeys[0]); - - if (IsKeyOrphaned(originalKeyCode, _mappingService)) - { - string keyName = _mappingService.GetKeyDisplayName(originalKeyCode); - - OrphanedKeysTeachingTip.Target = RemappingControl; - OrphanedKeysTeachingTip.Subtitle = $"The key {keyName} will become orphaned (inaccessible) after remapping. Please confirm if you want to proceed."; - OrphanedKeysTeachingTip.Tag = args; - OrphanedKeysTeachingTip.IsOpen = true; - - args.Cancel = true; - return; - } - } - - // If in edit mode, delete the existing remapping before saving the new one - if (_isEditMode && _editingRemapping != null) - { - if (!RemappingHelper.DeleteRemapping(_mappingService!, _editingRemapping)) - { - return; - } - } - - // If no errors, proceed to save the remapping - bool saved = RemappingHelper.SaveMapping(_mappingService!, originalKeys, remappedKeys, isAppSpecific, appName); - if (saved) - { - // Display the remapping in the list after saving - LoadMappings(); - } - } - - private void DeleteButton_Click(object sender, RoutedEventArgs e) - { - if (sender is Button button && button.DataContext is Remapping remapping) - { - if (RemappingHelper.DeleteRemapping(_mappingService!, remapping)) - { - LoadMappings(); - } - } - } - - private void ValidationTeachingTip_CloseButtonClick(TeachingTip sender, object args) - { - sender.IsOpen = false; - } - - private void OrphanedKeysTeachingTip_ActionButtonClick(TeachingTip sender, object args) - { - // User pressed continue anyway button - sender.IsOpen = false; - - if (_isEditMode && _editingRemapping != null) - { - if (!RemappingHelper.DeleteRemapping(_mappingService!, _editingRemapping)) - { - return; - } - } - - bool saved = RemappingHelper.SaveMapping( - _mappingService!, RemappingControl.GetOriginalKeys(), RemappingControl.GetRemappedKeys(), RemappingControl.GetIsAppSpecific(), RemappingControl.GetAppName()); - if (saved) - { - KeyDialog.Hide(); - LoadMappings(); - } - } - - private void OrphanedKeysTeachingTip_CloseButtonClick(TeachingTip sender, object args) - { - // Just close the teaching tip if the user canceled - sender.IsOpen = false; - } - - private void LoadMappings() - { - if (_mappingService == null) - { - return; - } - - SingleKeyMappings.Clear(); - ShortcutKeyMappings.Clear(); - RemappingList.Clear(); - - // Load all single key mappings - foreach (var mapping in _mappingService.GetSingleKeyMappings()) - { - SingleKeyMappings.Add(mapping); - - string[] targetKeyCodes = mapping.TargetKey.Split(';'); - var targetKeyNames = new List(); - - foreach (var keyCode in targetKeyCodes) - { - if (int.TryParse(keyCode, out int code)) - { - targetKeyNames.Add(_mappingService.GetKeyDisplayName(code)); - } - } - - RemappingList.Add(new Remapping - { - Shortcut = new List { _mappingService.GetKeyDisplayName(mapping.OriginalKey) }, - RemappedKeys = targetKeyNames, - IsAllApps = true, - }); - } - - // Load all shortcut key mappings - foreach (var mapping in _mappingService.GetShortcutMappingsByType(ShortcutOperationType.RemapShortcut)) - { - ShortcutKeyMappings.Add(mapping); - - string[] originalKeyCodes = mapping.OriginalKeys.Split(';'); - string[] targetKeyCodes = mapping.TargetKeys.Split(';'); - - var originalKeyNames = new List(); - var targetKeyNames = new List(); - - foreach (var keyCode in originalKeyCodes) - { - if (int.TryParse(keyCode, out int code)) - { - originalKeyNames.Add(_mappingService.GetKeyDisplayName(code)); - } - } - - foreach (var keyCode in targetKeyCodes) - { - if (int.TryParse(keyCode, out int code)) - { - targetKeyNames.Add(_mappingService.GetKeyDisplayName(code)); - } - } - - RemappingList.Add(new Remapping - { - Shortcut = originalKeyNames, - RemappedKeys = targetKeyNames, - IsAllApps = string.IsNullOrEmpty(mapping.TargetApp), - AppName = string.IsNullOrEmpty(mapping.TargetApp) ? string.Empty : mapping.TargetApp, - }); - } - } - - private bool ShowValidationError(ValidationErrorType errorType, ContentDialogButtonClickEventArgs args) - { - var (title, message) = ValidationMessages[errorType]; - - ValidationTeachingTip.Title = title; - ValidationTeachingTip.Subtitle = message; - ValidationTeachingTip.Target = RemappingControl; - ValidationTeachingTip.Tag = args; - ValidationTeachingTip.IsOpen = true; - args.Cancel = true; - return false; - } - - public void Dispose() - { - Dispose(true); - GC.SuppressFinalize(this); - } - - private void Dispose(bool disposing) - { - if (!_disposed) - { - if (disposing) - { - // Dispose managed resources - _mappingService?.Dispose(); - _mappingService = null; - } - - _disposed = true; - } - } - } -} diff --git a/src/modules/keyboardmanager/KeyboardManagerEditorUI/Pages/Text.xaml b/src/modules/keyboardmanager/KeyboardManagerEditorUI/Pages/Text.xaml deleted file mode 100644 index 76b897b02a..0000000000 --- a/src/modules/keyboardmanager/KeyboardManagerEditorUI/Pages/Text.xaml +++ /dev/null @@ -1,200 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/modules/keyboardmanager/KeyboardManagerEditorUI/Pages/Text.xaml.cs b/src/modules/keyboardmanager/KeyboardManagerEditorUI/Pages/Text.xaml.cs deleted file mode 100644 index f77d69d731..0000000000 --- a/src/modules/keyboardmanager/KeyboardManagerEditorUI/Pages/Text.xaml.cs +++ /dev/null @@ -1,332 +0,0 @@ -// Copyright (c) Microsoft Corporation -// The Microsoft Corporation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.Globalization; -using System.Linq; -using System.Threading.Tasks; -using KeyboardManagerEditorUI.Helpers; -using KeyboardManagerEditorUI.Interop; -using ManagedCommon; -using Microsoft.UI.Xaml; -using Microsoft.UI.Xaml.Controls; -using Microsoft.UI.Xaml.Controls.Primitives; - -namespace KeyboardManagerEditorUI.Pages -{ - public sealed partial class Text : Page, IDisposable - { - private KeyboardMappingService? _mappingService; - - // Flag to indicate if the user is editing an existing mapping - private bool _isEditMode; - private TextMapping? _editingMapping; - - private bool _disposed; - - // The list of text mappings - public ObservableCollection TextMappings { get; } = new ObservableCollection(); - - public Text() - { - this.InitializeComponent(); - - try - { - _mappingService = new KeyboardMappingService(); - LoadTextMappings(); - } - catch (Exception ex) - { - Logger.LogError("Failed to initialize KeyboardMappingService: " + ex.Message); - System.Diagnostics.Debug.WriteLine(ex.Message); - } - - this.Unloaded += Text_Unloaded; - } - - private void Text_Unloaded(object sender, RoutedEventArgs e) - { - // Make sure we unregister the handler when the page is unloaded - UnregisterWindowActivationHandler(); - KeyboardHookHelper.Instance.CleanupHook(); - } - - private void RegisterWindowActivationHandler() - { - // Get the current window that contains this page - if (App.MainWindow is Window window) - { - // Register for window activation events - window.Activated += Dialog_WindowActivated; - } - } - - private void UnregisterWindowActivationHandler() - { - // Unregister to prevent memory leaks - if (App.MainWindow is Window window) - { - window.Activated -= Dialog_WindowActivated; - } - } - - private void Dialog_WindowActivated(object sender, WindowActivatedEventArgs args) - { - // When window is deactivated (user switched to another app) - if (args.WindowActivationState == WindowActivationState.Deactivated) - { - // Make sure to cleanup the keyboard hook when the window loses focus - KeyboardHookHelper.Instance.CleanupHook(); - - TextInputControl.ClearKeys(); - TextInputControl.UpdateAllAppsCheckBoxState(); - } - } - - private void LoadTextMappings() - { - if (_mappingService == null) - { - return; - } - - TextMappings.Clear(); - - // Load key-to-text mappings - var keyToTextMappings = _mappingService.GetKeyToTextMappings(); - foreach (var mapping in keyToTextMappings) - { - TextMappings.Add(new TextMapping - { - Shortcut = new List { _mappingService.GetKeyDisplayName(mapping.OriginalKey) }, - Text = mapping.TargetText, - IsAllApps = true, - AppName = string.Empty, - }); - } - - // Load shortcut-to-text mappings - foreach (var mapping in _mappingService.GetShortcutMappingsByType(ShortcutOperationType.RemapText)) - { - string[] originalKeyCodes = mapping.OriginalKeys.Split(';'); - var originalKeyNames = new List(); - foreach (var keyCode in originalKeyCodes) - { - if (int.TryParse(keyCode, out int code)) - { - originalKeyNames.Add(_mappingService.GetKeyDisplayName(code)); - } - } - - TextMappings.Add(new TextMapping - { - Shortcut = originalKeyNames, - Text = mapping.TargetText, - IsAllApps = string.IsNullOrEmpty(mapping.TargetApp), - AppName = string.IsNullOrEmpty(mapping.TargetApp) ? string.Empty : mapping.TargetApp, - }); - } - } - - private async void NewShortcutBtn_Click(object sender, RoutedEventArgs e) - { - _isEditMode = false; - _editingMapping = null; - - TextInputControl.ClearKeys(); - TextInputControl.SetTextContent(string.Empty); - TextInputControl.SetAppSpecific(false, string.Empty); - - RegisterWindowActivationHandler(); - - KeyDialog.PrimaryButtonClick += KeyDialog_PrimaryButtonClick; - await KeyDialog.ShowAsync(); - KeyDialog.PrimaryButtonClick -= KeyDialog_PrimaryButtonClick; - - UnregisterWindowActivationHandler(); - KeyboardHookHelper.Instance.CleanupHook(); - } - - private async void ListView_ItemClick(object sender, ItemClickEventArgs e) - { - if (e.ClickedItem is TextMapping selectedMapping) - { - _isEditMode = true; - _editingMapping = selectedMapping; - - TextInputControl.SetShortcutKeys(selectedMapping.Shortcut); - TextInputControl.SetTextContent(selectedMapping.Text); - TextInputControl.SetAppSpecific(!selectedMapping.IsAllApps, selectedMapping.AppName); - - RegisterWindowActivationHandler(); - - KeyDialog.PrimaryButtonClick += KeyDialog_PrimaryButtonClick; - await KeyDialog.ShowAsync(); - KeyDialog.PrimaryButtonClick -= KeyDialog_PrimaryButtonClick; - - UnregisterWindowActivationHandler(); - - KeyboardHookHelper.Instance.CleanupHook(); - - // Reset the edit status - _isEditMode = false; - _editingMapping = null; - } - } - - private void KeyDialog_PrimaryButtonClick(ContentDialog sender, ContentDialogButtonClickEventArgs args) - { - if (_mappingService == null) - { - return; - } - - List keys = TextInputControl.GetShortcutKeys(); - string textContent = TextInputControl.GetTextContent(); - bool isAppSpecific = TextInputControl.GetIsAppSpecific(); - string appName = TextInputControl.GetAppName(); - - // Validate inputs - ValidationErrorType errorType = ValidationHelper.ValidateTextMapping( - keys, textContent, isAppSpecific, appName, _mappingService); - - if (errorType != ValidationErrorType.NoError) - { - ShowValidationError(errorType, args); - return; - } - - bool saved = false; - - try - { - // Delete existing mapping if in edit mode - if (_isEditMode && _editingMapping != null) - { - if (_editingMapping.Shortcut.Count == 1) - { - int originalKey = _mappingService.GetKeyCodeFromName(_editingMapping.Shortcut[0]); - if (originalKey != 0) - { - _mappingService.DeleteSingleKeyToTextMapping(originalKey); - } - } - else - { - string originalKeys = string.Join(";", _editingMapping.Shortcut.Select(k => _mappingService.GetKeyCodeFromName(k).ToString(CultureInfo.InvariantCulture))); - _mappingService.DeleteShortcutMapping(originalKeys, _editingMapping.IsAllApps ? string.Empty : _editingMapping.AppName); - } - } - - // Add new mapping - if (keys.Count == 1) - { - // Single key to text mapping - int originalKey = _mappingService.GetKeyCodeFromName(keys[0]); - if (originalKey != 0) - { - saved = _mappingService.AddSingleKeyToTextMapping(originalKey, textContent); - } - } - else - { - // Shortcut to text mapping - string originalKeysString = string.Join(";", keys.Select(k => _mappingService.GetKeyCodeFromName(k).ToString(CultureInfo.InvariantCulture))); - - if (isAppSpecific && !string.IsNullOrEmpty(appName)) - { - saved = _mappingService.AddShortcutMapping(originalKeysString, textContent, appName, ShortcutOperationType.RemapText); - } - else - { - saved = _mappingService.AddShortcutMapping(originalKeysString, textContent, operationType: ShortcutOperationType.RemapText); - } - } - - if (saved) - { - _mappingService.SaveSettings(); - LoadTextMappings(); // Refresh the list - } - } - catch (Exception ex) - { - Logger.LogError("Error saving text mapping: " + ex.Message); - args.Cancel = true; - } - } - - private void DeleteButton_Click(object sender, RoutedEventArgs e) - { - if (_mappingService == null || !(sender is Button button) || !(button.DataContext is TextMapping mapping)) - { - return; - } - - try - { - bool deleted = false; - if (mapping.Shortcut.Count == 1) - { - // Single key mapping - int originalKey = _mappingService.GetKeyCodeFromName(mapping.Shortcut[0]); - if (originalKey != 0) - { - deleted = _mappingService.DeleteSingleKeyToTextMapping(originalKey); - } - } - else - { - // Shortcut mapping - string originalKeys = string.Join(";", mapping.Shortcut.Select(k => _mappingService.GetKeyCodeFromName(k))); - deleted = _mappingService.DeleteShortcutMapping(originalKeys, mapping.IsAllApps ? string.Empty : mapping.AppName); - } - - if (deleted) - { - _mappingService.SaveSettings(); - TextMappings.Remove(mapping); - } - } - catch (Exception ex) - { - Logger.LogError("Error deleting text mapping: " + ex.Message); - } - } - - private void ShowValidationError(ValidationErrorType errorType, ContentDialogButtonClickEventArgs args) - { - if (ValidationHelper.ValidationMessages.TryGetValue(errorType, out (string Title, string Message) error)) - { - ValidationTip.Title = error.Title; - ValidationTip.Subtitle = error.Message; - ValidationTip.IsOpen = true; - args.Cancel = true; - } - } - - public void Dispose() - { - Dispose(true); - GC.SuppressFinalize(this); - } - - private void Dispose(bool disposing) - { - if (!_disposed) - { - if (disposing) - { - _mappingService?.Dispose(); - _mappingService = null; - } - - _disposed = true; - } - } - } -} diff --git a/src/modules/keyboardmanager/KeyboardManagerEditorUI/Pages/URLs.xaml b/src/modules/keyboardmanager/KeyboardManagerEditorUI/Pages/URLs.xaml deleted file mode 100644 index 73b807daea..0000000000 --- a/src/modules/keyboardmanager/KeyboardManagerEditorUI/Pages/URLs.xaml +++ /dev/null @@ -1,159 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/modules/keyboardmanager/KeyboardManagerEditorUI/Pages/URLs.xaml.cs b/src/modules/keyboardmanager/KeyboardManagerEditorUI/Pages/URLs.xaml.cs deleted file mode 100644 index 8ec91db0b3..0000000000 --- a/src/modules/keyboardmanager/KeyboardManagerEditorUI/Pages/URLs.xaml.cs +++ /dev/null @@ -1,261 +0,0 @@ -// Copyright (c) Microsoft Corporation -// The Microsoft Corporation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.Globalization; -using System.IO; -using System.Linq; -using System.Runtime.InteropServices; -using System.Runtime.InteropServices.WindowsRuntime; -using System.Text; -using KeyboardManagerEditorUI.Helpers; -using KeyboardManagerEditorUI.Interop; -using ManagedCommon; -using Microsoft.UI.Xaml; -using Microsoft.UI.Xaml.Controls; -using Microsoft.UI.Xaml.Controls.Primitives; -using Microsoft.UI.Xaml.Data; -using Microsoft.UI.Xaml.Input; -using Microsoft.UI.Xaml.Media; -using Microsoft.UI.Xaml.Navigation; -using Windows.Foundation; -using Windows.Foundation.Collections; -using static KeyboardManagerEditorUI.Interop.ShortcutKeyMapping; - -namespace KeyboardManagerEditorUI.Pages -{ - /// - /// An empty page that can be used on its own or navigated to within a Frame. - /// - public sealed partial class URLs : Page, IDisposable - { - private KeyboardMappingService? _mappingService; - - private bool _disposed; - - private bool _isEditMode; - private URLShortcut? _editingMapping; - - public ObservableCollection Shortcuts { get; set; } - - [DllImport("PowerToys.KeyboardManagerEditorLibraryWrapper.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode)] - private static extern void GetKeyDisplayName(int keyCode, [Out] StringBuilder keyName, int maxLength); - - public URLs() - { - this.InitializeComponent(); - - Shortcuts = new ObservableCollection(); - - _mappingService = new KeyboardMappingService(); - - LoadUrlShortcuts(); - } - - public void LoadUrlShortcuts() - { - if (_mappingService == null) - { - return; - } - - foreach (var mapping in _mappingService.GetShortcutMappingsByType(ShortcutOperationType.OpenUri)) - { - string[] originalKeyCodes = mapping.OriginalKeys.Split(';'); - var originalKeyNames = new List(); - foreach (var keyCode in originalKeyCodes) - { - if (int.TryParse(keyCode, out int code)) - { - originalKeyNames.Add(GetKeyDisplayName(code)); - } - } - - var shortcut = new URLShortcut - { - Shortcut = originalKeyNames, - URL = mapping.UriToOpen, - }; - - Shortcuts.Add(shortcut); - } - } - - public static string GetKeyDisplayName(int keyCode) - { - var keyName = new StringBuilder(64); - GetKeyDisplayName(keyCode, keyName, keyName.Capacity); - return keyName.ToString(); - } - - private async void NewShortcutBtn_Click(object sender, RoutedEventArgs e) - { - _isEditMode = false; - _editingMapping = null; - - UrlShortcutControl.ClearKeys(); - UrlShortcutControl.SetUrlPathContent(string.Empty); - await KeyDialog.ShowAsync(); - } - - private async void ListView_ItemClick(object sender, ItemClickEventArgs e) - { - if (e.ClickedItem is URLShortcut urlShortcut) - { - _isEditMode = true; - _editingMapping = urlShortcut; - - UrlShortcutControl.SetShortcutKeys(urlShortcut.Shortcut); - UrlShortcutControl.SetUrlPathContent(urlShortcut.URL); - await KeyDialog.ShowAsync(); - } - } - - public void Dispose() - { - Dispose(true); - GC.SuppressFinalize(this); - } - - private void Dispose(bool disposing) - { - if (!_disposed) - { - if (disposing) - { - // Dispose managed resources - _mappingService?.Dispose(); - _mappingService = null; - } - - _disposed = true; - } - } - - private void KeyDialog_PrimaryButtonClick(ContentDialog sender, ContentDialogButtonClickEventArgs args) - { - if (_mappingService == null) - { - return; - } - - List keys = UrlShortcutControl.GetShortcutKeys(); - string urlPath = UrlShortcutControl.GetUrlPathContent(); - - // Validate inputs - ValidationErrorType errorType = ValidationHelper.ValidateProgramOrUrlMapping(keys, false, string.Empty, _mappingService); - - if (errorType != ValidationErrorType.NoError) - { - ShowValidationError(errorType, args); - return; - } - - bool saved = false; - - try - { - // Delete existing mapping if in edit mode - if (_isEditMode && _editingMapping != null) - { - if (_editingMapping.Shortcut.Count == 1) - { - int originalKey = _mappingService.GetKeyCodeFromName(_editingMapping.Shortcut[0]); - if (originalKey != 0) - { - _mappingService.DeleteSingleKeyMapping(originalKey); - } - } - else - { - string originalKeys = string.Join(";", _editingMapping.Shortcut.Select(k => _mappingService.GetKeyCodeFromName(k).ToString(CultureInfo.InvariantCulture))); - _mappingService.DeleteShortcutMapping(originalKeys); - } - } - - // Shortcut to text mapping - string originalKeysString = string.Join(";", keys.Select(k => _mappingService.GetKeyCodeFromName(k).ToString(CultureInfo.InvariantCulture))); - - // if (isAppSpecific && !string.IsNullOrEmpty(appName)) - // { - // saved = _mappingService.AddShortcutMapping(originalKeysString, programPath, appName, ShortcutOperationType.RemapText); - // } - // else - // { - ShortcutKeyMapping shortcutKeyMapping = new ShortcutKeyMapping() - { - OperationType = ShortcutOperationType.OpenUri, - OriginalKeys = originalKeysString, - TargetKeys = originalKeysString, - UriToOpen = urlPath, - }; - - saved = _mappingService.AddShorcutMapping(shortcutKeyMapping); - - if (saved) - { - _mappingService.SaveSettings(); - LoadUrlShortcuts(); - } - } - catch (Exception ex) - { - Logger.LogError("Error saving text mapping: " + ex.Message); - args.Cancel = true; - } - } - - private void ShowValidationError(ValidationErrorType errorType, ContentDialogButtonClickEventArgs args) - { - // if (ValidationHelper.ValidationMessages.TryGetValue(errorType, out (string Title, string Message) error)) - // { - // ValidationTip.Title = error.Title; - // ValidationTip.Subtitle = error.Message; - // ValidationTip.IsOpen = true; - // args.Cancel = true; - // } - } - - private void DeleteButton_Click(object sender, RoutedEventArgs e) - { - if (_mappingService == null || !(sender is Button button) || !(button.DataContext is URLShortcut shortcut)) - { - return; - } - - try - { - bool deleted = false; - if (shortcut.Shortcut.Count == 1) - { - // Single key mapping - int originalKey = _mappingService.GetKeyCodeFromName(shortcut.Shortcut[0]); - if (originalKey != 0) - { - deleted = _mappingService.DeleteSingleKeyToTextMapping(originalKey); - } - } - else - { - // Shortcut mapping - string originalKeys = string.Join(";", shortcut.Shortcut.Select(k => _mappingService.GetKeyCodeFromName(k))); - deleted = _mappingService.DeleteShortcutMapping(originalKeys); - } - - if (deleted) - { - _mappingService.SaveSettings(); - Shortcuts.Remove(shortcut); - LoadUrlShortcuts(); - } - } - catch (Exception ex) - { - Logger.LogError("Error deleting text mapping: " + ex.Message); - } - } - } -} diff --git a/src/modules/keyboardmanager/KeyboardManagerEditorUI/Styles/Button.xaml b/src/modules/keyboardmanager/KeyboardManagerEditorUI/Styles/Button.xaml index ab57b46c26..ca66de1435 100644 --- a/src/modules/keyboardmanager/KeyboardManagerEditorUI/Styles/Button.xaml +++ b/src/modules/keyboardmanager/KeyboardManagerEditorUI/Styles/Button.xaml @@ -1,4 +1,4 @@ - + -