Fcitx
key.h
Go to the documentation of this file.
1 /*
2  * SPDX-FileCopyrightText: 2015-2015 CSSlayer <wengxt@gmail.com>
3  *
4  * SPDX-License-Identifier: LGPL-2.1-or-later
5  *
6  */
7 
8 #ifndef _FCITX_UTILS_KEY_H_
9 #define _FCITX_UTILS_KEY_H_
10 
11 /// \addtogroup FcitxUtils
12 /// \{
13 /// \file
14 /// \brief Class to represent a key.
15 
16 #include <algorithm>
17 #include <cstddef>
18 #include <cstdint>
19 #include <string>
20 #include <vector>
21 #include <fcitx-utils/flags.h>
22 #include <fcitx-utils/keysym.h>
23 #include "fcitxutils_export.h"
24 
25 namespace fcitx {
26 class Key;
27 using KeySym = FcitxKeySym;
28 using KeyStates = Flags<KeyState>;
29 using KeyList = std::vector<Key>;
30 
31 /// Control the behavior of toString function.
32 enum class KeyStringFormat {
33  /// Can be used to parse from a string.
34  Portable,
35  /// Return the human readable string in localized format.
36  Localized,
37 };
38 
39 /// Describe a Key in fcitx.
40 class FCITXUTILS_EXPORT Key {
41 public:
42  explicit Key(KeySym sym = FcitxKey_None, KeyStates states = KeyStates(),
43  int code = 0)
44  : sym_(sym), states_(states), code_(code) {}
45 
46  /// Parse a key from string. If string is invalid, it will be set to
47  /// FcitxKey_None
48  explicit Key(const char *keyString);
49 
50  /// Parse a key from std::string.
51  /// \see fcitx::Key::Key(const char *)
52  explicit Key(const std::string &keyString) : Key(keyString.c_str()) {}
53 
54  FCITX_INLINE_DEFINE_DEFAULT_DTOR_COPY_AND_MOVE(Key)
55 
56  /// Create a key code based key with empty key symbol.
57  static Key fromKeyCode(int code = 0, KeyStates states = KeyStates()) {
58  return Key(FcitxKey_None, states, code);
59  }
60 
61  /// Check if key is exactly same.
62  bool operator==(const Key &key) const {
63  return sym_ == key.sym_ && states_ == key.states_ && code_ == key.code_;
64  }
65 
66  /// Check if key is not same;
67  bool operator!=(const Key &key) const { return !operator==(key); }
68 
69  /// Check if current key match the key.
70  bool check(const Key &key) const;
71 
72  /// Check if current key match the sym and states.
73  /// \see fcitx::Key::check(const Key &key)
74  bool check(KeySym sym = FcitxKey_None,
75  KeyStates states = KeyStates()) const {
76  return check(Key(sym, states));
77  }
78 
79  /**
80  * Check if current key is a key release of given modifier only key.
81  *
82  * This is a very specialized check for modifier release case.
83  * And it's designed to handle modifier only key.
84  *
85  * For example, if Alt+Shift_L is pressed, then the following release key of
86  * this event can be either: Alt+Shift+Shift_L, or Alt+Shift+Meta_{L,R}.
87  * This is because: Alt -> Meta_{L,R}, if alt is released first, then it
88  * will produce Alt+Shift+Meta_{L,R}. If shift is released first, then it
89  * will produce Alt+Shift+Shift_L.
90  *
91  * Return false if key is not a modifier.
92  */
93  bool isReleaseOfModifier(const Key &key) const;
94 
95  /**
96  * Check if key is digit key or keypad digit key.
97  *
98  * Since 5.0.20, it will also return true for keypad digit key.
99  * @return Whether the key is a digit key without modifier.
100  */
101  bool isDigit() const;
102 
103  /**
104  * Return the value of digit key.
105  *
106  * The key must not have modifier.
107  * For example, FcitxKey_7 will return 7.
108  *
109  * @return value of digit key. If the key is not a digit key, it returns -1.
110  * @since 5.0.20
111  */
112  int digit() const;
113 
114  /**
115  * Return index when using digit key for selection.
116  *
117  * The return value will return in the order of 1234567890.
118  *
119  * @return index of digit key. If the key is not a digit key, it returns -1.
120  * @since 5.0.20
121  * @see digit
122  */
123  int digitSelection(KeyStates states = KeyStates()) const;
124 
125  /// Check if key is upper case.
126  bool isUAZ() const;
127 
128  /// Check if key is lower case.
129  bool isLAZ() const;
130 
131  /// Check if key is in the range of ascii and has no states.
132  bool isSimple() const;
133 
134  /// Check if the key is a modifier press.
135  bool isModifier() const;
136 
137  /// Check if this key will cause cursor to move, e.g. arrow key and page up/
138  /// down.
139  bool isCursorMove() const;
140 
141  /// Check if this key is a key pad key.
142  bool isKeyPad() const;
143 
144  /// Check if states has modifier.
145  bool hasModifier() const;
146 
147  /// Check if states has virtual bit
148  bool isVirtual() const;
149 
150  /// \brief Normalize a key, usually used when key is from frontend.
151  ///
152  /// states will be filtered to have only ctrl alt shift and super.
153  /// Shift will be removed if it is key symbol is a-z/A-Z.
154  /// Shift + any other modifier and a-z will be reset to A-Z. So
155  /// key in configuration does not need to bother the case.
156  Key normalize() const;
157 
158  /// \brief Convert key to a string.
159  ///
160  /// \arg format will control the format of return value.
161  std::string
162  toString(KeyStringFormat format = KeyStringFormat::Portable) const;
163 
164  /// Check if the sym is not FcitxKey_None or FcitxKey_VoidSymbol.
165  bool isValid() const;
166 
167  inline KeySym sym() const { return sym_; }
168  inline KeyStates states() const { return states_; }
169  inline int code() const { return code_; }
170 
171  /// Convert the modifier symbol to its corresponding states.
172  static KeyStates keySymToStates(KeySym sym);
173 
174  /// Convert a key symbol string to KeySym.
175  static KeySym keySymFromString(const std::string &keyString);
176 
177  /// \brief Convert keysym to a string.
178  ///
179  /// \arg format will control the format of return value.
180  static std::string
181  keySymToString(KeySym sym,
183 
184  /// Convert unicode to key symbol. Useful when you want to create a
185  /// synthetic key event.
186  static KeySym keySymFromUnicode(uint32_t unicode);
187 
188  /// Convert keysym to a unicode. Will return a valid value UCS-4 value if
189  /// this key may produce a character.
190  static uint32_t keySymToUnicode(KeySym sym);
191 
192  /// Convert keysym to a unicode string. Will return a non empty value UTF-8
193  /// string if this key may produce a character.
194  /// \see fcitx::Key::keySymToUnicode
195  static std::string keySymToUTF8(KeySym sym);
196 
197  /// Parse a list of key string into a KeyList.
198  static KeyList keyListFromString(const std::string &str);
199 
200  /// Convert a key list to string.
201  template <typename Container>
202  static std::string
203  keyListToString(const Container &container,
205  std::string result;
206  bool first = true;
207  for (const auto &k : container) {
208  if (first) {
209  first = false;
210  } else {
211  result += " ";
212  }
213  result += k.toString(format);
214  }
215  return result;
216  }
217 
218  /// Check the current key against a key list.
219  /// \see fcitx::Key::check
220  template <typename Container>
221  bool checkKeyList(const Container &c) const {
222  return std::find_if(c.begin(), c.end(), [this](const Key &toCheck) {
223  return check(toCheck);
224  }) != c.end();
225  }
226 
227  /// Check the current key against a key list and get the matched key index.
228  /// \return Returns the matched key index or -1 if there is no match.
229  /// \see fcitx::Key::check
230  template <typename Container>
231  int keyListIndex(const Container &c) const {
232  size_t idx = 0;
233  for (auto &toCheck : c) {
234  if (check(toCheck)) {
235  break;
236  }
237  idx++;
238  }
239  if (idx == c.size()) {
240  return -1;
241  }
242  return static_cast<int>(idx);
243  }
244 
245 private:
246  KeySym sym_;
247  KeyStates states_;
248  int code_;
249 };
250 } // namespace fcitx
251 
252 #endif // _FCITX_UTILS_KEY_H_
Describe a Key in fcitx.
Definition: key.h:40
bool operator!=(const Key &key) const
Check if key is not same;.
Definition: key.h:67
bool checkKeyList(const Container &c) const
Check the current key against a key list.
Definition: key.h:221
Definition: action.cpp:12
KeyStringFormat
Control the behavior of toString function.
Definition: key.h:32
Can be used to parse from a string.
bool operator==(const Key &key) const
Check if key is exactly same.
Definition: key.h:62
bool check(KeySym sym=FcitxKey_None, KeyStates states=KeyStates()) const
Check if current key match the sym and states.
Definition: key.h:74
int keyListIndex(const Container &c) const
Check the current key against a key list and get the matched key index.
Definition: key.h:231
Return the human readable string in localized format.
Key sym related types.
Helper template class to make easier to use type safe enum flags.
static std::string keyListToString(const Container &container, KeyStringFormat format=KeyStringFormat::Portable)
Convert a key list to string.
Definition: key.h:203
Key(const std::string &keyString)
Parse a key from std::string.
Definition: key.h:52