2 Copyright © 2003-2015, The AROS Development Team. All rights reserved.
6 #include <aros/debug.h>
8 #include <proto/alib.h>
9 #include <proto/codesets.h>
10 #include <proto/intuition.h>
11 #include <proto/utility.h>
12 #include <proto/muimaster.h>
14 #include <zune/customclasses.h>
15 #include <zune/prefseditor.h>
20 #include "registertab.h"
21 #include "page_language.h"
22 #include "languagelist.h"
24 /*** Instance Data **********************************************************/
41 char **strings_available
;
42 char **strings_preferred
;
43 STRPTR
*strings_charsets
;
45 char *langpreferred
[10]; /* result array for MUIA_Language_Preferred */
48 struct MUI_CustomClass
*Language_CLASS
;
50 static struct Hook hook_available
;
51 static struct Hook hook_preferred
;
52 static struct Hook hook_clear
;
54 /*** Helpers *****************************************************************/
56 STATIC VOID
init_language_lists(struct Language_DATA
*data
)
59 struct LanguageEntry
*entry
;
60 LONG i
= 0, p
= 0, a
= 0;
62 data
->nr_languages
= 0;
63 ForeachNode(&language_list
, entry
)
67 D(bug("[LocalePrefs-LanguageClass]: nr of languages: %d\n",data
->nr_languages
));
69 data
->strings_available
= AllocVec(sizeof(char *) * (data
->nr_languages
+1), MEMF_CLEAR
);
70 data
->strings_preferred
= AllocVec(sizeof(char *) * (data
->nr_languages
+1), MEMF_CLEAR
);
72 ForeachNode(&language_list
, entry
)
74 D(bug("[LocalePrefs-LanguageClass] language '%s' ('%s')\n", entry
->lve
.node
.ln_Name
, entry
->lve
.realname
));
75 BOOL preferred
= FALSE
;
77 /* max 10 preferred langs, see prefs/locale.h */
78 for (i
= 0; (i
< 10) && (localeprefs
.lp_PreferredLanguages
[i
][0]); i
++)
80 if (Stricmp(localeprefs
.lp_PreferredLanguages
[i
], entry
->lve
.realname
) == 0)
82 D(bug("[LocalePrefs-LanguageClass] %s is preferred\n", entry
->lve
.realname
));
89 data
->strings_preferred
[p
++] = entry
->lve
.node
.ln_Name
;
91 data
->strings_available
[a
++] = entry
->lve
.node
.ln_Name
;
95 data
->strings_available
[a
] = NULL
;
96 data
->strings_preferred
[p
] = NULL
;
99 /*** Hooks ******************************************************************
101 * hook_func_available
102 * handles double clicks on the available languages
104 * hook_func_preferred
105 * handles double clicks on the preferred languages
108 * handles clearing of preferred languages
110 ****************************************************************************/
112 STATIC VOID
func_move_to_selected(char* selstr
, struct Language_DATA
*data
)
114 struct LanguageEntry
*entry
= NULL
;
118 D(bug("[LocalePrefs-LanguageClass] func_move_to_selected('%s')\n", selstr
));
121 ForeachNode(&language_list
, entry
)
123 if (Stricmp(selstr
, entry
->lve
.realname
) == 0)
125 DoMethod(data
->preferred
,
126 MUIM_List_InsertSingle
, entry
->lve
.node
.ln_Name
,
127 MUIV_List_Insert_Bottom
);
134 * DoMethod(data->available,MUIM_List_Remove, MUIV_List_Remove_Active);
135 * of course, but I also want to be able to use that for
141 GET(data
->available
, MUIA_List_Entries
, &i
);
145 DoMethod(data
->available
, MUIM_List_GetEntry
, i
, &test
);
146 if (Stricmp(entry
->lve
.node
.ln_Name
, test
) == 0)
148 DoMethod(data
->available
, MUIM_List_Remove
, i
);
157 void, hook_func_available
,
158 AROS_UFHA(struct Hook
*, hook
, A0
),
159 AROS_UFHA(APTR
, obj
, A2
)
164 struct Language_DATA
*data
= hook
->h_Data
;
165 struct LanguageEntry
*entry
;
169 D(bug("[LocalePrefs-LanguageClass] hook_func_available\n"));
171 DoMethod(obj
,MUIM_List_GetEntry
,
172 MUIV_List_GetEntry_Active
, &selstr
);
174 ForeachNode(&language_list
, entry
)
176 if (Stricmp(selstr
, entry
->lve
.node
.ln_Name
) == 0)
178 func_move_to_selected(entry
->lve
.realname
, data
);
188 void, hook_func_preferred
,
189 AROS_UFHA(struct Hook
*, hook
, A0
),
190 AROS_UFHA(APTR
, obj
, A2
)
195 struct Language_DATA
*data
= hook
->h_Data
;
197 struct LanguageEntry
*entry
;
199 D(bug("[LocalePrefs-LanguageClass] hook_func_preferred\n"));
201 DoMethod(obj
,MUIM_List_GetEntry
,
202 MUIV_List_GetEntry_Active
, &selstr
);
206 D(bug("move: %s\n",selstr
));
208 ForeachNode(&language_list
, entry
)
210 if (Stricmp(selstr
, entry
->lve
.node
.ln_Name
) == 0)
212 DoMethod(data
->available
,
213 MUIM_List_InsertSingle
, entry
->lve
.node
.ln_Name
,
214 MUIV_List_Insert_Sorted
);
217 DoMethod(obj
, MUIM_List_Remove
, MUIV_List_Remove_Active
);
223 STATIC VOID
func_clear(struct Language_DATA
*data
)
225 struct LanguageEntry
*entry
;
227 D(bug("[LocalePrefs-LanguageClass] func_clear\n"));
230 DoMethod(data
->preferred
, MUIM_List_Clear
);
232 /* add all old preferred languages again */
233 set(data
->available
, MUIA_List_Quiet
, TRUE
);
234 DoMethod(data
->available
, MUIM_List_Clear
);
236 ForeachNode(&language_list
, entry
)
238 DoMethod(data
->available
,
239 MUIM_List_InsertSingle
, entry
->lve
.node
.ln_Name
,
240 MUIV_List_Insert_Sorted
);
243 set(data
->available
, MUIA_List_Quiet
, FALSE
);
247 void, hook_func_clear
,
248 AROS_UFHA(struct Hook
*, hook
, A0
),
249 AROS_UFHA(APTR
*, obj
, A2
)
254 struct Language_DATA
*data
= hook
->h_Data
;
257 SET(data
->prefs
, MUIA_PrefsEditor_Changed
, TRUE
);
264 void, charset_popup_to_string
,
265 AROS_UFHA(struct Hook
*, hook
, A0
),
266 AROS_UFHA(Object
*, list
, A2
),
267 AROS_UFHA(Object
*, string
, A1
)
275 GetAttr(MUIA_Text_Contents
, string
, (IPTR
*)&oldentry
);
276 DoMethod(list
, MUIM_List_GetEntry
, MUIV_List_GetEntry_Active
, (IPTR
)&listentry
);
277 if (Stricmp(listentry
, oldentry
))
279 SetAttrs(string
, MUIA_Text_Contents
, listentry
, TAG_DONE
);
280 SetAttrs(hook
->h_Data
, MUIA_PrefsEditor_Changed
, TRUE
, TAG_DONE
);
288 ULONG
, charset_string_to_popup
,
289 AROS_UFHA(struct Hook
*, hook
, A0
),
290 AROS_UFHA(Object
*, list
, A2
),
291 AROS_UFHA(Object
*, str
, A1
)
296 STRPTR strtext
, listentry
;
299 GetAttr(MUIA_Text_Contents
, str
, (IPTR
*)&strtext
);
301 for(index
= 0; ; index
++)
303 DoMethod(list
, MUIM_List_GetEntry
, index
, (IPTR
)&listentry
);
307 SET(list
, MUIA_List_Active
, MUIV_List_Active_Off
);
311 if (Stricmp(strtext
, listentry
) == 0)
313 SET(list
, MUIA_List_Active
, index
);
323 static struct Hook charset_popup_to_string_hook
=
326 (HOOKFUNC
)AROS_ASMSYMNAME(charset_popup_to_string
),
331 static struct Hook charset_string_to_popup_hook
=
334 (HOOKFUNC
)AROS_ASMSYMNAME(charset_string_to_popup
),
339 /*** Methods ****************************************************************
343 static void free_strings(struct Language_DATA
*data
)
345 if (data
->strings_charsets
)
347 CodesetsFreeA(data
->strings_charsets
, NULL
);
348 data
->strings_charsets
= NULL
;
350 if(data
->strings_available
)
352 FreeVec(data
->strings_available
);
353 data
->strings_available
= NULL
;
356 if(data
->strings_preferred
)
358 FreeVec(data
->strings_preferred
);
359 data
->strings_preferred
= NULL
;
364 static Object
*handle_New_error(Object
*obj
, struct IClass
*cl
, char *error
)
366 struct Language_DATA
*data
;
369 D(bug("[LocalePrefs-LanguageClass] %s\n"));
374 data
= INST_DATA(cl
, obj
);
378 DisposeObject(data
->clear
);
384 DisposeObject(data
->available
);
385 data
->available
=NULL
;
390 DisposeObject(data
->preferred
);
391 data
->preferred
= NULL
;
396 DisposeObject(data
->child
);
401 DisposeObject(data
->charset
);
402 data
->charset
= NULL
;
406 DisposeObject(data
->cslist
);
410 if (data
->cslistview
) {
411 DisposeObject(data
->cslistview
);
416 DisposeObject(data
->popup
);
422 CoerceMethod(cl
, obj
, OM_DISPOSE
);
426 Object
*Language__OM_NEW(struct IClass
*cl
, Object
*obj
, struct opSet
*msg
)
428 struct Language_DATA
*data
;
429 struct TagItem
*tstate
, *tag
;
430 struct Object
*avail_list
, *pref_list
;
432 D(bug("[LocalePrefs-LanguageClass] Language Class New\n"));
435 * we create self first and then create the child,
436 * so we have self->data available already
439 obj
= (Object
*) DoSuperNewTags
447 return handle_New_error(obj
, cl
, "ERROR: Unable to create object!\n");
450 data
= INST_DATA(cl
, obj
);
452 tstate
=((struct opSet
*)msg
)->ops_AttrList
;
453 while ((tag
= (struct TagItem
*) NextTagItem((APTR
) &tstate
)))
458 data
->prefs
= (Object
*) tag
->ti_Data
;
464 return handle_New_error(obj
, cl
, "ERROR: MA_PrefsObject not supplied!\n");
466 init_language_lists(data
);
467 data
->strings_charsets
= CodesetsSupportedA(NULL
);
469 data
->clear
= MUI_MakeObject(MUIO_Button
, __(MSG_GAD_CLEAR_LANGUAGES
));
471 data
->available
= ListviewObject
, MUIA_Listview_List
,
472 avail_list
= NewObject(Languagelist_CLASS
->mcc_Class
, 0,
474 MUIA_Draggable
, TRUE
,
475 MUIA_List_SourceArray
, data
->strings_available
,
479 data
->preferred
= ListviewObject
, MUIA_Listview_List
,
480 pref_list
= NewObject(Languagelist_CLASS
->mcc_Class
, 0,
482 MUIA_Draggable
, TRUE
,
483 MUIA_List_SourceArray
, data
->strings_preferred
,
487 set(pref_list
, MUIA_UserData
, avail_list
);
488 set(avail_list
, MUIA_UserData
, pref_list
);
490 data
->charset
= TextObject
,
492 MUIA_Background
, MUII_TextBack
,
495 data
->cslist
= ListObject
,
496 MUIA_Frame
, MUIV_Frame_InputList
,
497 MUIA_Background
, MUII_ListBack
,
498 MUIA_List_AutoVisible
, TRUE
,
499 MUIA_List_SourceArray
, data
->strings_charsets
,
502 data
->cslistview
= ListviewObject
,
503 MUIA_Listview_List
, data
->cslist
,
506 charset_popup_to_string_hook
.h_Data
= data
->prefs
;
508 data
->popup
= PopobjectObject
,
509 MUIA_Popobject_Object
, data
->cslistview
,
510 MUIA_Popobject_StrObjHook
, &charset_string_to_popup_hook
,
511 MUIA_Popobject_ObjStrHook
, &charset_popup_to_string_hook
,
512 MUIA_Popstring_Button
, PopButton(MUII_PopUp
),
513 MUIA_Popstring_String
, data
->charset
,
516 if(!data
->clear
|| !data
->available
|| !data
->preferred
|| !data
->charset
|| !data
->cslist
||
517 !data
->cslistview
|| !data
->popup
)
518 return handle_New_error(obj
,cl
,"ERROR: MakeObject failed\n");
520 DoMethod(data
->cslist
, MUIM_List_Sort
);
521 DoMethod(data
->cslist
, MUIM_List_InsertSingle
, _(MSG_NOT_SPECIFIED
), MUIV_List_Insert_Top
);
523 data
->child
= VGroup
,
525 Child
, VGroup
, /* Available Languages */
526 Child
, CLabel1(_(MSG_GAD_AVAIL_LANGUAGES
)),
527 Child
, data
->available
,
529 Child
, VGroup
, /* Preferred Languages */
530 Child
, CLabel1(_(MSG_GAD_PREF_LANGUAGES
)),
531 Child
, data
->preferred
,
536 Child
, CLabel1(_(MSG_CHARACTER_SET
)),
542 return handle_New_error(obj
, cl
, "ERROR: create child failed\n");
545 DoMethod(obj
, OM_ADDMEMBER
, data
->child
);
548 DoMethod(data
->cslistview
, MUIM_Notify
, MUIA_Listview_DoubleClick
, TRUE
, data
->popup
, 2, MUIM_Popstring_Close
, TRUE
);
551 hook_available
.h_Entry
= (HOOKFUNC
) hook_func_available
;
552 hook_available
.h_Data
= data
;
555 data
->available
, MUIM_Notify
, MUIA_Listview_DoubleClick
, MUIV_EveryTime
, data
->available
,
556 2, MUIM_CallHook
, (IPTR
) &hook_available
559 hook_preferred
.h_Entry
= (HOOKFUNC
) hook_func_preferred
;
560 hook_preferred
.h_Data
= data
;
563 data
->preferred
, MUIM_Notify
, MUIA_Listview_DoubleClick
, MUIV_EveryTime
, data
->preferred
,
564 2, MUIM_CallHook
, (IPTR
) &hook_preferred
568 hook_clear
.h_Entry
= (HOOKFUNC
) hook_func_clear
;
569 hook_clear
.h_Data
= data
;
572 data
->clear
, MUIM_Notify
, MUIA_Selected
, MUIV_EveryTime
, data
->preferred
,
573 2, MUIM_CallHook
, (IPTR
) &hook_clear
579 pref_list
, MUIM_Notify
, MUIA_List_Entries
, MUIV_EveryTime
,
580 (IPTR
) data
->prefs
, 3, MUIM_Set
, MUIA_PrefsEditor_Changed
, TRUE
586 /*** Get ******************************************************************/
588 static IPTR
Language__OM_GET(struct IClass
*cl
, Object
*obj
, struct opGet
*msg
)
590 struct Language_DATA
*data
= INST_DATA(cl
, obj
);
594 switch (msg
->opg_AttrID
)
596 case MUIA_Language_Preferred
: /* return array of preferred language strings */
597 memset(data
->langpreferred
, 0, sizeof(data
->langpreferred
));
598 for (i
= 0; i
< 10; i
++)
600 struct LanguageEntry
*entry
;
601 char *langNative
= NULL
;
603 DoMethod(data
->preferred
, MUIM_List_GetEntry
, i
, &langNative
);
604 D(bug("[LocalePrefs-LanguageClass] Get: MUIA_Language_Preferred %02d = '%s'\n", i
, langNative
));
605 ForeachNode(&language_list
, entry
)
607 if(Stricmp(langNative
, entry
->lve
.node
.ln_Name
) == 0)
609 data
->langpreferred
[i
] = entry
->lve
.realname
;
610 D(bug("[LocalePrefs-LanguageClass] Get: BaseName = '%s'\n", data
->langpreferred
[i
]));
615 rc
= (IPTR
) data
->langpreferred
;
617 case MUIA_Language_Characterset
:
618 GetAttr(MUIA_List_Active
, data
->cslist
, (IPTR
*)&i
);
619 D(bug("[LocalePrefs-LanguageClass] Get: MUIA_Language_Characterset = %d\n", i
));
620 if ((i
== 0) || (i
== MUIV_List_Active_Off
))
621 *msg
->opg_Storage
= 0;
623 GetAttr(MUIA_Text_Contents
, data
->charset
, msg
->opg_Storage
);
626 return DoSuperMethodA(cl
, obj
, (Msg
)msg
);
629 *msg
->opg_Storage
= rc
;
633 /*** Set ******************************************************************/
634 static IPTR
Language__OM_SET(struct IClass
*cl
, Object
*obj
, struct opSet
*msg
)
636 struct Language_DATA
*data
= INST_DATA(cl
, obj
);
637 struct TagItem
*tstate
, *tag
;
641 tstate
= msg
->ops_AttrList
;
644 while ((tag
= (struct TagItem
*) NextTagItem((APTR
) &tstate
)))
648 case MUIA_Language_Preferred
:
649 /* clear preferred */
651 for (i
= 0; i
< 10; i
++)
653 if(localeprefs
.lp_PreferredLanguages
[i
][0] != '\0')
655 D(bug("[LocalePrefs-LanguageClass] OM_SET: MUIA_Language_Preferred %d = '%s'\n", i
, localeprefs
.lp_PreferredLanguages
[i
]));
656 func_move_to_selected(localeprefs
.lp_PreferredLanguages
[i
], data
);
662 case MUIA_Language_Characterset
:
664 char *charset
= (char *)tag
->ti_Data
;
666 D(bug("[LocalePrefs-LanguageClass] OM_SET: MUIA_Language_Characterset = '%s'\n", i
, charset
));
668 if (!charset
|| !*charset
)
669 DoMethod(data
->cslist
, MUIM_List_GetEntry
, 0, (IPTR
*)&charset
);
670 SetAttrs(data
->charset
, MUIA_Text_Contents
, charset
, TAG_DONE
);
675 return DoSuperMethodA(cl
, obj
, (Msg
)msg
);
681 MUI_Redraw(obj
, MADF_DRAWOBJECT
);
687 static IPTR
Language__OM_DISPOSE(struct IClass
*cl
, Object
*obj
, Msg msg
)
689 struct Language_DATA
*data
= INST_DATA(cl
, obj
);
691 D(bug("[LocalePrefs-LanguageClass] OM_DISPOSE()\n"));
695 return DoSuperMethodA(cl
, obj
, msg
);
698 /*** Setup ******************************************************************/
701 Language
, NULL
, MUIC_Group
, NULL
,
702 OM_NEW
, struct opSet
*,
703 OM_SET
, struct opSet
*,
704 OM_GET
, struct opGet
*,