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