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