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