Use hardcoded settings for VIA VT1708S (they are reported to work
[AROS.git] / workbench / prefs / locale / page_language.c
blobc40d933f22ef673946bc5abad6b3c2d7fd78ad2f
1 /*
2 Copyright © 2003-2011, The AROS Development Team. All rights reserved.
3 $Id$
4 */
6 // #define MUIMASTER_YES_INLINE_STDARG
8 //#define DEBUG 1
9 #include <zune/customclasses.h>
10 #include <zune/prefseditor.h>
12 #include <proto/alib.h>
13 #include <proto/codesets.h>
14 #include <proto/intuition.h>
15 #include <proto/utility.h>
16 #include <proto/muimaster.h>
18 #include <aros/debug.h>
20 #include "locale.h"
21 #include "prefs.h"
22 #include "misc.h"
23 #include "registertab.h"
24 #include "page_language.h"
26 /*** Instance Data **********************************************************/
28 struct Language_DATA
30 int nr_languages;
31 int nr_preferred;
33 Object *child;
34 Object *available;
35 Object *preferred;
36 Object *charset;
37 Object *cslist;
38 Object *cslistview;
39 Object *popup;
40 Object *clear;
41 Object *prefs;
43 char **strings_available;
44 char **strings_preferred;
45 STRPTR *strings_charsets;
47 char *result[10]; /* result array for Gadget2Prefs */
50 struct MUI_CustomClass *Language_CLASS;
52 static struct Hook hook_available;
53 static struct Hook hook_preferred;
54 static struct Hook hook_clear;
56 /*** Helpers *****************************************************************/
58 STATIC VOID update_language_lists(struct Language_DATA *data)
60 struct LanguageEntry *entry;
61 int a;
62 int p;
64 a=0;
65 p=0;
66 ForeachNode(&language_list, entry)
68 if(entry->preferred)
70 data->strings_preferred[p] = entry->lve.name;
71 p++;
73 else
75 data->strings_available[a] = entry->lve.name;
76 a++;
79 data->strings_available[a] = NULL;
80 data->strings_preferred[p] = NULL;
83 STATIC VOID init_language_lists(struct Language_DATA *data)
86 struct LanguageEntry *entry;
87 int i;
89 data->nr_languages = 0;
90 ForeachNode(&language_list, entry)
92 D(bug("entry->lve.name: %s\n",entry->lve.name));
93 entry->preferred = FALSE;
94 i = 0;
95 D(bug("[language class] language %s\n",entry->lve.name));
96 while (i < 10 && /* max 10 preferred langs, see prefs/locale.h */
97 entry->preferred == FALSE &&
98 localeprefs.lp_PreferredLanguages[i][0])
101 if (Stricmp(localeprefs.lp_PreferredLanguages[i], entry->lve.name) == 0)
103 D(bug("[language class] %s is preferred\n",
104 entry->lve.name));
105 entry->preferred = TRUE;
107 i++;
109 data->nr_languages++;
112 D(bug("[language class]: nr of languages: %d\n",data->nr_languages));
114 data->strings_available = AllocVec(sizeof(char *) * (data->nr_languages+1), MEMF_CLEAR);
115 data->strings_preferred = AllocVec(sizeof(char *) * (data->nr_languages+1), MEMF_CLEAR);
117 update_language_lists(data);
120 /*** Hooks ******************************************************************
122 * hook_func_available
123 * handles double clicks on the available languages
125 * hook_func_preferred
126 * handles double clicks on the preferred languages
128 * hook_func_clear
129 * handles clearing of preferred languages
131 ****************************************************************************/
133 STATIC VOID func_move_to_selected(char* selstr, struct Language_DATA *data)
135 struct LanguageEntry *entry;
136 unsigned int i = 0;
137 char *test;
139 D(bug("func_move_to_selected(%s,..)\n",selstr));
141 if(selstr) {
142 ForeachNode(&language_list, entry)
144 if (stricmp(selstr, entry->lve.name) == 0)
146 DoMethod(data->preferred,
147 MUIM_List_InsertSingle, entry->lve.name,
148 MUIV_List_Insert_Bottom);
150 entry->preferred = TRUE;
155 /* we could use
156 * DoMethod(data->available,MUIM_List_Remove, MUIV_List_Remove_Active);
157 * of course, but I also want to be able to use that for
158 * the Set method.
161 GET(data->available,MUIA_List_Entries,&i);
162 while(i)
164 i--;
165 DoMethod(data->available, MUIM_List_GetEntry, i, &test);
166 if (stricmp(selstr, test) == 0)
168 DoMethod(data->available, MUIM_List_Remove, i);
169 i = 0;
174 AROS_UFH2
176 void, hook_func_available,
177 AROS_UFHA(struct Hook *, hook, A0),
178 AROS_UFHA(APTR, obj, A2)
181 AROS_USERFUNC_INIT
183 struct Language_DATA *data= hook->h_Data;
184 char *selstr;
186 D(bug("[register class] hook_func_available\n"));
188 DoMethod(obj,MUIM_List_GetEntry,
189 MUIV_List_GetEntry_Active, &selstr);
191 func_move_to_selected(selstr, data);
193 AROS_USERFUNC_EXIT
196 AROS_UFH2
198 void, hook_func_preferred,
199 AROS_UFHA(struct Hook *, hook, A0),
200 AROS_UFHA(APTR, obj, A2)
203 AROS_USERFUNC_INIT
205 struct Language_DATA *data= hook->h_Data;
206 char *selstr;
207 struct LanguageEntry *entry;
209 D(bug("[register class] hook_func_preferred\n"));
211 DoMethod(obj,MUIM_List_GetEntry,
212 MUIV_List_GetEntry_Active, &selstr);
214 if(selstr)
216 D(bug("move: %s\n",selstr));
218 ForeachNode(&language_list, entry)
220 if (strcmp(selstr, entry->lve.name) == 0)
222 DoMethod(data->available,
223 MUIM_List_InsertSingle, entry->lve.name,
224 MUIV_List_Insert_Sorted);
225 entry->preferred = FALSE;
228 DoMethod(obj, MUIM_List_Remove, MUIV_List_Remove_Active);
231 AROS_USERFUNC_EXIT
234 STATIC VOID func_clear(struct Language_DATA *data)
236 struct LanguageEntry *entry;
238 D(bug("[register class] func_clear\n"));
240 /* clear it */
241 DoMethod(data->preferred, MUIM_List_Clear);
243 /* add all old preferred languages again */
244 DoMethod(data->available, MUIM_Group_InitChange);
245 ForeachNode(&language_list, entry)
247 if(entry->preferred)
249 entry->preferred = FALSE;
250 DoMethod(data->available,
251 MUIM_List_InsertSingle, entry->lve.name,
252 MUIV_List_Insert_Bottom);
255 DoMethod(data->available, MUIM_List_Sort);
256 DoMethod(data->available, MUIM_Group_ExitChange);
260 AROS_UFH2(
261 void, hook_func_clear,
262 AROS_UFHA(struct Hook *, hook, A0),
263 AROS_UFHA(APTR *, obj, A2)
266 AROS_USERFUNC_INIT
268 struct Language_DATA *data = hook->h_Data;
270 func_clear(data);
272 AROS_USERFUNC_EXIT
275 AROS_UFH3
277 void, charset_popup_to_string,
278 AROS_UFHA(struct Hook*, hook, A0),
279 AROS_UFHA(Object *, list, A2),
280 AROS_UFHA(Object *, string, A1)
283 AROS_USERFUNC_INIT
285 STRPTR listentry;
286 STRPTR oldentry;
288 GetAttr(MUIA_Text_Contents, string, (IPTR *)&oldentry);
289 DoMethod(list, MUIM_List_GetEntry, MUIV_List_GetEntry_Active, (IPTR)&listentry);
290 if (strcmp(listentry, oldentry))
292 SetAttrs(string, MUIA_Text_Contents, listentry, TAG_DONE);
293 SetAttrs(hook->h_Data, MUIA_PrefsEditor_Changed, TRUE, TAG_DONE);
296 AROS_USERFUNC_EXIT
299 AROS_UFH3
301 ULONG, charset_string_to_popup,
302 AROS_UFHA(struct Hook*, hook, A0),
303 AROS_UFHA(Object *, list, A2),
304 AROS_UFHA(Object *, str, A1)
307 AROS_USERFUNC_INIT
309 STRPTR strtext, listentry;
310 LONG index;
312 GetAttr(MUIA_Text_Contents, str, (IPTR *)&strtext);
314 for(index = 0; ; index++)
316 DoMethod(list, MUIM_List_GetEntry, index, (IPTR)&listentry);
318 if (!listentry)
320 SET(list, MUIA_List_Active, MUIV_List_Active_Off);
321 break;
324 if (stricmp(strtext, listentry) == 0)
326 SET(list, MUIA_List_Active, index);
327 break;
331 return TRUE;
333 AROS_USERFUNC_EXIT
336 static struct Hook charset_popup_to_string_hook =
338 {NULL, NULL},
339 (HOOKFUNC)AROS_ASMSYMNAME(charset_popup_to_string),
340 NULL,
341 NULL
344 static struct Hook charset_string_to_popup_hook =
346 {NULL, NULL},
347 (HOOKFUNC)AROS_ASMSYMNAME(charset_string_to_popup),
348 NULL,
349 NULL
352 /*** Methods ****************************************************************
356 static void free_strings(struct Language_DATA *data)
358 if (data->strings_charsets)
360 CodesetsFreeA(data->strings_charsets, NULL);
361 data->strings_charsets = NULL;
363 if(data->strings_available)
365 FreeVec(data->strings_available);
366 data->strings_available = NULL;
369 if(data->strings_preferred)
371 FreeVec(data->strings_preferred);
372 data->strings_preferred = NULL;
377 static Object *handle_New_error(Object *obj, struct IClass *cl, char *error)
379 struct Language_DATA *data;
381 ShowMessage(error);
382 D(bug("[Language class] %s\n"));
384 if(!obj)
385 return NULL;
387 data = INST_DATA(cl, obj);
389 if(data->clear)
391 DisposeObject(data->clear);
392 data->clear=NULL;
395 if(data->available)
397 DisposeObject(data->available);
398 data->available=NULL;
401 if(data->preferred)
403 DisposeObject(data->preferred);
404 data->preferred = NULL;
407 if(data->child)
409 DisposeObject(data->child);
410 data->child = NULL;
413 if (data->charset) {
414 DisposeObject(data->charset);
415 data->charset = NULL;
418 if (data->cslist) {
419 DisposeObject(data->cslist);
420 data->cslist = NULL;
423 if (data->cslistview) {
424 DisposeObject(data->cslistview);
425 data->cslist = NULL;
428 if (data->popup) {
429 DisposeObject(data->popup);
430 data->popup = NULL;
433 free_strings(data);
435 CoerceMethod(cl, obj, OM_DISPOSE);
436 return NULL;
439 Object *Language__OM_NEW(struct IClass *cl, Object *obj, struct opSet *msg)
441 struct Language_DATA *data;
442 struct TagItem *tstate, *tag;
444 D(bug("[language class] Language Class New\n"));
447 * we create self first and then create the child,
448 * so we have self->data available already
451 obj = (Object *) DoSuperNewTags
453 cl, obj, NULL,
454 TAG_DONE
457 if (obj == NULL)
459 return handle_New_error(obj, cl, "ERROR: Unable to create object!\n");
462 data = INST_DATA(cl, obj);
464 tstate=((struct opSet *)msg)->ops_AttrList;
465 while ((tag = (struct TagItem *) NextTagItem((APTR) &tstate)))
467 switch (tag->ti_Tag)
469 case MUIA_UserData:
470 data->prefs = (Object *) tag->ti_Data;
471 break;
475 if(!data->prefs)
476 return handle_New_error(obj, cl, "ERROR: MA_PrefsObject not supplied!\n");
478 init_language_lists(data);
479 data->strings_charsets = CodesetsSupportedA(NULL);
481 data->clear = MUI_MakeObject(MUIO_Button, __(MSG_GAD_CLEAR_LANGUAGES));
483 data->available = ListviewObject, MUIA_Listview_List,
484 ListObject,
485 InputListFrame,
486 MUIA_List_SourceArray, data->strings_available,
487 End,
488 End;
490 data->preferred = ListviewObject, MUIA_Listview_List,
491 ListObject,
492 InputListFrame,
493 MUIA_List_SourceArray, data->strings_preferred,
494 End,
495 End;
497 data->charset = TextObject,
498 TextFrame,
499 MUIA_Background, MUII_TextBack,
500 End;
502 data->cslist = ListObject,
503 MUIA_Frame, MUIV_Frame_InputList,
504 MUIA_Background, MUII_ListBack,
505 MUIA_List_AutoVisible, TRUE,
506 MUIA_List_SourceArray, data->strings_charsets,
507 End;
509 data->cslistview = ListviewObject,
510 MUIA_Listview_List, data->cslist,
511 End;
513 charset_popup_to_string_hook.h_Data = data->prefs;
515 data->popup = PopobjectObject,
516 MUIA_Popobject_Object, data->cslistview,
517 MUIA_Popobject_StrObjHook, &charset_string_to_popup_hook,
518 MUIA_Popobject_ObjStrHook, &charset_popup_to_string_hook,
519 MUIA_Popstring_Button, PopButton(MUII_PopUp),
520 MUIA_Popstring_String, data->charset,
521 End;
523 if(!data->clear || !data->available || !data->preferred || !data->charset || !data->cslist ||
524 !data->cslistview || !data->popup)
525 return handle_New_error(obj,cl,"ERROR: MakeObject failed\n");
527 DoMethod(data->cslist, MUIM_List_Sort);
528 DoMethod(data->cslist, MUIM_List_InsertSingle, _(MSG_NOT_SPECIFIED), MUIV_List_Insert_Top);
530 data->child = VGroup,
531 Child, HGroup,
532 Child, VGroup, /* Available Languages */
533 Child, CLabel1(_(MSG_GAD_AVAIL_LANGUAGES)),
534 Child, data->available,
535 End,
536 Child, VGroup, /* Preferred Languages */
537 Child, CLabel1(_(MSG_GAD_PREF_LANGUAGES)),
538 Child, data->preferred,
539 End,
540 End,
541 Child, data->clear,
542 Child, HGroup,
543 Child, CLabel1(_(MSG_CHARACTER_SET)),
544 Child, data->popup,
545 End,
546 End;
548 if(!data->child)
549 return handle_New_error(obj, cl, "ERROR: create child failed\n");
551 /* add to self */
552 DoMethod(obj, OM_ADDMEMBER, data->child);
554 /* setup hooks */
555 DoMethod(data->cslistview, MUIM_Notify, MUIA_Listview_DoubleClick, TRUE, data->popup, 2, MUIM_Popstring_Close, TRUE);
557 /* move hooks */
558 hook_available.h_Entry = (HOOKFUNC) hook_func_available;
559 hook_available.h_Data = data ;
560 DoMethod
562 data->available, MUIM_Notify, MUIA_Listview_DoubleClick, MUIV_EveryTime, data->available,
563 2, MUIM_CallHook, (IPTR) &hook_available
566 hook_preferred.h_Entry = (HOOKFUNC) hook_func_preferred;
567 hook_preferred.h_Data = data ;
568 DoMethod
570 data->preferred, MUIM_Notify, MUIA_Listview_DoubleClick, MUIV_EveryTime, data->preferred,
571 2, MUIM_CallHook, (IPTR) &hook_preferred
574 /* clear hook */
575 hook_clear.h_Entry = (HOOKFUNC) hook_func_clear;
576 hook_clear.h_Data = data ;
577 DoMethod
579 data->clear, MUIM_Notify, MUIA_Selected, MUIV_EveryTime, data->preferred,
580 2, MUIM_CallHook, (IPTR) &hook_clear
583 /* changed hooks */
584 DoMethod
586 data->preferred, MUIM_Notify, MUIA_Listview_DoubleClick, MUIV_EveryTime, (IPTR) data->prefs,
587 3, MUIM_Set, MUIA_PrefsEditor_Changed, TRUE
589 DoMethod
591 data->available, MUIM_Notify, MUIA_Listview_DoubleClick, MUIV_EveryTime, (IPTR) data->prefs,
592 3, MUIM_Set, MUIA_PrefsEditor_Changed, TRUE
595 return obj;
598 /*** Get ******************************************************************/
600 static IPTR Language__OM_GET(struct IClass *cl, Object *obj, struct opGet *msg)
602 struct Language_DATA *data = INST_DATA(cl, obj);
603 IPTR rc;
604 IPTR i;
606 switch (msg->opg_AttrID)
608 case MUIA_Language_Preferred: /* return array of preferred language strings */
609 for (i = 0; i < 10; i++)
611 DoMethod(data->preferred, MUIM_List_GetEntry, i, &data->result[i]);
613 rc = (IPTR) data->result;
614 break;
615 case MUIA_Language_Characterset:
616 GetAttr(MUIA_List_Active, data->cslist, (IPTR *)&i);
617 D(bug("[Language::Get] Active character set entry is %d\n", i));
618 if ((i == 0) || (i == MUIV_List_Active_Off))
619 *msg->opg_Storage = 0;
620 else
621 GetAttr(MUIA_Text_Contents, data->charset, msg->opg_Storage);
622 return TRUE;
623 default:
624 return DoSuperMethodA(cl, obj, (Msg)msg);
627 *msg->opg_Storage = rc;
628 return TRUE;
631 /*** Set ******************************************************************/
632 static IPTR Language__OM_SET(struct IClass *cl, Object *obj, struct opSet *msg)
634 struct Language_DATA *data = INST_DATA(cl, obj);
635 struct TagItem *tstate, *tag;
636 ULONG update;
637 ULONG i;
639 tstate = msg->ops_AttrList;
640 update = FALSE;
642 while ((tag = (struct TagItem *) NextTagItem((APTR) &tstate)))
644 switch (tag->ti_Tag)
646 case MUIA_Language_Preferred:
647 /* clear preferred */
648 func_clear(data);
649 for (i = 0; i < 10; i++)
651 if(localeprefs.lp_PreferredLanguages[i][0] != '\0')
653 func_move_to_selected(localeprefs.lp_PreferredLanguages[i], data);
657 update = TRUE;
658 break;
659 case MUIA_Language_Characterset:
661 char *charset = (char *)tag->ti_Data;
663 if (!charset || !*charset)
664 DoMethod(data->cslist, MUIM_List_GetEntry, 0, (IPTR *)&charset);
665 SetAttrs(data->charset, MUIA_Text_Contents, charset, TAG_DONE);
667 break;
669 default:
670 return DoSuperMethodA(cl, obj, (Msg)msg);
674 if(update)
676 MUI_Redraw(obj, MADF_DRAWOBJECT);
679 return TRUE;
682 static IPTR Language__OM_DISPOSE(struct IClass *cl, Object *obj, Msg msg)
684 struct Language_DATA *data = INST_DATA(cl, obj);
686 D(bug("Language_Dispose\n"));
688 free_strings(data);
690 return DoSuperMethodA(cl, obj, msg);
693 /*** Setup ******************************************************************/
694 ZUNE_CUSTOMCLASS_4
696 Language, NULL, MUIC_Group, NULL,
697 OM_NEW, struct opSet *,
698 OM_SET, struct opSet *,
699 OM_GET, struct opGet *,
700 OM_DISPOSE, Msg