]> git.lyx.org Git - lyx.git/blob - src/intl.C
Fixes from Dekel and John
[lyx.git] / src / intl.C
1 /* This file is part of
2  * ====================================================== 
3  * 
4  *           LyX, The Document Processor
5  *       
6  *           Copyright 1995 Matthias Ettrich
7  *           Copyright 1995-2000 The LyX Team.
8  *
9  * ====================================================== */
10
11 /*
12  *      International support for LyX
13  */
14
15 #include <config.h>
16
17 #ifdef __GNUG__
18 #pragma implementation
19 #endif
20  
21 #include FORMS_H_LOCATION
22 #include "intl.h"
23 #include "form1.h"
24 #include "tex-strings.h"
25 #include "combox.h"
26 #include "lyx_gui_misc.h" // CancelCloseBoxCB
27 #include "debug.h"
28 #include "lyxrc.h"
29 #include "trans_mgr.h"
30 #include "support/lstrings.h"
31 #include "language.h"
32
33 using std::endl;
34
35 // a wrapper around the callback static member.
36 extern "C" void C_Intl_DispatchCallback(FL_OBJECT * ob, long code);
37
38
39 Intl::Intl()
40         : prim_lang(lyxrc.primary_kbmap), 
41         sec_lang(lyxrc.secondary_kbmap),
42         trans(new TransManager)
43 {
44         keymapon = lyxrc.use_kbmap;
45         chsetcode = 0;
46         primarykeymap = false;
47         curkeymap = 0;
48         otherkeymap = 0;
49 }
50
51 Intl::~Intl()
52 {
53         delete trans;
54 }
55
56
57 int Intl::SetPrimary(string const & lang)
58 {
59         if (lyxerr.debugging(Debug::KBMAP))
60                 lyxerr << "Primary: `" << lang << "'" << endl;
61         return trans->SetPrimary(lang);
62 }
63
64
65 int Intl::SetSecondary(string const & lang)
66 {
67         if (lyxerr.debugging(Debug::KBMAP))
68                 lyxerr << "Secondary: `" << lang << "'" << endl;
69         return trans->SetSecondary(lang);
70 }
71
72
73 void Intl::update()
74 {
75         int off = 0;
76         int prim = 0;
77         int sec = 0;
78         
79         if (!keymapon) {
80                 off = 1;
81         } else {
82                 if (primarykeymap) {
83                         prim = 1;
84                 } else {
85                         sec = 1;
86                 }
87         }
88         
89         fl_set_button(fd_form_keymap->KeyOffBtn, off);
90         fl_set_button(fd_form_keymap->KeyOnBtn, prim);
91         fl_set_button(fd_form_keymap->KeyOnBtn2, sec);
92 }
93
94
95 void Intl::KeyMapOn(bool on)
96         /* turn on/off key mappings, status in keymapon */
97 {
98         keymapon = on;
99
100         if (!fd_form_keymap) return;
101         
102         fl_set_button(fd_form_keymap->KeyOffBtn, 0);
103         fl_set_button(fd_form_keymap->KeyOnBtn, 0);
104         fl_set_button(fd_form_keymap->KeyOnBtn2, 0);
105
106         if (on) {
107                 if (primarykeymap) {
108                         KeyMapPrim();
109                 } else {
110                         KeyMapSec();
111                 }
112         } else {
113                 fl_set_button(fd_form_keymap->KeyOffBtn, 1);
114                 fl_hide_object(fd_form_keymap->KeymapErr);
115                 trans->DisableKeymap();
116         }
117 }
118
119
120 void Intl::ToggleKeyMap()
121 {
122         if (keymapon && primarykeymap) {
123                 KeyMapSec();
124         } else if (keymapon) {
125                 KeyMapOn(false);
126         } else  
127                 KeyMapPrim();
128 }
129
130
131 void Intl::KeyMapPrim()
132 {
133         fl_set_button(fd_form_keymap->KeyOffBtn, 0);
134         fl_set_button(fd_form_keymap->KeyOnBtn, 1);
135         fl_set_button(fd_form_keymap->KeyOnBtn2, 0);
136
137         /* read text from choice */
138         int i = Language->get();
139
140         string p;
141         if (i == otherkeymap)
142                 p = fl_get_input(fd_form_keymap->OtherKeymap);
143         else
144                 p = Language->getline();
145
146         curkeymap = i;
147
148         if (p.empty() || trans->SetPrimary(p)) {
149                 // error selecting keymap
150                 fl_show_object(fd_form_keymap->KeymapErr);
151                 update();
152         } else {
153                 // no error
154                 trans->EnablePrimary();
155                 keymapon = true;
156                 primarykeymap = true;
157                 fl_hide_object(fd_form_keymap->KeymapErr);
158         }
159 }
160
161
162 void Intl::KeyMapSec()
163 {
164         fl_set_button(fd_form_keymap->KeyOffBtn, 0);
165         fl_set_button(fd_form_keymap->KeyOnBtn, 0);
166         fl_set_button(fd_form_keymap->KeyOnBtn2, 1);
167
168         /* read text from choice */
169         int i = Language2->get();
170
171         string p;
172         if (i == otherkeymap)
173                 p = fl_get_input(fd_form_keymap->OtherKeymap2);
174         else
175                 p = Language2->getline();
176         curkeymap = i;
177
178         if (p.empty() || trans->SetSecondary(p)) {
179                 // error selecting keymap
180                 fl_show_object(fd_form_keymap->KeymapErr);
181                 update();
182         } else {
183                 // no error
184                 trans->EnableSecondary();
185                 keymapon = true;
186                 primarykeymap = false;
187                 fl_hide_object(fd_form_keymap->KeymapErr);
188         }
189 }
190
191 void Intl::LCombo(int, void * v, Combox * combox)
192 {
193         Intl * itl = static_cast<Intl*>(v);
194         if (combox == itl->Language)
195             itl->Keymap(23);
196         else if (combox == itl->Language2)
197             itl->Keymap(43);
198         return;
199 }
200
201 void Intl::DispatchCallback(FL_OBJECT * ob, long code)
202 {
203         if (ob && (code == 0)) {
204                 fl_hide_form(ob->form);
205                 return;
206         }
207         if (!ob || !(ob->u_vdata))
208                 return;
209         
210         Intl * itl = static_cast<Intl *>(ob->u_vdata);
211
212         if (itl!= 0) itl->Keymap(code);
213 }
214
215
216 extern "C" void C_Intl_DispatchCallback(FL_OBJECT * ob, long code)
217 {
218         Intl::DispatchCallback(ob, code);
219 }
220
221
222 void Intl::InitKeyMapper(bool on)
223         /* initialize key mapper */
224 {
225         lyxerr[Debug::INIT] << "Initializing key mappings..." << endl;
226
227         if (prim_lang.empty() && sec_lang.empty())
228                 keymapon = false; 
229         else
230                 keymapon = on;
231
232         Language = new Combox(FL_COMBOX_DROPLIST);
233         Language2 = new Combox(FL_COMBOX_DROPLIST);
234         Language->setcallback(LCombo, this);
235         Language2->setcallback(LCombo, this);
236
237         fd_form_keymap = create_form_KeyMap();
238
239         // Add the Intl* pointer
240         fd_form_keymap->AcceptChset->u_vdata =
241                 fd_form_keymap->Charset->u_vdata =
242                 fd_form_keymap->Accept->u_vdata =
243                 fd_form_keymap->OtherKeymap->u_vdata =
244                 fd_form_keymap->KeyOnBtn->u_vdata =
245                 fd_form_keymap->KeyOffBtn->u_vdata =
246                 fd_form_keymap->KeyOnBtn2->u_vdata = this;
247
248         // add the callbacks.
249         fl_set_object_callback(fd_form_keymap->AcceptChset,
250                                C_Intl_DispatchCallback, 27);
251         fl_set_object_callback(fd_form_keymap->Charset,
252                                C_Intl_DispatchCallback, 26);
253         fl_set_object_callback(fd_form_keymap->Accept,
254                                C_Intl_DispatchCallback, 0);
255
256         fl_set_object_callback(fd_form_keymap->KeyOnBtn,
257                                C_Intl_DispatchCallback, 23);
258         fl_set_object_callback(fd_form_keymap->KeyOffBtn,
259                                C_Intl_DispatchCallback, 3);
260         fl_set_object_callback(fd_form_keymap->KeyOnBtn2,
261                                C_Intl_DispatchCallback, 43);
262         
263         // Make sure pressing the close box does not kill LyX. (RvdK)
264         fl_set_form_atclose(fd_form_keymap->KeyMap, CancelCloseBoxCB, 0);
265
266         fl_hide_object(fd_form_keymap->KeymapErr);
267         fl_hide_object(fd_form_keymap->ChsetErr);
268         fl_set_input(fd_form_keymap->Charset, lyxrc.font_norm.c_str());
269
270         // Adds two comboxes to the keyboard map
271         fl_addto_form(fd_form_keymap->KeyMap);
272         Language->add(120, 30, 160, 30, 300);   // Primary
273         Language2->add(120, 110, 160, 30, 300); // Secondary
274         fl_end_form();
275
276         int n = 0;
277         // Default is not in the language map
278 #ifdef DO_USE_DEFAULT_LANGUAGE
279         Language->addto("default");
280         Language2->addto("default");
281         ++n;
282 #endif
283         for (Languages::const_iterator cit = languages.begin();
284              cit != languages.end(); ++cit) {
285                 Language->addto((*cit).second.lang());
286                 Language2->addto((*cit).second.lang());
287                 ++n;
288         }
289
290         Language->addto(_("other..."));
291         Language2->addto(_("other..."));
292         otherkeymap = n + 1;
293         if (!Language->select_text(prim_lang)) {
294                 Language->select(n+1);
295                 fl_set_input(fd_form_keymap->OtherKeymap, prim_lang.c_str());
296         }
297         else 
298                 trans->SetPrimary(prim_lang);
299
300         if (!Language2->select_text(sec_lang)) {
301                 Language2->select(n + 1);
302                 fl_set_input(fd_form_keymap->OtherKeymap2, sec_lang.c_str());
303         }
304         else
305                 trans->SetSecondary(sec_lang);
306
307         KeyMapOn(keymapon);
308         if (keymapon)
309                 Keymap(23); // turn primary on
310
311         trans->setCharset(lyxrc.font_norm);
312 }
313
314
315 void Intl::Keymap(long code)
316 {
317         if (lyxerr.debugging(Debug::KBMAP))
318                 lyxerr << "KeyMap callback: " << code << endl;
319
320         // Did you wonder if it is possible to write spagetti code with
321         // other constructs thatn goto's? Well here we have a nice small
322         // spagetti example using a switch... (Lgb)
323         switch (code) {
324         case 0:
325                 /* cancel/hide */
326                 fl_hide_form(fd_form_keymap->KeyMap);
327                 break;
328         case 3:
329         case 23:
330         case 43:
331                 if (code == 3) {
332                         KeyMapOn(false);
333                         return;
334                 }
335                 code -= 19;     // change to language change type code
336                 
337         case 4: // 4 and 24 will never be called directly, they will only be
338         case 24: // called through 3, 23, 43 (lgb)
339                 if (code == 4) {
340                         KeyMapPrim();
341                 } else {
342                         KeyMapSec();
343                 }
344                 break;
345         case 27:        /* set new font norm */
346                 char const * p = fl_get_input(fd_form_keymap->Charset);
347                 if (trans->setCharset(p))
348                         fl_show_object(fd_form_keymap->ChsetErr);
349                 else
350                         fl_hide_object(fd_form_keymap->ChsetErr);
351                 break;
352         }
353 }
354
355
356 void Intl::MenuKeymap()
357 {
358         if (fd_form_keymap->KeyMap->visible) {
359                 fl_raise_form(fd_form_keymap->KeyMap);
360         } else fl_show_form(fd_form_keymap->KeyMap, FL_PLACE_MOUSE,
361                             FL_FULLBORDER, _("Key Mappings"));
362 }