accelerator_util.cc 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  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 "atom/browser/ui/accelerator_util.h"
  5. #include <stdio.h>
  6. #include <string>
  7. #include <vector>
  8. #include "atom/common/keyboard_util.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. namespace accelerator_util {
  14. bool StringToAccelerator(const std::string& shortcut,
  15. ui::Accelerator* accelerator) {
  16. if (!base::IsStringASCII(shortcut)) {
  17. LOG(ERROR) << "The accelerator string can only contain ASCII characters";
  18. return false;
  19. }
  20. std::vector<std::string> tokens = base::SplitString(
  21. shortcut, "+", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
  22. // Now, parse it into an accelerator.
  23. int modifiers = ui::EF_NONE;
  24. ui::KeyboardCode key = ui::VKEY_UNKNOWN;
  25. for (const auto& token : tokens) {
  26. bool shifted = false;
  27. ui::KeyboardCode code = atom::KeyboardCodeFromStr(token, &shifted);
  28. if (shifted)
  29. modifiers |= ui::EF_SHIFT_DOWN;
  30. switch (code) {
  31. // The token can be a modifier.
  32. case ui::VKEY_SHIFT:
  33. modifiers |= ui::EF_SHIFT_DOWN;
  34. break;
  35. case ui::VKEY_CONTROL:
  36. modifiers |= ui::EF_CONTROL_DOWN;
  37. break;
  38. case ui::VKEY_MENU:
  39. modifiers |= ui::EF_ALT_DOWN;
  40. break;
  41. case ui::VKEY_COMMAND:
  42. modifiers |= ui::EF_COMMAND_DOWN;
  43. break;
  44. case ui::VKEY_ALTGR:
  45. modifiers |= ui::EF_ALTGR_DOWN;
  46. break;
  47. // Or it is a normal key.
  48. default:
  49. key = code;
  50. }
  51. }
  52. if (key == ui::VKEY_UNKNOWN) {
  53. LOG(WARNING) << shortcut << " doesn't contain a valid key";
  54. return false;
  55. }
  56. *accelerator = ui::Accelerator(key, modifiers);
  57. SetPlatformAccelerator(accelerator);
  58. return true;
  59. }
  60. void GenerateAcceleratorTable(AcceleratorTable* table,
  61. atom::AtomMenuModel* model) {
  62. int count = model->GetItemCount();
  63. for (int i = 0; i < count; ++i) {
  64. atom::AtomMenuModel::ItemType type = model->GetTypeAt(i);
  65. if (type == atom::AtomMenuModel::TYPE_SUBMENU) {
  66. auto* submodel = model->GetSubmenuModelAt(i);
  67. GenerateAcceleratorTable(table, submodel);
  68. } else {
  69. ui::Accelerator accelerator;
  70. if (model->GetAcceleratorAtWithParams(i, true, &accelerator)) {
  71. MenuItem item = {i, model};
  72. (*table)[accelerator] = item;
  73. }
  74. }
  75. }
  76. }
  77. bool TriggerAcceleratorTableCommand(AcceleratorTable* table,
  78. const ui::Accelerator& accelerator) {
  79. if (base::ContainsKey(*table, accelerator)) {
  80. const accelerator_util::MenuItem& item = (*table)[accelerator];
  81. if (item.model->IsEnabledAt(item.position)) {
  82. item.model->ActivatedAt(item.position);
  83. return true;
  84. }
  85. }
  86. return false;
  87. }
  88. } // namespace accelerator_util