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
29U_NAMESPACE_USE
30
31
32BLanguage::BLanguage()
33	:
34	fDirection(B_LEFT_TO_RIGHT),
35	fICULocale(NULL)
36{
37	SetTo(NULL);
38}
39
40
41BLanguage::BLanguage(const char* language)
42	:
43	fDirection(B_LEFT_TO_RIGHT),
44	fICULocale(NULL)
45{
46	SetTo(language);
47}
48
49
50BLanguage::BLanguage(const BLanguage& other)
51	:
52	fICULocale(NULL)
53{
54	*this = other;
55}
56
57
58BLanguage::~BLanguage()
59{
60	delete fICULocale;
61}
62
63
64status_t
65BLanguage::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
79status_t
80BLanguage::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
94status_t
95BLanguage::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
123status_t
124BLanguage::GetIcon(BBitmap* result) const
125{
126	return BLocaleRoster::Default()->GetFlagIconForCountry(result, Code());
127}
128
129
130const char*
131BLanguage::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
145const char*
146BLanguage::Code() const
147{
148	return fICULocale->getLanguage();
149}
150
151
152const char*
153BLanguage::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
163const char*
164BLanguage::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
174const char*
175BLanguage::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
185const char*
186BLanguage::ID() const
187{
188	return fICULocale->getName();
189}
190
191
192bool
193BLanguage::IsCountrySpecific() const
194{
195	return CountryCode() != NULL;
196}
197
198
199bool
200BLanguage::IsVariant() const
201{
202	return Variant() != NULL;
203}
204
205
206uint8
207BLanguage::Direction() const
208{
209	return fDirection;
210}
211
212
213BLanguage&
214BLanguage::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