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