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