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