]> git.lyx.org Git - lyx.git/blob - src/trans_mgr.C
"Inter-word Space"
[lyx.git] / src / trans_mgr.C
1 #include <config.h>
2
3 #include "trans_mgr.h"
4 #include "trans.h"
5 #include "lyxtext.h"
6 #include "LString.h"
7 #include "debug.h"
8 #include "chset.h"
9 #include "insets/insetlatexaccent.h"
10 #include "BufferView.h"
11 #include "buffer.h"
12 #include "lyxrc.h"
13 #include "support/lstrings.h"
14
15 using std::endl;
16 using std::pair;
17
18 extern string const DoAccent(string const &, tex_accent);
19 extern string const DoAccent(char, tex_accent);
20
21
22 // TransFSMData
23 TransFSMData::TransFSMData()
24 {
25         deadkey_ = deadkey2_ = 0;
26         deadkey_info_.accent = deadkey2_info_.accent = TEX_NOACCENT;
27 }
28
29
30 // TransState
31 char const TransState::TOKEN_SEP = 4;
32
33
34 // TransInitState
35 TransInitState::TransInitState()
36 {
37         init_state_ = this;
38 }
39
40
41 string const TransInitState::normalkey(char c)
42 {
43         string res;
44         res = c;
45         return res;
46 }
47
48
49 string const TransInitState::deadkey(char c, KmodInfo d)
50 {
51         deadkey_ = c;
52         deadkey_info_ = d;
53         currentState = deadkey_state_;
54         return string();
55 }
56
57
58 // TransDeadkeyState
59 TransDeadkeyState::TransDeadkeyState()
60 {
61         deadkey_state_ = this;
62 }
63
64
65 string const TransDeadkeyState::normalkey(char c)
66 {
67         string res;
68
69         KmodException::iterator it = deadkey_info_.exception_list.begin();
70         KmodException::iterator end = deadkey_info_.exception_list.end();
71
72         for (; it != end; ++it) {
73                 if (it->c == c) {
74                         res = it->data;
75                         break;
76                 }
77         }
78         if (it == end) {
79                 res = DoAccent(c, deadkey_info_.accent);
80         }
81         currentState = init_state_;
82         return res;
83 }
84
85
86 string const TransDeadkeyState::deadkey(char c, KmodInfo d)
87 {
88         string res;
89
90         // Check if the same deadkey was typed twice
91         if (deadkey_ == c) {
92                 res = deadkey_;
93                 deadkey_ = 0;
94                 deadkey_info_.accent = TEX_NOACCENT;
95                 currentState = init_state_;
96                 return res;
97         }
98
99         // Check if it is a combination or an exception
100         KmodException::const_iterator cit = deadkey_info_.exception_list.begin();
101         KmodException::const_iterator end = deadkey_info_.exception_list.end();
102         for (; cit != end; ++cit) {
103                 if (cit->combined == true && cit->accent == d.accent) {
104                         deadkey2_ = c;
105                         deadkey2_info_ = d;
106                         comb_info_ = (*cit);
107                         currentState = combined_state_;
108                         return string();
109                 }
110                 if (cit->c == c) {
111                         res = cit->data;
112                         deadkey_ = 0;
113                         deadkey_info_.accent = TEX_NOACCENT;
114                         currentState = init_state_;
115                         return res;
116                 }
117         }
118
119         // Not a combination or an exception.
120         // Output deadkey1 and keep deadkey2
121
122         if (deadkey_!= 0)
123                 res = deadkey_;
124         deadkey_ = c;
125         deadkey_info_ = d;
126         currentState = deadkey_state_;
127         return res;
128 }
129
130
131 TransCombinedState::TransCombinedState()
132 {
133         combined_state_ = this;
134 }
135
136
137 string const TransCombinedState::normalkey(char c)
138 {
139         string const temp = DoAccent(c, deadkey2_info_.accent);
140         string const res = DoAccent(temp, deadkey_info_.accent);
141         currentState = init_state_;
142         return res;
143 }
144
145
146 string const TransCombinedState::deadkey(char c, KmodInfo d)
147 {
148         // Third key in a row. Output the first one and
149         // reenter with shifted deadkeys
150         string res;
151         if (deadkey_ != 0)
152                 res = deadkey_;
153         res += TOKEN_SEP;
154         deadkey_ = deadkey2_;
155         deadkey_info_ = deadkey2_info_;
156         res += deadkey_state_->deadkey(c, d);
157         return res;
158 }
159
160
161 // TransFSM
162 TransFSM::TransFSM():
163         TransFSMData(),
164         TransInitState(),
165         TransDeadkeyState(),
166         TransCombinedState()
167 {
168         currentState = init_state_;
169 }
170
171
172 // TransManager
173
174 // Initialize static member.
175 Trans TransManager::default_;
176
177
178 TransManager::TransManager()
179         : active_(0), t1_(new Trans), t2_(new Trans)
180 {}
181
182
183 TransManager::~TransManager()
184 {
185         delete t1_;
186         delete t2_;
187 }
188
189
190 int TransManager::SetPrimary(string const & language)
191 {
192         if (t1_->GetName() == language)
193                 return 0;
194
195         return t1_->Load(language);
196 }
197
198
199 int TransManager::SetSecondary(string const & language)
200 {
201         if (t2_->GetName() == language)
202                 return 0;
203
204         return t2_->Load(language);
205 }
206
207
208 bool TransManager::setCharset(string const & str)
209 {
210         return chset_.loadFile(str);
211 }
212
213
214 void TransManager::EnablePrimary()
215 {
216         if (t1_->IsDefined())
217                 active_ = t1_;
218
219         lyxerr[Debug::KBMAP] << "Enabling primary keymap" << endl;
220 }
221
222
223 void TransManager::EnableSecondary()
224 {
225         if (t2_->IsDefined())
226                 active_ = t2_;
227         lyxerr[Debug::KBMAP] << "Enabling secondary keymap" << endl;
228 }
229
230
231 void TransManager::DisableKeymap()
232 {
233         active_ = &default_;
234         lyxerr[Debug::KBMAP] << "Disabling keymap" << endl;
235 }
236
237
238 void  TransManager::TranslateAndInsert(char c, LyXText * text)
239 {
240         string res = active_->process(c, *this);
241
242         // Process with tokens
243         string temp;
244
245         while (res.length() > 0) {
246                 res = split(res, temp, TransState::TOKEN_SEP);
247                 insert(temp, text);
248         }
249 }
250
251
252 void TransManager::insertVerbatim(string const & str, LyXText * text)
253 {
254         string::size_type const l = str.length();
255
256         for (string::size_type i = 0; i < l; ++i) {
257                 text->insertChar(str[i]);
258         }
259 }
260
261
262 void TransManager::insert(string const & str, LyXText * text)
263 {
264         // Go through the character encoding only if the current
265         // encoding (chset_->name()) matches the current font_norm
266         // (lyrxc->font_norm)
267
268         // Is false to speak about "only if" the current encoding will
269         // almost always be equal to font_norm.
270         pair<bool, int> enc = chset_.encodeString(str);
271         if (chset_.getName() != lyxrc.font_norm ||
272             !enc.first) {
273                 // Could not find an encoding
274                 InsetLatexAccent ins(str);
275                 if (ins.canDisplay()) {
276                         text->insertInset(
277                                           new InsetLatexAccent(ins));
278                 } else {
279                         insertVerbatim(str, text);
280                 }
281                 return;
282         }
283         string tmp;
284         tmp += static_cast<char>(enc.second);
285         insertVerbatim(tmp, text);
286 }
287
288
289 void TransManager::deadkey(char c, tex_accent accent, LyXText * t)
290 {
291         if (c == 0 && active_ != &default_) {
292                 // A deadkey was pressed that cannot be printed
293                 // or a accent command was typed in the minibuffer
294                 KmodInfo i;
295                 if (active_->isAccentDefined(accent, i) == true) {
296                         string const res = trans_fsm_
297                                 .currentState->deadkey(c, i);
298                         insert(res, t);
299                         return;
300                 }
301         }
302
303         if (active_ == &default_ || c == 0) {
304                 KmodInfo i;
305                 i.accent = accent;
306                 i.data.erase();
307                 string res = trans_fsm_.currentState->deadkey(c, i);
308                 insert(res, t);
309         } else {
310                 // Go through the translation
311                 TranslateAndInsert(c, t);
312         }
313 }