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