]> git.lyx.org Git - lyx.git/blob - src/trans_mgr.C
Fix working of the spellchecker dialog with ispell when there are no
[lyx.git] / src / trans_mgr.C
1 #include <config.h>
2
3 #ifdef __GNUG__
4 #pragma implementation "trans_mgr.h"
5 #endif
6
7 #include "trans_mgr.h"
8 #include "trans.h"
9 #include "lyxtext.h"
10 #include "LString.h"
11 #include "debug.h"
12 #include "chset.h"
13 #include "insets/insetlatexaccent.h"
14 #include "BufferView.h"
15 #include "buffer.h"
16 #include "lyxrc.h"
17 #include "support/lstrings.h"
18
19 using std::endl;
20 using std::pair;
21
22 extern string const DoAccent(string const &, tex_accent);
23 extern string const DoAccent(char, tex_accent);
24 extern BufferView * current_view;
25
26
27 // TransFSMData
28 TransFSMData::TransFSMData()
29 {
30         deadkey_ = deadkey2_ = 0;
31         deadkey_info_.accent = deadkey2_info_.accent = TEX_NOACCENT;
32 #if 0
33         comb_info_ = 0;
34 #endif
35 }
36
37
38 // TransState
39 char const TransState::TOKEN_SEP = 4;
40
41
42 // TransInitState
43 TransInitState::TransInitState()
44 {
45         init_state_ = this;
46 }
47
48
49 #if 0
50 string const TransInitState::normalkey(char c, string const & t)
51 {
52         string res;
53         if (!t.empty()) res = t;
54         else res = c;
55         
56         return res;
57 }
58 #else
59 string const TransInitState::normalkey(char c)
60 {
61         string res;
62         res = c;
63         return res;
64 }
65 #endif
66
67
68 string const TransInitState::deadkey(char c, KmodInfo d)
69 {
70         deadkey_ = c;
71         deadkey_info_ = d;
72         currentState = deadkey_state_;
73         return string();
74 }
75
76
77 // TransDeadkeyState
78 TransDeadkeyState::TransDeadkeyState()
79 {
80         deadkey_state_ = this;
81 }
82
83
84 #if 0
85 string const TransDeadkeyState::normalkey(char c, string const & trans)
86 {
87         string res;
88         
89         // Check if it is an exception
90         KmodException l = deadkey_info_.exception_list;
91         while(l != 0) {
92                 if (l->c == c) {
93                         res = l->data;
94                         break;
95                 }
96                 l = l->next;
97         }
98         if (l == 0) {
99                 // Not an exception. Check if it allowed
100                 if (countChar(deadkey_info_.allowed, c) > 0) {
101                         res = DoAccent(c, deadkey_info_.accent);
102                 } else {
103                         // Not allowed
104                         if (deadkey_!= 0)
105                                 res = deadkey_;
106                         res+= TOKEN_SEP;
107                         res+= trans;
108                 }
109         }
110         currentState = init_state_;
111         return res;
112 }
113 #else
114 string const TransDeadkeyState::normalkey(char c)
115 {
116 #if 0
117         string res;
118         
119         // Check if it is an exception
120         KmodException l = deadkey_info_.exception_list;
121         while(l != 0) {
122                 if (l->c == c) {
123                         res = l->data;
124                         break;
125                 }
126                 l = l->next;
127         }
128         if (l == 0) {
129                         res = DoAccent(c, deadkey_info_.accent);
130         }
131         currentState = init_state_;
132         return res;
133 #else
134         string res;
135         
136         KmodException::iterator it = deadkey_info_.exception_list.begin();
137         KmodException::iterator end = deadkey_info_.exception_list.end();
138
139         for (; it != end; ++it) {
140                 if (it->c == c) {
141                         res = it->data;
142                         break;
143                 }
144         }
145         if (it == end) {
146                 res = DoAccent(c, deadkey_info_.accent);
147         }
148         currentState = init_state_;
149         return res;
150 #endif
151 }
152 #endif
153
154
155 string const TransDeadkeyState::deadkey(char c, KmodInfo d)
156 {
157         string res;
158         
159         // Check if the same deadkey was typed twice
160         if (deadkey_ == c) {
161                 res = deadkey_;
162                 deadkey_ = 0;
163                 deadkey_info_.accent = TEX_NOACCENT;
164                 currentState = init_state_;
165                 return res;
166         }
167         
168         // Check if it is a combination or an exception
169 #if 0
170         KmodException l;
171         l = deadkey_info_.exception_list;
172         
173         while (l) {
174                 if (l->combined == true && l->accent == d.accent) {
175                         deadkey2_ = c;
176                         deadkey2_info_ = d;
177                         comb_info_ = l;
178                         currentState = combined_state_;
179                         return string();
180                 }
181                 if (l->c == c) {
182                         res = l->data;
183                         deadkey_ = 0;
184                         deadkey_info_.accent = TEX_NOACCENT;
185                         currentState = init_state_;
186                         return res;
187                 }
188                 l = l->next;
189         }
190 #else
191         KmodException::const_iterator cit = deadkey_info_.exception_list.begin();
192         KmodException::const_iterator end = deadkey_info_.exception_list.end();
193         for (; cit != end; ++cit) {
194                 if (cit->combined == true && cit->accent == d.accent) {
195                         deadkey2_ = c;
196                         deadkey2_info_ = d;
197                         comb_info_ = (*cit);
198                         currentState = combined_state_;
199                         return string();
200                 }
201                 if (cit->c == c) {
202                         res = cit->data;
203                         deadkey_ = 0;
204                         deadkey_info_.accent = TEX_NOACCENT;
205                         currentState = init_state_;
206                         return res;
207                 }
208         }
209 #endif
210         // Not a combination or an exception. 
211         // Output deadkey1 and keep deadkey2
212         
213         if (deadkey_!= 0)
214                 res = deadkey_;
215         deadkey_ = c;
216         deadkey_info_ = d;
217         currentState = deadkey_state_;
218         return res;
219 }
220
221
222 TransCombinedState::TransCombinedState()
223 {
224         combined_state_ = this;
225 }
226
227
228 #if 0
229 string const TransCombinedState::normalkey(char c, string const & trans)
230 {
231         string res;
232
233         // Check if the key is allowed on the combination
234         if (countChar(comb_info_->data, c) > 0) {
235                 string const temp = DoAccent(c, deadkey2_info_.accent);
236                 res = DoAccent(temp, deadkey_info_.accent);
237                 currentState = init_state_;
238         } else {
239                 // Not allowed. Output deadkey1 and check deadkey2 + c
240                 if (deadkey_ != 0)
241                         res += deadkey_;
242                 res += TOKEN_SEP;
243                 deadkey_ = deadkey2_;
244                 deadkey_info_ = deadkey2_info_;
245                 // Call deadkey state and leave it to setup the FSM
246                 res += deadkey_state_->normalkey(c, trans);
247         }
248         return res;
249 }
250 #else
251 string const TransCombinedState::normalkey(char c)
252 {
253         string res;
254
255         string const temp = DoAccent(c, deadkey2_info_.accent);
256         res = DoAccent(temp, deadkey_info_.accent);
257         currentState = init_state_;
258         return res;
259 }
260 #endif
261
262
263 string const TransCombinedState::deadkey(char c, KmodInfo d)
264 {
265         // Third key in a row. Output the first one and
266         // reenter with shifted deadkeys
267         string res;
268         if (deadkey_ != 0)
269                 res = deadkey_;
270         res += TOKEN_SEP;
271         deadkey_ = deadkey2_;
272         deadkey_info_ = deadkey2_info_;
273         res += deadkey_state_->deadkey(c, d);
274         return res;
275 }
276
277
278 // TransFSM
279 TransFSM::TransFSM():
280         TransFSMData(),
281         TransInitState(),
282         TransDeadkeyState(),
283         TransCombinedState()
284 {
285         currentState = init_state_;
286 }
287
288
289 // TransManager
290
291 // Initialize static member.
292 Trans TransManager::default_;
293
294
295 TransManager::TransManager()
296         : active_(0), t1_(new Trans), t2_(new Trans)
297 {}
298
299
300 TransManager::~TransManager() 
301
302         delete t1_;
303         delete t2_;
304 }
305
306
307 int TransManager::SetPrimary(string const & language)
308 {
309         if (t1_->GetName() == language) 
310                 return 0;
311         
312         return t1_->Load(language);
313 }
314
315
316 int TransManager::SetSecondary(string const & language)
317 {
318         if (t2_->GetName() == language)
319                 return 0;
320         
321         return t2_->Load(language);
322 }
323
324
325 bool TransManager::setCharset(string const & str)
326 {
327         return chset_.loadFile(str);
328 }
329
330
331 void TransManager::EnablePrimary()
332 {
333         if (t1_->IsDefined())
334                 active_ = t1_;
335         
336         lyxerr[Debug::KBMAP] << "Enabling primary keymap" << endl;
337 }
338
339
340 void TransManager::EnableSecondary()
341 {
342         if (t2_->IsDefined())
343                 active_ = t2_;
344         lyxerr[Debug::KBMAP] << "Enabling secondary keymap" << endl;
345 }
346
347
348 void TransManager::DisableKeymap()
349 {
350         active_ = &default_;
351         lyxerr[Debug::KBMAP] << "Disabling keymap" << endl;
352 }
353
354
355 void  TransManager::TranslateAndInsert(char c, LyXText * text)
356 {
357         string res = active_->process(c, *this);
358         
359         // Process with tokens
360         string temp;
361         
362         while(res.length() > 0) {
363                 res = split(res, temp, TransState::TOKEN_SEP);
364                 insert(temp, text);
365         }
366 }
367
368
369 void TransManager::insertVerbatim(string const & str, LyXText * text)
370 {       
371         string::size_type const l = str.length();
372         
373         for (string::size_type i = 0; i < l; ++i) {
374                 text->insertChar(current_view, str[i]);
375         }
376 }
377
378
379 void TransManager::insert(string const & str, LyXText * text)
380 {
381         // Go through the character encoding only if the current 
382         // encoding (chset_->name()) matches the current font_norm
383         // (lyrxc->font_norm)
384         
385         // Is false to speak about "only if" the current encoding will
386         // almost always be equal to font_norm.
387         pair<bool, int> enc = chset_.encodeString(str);
388         if (chset_.getName() != lyxrc.font_norm || 
389             !enc.first) {
390                 // Could not find an encoding
391                 InsetLatexAccent ins(str);
392                 if (ins.canDisplay()) {
393                         text->insertInset(current_view,
394                                           new InsetLatexAccent(ins));
395                 } else {
396                         insertVerbatim(str, text);
397                 }
398                 return;
399         }
400         string tmp;
401         tmp += static_cast<char>(enc.second);
402         insertVerbatim(tmp, text);
403 }
404
405
406 void TransManager::deadkey(char c, tex_accent accent, LyXText * t)
407 {
408         if (c == 0 && active_ != &default_) {
409                 // A deadkey was pressed that cannot be printed
410                 // or a accent command was typed in the minibuffer
411                 KmodInfo i;
412                 if (active_->isAccentDefined(accent, i) == true) {
413                         string const res = trans_fsm_
414                                 .currentState->deadkey(c, i);
415                         insert(res, t);
416                         return;
417                 }
418         }
419         
420         if (active_ == &default_ || c == 0) {
421                 KmodInfo i;
422                 i.accent = accent;
423 #if 0
424                 i.allowed = lyx_accent_table[accent].native;
425 #endif
426                 i.data.erase();
427 #if 0
428                 i.exception_list = 0;
429 #endif  
430                 string res = trans_fsm_.currentState->deadkey(c, i);
431                 insert(res, t);
432         } else {
433                 // Go through the translation
434                 TranslateAndInsert(c, t);
435         }
436 }