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