]> git.lyx.org Git - lyx.git/blob - src/frontends/qt4/GuiKeySymbol.cpp
PrefShortcuts: ShortcutEdit, adapted from Edwin's patch
[lyx.git] / src / frontends / qt4 / GuiKeySymbol.cpp
1 /**
2  * \file qt4/KeySymbolFactory.cpp
3  * This file is part of LyX, the document processor.
4  * Licence details can be found in the file COPYING.
5  *
6  * \author Asger & Jürgen
7  *
8  * Full author contact details are available in file CREDITS.
9  */
10
11 #include <config.h>
12
13 #include "KeySymbol.h"
14
15 #include "qlkey.h"
16 #include "qt_helpers.h"
17
18 #include "debug.h"
19
20 #include "support/lstrings.h"
21 #include "support/environment.h"
22 #include "support/unicode.h"
23
24 #include "Encoding.h"
25 #include "Language.h"
26
27 #include <QKeyEvent>
28 #include <QKeySequence>
29 #include <QEvent>
30 #include <QTextCodec>
31
32 #include <map>
33
34
35 namespace lyx {
36
37 using std::endl;
38 using std::string;
39 using std::map;
40 using lyx::support::contains;
41 using lyx::support::getEnv;
42
43
44 static char encode(string const & encoding, QString const & str)
45 {
46         typedef map<string, QTextCodec *> EncodingMap;
47         EncodingMap encoding_map;
48
49         QTextCodec * codec = 0;
50
51         EncodingMap::const_iterator cit = encoding_map.find(encoding);
52         if (cit == encoding_map.end()) {
53                 LYXERR(Debug::KEY) << "Unrecognised encoding '" << encoding
54                                    << "'." << endl;
55                 codec = encoding_map.find("")->second;
56         } else {
57                 codec = cit->second;
58         }
59
60         if (!codec) {
61                 LYXERR(Debug::KEY) << "No codec for encoding '" << encoding
62                                    << "' found." << endl;
63                 return 0;
64         }
65
66         LYXERR(Debug::KEY) << "Using codec " << fromqstr(codec->name()) << endl;
67
68         if (!codec->canEncode(str)) {
69                 LYXERR(Debug::KEY) << "Oof. Can't encode the text !" << endl;
70                 return 0;
71         }
72
73         return codec->fromUnicode(str).data()[0];
74 }
75
76
77 void setKeySymbol(KeySymbol * sym, QKeyEvent * ev)
78 {
79         sym->setKey(ev->key());
80         if (ev->text().isNull()) {
81                 LYXERR(Debug::KEY) << "keyevent has isNull() text !" << endl;
82                 sym->setText(docstring());
83                 return;
84         }
85         sym->setText(qstring_to_ucs4(ev->text()));
86         LYXERR(Debug::KEY) << "Setting key to " << sym->key() << ", "
87                 << to_utf8(sym->text()) << endl;
88 }
89
90
91 void KeySymbol::init(string const & symbolname)
92 {
93         key_ = string_to_qkey(symbolname);
94         text_ = from_utf8(symbolname);
95         LYXERR(Debug::KEY) << "Init key to " << key_ << ", "
96                 << to_utf8(text_) << endl;
97 }
98
99
100 bool KeySymbol::isOK() const
101 {
102         bool const ok = !(text_.empty() && key_ == Qt::Key_unknown);
103         LYXERR(Debug::KEY) << "isOK is " << ok << endl;
104         return ok;
105 }
106
107
108 bool KeySymbol::isModifier() const
109 {
110         bool const mod = q_is_modifier(key_);
111         LYXERR(Debug::KEY) << "isMod is " << mod << endl;
112         return mod;
113 }
114
115
116 string KeySymbol::getSymbolName() const
117 {
118         string name = qkey_to_string(key_);
119
120         // e.g. A-Za-z, and others
121         if (name.empty())
122                 name = to_utf8(text_);
123
124         return name;
125 }
126
127
128 char_type KeySymbol::getUCSEncoded() const
129 {
130         if (text_.empty())
131                 return 0;
132
133         // UTF16 has a maximum of two characters.
134         BOOST_ASSERT(text_.size() <= 2);
135
136         if (lyxerr.debugging() && text_.size() > 1) {
137                 // We don't know yet how well support the full ucs4 range.
138                 LYXERR(Debug::KEY) << "KeySymbol::getUCSEncoded()" << endl;
139                 for (int i = 0; i != int(text_.size()); ++i) {
140                         LYXERR(Debug::KEY) << "char " << i << ": "
141                                 << int(text_[i]) << endl;
142                 }
143         }
144
145         return text_[0];
146 }
147
148
149 docstring const KeySymbol::print(KeyModifier mod, bool forgui) const
150 {
151         int tmpkey = key_;
152
153         if (mod & ShiftModifier)
154                 tmpkey += Qt::ShiftModifier;
155         if (mod & ControlModifier)
156                 tmpkey += Qt::ControlModifier;
157         if (mod & AltModifier)
158                 tmpkey += Qt::AltModifier;
159
160         QKeySequence seq(tmpkey);
161
162         return qstring_to_ucs4(seq.toString(forgui ? QKeySequence::NativeText
163                                             : QKeySequence::PortableText));
164 }
165
166
167 bool KeySymbol::isText() const
168 {
169         if (!text_.empty())
170                 return true;
171         LYXERR(Debug::KEY) << "text_ empty, isText() == false" << endl;
172         return false;
173 }
174
175
176 bool KeySymbol::operator==(KeySymbol const & ks) const
177 {
178         // we do not have enough info for a fair comparison, so return
179         // false. This works out OK because unknown text from Qt will
180         // get inserted anyway after the isText() check
181         if (key_ == Qt::Key_unknown || ks.key_ == Qt::Key_unknown)
182                 return false;
183         return key_ == ks.key_;
184 }
185
186
187 KeyModifier q_key_state(Qt::KeyboardModifiers state)
188 {
189         KeyModifier k = NoModifier;
190         if (state & Qt::ControlModifier)
191                 k |= ControlModifier;
192         if (state & Qt::ShiftModifier)
193                 k |= ShiftModifier;
194         if (state & Qt::AltModifier || state & Qt::MetaModifier)
195                 k |= AltModifier;
196         return k;
197 }
198
199 } // namespace lyx