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