]> git.lyx.org Git - lyx.git/blob - src/trans_mgr.C
a couple of name changes and new functionality in lyxvc and vc-backend
[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 <cassert>
8 #include "trans_mgr.h"
9 #include "trans.h"
10 #include "lyxtext.h"
11 #include "LString.h"
12 #include "debug.h"
13 #include "chset.h"
14 #include "insets/insetlatexaccent.h"
15 #include "BufferView.h"
16 #include "buffer.h"
17 #include "lyxrc.h"
18 #include "support/lstrings.h"
19
20 extern LyXRC* lyxrc;
21 extern string DoAccent(const string&,tex_accent);
22 extern void InsertCorrectQuote();
23 extern string 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     comb_info_=0;
33 }
34
35
36 // TransState
37 const char TransState::TOKEN_SEP=4;
38
39
40 TransState::~TransState()
41 {}
42
43
44 // TransInitState
45 TransInitState::TransInitState()
46 {
47     init_state_=this;
48 }
49
50
51 string TransInitState::normalkey(char c,char *t)
52 {
53     string res;
54     if (t!=0)
55         res=t;
56     else
57         res=c;
58         
59     return res;
60 }
61
62
63 //bool TransInitState::backspace()
64 //{
65 //    return true;
66 //}
67
68
69 string TransInitState::deadkey(char c,KmodInfo d)
70 {
71     deadkey_=c;
72     deadkey_info_=d;
73     currentState=deadkey_state_;
74     return string();
75 }
76
77
78 // TransDeadkeyState
79 TransDeadkeyState::TransDeadkeyState()
80 {
81     deadkey_state_=this;
82 }
83
84
85 string TransDeadkeyState::normalkey(char c,char *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 (current_view->buffer()->params.allowAccents==true ||
101             countChar(deadkey_info_.allowed, c) > 0) {
102             res=DoAccent(c,deadkey_info_.accent);
103         } else {
104             // Not allowed
105             if (deadkey_!=0)
106                 res=deadkey_;
107             res+=TOKEN_SEP;
108             res+=trans;
109         }
110     }
111     currentState=init_state_;
112     return res;
113 }
114
115
116 //bool TransDeadkeyState::backspace()
117 //{
118 //    currentState=init_state_;
119 //    return false;
120 //}
121
122
123 string TransDeadkeyState::deadkey(char c,KmodInfo d)
124 {
125     string res;
126     
127     // Check if the same deadkey was typed twice
128     if (deadkey_==c) {
129         res=deadkey_;
130         deadkey_=0;
131         deadkey_info_.accent=TEX_NOACCENT;
132         currentState=init_state_;
133         return res;
134     }
135     
136     // Check if it is a combination or an exception
137     KmodException l;
138     l=deadkey_info_.exception_list;
139     
140     while(l) {
141         if (l->combined==true && l->accent==d.accent) {
142             deadkey2_=c;
143             deadkey2_info_=d;
144             comb_info_=l;
145             currentState=combined_state_;
146             return string();
147         }
148         if (l->c==c) {
149             res=l->data;
150             deadkey_=0;
151             deadkey_info_.accent=TEX_NOACCENT;
152             currentState=init_state_;
153             return res;
154         }
155         
156         l=l->next;
157     }
158     
159     // Not a combination or an exception. 
160     // Output deadkey1 and keep deadkey2
161     
162     if (deadkey_!=0)
163         res=deadkey_;
164     deadkey_=c;
165     deadkey_info_=d;
166     currentState=deadkey_state_;
167     return res;
168 }
169
170
171 TransCombinedState::TransCombinedState()
172 {
173     combined_state_=this;
174 }
175
176
177 string TransCombinedState::normalkey(char c,char *trans)
178 {
179     string res;
180     
181     // Check if the key is allowed on the combination
182     if (countChar(comb_info_->data, c) > 0) {
183         string temp;
184         temp=DoAccent(c,deadkey2_info_.accent);
185         res=DoAccent(temp,deadkey_info_.accent);
186         currentState=init_state_;
187     } else {
188         // Not allowed. Output deadkey1 and check deadkey2 + c
189         if (deadkey_!=0)
190             res+=deadkey_;
191         res+=TOKEN_SEP;
192         deadkey_=deadkey2_;
193         deadkey_info_=deadkey2_info_;
194         // Call deadkey state and leave it to setup the FSM
195         res+=deadkey_state_->normalkey(c,trans);
196     }
197     return res;
198 }
199
200
201 // bool TransCombinedState::backspace()
202 // {
203 //     // cancel the second deadkey
204 //     deadkey2_=0;
205 //     deadkey2_info_.accent=TEX_NOACCENT;
206 //     currentState=deadkey_state_;
207     
208 //     return false;
209 // }
210
211
212 string TransCombinedState::deadkey(char c,KmodInfo d)
213 {
214     // Third key in a row. Output the first one and
215     // reenter with shifted deadkeys
216     string res;
217     if (deadkey_!=0)
218         res=deadkey_;
219     res+=TOKEN_SEP;
220     deadkey_=deadkey2_;
221     deadkey_info_=deadkey2_info_;
222     res+=deadkey_state_->deadkey(c,d);
223     return res;
224 }
225
226
227 // TransFSM
228 TransFSM::TransFSM():
229     TransFSMData(),
230     TransInitState(),
231     TransDeadkeyState(),
232     TransCombinedState()
233 {
234     currentState=init_state_;
235 }
236
237
238 // TransManager
239     
240 TransManager::TransManager()
241     : active_(0),t1_(new Trans),t2_(new Trans),chset_(new CharacterSet)
242 {}
243
244
245 Trans* TransManager::default_=new Trans;
246
247
248 TransManager::~TransManager() 
249
250     delete t1_;
251     delete t2_;
252     delete chset_;
253 }
254
255
256 int TransManager::SetPrimary(string const & language)
257 {
258     if (t1_->GetName()==language) 
259         return 0;
260         
261     return t1_->Load(language);
262 }
263
264
265 int TransManager::SetSecondary(string const & language)
266 {
267     if (t2_->GetName()==language)
268         return 0;
269         
270     return t2_->Load(language);
271 }
272
273
274 bool TransManager::setCharset(const char *set)
275 {
276     return chset_->loadFile(set);
277 }
278
279
280 void TransManager::EnablePrimary()
281 {
282     if (t1_->IsDefined())
283         active_=t1_;
284
285     lyxerr[Debug::KBMAP] << "Enabling primary keymap" << endl;
286 }
287
288
289 void TransManager::EnableSecondary()
290 {
291     if (t2_->IsDefined( ))
292         active_=t2_;
293     lyxerr[Debug::KBMAP] << "Enabling secondary keymap" << endl;
294 }
295
296
297 void TransManager::DisableKeymap()
298 {
299     active_=default_;
300     lyxerr[Debug::KBMAP] << "Disabling keymap" << endl;
301 }
302
303
304 void  TransManager::TranslateAndInsert(char c,LyXText *text)
305 {
306     string res;
307         
308     res=active_->process(c,*this);
309     
310     // Process with tokens
311     string temp;
312         
313     while(res.length()>0) {
314         res=split(res, temp,TransState::TOKEN_SEP);
315         insert(temp,text);
316     }
317 }
318
319
320 void TransManager::insertVerbatim(const string& str,LyXText *text)
321 {       
322     int l=str.length();
323         
324     for (int i=0;i<l;i++){
325         if (str[i]=='\"' 
326             && text->GetFont(text->cursor.par,
327                              text->cursor.pos).latex() == LyXFont::OFF)
328             InsertCorrectQuote();
329         else
330             text->InsertChar(str[i]);
331     }
332 }
333
334
335 void TransManager::insert(string str,LyXText *text)
336 {
337     string t=str;
338     
339     // Go through the character encoding only if the current 
340     // encoding (chset_->name()) matches the current font_norm
341     // (lyrxc->font_norm
342
343     if (chset_->getName()!=lyxrc->font_norm || 
344         chset_->encodeString(str)==false) {
345         // Could not find an encoding
346         InsetLatexAccent ins(str);
347         if (ins.CanDisplay()) {
348             text->InsertInset(new InsetLatexAccent(ins));
349             return;
350         }
351     }
352     
353     insertVerbatim(str,text);
354 }
355
356
357 //bool TransManager::backspace()
358 //{
359 //    return trans_fsm_.currentState->backspace();
360 //}
361
362
363 void TransManager::deadkey(char c,tex_accent accent,LyXText *t)
364 {
365     KmodInfo i;
366     string res;
367     
368     if (c==0 && active_!=default_) {
369         // A deadkey was pressed that cannot be printed
370         // or a accent command was typed in the minibuffer
371         
372         if (active_->isAccentDefined(accent,i)==true) {
373             res=trans_fsm_.currentState->deadkey(c,i);
374             insert(res,t);
375             return;
376         }
377     }// else {
378         // Fall through to the next case
379     //}
380     
381     if (active_==default_ || c==0) {
382         i.accent=accent;
383         i.allowed=lyx_accent_table[accent].native;
384         i.data.clear();
385         i.exception_list=0;
386         
387         string res=trans_fsm_.currentState->deadkey(c,i);
388         insert(res,t);
389     } else {
390         // Go through the translation
391         TranslateAndInsert(c,t);
392     }
393 }