klavaro  3.13
About: Klavaro is a touch typing tutor program.
  Fossies Dox: klavaro-3.13.tar.bz2  ("unofficial" and yet experimental doxygen-generated source code documentation)  

translation.c
Go to the documentation of this file.
1 /**************************************************************************/
2 /* Klavaro - a flexible touch typing tutor */
3 /* Copyright (C) 2005-2021 Felipe Emmanuel Ferreira de Castro */
4 /* */
5 /* This file is part of Klavaro, which is a free software: you can */
6 /* redistribute it and/or modify it under the terms of the GNU General */
7 /* Public License as published by the Free Software Foundation, either */
8 /* version 3 of the License, or (at your option) any later version. */
9 /* */
10 /* Klavaro is distributed in the hope that it will be useful, */
11 /* but WITHOUT ANY WARRANTY; without even the implied warranty of */
12 /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
13 /* GNU General Public License for more details (in the file COPYING). */
14 /* You should have received a copy of the GNU General Public License */
15 /* along with Klavaro. If not, see <https://www.gnu.org/licenses/> */
16 /**************************************************************************/
17 
18 /*
19  * Set of functions to deal with internationalization (translation).
20  */
21 #include <stdio.h>
22 #include <string.h>
23 #include <locale.h>
24 #include <glib.h>
25 #include <glib/gstdio.h>
26 #include <gtk/gtk.h>
27 
28 #include "auxiliar.h"
29 #include "main.h"
30 #include "callbacks.h"
31 #include "keyboard.h"
32 #include "velocity.h"
33 #include "fluidness.h"
34 #include "translation.h"
35 
36 /**********************************************************************
37  * Variables
38  */
40 static gint lang_num = 0;
41 
42 /**********************************************************************
43  * Get country name from its "ISO code" (eo and xx are just languages...)
44  */
45 const gchar *
46 trans_code_to_country (gchar *code)
47 {
48 #define COUNTRY_N 50
49  gsize i;
50  gchar *dummy = NULL;
51  static gchar map[COUNTRY_N][3][64] = {
52  {"xx","Esperantio"},
53  {"ad","Andorra"},
54  {"ar","العالم العربي"},
55  {"be","België"},
56  {"bg","България"},
57  {"bo","ཧི་མ་ལ་ཡ།"},
58  {"br","Brasil"},
59  {"ca","Canada"},
60  {"ch","Schweiz / Suisse"},
61  /* 10 */
62  {"cn","中华人民共和国"},
63  {"cz","Česká republika"},
64  {"dk","Danmark"},
65  {"de","Deutschland"},
66  {"eo","Esperantujo"},
67  {"es","España"},
68  {"eu","Euskal Herria"},
69  {"fi","Suomi"},
70  {"fr","France"},
71  {"gr","Ελλάδα"},
72  /* 20 */
73  {"il","ישראל"},
74  {"hr","Hrvatska"},
75  {"hu","Magyarország"},
76  {"id","Indonesia"},
77  {"in","India"},
78  {"it","Italia"},
79  {"jp","日本 (Nippon)"},
80  {"kk","Қазақстан"},
81  {"kr","대한민국"}, /* Korea */
82  {"no","Norge"},
83  /* 30 */
84  {"pl","Polska"},
85  {"pk","پاکستان"},
86  {"pt","Portugal"},
87  {"rs","Србија"}, /* Serbia */
88  {"ru","Россия"},
89  {"se","Sverige"},
90  {"si","Slovenija"},
91  {"sk","Slovensko"},
92  {"tr","Türkiye"},
93  {"ua","Україна"},
94  /* 40 */
95  {"uk","United Kingdom"},
96  {"us","USA"},
97  {"",""},
98  {"",""},
99  {"",""},
100  {"",""},
101  {"",""},
102  {"",""},
103  {"",""},
104  {"",""},
105  /* 50 */
106  {"",""}
107  };
108 
109  for (i = 0; i < COUNTRY_N; i++)
110  if (g_str_equal (code, map[i][0]))
111  return (map[i][1]);
112  dummy = g_strdup_printf ("(%s)", code);
113  return (dummy);
114 }
115 
116 /**********************************************************************
117  * Get a 'reazonable' value for keyboard, that is, QWERTY... :-(
118  */
119 gchar *
121 {
122  gint i;
123  gchar *tmp;
124 
125  if (lang_num == 0)
126  {
127  g_warning ("Internal error: trying to use language data not initialized!");
128  return (NULL);
129  }
130 
131  tmp = main_preferences_get_string ("interface", "language");
132  for (i = 0; i < lang_num; i++)
133  if (g_str_equal (lang[i].code, tmp))
134  {
135  g_free (tmp);
136  return (lang[i].kbd);
137  }
138 
139  g_free (tmp);
140  return (NULL);
141 }
142 
143 /**********************************************************************
144  * Initialize 'lang', 'code' and 'kbd' accordingly to 'language_set',
145  * which was defined in "languages.h".
146  */
147 void
149 {
150  static gboolean init = FALSE;
151  gint i;
152  gchar *tmp;
153  gchar **temp_lang = NULL;
154  const gchar languages_set[] = LANG_SET;
155 
156  if (init)
157  {
158  g_warning ("Not initializing again the language data");
159  return;
160  }
161  init = TRUE;
162 
163  /* Number of configured languages
164  */
165  temp_lang = g_strsplit (languages_set, "\n", -1);
166  i = 0;
167  while (temp_lang[i] != NULL)
168  i++;
169  g_assert (i > 0);
170  lang = g_new (Lang_Name_Code, i);
171  lang_num = i;
172 
173  for (i = 0; i < lang_num; i++)
174  {
175  gchar *end;
176  gchar *begin;
177 
178  tmp = g_strdup (temp_lang[i]);
179  /* Initialize 'lang'
180  */
181  end = strchr (tmp, '(');
182  if (end)
183  end -= ( ((end - tmp) > 1) ? 1 : 0 );
184  else
185  g_error ("Internal lang error: found nothing like '(LL...'");
186  lang[i].name = g_strndup (tmp, end - tmp);
187 
188  /* Initialize 'code'
189  */
190  begin = strchr (end, '(') + 1;
191  end = strchr (begin, ')');
192  if (end == NULL)
193  g_error ("Internal lang error: found nothing like '(LL)'");
194  lang[i].code = g_strndup (begin, end - begin);
195 
196  /* Initialize 'cd'
197  */
198  if (lang[i].code[0] == 'C')
199  strcpy (lang[i].cd, "en");
200  else
201  strncpy (lang[i].cd, lang[i].code, 2);
202  lang[i].cd[2] = '\0';
203 
204  /* Initialize 'kbd'
205  */
206  begin = strchr (end, '[') + 1;
207  end = strchr (begin, ']');
208  if (end == NULL)
209  g_error ("Internal lang error: found nothing like '[yy_zz]'");
210  lang[i].kbd = g_strndup (begin, end - begin);
211 
212  //g_printf ("%s : %s : %s : %s\n", lang[i].name, lang[i].code, lang[i].cd, lang[i].kbd);
213  }
214  g_strfreev (temp_lang);
215 }
216 
217 gchar *
219 {
220  if (i >= lang_num || i < 0)
221  return (NULL);
222  return (lang[i].cd);
223 }
224 
225 gboolean
226 trans_lang_is_available (gchar * langcode)
227 {
228  gint i;
229 
230  for (i = 0; i < lang_num; i++)
231  if (g_str_equal (lang[i].code, langcode))
232  break;
233  return (i == lang_num ? FALSE : TRUE);
234 }
235 
236 /**********************************************************************
237  * Define if we may put a stop mark at the end of "phrases".
238  */
239 gboolean
241 {
242  gboolean stopmark;
243  gchar *hlp;
244 
245  hlp = main_preferences_get_string ("interface", "language");
246  stopmark = g_str_has_prefix (hlp, "ur") ||
247  g_str_has_prefix (hlp, "ar") ||
248  g_str_has_prefix (hlp, "bn") ||
249  g_str_has_prefix (hlp, "bo") ||
250  g_str_has_prefix (hlp, "pa");
251  g_free (hlp);
252 
253  return (!stopmark);
254 }
255 
256 /**********************************************************************
257  * Private auxiliar function
258  */
259 static gboolean
261 {
262  gint i;
263  gchar aux_code_2[3];
264 
265  /* Prefer C over en_GB for English variants other than en_GB. (Debian patch 02) */
266  if (g_str_has_prefix (test, "en"))
267  {
268  g_free (test);
269  test = g_strdup ("C");
270  return (TRUE);
271  }
272 
273  if (g_str_equal (test, "C"))
274  return TRUE;
275 
276  strncpy (aux_code_2, test, 2);
277  aux_code_2[2] = '\0';
278 
279  for (i = 0; i < lang_num; i++)
280  {
281  if (strstr (lang[i].code, aux_code_2))
282  {
283  g_free (test);
284  test = g_strdup (lang[i].code);
285  break;
286  }
287  }
288  if (i == lang_num && g_str_has_prefix (test, "en"))
289  {
290  g_free (test);
291  test = g_strdup ("C");
292  return (TRUE);
293  }
294  return (i == lang_num ? FALSE : TRUE);
295 }
296 
297 /**********************************************************************
298  * Get the current locale and change it if necessary
299  */
300 void
302 {
303  gchar *tmp_code;
304  gboolean lang_ok;
305  gint i;
306 
307  /*
308  * If the language is already set in preferences, just use it
309  */
310  lang_ok = FALSE;
311  if (main_preferences_exist ("interface", "language"))
312  {
313  lang_ok = TRUE;
314  tmp_code = main_preferences_get_string ("interface", "language");
315  if (trans_lang_is_available (tmp_code) == FALSE)
316  {
317  tmp_code[2] = '\0';
318  if (trans_lang_is_available (tmp_code) == FALSE)
319  {
320  lang_ok = FALSE;
321  main_preferences_remove ("interface", "language");
322  }
323  else
324  main_preferences_set_string ("interface", "language", tmp_code);
325  }
326  }
327 
328  if (lang_ok == FALSE)
329  {
330  /*
331  * Read the current locale
332  */
333 #ifdef G_OS_UNIX
334  i = 0;
335  while ((tmp_code = g_strdup (g_get_language_names ()[i])))
336  {
337  if (tmp_code[0] == 'C')
338  {
339  lang_ok = (i == 0 ? TRUE : FALSE);
340  break;
341  }
342  lang_ok = trans_lang_is_available (tmp_code);
343  if (lang_ok == TRUE)
344  break;
345  g_free (tmp_code);
346  lang_ok = FALSE;
347  i++;
348  }
349  if (lang_ok == FALSE)
350  {
351  i = 0;
352  while ((tmp_code = g_strdup (g_get_language_names ()[i])))
353  {
354  if (tmp_code[0] == 'C')
355  {
356  lang_ok = (i == 0 ? TRUE : FALSE);
357  break;
358  }
359  lang_ok = trans_lang_get_similar (tmp_code);
360  if (lang_ok == TRUE)
361  break;
362  g_free (tmp_code);
363  lang_ok = FALSE;
364  i++;
365  }
366  }
367 #else
368  tmp_code = g_win32_getlocale ();
369  lang_ok = trans_lang_is_available (tmp_code);
370  if (lang_ok == FALSE)
371  lang_ok = trans_lang_get_similar (tmp_code);
372 #endif
373  }
374  if (tmp_code == NULL)
375  tmp_code = g_strdup ("xx");
376 
377  /* If even a similar is not available...
378  */
379  if (lang_ok == FALSE)
380  {
381  g_message ("as your locale (%s) isn't available, "
382  "we are using \"C\"", tmp_code);
383  g_free (tmp_code);
384  tmp_code = g_strdup ("C");
385  }
386 
387 #ifdef G_OS_WIN32
388  g_setenv ("LANGUAGE", tmp_code, TRUE);
389 #endif
390  main_preferences_set_string ("interface", "language", tmp_code);
391  g_free (tmp_code);
392 }
393 
394 /**********************************************************************
395  * Inserts the list of available languages in the 'combo_language'.
396  */
397 void
399 {
400  static gboolean recur = FALSE;
401  gint i;
402  gint i_env;
403  gchar *tmp_code;
404  gchar *langcode;
405  GtkComboBox *cmb;
406 
407  callbacks_shield_set (TRUE);
408 
409  if (recur)
410  cmb = GTK_COMBO_BOX (get_wg ("combobox_top10_language"));
411  else
412  cmb = GTK_COMBO_BOX (get_wg ("combobox_language"));
413 
414  tmp_code = main_preferences_get_string ("interface", "language");
415  if (tmp_code == NULL || g_str_equal ("en_US", tmp_code))
416  {
417  g_message ("Using \"C\" as language code.");
418  main_preferences_set_string ("interface", "language", "C");
419  if (tmp_code)
420  g_free (tmp_code);
421  tmp_code = g_strdup ("C");
422  }
423  gtk_combo_box_text_remove (GTK_COMBO_BOX_TEXT (cmb), 0);
424  for (i = 0, i_env = -1; i < lang_num; i++)
425  {
426  langcode = g_strdup_printf ("%s (%s)", lang[i].name, lang[i].code);
427  gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (cmb), langcode);
428  if (g_str_equal (lang[i].code, tmp_code))
429  i_env = i;
430  else if (g_str_has_prefix (tmp_code, lang[i].code))
431  {
432  i_env = i;
433  main_preferences_set_string ("interface", "language", lang[i].code);
434  }
435  g_free (langcode);
436  }
437  if (i_env == -1)
438  {
439  g_warning ("set_combo_language() ==> the locale \"%s\" is not available!", tmp_code);
440  g_message ("Using \"C\" as language code.");
441  g_free (tmp_code);
442  tmp_code = g_strdup ("C");
443  main_preferences_set_string ("interface", "language", "C");
444  gtk_combo_box_set_active (cmb, 8);
445  }
446  else
447  gtk_combo_box_set_active (cmb, i_env);
448 
449  callbacks_shield_set (FALSE);
450 
451  if (! recur)
452  {
453  recur = TRUE;
455  return;
456  }
457  recur = FALSE;
458 
459  if (g_str_has_prefix (tmp_code, "en") || g_str_equal (tmp_code, "C"))
460  gtk_widget_show (get_wg ("checkbutton_speech"));
461  else
462  gtk_widget_hide (get_wg ("checkbutton_speech"));
463 
464  g_free (tmp_code);
465 }
466 
467 /**********************************************************************
468  * Get the current language name, mapped from the preference's key code
469  */
470 gchar *
472 {
473  gchar *tmp_code;
474  gint i;
475 
476  if (lang_num == 0)
477  {
478  g_warning ("Internal error: trying to use language data not initialized!");
479  return (NULL);
480  }
481 
482  tmp_code = main_preferences_get_string ("interface", "language");
483  for (i = 0; i < lang_num; i++)
484  if (g_str_equal (lang[i].code, tmp_code))
485  {
486  g_free (tmp_code);
487  return (lang[i].name);
488  }
489  g_free (tmp_code);
490  return ("??");
491 }
492 
493 /**********************************************************************
494  * Update the current language used accordingly to that selected in the
495  * 'combo_language'
496  */
497 void
499 {
500  gint i;
501  gchar *tmp_code;
502 
503  /* Keep decreasing order of scanning, for not missing "English UK", for instance. */
504  for (i = lang_num-1; i >= 0; i--)
505  if (g_str_has_prefix (language, lang[i].name))
506  break;
507 
508  if (i == lang_num)
509  {
510  g_warning ("change_language() --> couldn't find the language: %s", language);
511  return;
512  }
513 
514  main_preferences_set_string ("interface", "language", lang[i].code);
515 
516  velo_reset_dict ();
518 
519  /* Check if the interface language is the same of the selected in the combo,
520  * so that it may be spoken
521  */
522  if (lang[i].code[0] == 'C')
523  tmp_code = g_strdup ("en");
524  else
525  tmp_code = g_strdup (lang[i].code);
526  if (tmp_code[0] == _("en")[0] && tmp_code[1] == _("en")[1])
527  gtk_widget_show (get_wg ("checkbutton_speech"));
528  else
529  gtk_widget_hide (get_wg ("checkbutton_speech"));
530  g_free (tmp_code);
531 }
532 
533 /**********************************************************************
534  * Find a file whose language prefix is similar to the current one
535  */
536 FILE *
537 trans_lang_get_similar_file (const gchar * file_end)
538 {
539  gint i;
540  gchar *tmp_code;
541  gchar *tmp_path = NULL;
542  FILE *fh = NULL;
543 
544  tmp_code = main_preferences_get_string ("interface", "language");
545  for (i = 0; i < lang_num && fh == NULL; i++)
546  {
547  if (g_str_equal (lang[i].code, tmp_code))
548  continue;
549  if (lang[i].code[0] == tmp_code[0] && lang[i].code[1] == tmp_code[1])
550  {
551  g_free (tmp_path);
552  tmp_path =
553  g_strconcat (main_path_data (), G_DIR_SEPARATOR_S, lang[i].code, file_end, NULL);
554  fh = (FILE *) g_fopen (tmp_path, "r");
555  }
556  }
557  g_free (tmp_code);
558  g_free (tmp_path);
559  i--;
560  if (fh)
561  g_message ("applying similar file: %s%s", lang[i].code, file_end);
562  return (fh);
563 }
564 
565 /**********************************************************************
566  * Find a file whose language prefix is similar to the current one, returnig
567  * its name
568  */
569 gchar *
570 trans_lang_get_similar_file_name (const gchar * file_end)
571 {
572  gint i;
573  gchar *tmp_code;
574  gchar *tmp_path = NULL;
575 
576  tmp_code = main_preferences_get_string ("interface", "language");
577  for (i = 0; i < lang_num; i++)
578  {
579  if (g_str_equal (lang[i].code, tmp_code))
580  continue;
581  if (lang[i].code[0] == tmp_code[0] && lang[i].code[1] == tmp_code[1])
582  {
583  g_free (tmp_path);
584  tmp_path =
585  g_strconcat (main_path_data (), G_DIR_SEPARATOR_S, lang[i].code, file_end, NULL);
586  if (g_file_test (tmp_path, G_FILE_TEST_IS_REGULAR))
587  break;
588  }
589  }
590  if (tmp_path == NULL)
591  tmp_path = g_strconcat (main_path_data (), G_DIR_SEPARATOR_S, "C", file_end, NULL);
592  g_free (tmp_code);
593  return (tmp_path);
594 }
595 
596 /**********************************************************************
597  * Reads the text of a file to be presented at some dialog,
598  * accordingly to the environment language.
599  * 'text': new buffer where the text is copied into.
600  * 'file_end': how the file name ends
601  */
602 
603 gchar *
604 trans_read_text (const gchar * file_end)
605 {
606  gchar *buf;
607  gchar *tmp_name = NULL;
608  gchar *tmp_path = NULL;
609  gchar *tmp_code;
610  FILE *fh;
611 
612  gchar *basic1 = _(
613 "The basic course focuses on having you read the characters presented to you on screen "
614 "and typing the corresponding keys. Remember to keep your hands correctly oriented "
615 "on the home row of the keyboard at all times (see introduction on main menu).");
616  gchar *basic2 = _(
617 "The key set used in each series will be shown in the above message line. "
618 "The [Space], [Shift] and [Enter] keys may not show up there but are used very often.");
619  gchar *basic3 = _(
620 "The message line below follows and echoes your key presses. "
621 "If required, it changes and displays instructions for actions required from you.");
622 
623  gchar *adapt1 = _(
624 "Here you may practice and improve your memorization of all keys. "
625 "There will be sentences presented with nonsense words which mix some numbers and symbols.");
626  gchar *adapt2 = _(
627 "In order to keep the lesson contents language and keyboard independent, "
628 "accented letter combinations will probably not appear. For real word sentences, "
629 "please use the fourth option of the main menu (about fluidness).");
630  gchar *adapt3 = _(
631 "After each exercise there will be a brief statistics panel "
632 "reviewing your performance along with some relevant comments.");
633 
634  gchar *velo1 = _(
635 "This exercise is very similar to the second one, for adaptability. "
636 "The difference is that here you'll type real words.");
637  gchar *velo2 = _(
638 "The default language is the actual one of the interface. "
639 "But you may select any other texts with words you would like to use. "
640 "Press the 'Other' option above and add files containing those texts.");
641  gchar *velo3 = _(
642 "With this exercise the focus is on speed. "
643 "So, you are supposed to type really fast and I will only flatter you when you deserve it!");
644 
645  gchar *fluid1 = _(
646 "We will now use complete sentences and paragraphs which make logical sense. "
647 "This may distract you while you type if you try to understand what you are entering. "
648 "The previous exercises were aimed at getting you to type without interpreting and analyzing the content.");
649  gchar *fluid2 = _(
650 "We do not mean to imply that the typists must behave like a robot, without understanding what they type. "
651 "We do aim to develop the skill of typing, making it an automatic reflex akin to the acts of walking, talking, etc. "
652 "After reaching this goal, the act of typing will become automatic and require little concentration. "
653 "Then you will be able to pay attention to the real meaning of the text.");
654  gchar *fluid3 = _("These exercises are longer. Each exercise consists of three paragraphs and "
655 "the emphasis is placed on correctness and rhythm, with a minimum speed requirement. "
656 "Here you will be required to use the backspace key to correct any mistakes. "
657 "In other words, only input without error will be accepted.");
658 
659  if (g_str_equal (file_end, "_basic_intro.txt"))
660  return (g_strdup_printf ("%s\n%s\n%s", basic1, basic2, basic3));
661 
662  if (g_str_equal (file_end, "_adapt_intro.txt"))
663  return (g_strdup_printf ("%s\n%s\n%s", adapt1, adapt2, adapt3));
664 
665  if (g_str_equal (file_end, "_velo_intro.txt"))
666  return (g_strdup_printf ("%s\n%s\n%s", velo1, velo2, velo3));
667 
668  if (g_str_equal (file_end, "_fluid_intro.txt"))
669  return (g_strdup_printf ("%s\n%s\n%s", fluid1, fluid2, fluid3));
670 
671  /* Use text files
672  */
673  tmp_code = main_preferences_get_string ("interface", "language");
674  tmp_name = g_strconcat (tmp_code, file_end, NULL);
675 
676  /* Try at HOME
677  */
678  tmp_path = g_build_filename (main_path_user (), tmp_name, NULL);
679  fh = (FILE *) g_fopen (tmp_path, "r");
680 
681  /* Try at PACKAGE_DATA
682  */
683  if (fh == NULL)
684  {
685  g_free (tmp_path);
686  tmp_path = g_build_filename (main_path_data (), tmp_name, NULL);
687  fh = (FILE *) g_fopen (tmp_path, "r");
688  }
689 
690  /*
691  * Try other "flavors" of the same language
692  */
693  if (fh == NULL && strlen (tmp_code) > 1)
694  fh = trans_lang_get_similar_file (file_end);
695 
696  /*
697  * Default to C
698  */
699  if (fh == NULL && ! g_str_equal (tmp_code, "C"))
700  {
701  g_message ("trans_read_text() --> couldn't open the data file: %s\n"
702  " So, we have to apply the default one: C%s", tmp_name, file_end);
703  main_preferences_set_string ("interface", "language", "C");
704  buf = trans_read_text (file_end);
705  main_preferences_set_string ("interface", "language", tmp_code);
706  g_free (tmp_code);
707  g_free (tmp_path);
708  g_free (tmp_name);
709  return buf;
710  }
711 
712  if (fh == NULL)
713  g_error ("trans_read_text() --> couldn't open the data file:\n %s", tmp_name);
714 
715  g_free (tmp_code);
716  g_free (tmp_path);
717  g_free (tmp_name);
718 
719  /*
720  * Process the file
721  */
722  gsize bufsize = 16;
723  gsize pos = 0;
724  buf = g_malloc (bufsize);
725  while (1)
726  {
727  gsize max = bufsize - pos - 1; // -1 for terminating zero
728  gsize ct = fread (buf + pos, 1, max, fh);
729  if (ct == 0)
730  break;
731  pos += ct;
732  if (ct == max)
733  {
734  bufsize *= 2;
735  buf = g_realloc (buf, bufsize);
736  }
737  }
738  buf[pos] = 0;
739  fclose (fh);
740  return buf;
741 }
GtkWidget * get_wg(gchar *name)
Definition: auxiliar.c:40
#define _(String)
Definition: auxiliar.h:45
void callbacks_shield_set(gboolean state)
Definition: callbacks.c:57
void fluid_reset_paragraph()
Definition: fluidness.c:58
guint i
Definition: keyboard.c:55
gchar * name
Definition: keyboard.c:45
struct @4::@6 pos
void main_preferences_remove(gchar *group, gchar *key)
Definition: main.c:103
gchar * main_preferences_get_string(gchar *group, gchar *key)
Definition: main.c:109
gchar * main_path_user()
Definition: main.c:61
gboolean main_preferences_exist(gchar *group, gchar *key)
Definition: main.c:97
void main_preferences_set_string(gchar *group, gchar *key, gchar *value)
Definition: main.c:115
gchar * main_path_data()
Definition: main.c:73
gchar language[50+1][80+1]
Definition: plot.c:93
gchar * code
Definition: translation.h:78
gchar cd[3]
Definition: translation.h:79
gchar * name
Definition: translation.h:77
gchar * trans_get_current_language()
Definition: translation.c:471
void trans_change_language(gchar *language)
Definition: translation.c:498
gboolean trans_lang_is_available(gchar *langcode)
Definition: translation.c:226
static Lang_Name_Code * lang
Definition: translation.c:39
void trans_init_language_env()
Definition: translation.c:301
gchar * trans_get_default_keyboard()
Definition: translation.c:120
static gint lang_num
Definition: translation.c:40
gboolean trans_lang_has_stopmark()
Definition: translation.c:240
static gboolean trans_lang_get_similar(gchar *test)
Definition: translation.c:260
void trans_init_lang_name_code()
Definition: translation.c:148
void trans_set_combo_language()
Definition: translation.c:398
FILE * trans_lang_get_similar_file(const gchar *file_end)
Definition: translation.c:537
const gchar * trans_code_to_country(gchar *code)
Definition: translation.c:46
gchar * trans_read_text(const gchar *file_end)
Definition: translation.c:604
#define COUNTRY_N
gchar * trans_lang_get_similar_file_name(const gchar *file_end)
Definition: translation.c:570
gchar * trans_get_code(gint i)
Definition: translation.c:218
#define LANG_SET
Definition: translation.h:30
void velo_reset_dict()
Definition: velocity.c:56