]> git.lyx.org Git - lyx.git/blob - src/frontends/qt4/QLyXKeySym.C
GUI API Cleanup step 2: merge of the "younes" branch. What's missing
[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 "encoding.h"
30 #include "language.h"
31
32 using std::endl;
33 using std::string;
34 using std::map;
35 using lyx::support::contains;
36 using lyx::support::getEnv;
37
38
39 namespace {
40
41 typedef map<string, QTextCodec *> EncodingMap;
42 EncodingMap encoding_map;
43
44 char const encode(string const & encoding, QString const & str)
45 {
46         QTextCodec * codec = 0;
47
48         EncodingMap::const_iterator cit = encoding_map.find(encoding);
49         if (cit == encoding_map.end()) {
50                 lyxerr[Debug::KEY] << "Unrecognised encoding '" << encoding
51                                    << "'." << endl;
52                 codec = encoding_map.find("")->second;
53         } else {
54                 codec = cit->second;
55         }
56
57         if (!codec) {
58                 lyxerr[Debug::KEY] << "No codec for encoding '" << encoding
59                                    << "' found." << endl;
60                 return 0;
61         }
62
63         lyxerr[Debug::KEY] << "Using codec " << fromqstr(codec->name()) << endl;
64
65         if (!codec->canEncode(str)) {
66                 lyxerr[Debug::KEY] << "Oof. Can't encode the text !" << endl;
67                 return 0;
68         }
69
70         return codec->fromUnicode(str).data()[0];
71 }
72
73 }
74
75
76 void initEncodings()
77 {
78         //const char * c = QTextCodec::locale();
79         //string s = c ? c : "";
80         // In this order, see support/filetools.C
81         string s = getEnv("LC_ALL");
82         if (s.empty()) {
83                 s = getEnv("LC_MESSAGES");
84                 if (s.empty()) {
85                         s = getEnv("LANG");
86                         if (s.empty())
87                                 s = "C";
88                 }
89         }
90
91         if (s.find("UTF") != string::npos || s.find("utf") != string::npos)
92         //if (contains(c, "UTF") || contains(c, "utf"))
93                 lyxerr << "Warning: this system's locale uses Unicode." << endl;
94
95         // strip off any encoding suffix
96         string::size_type i = s.find(".");
97         s = s.substr(0, i);
98
99         encoding_map["iso8859-1"] = QTextCodec::codecForName("ISO 8859-1");
100         encoding_map["iso8859-2"] = QTextCodec::codecForName("ISO 8859-2");
101         encoding_map["iso8859-3"] = QTextCodec::codecForName("ISO 8859-3");
102         encoding_map["iso8859-4"] = QTextCodec::codecForName("ISO 8859-4");
103         encoding_map["iso8859-5"] = QTextCodec::codecForName("ISO 8859-5");
104         encoding_map["iso8859-6"] = QTextCodec::codecForName("ISO 8859-6");
105         encoding_map["iso8859-7"] = QTextCodec::codecForName("ISO 8859-7");
106         encoding_map["iso8859-9"] = QTextCodec::codecForName("ISO 8859-9");
107         encoding_map["iso8859-15"] = QTextCodec::codecForName("ISO 8859-15");
108         encoding_map["cp1255"] = QTextCodec::codecForName("CP 1255");
109         encoding_map["cp1251"] = QTextCodec::codecForName("CP 1251");
110         encoding_map["koi8"] = QTextCodec::codecForName("KOI8-R");
111         encoding_map["koi8-u"] = QTextCodec::codecForName("KOI8-U");
112
113         // FIXME
114         encoding_map["tis620-0"] = 0;
115         encoding_map["pt154"] = 0;
116
117         // There are lots more codecs in Qt too ...
118
119         // when no document open
120         // use the appropriate encoding for the system language
121         lyxerr << "Language code:" << s << endl;
122         for (Languages::const_iterator it=languages.begin(); it != languages.end(); ++it) {
123                 //lyxerr << it->second.code() << ":" << it->second.encodingStr() << ":" << it->second.encoding() << endl;
124                 if (it->second.code() == s) {
125                         s = it->second.encodingStr();
126                         break;
127                 }
128         }
129         lyxerr << "Setting new locale for Qt:" << s << endl;
130         QTextCodec * defaultCodec = encoding_map[s];
131         encoding_map[""] = defaultCodec;
132
133         QTextCodec::setCodecForCStrings(defaultCodec);
134
135 }
136
137
138 QLyXKeySym::QLyXKeySym()
139         : LyXKeySym(), key_(0)
140 {
141 }
142
143
144 void QLyXKeySym::set(QKeyEvent * ev)
145 {
146         key_ = ev->key();
147         if (ev->text().isNull()) {
148                 if (lyxerr.debugging())
149                         lyxerr[Debug::KEY] << "keyevent has isNull() text !" << endl;
150                 text_ = "";
151                 return;
152         }
153         text_ = ev->text();
154         if (lyxerr.debugging())
155                 lyxerr[Debug::KEY] << "Setting key to " << key_ << ", " <<  fromqstr(text_) << endl;
156 }
157
158
159 void QLyXKeySym::init(string const & symbolname)
160 {
161         key_ = string_to_qkey(symbolname);
162         text_ = toqstr(symbolname);
163         if (lyxerr.debugging())
164                 lyxerr[Debug::KEY] << "Init key to " << key_ << ", " << fromqstr(text_) << endl;
165 }
166
167
168 bool QLyXKeySym::isOK() const
169 {
170         bool const ok(!(text_.isEmpty() && key_ == Qt::Key_unknown));
171         if (lyxerr.debugging())
172                 lyxerr[Debug::KEY] << "isOK is " << ok << endl;
173         return ok;
174 }
175
176
177 bool QLyXKeySym::isModifier() const
178 {
179         bool const mod(q_is_modifier(key_));
180         if (lyxerr.debugging())
181                 lyxerr[Debug::KEY] << "isMod is " << mod << endl;
182         return mod;
183 }
184
185
186 string QLyXKeySym::getSymbolName() const
187 {
188         string sym(qkey_to_string(key_));
189
190         // e.g. A-Za-z, and others
191         if (sym.empty())
192                 sym = fromqstr(text_);
193
194         return sym;
195 }
196
197
198 char QLyXKeySym::getISOEncoded(string const & encoding) const
199 {
200         if (lyxerr.debugging())
201                 lyxerr[Debug::KEY] << "encoding is " << encoding << endl;
202         unsigned char const c = encode(encoding, text_);
203         if (lyxerr.debugging())
204                 lyxerr[Debug::KEY] << "ISOEncoded returning value " << int(c) << endl;
205         return c;
206 }
207
208
209 QString const QLyXKeySym::qprint(key_modifier::state mod) const
210 {
211         int tmpkey = key_;
212
213         if (mod & key_modifier::shift)
214                 tmpkey += Qt::SHIFT;
215         if (mod & key_modifier::ctrl)
216                 tmpkey += Qt::CTRL;
217         if (mod & key_modifier::alt)
218                 tmpkey += Qt::ALT;
219
220         return QKeySequence(tmpkey).toString();
221 }
222
223
224 string const QLyXKeySym::print(key_modifier::state mod) const
225 {
226         return fromqstr(qprint(mod));
227 }
228
229
230 bool QLyXKeySym::isText() const
231 {
232         if (text_.isEmpty()) {
233                 if (lyxerr.debugging())
234                         lyxerr[Debug::KEY] << "text_ empty, isText() == false" << endl;
235                 return false;
236         }
237
238         QChar const c(text_[0]);
239         if (lyxerr.debugging())
240                 lyxerr[Debug::KEY] << "isText for key " << key_
241                         << " isPrint is " << c.isPrint() << endl;
242         return c.isPrint();
243 }
244
245
246 bool operator==(LyXKeySym const & k1, LyXKeySym const & k2)
247 {
248         QLyXKeySym const & q1(static_cast<QLyXKeySym const &>(k1));
249         QLyXKeySym const & q2(static_cast<QLyXKeySym const &>(k2));
250
251         // we do not have enough info for a fair comparison, so return
252         // false. This works out OK because unknown text from Qt will
253         // get inserted anyway after the isText() check
254         if (q1.key() == Qt::Key_unknown || q2.key() == Qt::Key_unknown)
255                 return false;
256
257         return q1.key() == q2.key();
258 }