EditorHelpers.cpp
  1  #include "pch.h"
  2  #include <common/interop/keyboard_layout.h>
  3  #include <keyboardmanager/common/Helpers.h>
  4  
  5  #include "ShortcutErrorType.h"
  6  
  7  using Helpers::GetKeyType;
  8  
  9  namespace EditorHelpers
 10  {
 11      // Function to check if two keys are equal or cover the same set of keys. Return value depends on type of overlap
 12      ShortcutErrorType DoKeysOverlap(DWORD first, DWORD second)
 13      {
 14          // If the keys are same
 15          if (first == second)
 16          {
 17              return ShortcutErrorType::SameKeyPreviouslyMapped;
 18          }
 19          else if ((GetKeyType(first) == GetKeyType(second)) && GetKeyType(first) != Helpers::KeyType::Action)
 20          {
 21              // If the keys are of the same modifier type and overlapping, i.e. one is L/R and other is common
 22              if (((first == VK_LWIN && second == VK_RWIN) || (first == VK_RWIN && second == VK_LWIN)) || ((first == VK_LCONTROL && second == VK_RCONTROL) || (first == VK_RCONTROL && second == VK_LCONTROL)) || ((first == VK_LMENU && second == VK_RMENU) || (first == VK_RMENU && second == VK_LMENU)) || ((first == VK_LSHIFT && second == VK_RSHIFT) || (first == VK_RSHIFT && second == VK_LSHIFT)))
 23              {
 24                  return ShortcutErrorType::NoError;
 25              }
 26              else
 27              {
 28                  return ShortcutErrorType::ConflictingModifierKey;
 29              }
 30          }
 31          // If no overlap
 32          else
 33          {
 34              return ShortcutErrorType::NoError;
 35          }
 36      }
 37  
 38      // Function to check if a modifier has been repeated in the previous drop downs
 39      bool CheckRepeatedModifier(const std::vector<int32_t>& currentKeys, int selectedKeyCode)
 40      {
 41          // Count the number of keys that are equal to 'selectedKeyCode'
 42          int numberOfSameType = 0;
 43          for (int i = 0; i < currentKeys.size(); i++)
 44          {
 45              numberOfSameType += Helpers::GetKeyType(selectedKeyCode) == Helpers::GetKeyType(currentKeys[i]);
 46          }
 47  
 48          // If we have at least two keys equal to 'selectedKeyCode' than modifier was repeated
 49          return numberOfSameType > 1;
 50      }
 51  
 52      // Function to return true if the shortcut is valid. A valid shortcut has at least one modifier, as well as an action key
 53      bool IsValidShortcut(Shortcut shortcut)
 54      {
 55          if (shortcut.operationType == Shortcut::OperationType::RunProgram && shortcut.runProgramFilePath.length() > 0)
 56          {
 57              return true;
 58          }
 59  
 60          if (shortcut.operationType == Shortcut::OperationType::OpenURI && shortcut.uriToOpen.length() > 0)
 61          {
 62              return true;
 63          }
 64  
 65          if (shortcut.actionKey != NULL)
 66          {
 67              if (shortcut.winKey != ModifierKey::Disabled || shortcut.ctrlKey != ModifierKey::Disabled || shortcut.altKey != ModifierKey::Disabled || shortcut.shiftKey != ModifierKey::Disabled)
 68              {
 69                  return true;
 70              }
 71          }
 72  
 73          return false;
 74      }
 75  
 76      // Function to check if the two shortcuts are equal or cover the same set of keys. Return value depends on type of overlap
 77      ShortcutErrorType DoShortcutsOverlap(const Shortcut& first, const Shortcut& second)
 78      {
 79          if (IsValidShortcut(first) && IsValidShortcut(second))
 80          {
 81              // If the shortcuts are equal
 82              if (first == second)
 83              {
 84                  return ShortcutErrorType::SameShortcutPreviouslyMapped;
 85              }
 86              // action keys match
 87              else if (first.actionKey == second.actionKey)
 88              {
 89                  // corresponding modifiers are either both disabled or both not disabled - this ensures that both match in types of modifiers i.e. Ctrl(l/r/c) Shift (l/r/c) A matches Ctrl(l/r/c) Shift (l/r/c) A
 90                  if (((first.winKey != ModifierKey::Disabled && second.winKey != ModifierKey::Disabled) || (first.winKey == ModifierKey::Disabled && second.winKey == ModifierKey::Disabled)) &&
 91                      ((first.ctrlKey != ModifierKey::Disabled && second.ctrlKey != ModifierKey::Disabled) || (first.ctrlKey == ModifierKey::Disabled && second.ctrlKey == ModifierKey::Disabled)) &&
 92                      ((first.altKey != ModifierKey::Disabled && second.altKey != ModifierKey::Disabled) || (first.altKey == ModifierKey::Disabled && second.altKey == ModifierKey::Disabled)) &&
 93                      ((first.shiftKey != ModifierKey::Disabled && second.shiftKey != ModifierKey::Disabled) || (first.shiftKey == ModifierKey::Disabled && second.shiftKey == ModifierKey::Disabled)))
 94                  {
 95                      // If one of the modifier is common
 96                      if ((first.winKey == ModifierKey::Both || second.winKey == ModifierKey::Both) ||
 97                          (first.ctrlKey == ModifierKey::Both || second.ctrlKey == ModifierKey::Both) ||
 98                          (first.altKey == ModifierKey::Both || second.altKey == ModifierKey::Both) ||
 99                          (first.shiftKey == ModifierKey::Both || second.shiftKey == ModifierKey::Both))
100                      {
101                          return ShortcutErrorType::ConflictingModifierShortcut;
102                      }
103                  }
104              }
105          }
106  
107          return ShortcutErrorType::NoError;
108      }
109  
110      // Function to return a vector of hstring for each key in the display order
111      std::vector<winrt::hstring> GetKeyVector(Shortcut shortcut, LayoutMap& keyboardMap)
112      {
113          std::vector<winrt::hstring> keys;
114          if (shortcut.winKey != ModifierKey::Disabled)
115          {
116              keys.push_back(winrt::to_hstring(keyboardMap.GetKeyName(shortcut.GetWinKey(ModifierKey::Both)).c_str()));
117          }
118          if (shortcut.ctrlKey != ModifierKey::Disabled)
119          {
120              keys.push_back(winrt::to_hstring(keyboardMap.GetKeyName(shortcut.GetCtrlKey(ModifierKey::Both)).c_str()));
121          }
122          if (shortcut.altKey != ModifierKey::Disabled)
123          {
124              keys.push_back(winrt::to_hstring(keyboardMap.GetKeyName(shortcut.GetAltKey(ModifierKey::Both)).c_str()));
125          }
126          if (shortcut.shiftKey != ModifierKey::Disabled)
127          {
128              keys.push_back(winrt::to_hstring(keyboardMap.GetKeyName(shortcut.GetShiftKey(ModifierKey::Both)).c_str()));
129          }
130          if (shortcut.actionKey != NULL)
131          {
132              keys.push_back(winrt::to_hstring(keyboardMap.GetKeyName(shortcut.actionKey).c_str()));
133          }
134          return keys;
135      }
136  
137      // Function to check if the shortcut is illegal (i.e. Win+L or Ctrl+Alt+Del)
138      ShortcutErrorType IsShortcutIllegal(Shortcut shortcut)
139      {
140          // Win+L
141          if (shortcut.winKey != ModifierKey::Disabled && shortcut.ctrlKey == ModifierKey::Disabled && shortcut.altKey == ModifierKey::Disabled && shortcut.shiftKey == ModifierKey::Disabled && shortcut.actionKey == 0x4C)
142          {
143              return ShortcutErrorType::WinL;
144          }
145  
146          // Ctrl+Alt+Del
147          if (shortcut.winKey == ModifierKey::Disabled && shortcut.ctrlKey != ModifierKey::Disabled && shortcut.altKey != ModifierKey::Disabled && shortcut.shiftKey == ModifierKey::Disabled && shortcut.actionKey == VK_DELETE)
148          {
149              return ShortcutErrorType::CtrlAltDel;
150          }
151  
152          return ShortcutErrorType::NoError;
153      }
154  }