Updated PCI IDs to latest snapshot.
[tangerine.git] / workbench / prefs / locale / page_language.c
blobcfc104abef52e2ef33b573d495465cf9cd212d16
1 /*
2 Copyright 2003-2008, The AROS Development Team. All rights reserved.
3 $Id$
4 */
6 // #define MUIMASTER_YES_INLINE_STDARG
8 #include <exec/types.h>
9 #include <utility/tagitem.h>
10 #include <libraries/asl.h>
11 #include <libraries/mui.h>
12 #include <prefs/locale.h>
13 #include <prefs/prefhdr.h>
14 //#define DEBUG 1
15 #include <zune/customclasses.h>
16 #include <zune/prefseditor.h>
18 #include <proto/exec.h>
19 #include <proto/intuition.h>
20 #include <proto/utility.h>
21 #include <proto/muimaster.h>
22 #include <proto/dos.h>
23 #include <proto/iffparse.h>
25 #include <string.h>
26 #include <stdio.h>
27 #include <stdlib.h>
29 #include <aros/debug.h>
31 #include "global.h"
32 #include "locale.h"
33 #include "registertab.h"
34 #include "page_language.h"
36 /*** Instance Data **********************************************************/
38 struct MUI_LanguageData
40 int nr_languages;
41 int nr_preferred;
43 Object *child;
44 Object *available;
45 Object *preferred;
46 Object *clear;
47 Object *prefs;
49 char **strings_available;
50 char **strings_preferred;
52 char *result[10]; /* result array for Gadget2Prefs */
55 struct MUI_CustomClass *Language_CLASS;
57 static struct Hook hook_available;
58 static struct Hook hook_preferred;
59 static struct Hook hook_clear;
61 VOID ShowMsg(char *msg);
63 /*** Helpers *****************************************************************/
65 STATIC VOID update_language_lists(struct MUI_LanguageData *data) {
66 struct LanguageEntry *entry;
67 int a;
68 int p;
70 a=0;
71 p=0;
72 ForeachNode(&language_list, entry)
74 if(entry->preferred)
76 data->strings_preferred[p]=entry->lve.name;
77 p++;
79 else
81 data->strings_available[a]=entry->lve.name;
82 a++;
85 data->strings_available[a]=NULL;
86 data->strings_preferred[p]=NULL;
89 STATIC VOID init_language_lists(struct MUI_LanguageData *data) {
91 struct LanguageEntry *entry;
92 int i;
94 data->nr_languages=0;
95 ForeachNode(&language_list, entry)
97 /* D(bug("entry->lve.name: %s\n",entry->lve.name)); */
98 entry->preferred=FALSE;
99 i=0;
100 D(bug("[language class] language %s\n",entry->lve.name));
101 while(i<10 && /* max 10 preferred langs, see prefs/locale.h */
102 entry->preferred==FALSE &&
103 localeprefs.lp_PreferredLanguages[i][0])
106 if (Stricmp(localeprefs.lp_PreferredLanguages[i], entry->lve.name) == 0)
108 D(bug("[language class] %s is preferred\n",
109 entry->lve.name));
110 entry->preferred=TRUE;
112 i++;
114 data->nr_languages++;
117 D(bug("[language class]: nr of languages: %d\n",data->nr_languages));
119 data->strings_available=AllocVec(sizeof(char *) * (data->nr_languages+1), MEMF_CLEAR);
120 data->strings_preferred=AllocVec(sizeof(char *) * (data->nr_languages+1), MEMF_CLEAR);
122 update_language_lists(data);
125 /*** Hooks ******************************************************************
127 * hook_func_available
128 * handles double clicks on the available languages
130 * hook_func_preferred
131 * handles double clicks on the preferred languages
133 * hook_func_clear
134 * handles clearing of preferred languages
136 ****************************************************************************/
138 STATIC VOID func_move_to_selected(char* selstr, struct MUI_LanguageData *data)
140 struct LanguageEntry *entry;
141 unsigned int i;
142 char *test;
144 D(bug("func_move_to_selected(%s,..)\n",selstr));
146 if(selstr) {
147 ForeachNode(&language_list, entry)
149 if (stricmp(selstr, entry->lve.name) == 0)
151 DoMethod(data->preferred,
152 MUIM_List_InsertSingle, entry->lve.name,
153 MUIV_List_Insert_Bottom);
155 entry->preferred=TRUE;
160 /* we could use
161 * DoMethod(data->available,MUIM_List_Remove, MUIV_List_Remove_Active);
162 * of course, but I also want to be able to use that for
163 * the Set method.
166 get(data->available,MUIA_List_Entries,&i);
167 while(i)
169 i--;
170 DoMethod(data->available, MUIM_List_GetEntry, i, &test);
171 if (stricmp(selstr, test) == 0)
173 DoMethod(data->available, MUIM_List_Remove, i);
174 i=0;
179 AROS_UFH2(
180 void, hook_func_available,
181 AROS_UFHA(struct Hook *, hook, A0),
182 AROS_UFHA(APTR, obj, A2)
185 AROS_USERFUNC_INIT
187 struct MUI_LanguageData *data= hook->h_Data;
188 char *selstr;
190 D(bug("[register class] hook_func_available\n"));
192 DoMethod(obj,MUIM_List_GetEntry,
193 MUIV_List_GetEntry_Active,(ULONG) &selstr);
195 func_move_to_selected(selstr,data);
198 AROS_USERFUNC_EXIT
201 AROS_UFH2(
202 void, hook_func_preferred,
203 AROS_UFHA(struct Hook *, hook, A0),
204 AROS_UFHA(APTR, obj, A2)
207 AROS_USERFUNC_INIT
208 struct MUI_LanguageData *data= hook->h_Data;
209 char *selstr;
210 struct LanguageEntry *entry;
212 D(bug("[register class] hook_func_preferred\n"));
214 DoMethod(obj,MUIM_List_GetEntry,
215 MUIV_List_GetEntry_Active,(ULONG) &selstr);
217 if(selstr) {
218 D(bug("move: %s\n",selstr));
220 ForeachNode(&language_list, entry)
222 if (strcmp(selstr, entry->lve.name) == 0) {
223 DoMethod(data->available,
224 MUIM_List_InsertSingle, entry->lve.name,
225 MUIV_List_Insert_Sorted);
226 entry->preferred=FALSE;
229 DoMethod(obj,MUIM_List_Remove, MUIV_List_Remove_Active);
232 AROS_USERFUNC_EXIT
235 STATIC VOID func_clear(struct MUI_LanguageData *data)
237 struct LanguageEntry *entry;
239 D(bug("[register class] func_clear\n"));
241 /* clear it */
242 DoMethod(data->preferred,MUIM_List_Clear);
244 /* add all old preferred languages again */
245 DoMethod(data->available, MUIM_Group_InitChange);
246 ForeachNode(&language_list, entry)
248 if(entry->preferred)
250 entry->preferred=FALSE;
251 DoMethod(data->available,
252 MUIM_List_InsertSingle, entry->lve.name,
253 MUIV_List_Insert_Bottom);
256 DoMethod(data->available, MUIM_List_Sort);
257 DoMethod(data->available, MUIM_Group_ExitChange);
261 AROS_UFH2(
262 void, hook_func_clear,
263 AROS_UFHA(struct Hook *, hook, A0),
264 AROS_UFHA(APTR *, obj, A2)
267 AROS_USERFUNC_INIT
268 struct MUI_LanguageData *data= hook->h_Data;
270 func_clear(data);
272 AROS_USERFUNC_EXIT
274 /*** Methods ****************************************************************
278 static void free_strings(struct MUI_LanguageData *data)
280 if(data->strings_available)
282 FreeVec(data->strings_available);
283 data->strings_available=NULL;
286 if(data->strings_preferred)
288 FreeVec(data->strings_preferred);
289 data->strings_preferred=NULL;
294 static Object *handle_New_error(Object *obj, struct IClass *cl, char *error)
296 struct MUI_LanguageData *data;
298 ShowMsg(error);
299 D(bug("[Language class] %s\n"));
301 if(!obj)
302 return NULL;
304 data = INST_DATA(cl, obj);
306 if(data->clear)
308 DisposeObject(data->clear);
309 data->clear=NULL;
312 if(data->available)
314 DisposeObject(data->available);
315 data->available=NULL;
318 if(data->preferred)
320 DisposeObject(data->preferred);
321 data->preferred=NULL;
324 if(data->child)
326 DisposeObject(data->child);
327 data->child=NULL;
330 free_strings(data);
332 CoerceMethod(cl, obj, OM_DISPOSE);
333 return NULL;
336 Object *Language_New(struct IClass *cl, Object *obj, struct opSet *msg)
338 struct MUI_LanguageData *data;
339 struct TagItem *tstate, *tag;
341 D(bug("[language class] Language Class New\n"));
344 * we create self first and then create the child,
345 * so we have self->data available already
348 obj = (Object *) DoSuperNewTags(
349 cl, obj, NULL,
350 TAG_DONE
353 if (obj == NULL)
355 return handle_New_error(obj,cl,"ERROR: Unable to create object!\n");
358 data = INST_DATA(cl, obj);
360 tstate=((struct opSet *)msg)->ops_AttrList;
361 while ((tag = (struct TagItem *) NextTagItem((APTR) &tstate)))
363 switch (tag->ti_Tag)
365 case MA_PrefsObject:
366 data->prefs = (Object *) tag->ti_Data;
367 break;
371 if(!data->prefs)
372 return handle_New_error(obj,cl,"ERROR: MA_PrefsObject not supplied!\n");
374 init_language_lists(data);
376 data->clear=MUI_MakeObject(MUIO_Button, (ULONG) MSG(MSG_GAD_CLEAR_LANGUAGES));
378 data->available= ListviewObject, MUIA_Listview_List,
379 ListObject,
380 InputListFrame,
381 MUIA_List_SourceArray, data->strings_available,
382 End,
383 End;
385 data->preferred= ListviewObject, MUIA_Listview_List,
386 ListObject,
387 InputListFrame,
388 MUIA_List_SourceArray, data->strings_preferred,
389 End,
390 End;
392 if(!data->clear || !data->available || !data->preferred)
393 return handle_New_error(obj,cl,"ERROR: MakeObject failed\n");
395 data->child=
396 VGroup,
397 Child,
398 HGroup,
399 Child,
400 /* Available Languages */
401 VGroup,
402 Child,
403 CLabel1(MSG(MSG_GAD_AVAIL_LANGUAGES)),
404 Child,
405 data->available,
406 End,
407 Child,
408 /* Preferred Languages */
409 VGroup,
410 Child,
411 CLabel1(MSG(MSG_GAD_PREF_LANGUAGES)),
412 Child,
413 data->preferred,
414 End,
415 End,
416 End;
418 if(!data->child)
419 return handle_New_error(obj,cl,"ERROR: create child failed\n");
421 /* add clear button */
422 DoMethod(data->child,OM_ADDMEMBER,(ULONG) data->clear);
424 /* add to self */
425 DoMethod(obj,OM_ADDMEMBER,(ULONG) data->child);
427 /* setup hooks */
429 /* move hooks */
430 hook_available.h_Entry = (HOOKFUNC) hook_func_available;
431 hook_available.h_Data = data ;
432 DoMethod(data->available,MUIM_Notify,MUIA_Listview_DoubleClick,MUIV_EveryTime, (ULONG) data->available,2,MUIM_CallHook,(IPTR) &hook_available);
434 hook_preferred.h_Entry = (HOOKFUNC) hook_func_preferred;
435 hook_preferred.h_Data = data ;
436 DoMethod(data->preferred,MUIM_Notify,MUIA_Listview_DoubleClick,MUIV_EveryTime, (ULONG) data->preferred,2,MUIM_CallHook,(IPTR) &hook_preferred);
438 /* clear hook */
439 hook_clear.h_Entry = (HOOKFUNC) hook_func_clear;
440 hook_clear.h_Data = data ;
441 DoMethod(data->clear,MUIM_Notify,MUIA_Selected,MUIV_EveryTime, (ULONG) data->preferred,2,MUIM_CallHook,(IPTR) &hook_clear);
443 /* changed hooks */
444 DoMethod(data->preferred, MUIM_Notify, MUIA_Listview_DoubleClick, MUIV_EveryTime, (IPTR) data->prefs, 3, MUIM_Set, MUIA_PrefsEditor_Changed, TRUE);
445 DoMethod(data->available, MUIM_Notify, MUIA_Listview_DoubleClick, MUIV_EveryTime, (IPTR) data->prefs, 3, MUIM_Set, MUIA_PrefsEditor_Changed, TRUE);
447 return obj;
450 /*** Get ******************************************************************/
452 static IPTR Language_Get(struct IClass *cl, Object *obj, struct opGet *msg)
454 struct MUI_LanguageData *data = INST_DATA(cl, obj);
455 ULONG rc;
456 ULONG i;
458 switch (msg->opg_AttrID)
460 case MA_Preferred: /* return array of preferred language strings */
461 for(i=0;i<10;i++)
463 DoMethod(data->preferred,
464 MUIM_List_GetEntry,i,
465 &data->result[i]);
467 rc = (ULONG) data->result;
468 break;
469 default:
470 return DoSuperMethodA(cl, obj, (Msg)msg);
473 *msg->opg_Storage = rc;
474 return TRUE;
477 /*** Set ******************************************************************/
478 static IPTR Language_Set(struct IClass *cl, Object *obj, struct opSet *msg)
480 struct MUI_LanguageData *data = INST_DATA(cl, obj);
481 struct TagItem *tstate, *tag;
482 ULONG update;
483 ULONG i;
485 tstate = msg->ops_AttrList;
486 update = FALSE;
488 while ((tag = (struct TagItem *) NextTagItem((APTR) &tstate)))
490 switch (tag->ti_Tag)
492 case MA_Preferred:
493 /* clear preferred */
494 func_clear(data);
495 for(i=0; i<10; i++)
497 if(localeprefs.lp_PreferredLanguages[i][0] != '\0')
499 func_move_to_selected(localeprefs.lp_PreferredLanguages[i],data);
503 update=TRUE;
504 break;
506 default:
507 return DoSuperMethodA(cl, obj, (Msg)msg);
511 if(update)
513 MUI_Redraw(obj, MADF_DRAWOBJECT);
516 return TRUE;
519 static IPTR Language_Dispose(struct IClass *cl, Object *obj, Msg msg)
521 struct MUI_LanguageData *data = INST_DATA(cl, obj);
523 D(bug("Language_Dispose\n"));
526 free_strings(data);
528 return DoSuperMethodA(cl, obj, msg);
531 /*** Setup ******************************************************************/
533 BOOPSI_DISPATCHER(IPTR, Language_Dispatcher, cl, obj, msg)
535 switch (msg->MethodID)
537 case OM_NEW: return (IPTR) Language_New(cl, obj, (struct opSet *)msg);
538 case OM_GET: return Language_Get(cl, obj, (struct opGet *)msg);
539 case OM_SET: return Language_Set(cl, obj, (struct opSet *)msg);
540 case OM_DISPOSE: return Language_Dispose(cl, obj, msg);
543 return DoSuperMethodA(cl, obj, msg);
545 BOOPSI_DISPATCHER_END
548 * Class descriptor.
550 const struct __MUIBuiltinClass _MUIP_Language_desc =
552 "Language",
553 MUIC_Group,
554 sizeof(struct MUI_LanguageData),
555 (void*)Language_Dispatcher
558 void InitLanguage()
560 Language_CLASS=MUI_CreateCustomClass(NULL,MUIC_Group,NULL,sizeof(struct MUI_LanguageData),(APTR) &Language_Dispatcher);
564 void CleanLanguage()
566 if(Language_CLASS)
568 MUI_DeleteCustomClass(Language_CLASS);
569 Language_CLASS=NULL;