xref: /haiku/src/kits/locale/Language.cpp (revision a127b88ecbfab58f64944c98aa47722a18e363b2)
1 /*
2  * Copyright 2003-2011, Axel Dörfler, axeld@pinc-software.de.
3  * Distributed under the terms of the MIT License.
4  */
5 
6 
7 #include <unicode/uversion.h>
8 #include <Language.h>
9 
10 #include <stdlib.h>
11 #include <stdio.h>
12 #include <string.h>
13 #include <ctype.h>
14 
15 #include <iostream>
16 
17 #include <Catalog.h>
18 #include <Locale.h>
19 #include <LocaleRoster.h>
20 #include <Path.h>
21 #include <String.h>
22 #include <FindDirectory.h>
23 
24 #include <ICUWrapper.h>
25 
26 #include <unicode/locid.h>
27 
28 
29 U_NAMESPACE_USE
30 
31 
32 BLanguage::BLanguage()
33 	:
34 	fDirection(B_LEFT_TO_RIGHT),
35 	fICULocale(NULL)
36 {
37 	SetTo(NULL);
38 }
39 
40 
41 BLanguage::BLanguage(const char* language)
42 	:
43 	fDirection(B_LEFT_TO_RIGHT),
44 	fICULocale(NULL)
45 {
46 	SetTo(language);
47 }
48 
49 
50 BLanguage::BLanguage(const BLanguage& other)
51 	:
52 	fICULocale(NULL)
53 {
54 	*this = other;
55 }
56 
57 
58 BLanguage::~BLanguage()
59 {
60 	delete fICULocale;
61 }
62 
63 
64 status_t
65 BLanguage::SetTo(const char* language)
66 {
67 	delete fICULocale;
68 	fICULocale = new icu::Locale(language);
69 	if (fICULocale == NULL)
70 		return B_NO_MEMORY;
71 
72 	if (fICULocale->isBogus())
73 		return B_BAD_VALUE;
74 
75 	return B_OK;
76 }
77 
78 
79 status_t
80 BLanguage::GetNativeName(BString& name) const
81 {
82 	UnicodeString string;
83 	fICULocale->getDisplayName(*fICULocale, string);
84 	string.toTitle(NULL, *fICULocale);
85 
86 	name.Truncate(0);
87 	BStringByteSink converter(&name);
88 	string.toUTF8(converter);
89 
90 	return B_OK;
91 }
92 
93 
94 status_t
95 BLanguage::GetName(BString& name, const BLanguage* displayLanguage) const
96 {
97 	status_t status = B_OK;
98 
99 	BString appLanguage;
100 	if (displayLanguage == NULL) {
101 		BMessage preferredLanguage;
102 		status = BLocaleRoster::Default()->GetPreferredLanguages(
103 			&preferredLanguage);
104 		if (status == B_OK)
105 			status = preferredLanguage.FindString("language", 0, &appLanguage);
106 	} else {
107 		appLanguage = displayLanguage->Code();
108 	}
109 
110 	if (status == B_OK) {
111 		UnicodeString string;
112 		fICULocale->getDisplayName(Locale(appLanguage), string);
113 
114 		name.Truncate(0);
115 		BStringByteSink converter(&name);
116 		string.toUTF8(converter);
117 	}
118 
119 	return status;
120 }
121 
122 
123 status_t
124 BLanguage::GetIcon(BBitmap* result) const
125 {
126 	return BLocaleRoster::Default()->GetFlagIconForCountry(result, Code());
127 }
128 
129 
130 const char*
131 BLanguage::GetString(uint32 id) const
132 {
133 	if (id < B_LANGUAGE_STRINGS_BASE
134 		|| id >= B_LANGUAGE_STRINGS_BASE + B_NUM_LANGUAGE_STRINGS)
135 		return NULL;
136 
137 	return NULL;
138 
139 	// TODO: fetch string from ICU
140 
141 //	return fStrings[id - B_LANGUAGE_STRINGS_BASE];
142 }
143 
144 
145 const char*
146 BLanguage::Code() const
147 {
148 	return fICULocale->getLanguage();
149 }
150 
151 
152 const char*
153 BLanguage::CountryCode() const
154 {
155 	const char* country = fICULocale->getCountry();
156 	if (country == NULL || country[0] == '\0')
157 		return NULL;
158 
159 	return country;
160 }
161 
162 
163 const char*
164 BLanguage::ScriptCode() const
165 {
166 	const char* script = fICULocale->getScript();
167 	if (script == NULL || script[0] == '\0')
168 		return NULL;
169 
170 	return script;
171 }
172 
173 
174 const char*
175 BLanguage::Variant() const
176 {
177 	const char* variant = fICULocale->getVariant();
178 	if (variant == NULL || variant[0] == '\0')
179 		return NULL;
180 
181 	return variant;
182 }
183 
184 
185 const char*
186 BLanguage::ID() const
187 {
188 	return fICULocale->getName();
189 }
190 
191 
192 bool
193 BLanguage::IsCountrySpecific() const
194 {
195 	return CountryCode() != NULL;
196 }
197 
198 
199 bool
200 BLanguage::IsVariant() const
201 {
202 	return Variant() != NULL;
203 }
204 
205 
206 uint8
207 BLanguage::Direction() const
208 {
209 	return fDirection;
210 }
211 
212 
213 BLanguage&
214 BLanguage::operator=(const BLanguage& source)
215 {
216 	if (&source != this) {
217 		delete fICULocale;
218 
219 		fICULocale = source.fICULocale != NULL
220 			? source.fICULocale->clone()
221 			: NULL;
222 		fDirection = source.fDirection;
223 	}
224 
225 	return *this;
226 }
227