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