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