]> git.lyx.org Git - lyx.git/blob - src/frontends/qt4/QLyXKeySym.C
7580dc2e1128907ffce75d355e782260787770c0
[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 void initEncodings()
82 {
83 #if 0
84         //const char * c = QTextCodec::locale();
85         //string s = c ? c : "";
86         // In this order, see support/filetools.C
87         string s = getEnv("LC_ALL");
88         if (s.empty()) {
89                 s = getEnv("LC_MESSAGES");
90                 if (s.empty()) {
91                         s = getEnv("LANG");
92                         if (s.empty())
93                                 s = "C";
94                 }
95         }
96
97         if (s.find("UTF") != string::npos || s.find("utf") != string::npos)
98         //if (contains(c, "UTF") || contains(c, "utf"))
99                 lyxerr << "Warning: this system's locale uses Unicode." << endl;
100
101         // strip off any encoding suffix
102         string::size_type i = s.find(".");
103         s = s.substr(0, i);
104
105         encoding_map["iso8859-1"] = QTextCodec::codecForName("ISO 8859-1");
106         encoding_map["iso8859-2"] = QTextCodec::codecForName("ISO 8859-2");
107         encoding_map["iso8859-3"] = QTextCodec::codecForName("ISO 8859-3");
108         encoding_map["iso8859-4"] = QTextCodec::codecForName("ISO 8859-4");
109         encoding_map["iso8859-5"] = QTextCodec::codecForName("ISO 8859-5");
110         encoding_map["iso8859-6"] = QTextCodec::codecForName("ISO 8859-6");
111         encoding_map["iso8859-7"] = QTextCodec::codecForName("ISO 8859-7");
112         encoding_map["iso8859-9"] = QTextCodec::codecForName("ISO 8859-9");
113         encoding_map["iso8859-15"] = QTextCodec::codecForName("ISO 8859-15");
114         encoding_map["cp1255"] = QTextCodec::codecForName("CP 1255");
115         encoding_map["cp1251"] = QTextCodec::codecForName("CP 1251");
116         encoding_map["koi8"] = QTextCodec::codecForName("KOI8-R");
117         encoding_map["koi8-u"] = QTextCodec::codecForName("KOI8-U");
118
119         // FIXME
120         encoding_map["tis620-0"] = 0;
121         encoding_map["pt154"] = 0;
122
123         // There are lots more codecs in Qt too ...
124
125         // when no document open
126         // use the appropriate encoding for the system language
127         lyxerr << "Language code:" << s << endl;
128         for (Languages::const_iterator it=languages.begin(); it != languages.end(); ++it) {
129                 //lyxerr << it->second.code() << ":" << it->second.encodingStr() << ":" << it->second.encoding() << endl;
130                 if (it->second.code() == s) {
131                         s = it->second.encodingStr();
132                         break;
133                 }
134         }
135         lyxerr << "Setting new locale for Qt:" << s << endl;
136         QTextCodec * defaultCodec = encoding_map[s];
137         encoding_map[""] = defaultCodec;
138
139         QTextCodec::setCodecForCStrings(defaultCodec);
140 #endif
141 }
142
143
144 QLyXKeySym::QLyXKeySym()
145         : LyXKeySym(), key_(0)
146 {
147 }
148
149
150 void QLyXKeySym::set(QKeyEvent * ev)
151 {
152         key_ = ev->key();
153         if (ev->text().isNull()) {
154                 if (lyxerr.debugging())
155                         lyxerr[Debug::KEY] << "keyevent has isNull() text !" << endl;
156                 text_ = "";
157                 return;
158         }
159         text_ = ev->text();
160         if (lyxerr.debugging())
161                 lyxerr[Debug::KEY] << "Setting key to " << key_ << ", " <<  fromqstr(text_) << endl;
162 }
163
164
165 void QLyXKeySym::init(string const & symbolname)
166 {
167         key_ = string_to_qkey(symbolname);
168         text_ = toqstr(symbolname);
169         if (lyxerr.debugging())
170                 lyxerr[Debug::KEY] << "Init key to " << key_ << ", " << fromqstr(text_) << endl;
171 }
172
173
174 bool QLyXKeySym::isOK() const
175 {
176         bool const ok(!(text_.isEmpty() && key_ == Qt::Key_unknown));
177         if (lyxerr.debugging())
178                 lyxerr[Debug::KEY] << "isOK is " << ok << endl;
179         return ok;
180 }
181
182
183 bool QLyXKeySym::isModifier() const
184 {
185         bool const mod(q_is_modifier(key_));
186         if (lyxerr.debugging())
187                 lyxerr[Debug::KEY] << "isMod is " << mod << endl;
188         return mod;
189 }
190
191
192 string QLyXKeySym::getSymbolName() const
193 {
194         string sym(qkey_to_string(key_));
195
196         // e.g. A-Za-z, and others
197         if (sym.empty())
198                 sym = fromqstr(text_);
199
200         return sym;
201 }
202
203
204 size_t QLyXKeySym::getUCSEncoded() const
205 {
206         if (text_.isEmpty())
207                 return 0;
208
209         BOOST_ASSERT(text_.size() == 1);
210         return qchar_to_ucs4(text_[0]);
211 }
212
213
214 QString const QLyXKeySym::qprint(key_modifier::state mod) const
215 {
216         int tmpkey = key_;
217
218         if (mod & key_modifier::shift)
219                 tmpkey += Qt::SHIFT;
220         if (mod & key_modifier::ctrl)
221                 tmpkey += Qt::CTRL;
222         if (mod & key_modifier::alt)
223                 tmpkey += Qt::ALT;
224
225         return QKeySequence(tmpkey).toString();
226 }
227
228
229 string const QLyXKeySym::print(key_modifier::state mod) const
230 {
231         return fromqstr(qprint(mod));
232 }
233
234
235 bool QLyXKeySym::isText() const
236 {
237         if (text_.isEmpty()) {
238                 if (lyxerr.debugging())
239                         lyxerr[Debug::KEY] << "text_ empty, isText() == false" << endl;
240                 return false;
241         }
242
243         return true;
244 }
245
246
247 bool operator==(LyXKeySym const & k1, LyXKeySym const & k2)
248 {
249         QLyXKeySym const & q1(static_cast<QLyXKeySym const &>(k1));
250         QLyXKeySym const & q2(static_cast<QLyXKeySym const &>(k2));
251
252         // we do not have enough info for a fair comparison, so return
253         // false. This works out OK because unknown text from Qt will
254         // get inserted anyway after the isText() check
255         if (q1.key() == Qt::Key_unknown || q2.key() == Qt::Key_unknown)
256                 return false;
257
258         return q1.key() == q2.key();
259 }
260
261
262 } // namespace lyx