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