accelerator_util.cc 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. // Copyright (c) 2013 GitHub, Inc.
  2. // Use of this source code is governed by the MIT license that can be
  3. // found in the LICENSE file.
  4. #include "shell/browser/ui/accelerator_util.h"
  5. #include <stdio.h>
  6. #include <string>
  7. #include <vector>
  8. #include "base/logging.h"
  9. #include "base/stl_util.h"
  10. #include "base/strings/string_number_conversions.h"
  11. #include "base/strings/string_split.h"
  12. #include "base/strings/string_util.h"
  13. #include "shell/common/keyboard_util.h"
  14. namespace accelerator_util {
  15. bool StringToAccelerator(const std::string& shortcut,
  16. ui::Accelerator* accelerator) {
  17. if (!base::IsStringASCII(shortcut)) {
  18. LOG(ERROR) << "The accelerator string can only contain ASCII characters, "
  19. "invalid string: "
  20. << "\"" << shortcut << "\"";
  21. return false;
  22. }
  23. std::vector<std::string> tokens = base::SplitString(
  24. shortcut, "+", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
  25. // Now, parse it into an accelerator.
  26. int modifiers = ui::EF_NONE;
  27. ui::KeyboardCode key = ui::VKEY_UNKNOWN;
  28. absl::optional<char16_t> shifted_char;
  29. for (const auto& token : tokens) {
  30. ui::KeyboardCode code = electron::KeyboardCodeFromStr(token, &shifted_char);
  31. if (shifted_char)
  32. modifiers |= ui::EF_SHIFT_DOWN;
  33. switch (code) {
  34. // The token can be a modifier.
  35. case ui::VKEY_SHIFT:
  36. modifiers |= ui::EF_SHIFT_DOWN;
  37. break;
  38. case ui::VKEY_CONTROL:
  39. modifiers |= ui::EF_CONTROL_DOWN;
  40. break;
  41. case ui::VKEY_MENU:
  42. modifiers |= ui::EF_ALT_DOWN;
  43. break;
  44. case ui::VKEY_COMMAND:
  45. modifiers |= ui::EF_COMMAND_DOWN;
  46. break;
  47. case ui::VKEY_ALTGR:
  48. modifiers |= ui::EF_ALTGR_DOWN;
  49. break;
  50. // Or it is a normal key.
  51. default:
  52. key = code;
  53. }
  54. }
  55. if (key == ui::VKEY_UNKNOWN) {
  56. LOG(WARNING) << shortcut << " doesn't contain a valid key";
  57. return false;
  58. }
  59. *accelerator = ui::Accelerator(key, modifiers);
  60. accelerator->shifted_char = shifted_char;
  61. return true;
  62. }
  63. void GenerateAcceleratorTable(AcceleratorTable* table,
  64. electron::ElectronMenuModel* model) {
  65. size_t count = model->GetItemCount();
  66. for (size_t i = 0; i < count; ++i) {
  67. electron::ElectronMenuModel::ItemType type = model->GetTypeAt(i);
  68. if (type == electron::ElectronMenuModel::TYPE_SUBMENU) {
  69. auto* submodel = model->GetSubmenuModelAt(i);
  70. GenerateAcceleratorTable(table, submodel);
  71. } else {
  72. ui::Accelerator accelerator;
  73. if (model->ShouldRegisterAcceleratorAt(i)) {
  74. if (model->GetAcceleratorAtWithParams(i, true, &accelerator)) {
  75. MenuItem item = {i, model};
  76. (*table)[accelerator] = item;
  77. }
  78. }
  79. }
  80. }
  81. }
  82. bool TriggerAcceleratorTableCommand(AcceleratorTable* table,
  83. const ui::Accelerator& accelerator) {
  84. const auto iter = table->find(accelerator);
  85. if (iter != std::end(*table)) {
  86. const accelerator_util::MenuItem& item = iter->second;
  87. if (item.model->IsEnabledAt(item.position)) {
  88. const auto event_flags =
  89. accelerator.MaskOutKeyEventFlags(accelerator.modifiers());
  90. item.model->ActivatedAt(item.position, event_flags);
  91. return true;
  92. }
  93. }
  94. return false;
  95. }
  96. } // namespace accelerator_util