xref: /haiku/src/kits/locale/Country.cpp (revision ed24eb5ff12640d052171c6a7feba37fab8a75d1)
1 /*
2  * Copyright 2003-2011, Axel Dörfler, axeld@pinc-software.de.
3  * Copyright 2009-2019, Adrien Destugues, pulkomandy@gmail.com.
4  * Distributed under the terms of the MIT License.
5  */
6 
7 
8 #include <unicode/uversion.h>
9 #include <Country.h>
10 
11 #include <AutoDeleter.h>
12 #include <IconUtils.h>
13 #include <List.h>
14 #include <Language.h>
15 #include <LocaleRoster.h>
16 #include <Resources.h>
17 #include <String.h>
18 
19 #include <unicode/locid.h>
20 #include <unicode/ulocdata.h>
21 #include <ICUWrapper.h>
22 
23 #include <iostream>
24 #include <map>
25 #include <monetary.h>
26 #include <new>
27 #include <stdarg.h>
28 #include <stdlib.h>
29 
30 
31 U_NAMESPACE_USE
32 
33 
34 BCountry::BCountry(const char* countryCode)
35 	:
36 	fICULocale(NULL)
37 {
38 	SetTo(countryCode);
39 }
40 
41 
42 BCountry::BCountry(const BCountry& other)
43 	:
44 	fICULocale(new icu::Locale(*other.fICULocale))
45 {
46 }
47 
48 
49 BCountry&
50 BCountry::operator=(const BCountry& other)
51 {
52 	if (this == &other)
53 		return *this;
54 
55 	if (!fICULocale)
56 		fICULocale = new icu::Locale(*other.fICULocale);
57 	else
58 		*fICULocale = *other.fICULocale;
59 
60 	return *this;
61 }
62 
63 
64 BCountry::~BCountry()
65 {
66 	delete fICULocale;
67 }
68 
69 
70 status_t
71 BCountry::SetTo(const char* countryCode)
72 {
73 	delete fICULocale;
74 	fICULocale = new icu::Locale("", countryCode);
75 
76 	return InitCheck();
77 }
78 
79 
80 status_t
81 BCountry::InitCheck() const
82 {
83 	if (fICULocale == NULL)
84 		return B_NO_MEMORY;
85 
86 	if (fICULocale->isBogus())
87 		return B_BAD_DATA;
88 
89 	return B_OK;
90 }
91 
92 
93 status_t
94 BCountry::GetNativeName(BString& name) const
95 {
96 	status_t valid = InitCheck();
97 	if (valid != B_OK)
98 		return valid;
99 
100 	UnicodeString string;
101 	fICULocale->getDisplayCountry(*fICULocale, string);
102 	string.toTitle(NULL, *fICULocale);
103 
104 	name.Truncate(0);
105 	BStringByteSink converter(&name);
106 	string.toUTF8(converter);
107 
108 	return B_OK;
109 }
110 
111 
112 status_t
113 BCountry::GetName(BString& name, const BLanguage* displayLanguage) const
114 {
115 	status_t status = InitCheck();
116 	if (status != B_OK)
117 		return status;
118 
119 	BString appLanguage;
120 	if (displayLanguage == NULL) {
121 		BMessage preferredLanguages;
122 		status = BLocaleRoster::Default()->GetPreferredLanguages(
123 			&preferredLanguages);
124 		if (status == B_OK)
125 			status = preferredLanguages.FindString("language", 0, &appLanguage);
126 	} else {
127 		appLanguage = displayLanguage->Code();
128 	}
129 
130 	if (status == B_OK) {
131 		UnicodeString uString;
132 		fICULocale->getDisplayCountry(Locale(appLanguage), uString);
133 		name.Truncate(0);
134 		BStringByteSink stringConverter(&name);
135 		uString.toUTF8(stringConverter);
136 	}
137 
138 	return status;
139 }
140 
141 
142 status_t
143 BCountry::GetPreferredLanguage(BLanguage& language) const
144 {
145 #if U_ICU_VERSION_MAJOR_NUM < 63
146 	return ENOSYS;
147 #else
148 	status_t status = InitCheck();
149 	if (status != B_OK)
150 		return status;
151 
152 	icu::Locale* languageLocale = fICULocale->clone();
153 	if (languageLocale == NULL)
154 		return B_NO_MEMORY;
155 
156 	UErrorCode icuError = U_ZERO_ERROR;
157 	languageLocale->addLikelySubtags(icuError);
158 
159 	if (U_FAILURE(icuError))
160 		return B_ERROR;
161 
162 	status = language.SetTo(languageLocale->getLanguage());
163 
164 	delete languageLocale;
165 
166 	return status;
167 #endif
168 }
169 
170 
171 const char*
172 BCountry::Code() const
173 {
174 	status_t status = InitCheck();
175 	if (status != B_OK)
176 		return NULL;
177 
178 	return fICULocale->getCountry();
179 }
180 
181 
182 status_t
183 BCountry::GetIcon(BBitmap* result) const
184 {
185 	status_t status = InitCheck();
186 	if (status != B_OK)
187 		return status;
188 
189 	return BLocaleRoster::Default()->GetFlagIconForCountry(result, Code());
190 }
191 
192 
193 status_t
194 BCountry::GetAvailableTimeZones(BMessage* timeZones) const
195 {
196 	status_t status = InitCheck();
197 	if (status != B_OK)
198 		return status;
199 
200 	return BLocaleRoster::Default()->GetAvailableTimeZonesForCountry(timeZones,
201 		Code());
202 }
203 
204