Merge "[N_SE-33432] non-sqaure matrix is not set correctly" into tizen_2.1
[platform/framework/native/appfw.git] / src / locales / FLcl_NumberFormatterImpl.cpp
1 //
2 // Open Service Platform
3 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
4 //
5 // Licensed under the Apache License, Version 2.0 (the License);
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
8 //
9 // http://www.apache.org/licenses/LICENSE-2.0
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 //
17
18 /**
19  * @file        FLclNumberFormatterEx.cpp
20  * @brief       This is the implementation file for the NumberFormatterEx class.
21  */
22 #include <unique_ptr.h>
23 #include <unicode/decimfmt.h>
24 #include <locale.h>
25
26 #include <FBaseSysLog.h>
27 #include <FLclNumberFormatter.h>
28
29 #include "FLcl_LocaleData.h"
30 #include "FLcl_LocaleImpl.h"
31 #include "FLcl_LocaleManagerImpl.h"
32 #include "FLcl_NumberFormatterImpl.h"
33
34
35 using namespace Tizen::Base;
36
37 namespace Tizen { namespace Locales
38 {
39
40 _NumberFormatterImpl::_NumberFormatterImpl(void)
41         : __pIcuNumberFormatter(null)
42 {
43 }
44
45 _NumberFormatterImpl::~_NumberFormatterImpl(void)
46 {
47         delete __pIcuNumberFormatter;
48 }
49
50 NumberFormatter*
51 _NumberFormatterImpl::CreateNumberFormatterN(NumberFormatterStyle style)
52 {
53         return CreateNumberFormatterN(_LocaleManagerImpl::GetSystemLocale(), style);
54 }
55
56 NumberFormatter*
57 _NumberFormatterImpl::CreateNumberFormatterN(const Locale& locale, NumberFormatterStyle style)
58 {
59         IcuLocale icuLocale = _LocaleImpl::GetLocaleImpl(locale)->GetIcuLocale();
60         SysTryReturn(NID_LCL, !icuLocale.isBogus(), null, E_UNSUPPORTED_OPERATION,
61                                                 "[%s] Given locale is not supported", GetErrorMessage(E_UNSUPPORTED_OPERATION));
62
63         std::unique_ptr<NumberFormatter> pNewFormatter(new (std::nothrow) NumberFormatter);
64         SysTryReturn(NID_LCL, pNewFormatter, null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed", GetErrorMessage(E_OUT_OF_MEMORY));
65
66         std::unique_ptr<_NumberFormatterImpl> pNumberFormatterImpl(new (std::nothrow) _NumberFormatterImpl);
67         SysTryReturn(NID_LCL, pNumberFormatterImpl, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed");
68
69         UNumberFormatStyle icuStyle = UNUM_FORMAT_STYLE_COUNT;
70         switch(style)
71         {
72         case NUM_FORMATTER_STYLE_NUMBER:
73                 icuStyle = UNUM_DECIMAL;
74                 break;
75         case NUM_FORMATTER_STYLE_CURRENCY:
76                 icuStyle = UNUM_CURRENCY;
77                 break;
78         case NUM_FORMATTER_STYLE_PERCENT:
79                 icuStyle = UNUM_PERCENT;
80                 break;
81         case NUM_FORMATTER_STYLE_INVALID:
82                 break;
83         }
84
85         UErrorCode ec = U_ZERO_ERROR;
86         std::unique_ptr<IcuNumberFormat> pIcuNumberFormatter(IcuNumberFormat::createInstance(icuLocale, icuStyle, ec));
87         if (pIcuNumberFormatter)
88         {
89                 IcuDecimalFormat* pDecimalFmt = dynamic_cast<IcuDecimalFormat*>(pIcuNumberFormatter.get());
90                 if (pDecimalFmt)
91                 {
92                         pIcuNumberFormatter.release();
93                         pNumberFormatterImpl->__pIcuNumberFormatter = pDecimalFmt;
94                         pNumberFormatterImpl->__currency.Construct(locale);
95                         pNewFormatter->__pNumberFormatterImpl = pNumberFormatterImpl.release();
96
97                         SetLastResult(E_SUCCESS);
98                         return pNewFormatter.release();
99                 }
100         }
101
102         SetLastResult(E_INVALID_ARG);
103         return null;
104 }
105
106 result
107 _NumberFormatterImpl::ApplyPattern(const String& pattern, bool localized)
108 {
109         UErrorCode ec = U_ZERO_ERROR;
110         if (localized)
111         {
112                 __pIcuNumberFormatter->applyLocalizedPattern(_LocaleData::GetIcuString(pattern), ec);
113         }
114         else
115         {
116                 __pIcuNumberFormatter->applyPattern(_LocaleData::GetIcuString(pattern), ec);
117         }
118
119         return U_SUCCESS(ec) ? E_SUCCESS : E_INVALID_ARG;
120 }
121
122 result
123 _NumberFormatterImpl::Format(long number, String& str, _FieldPosition pos) const
124 {
125         IcuUnicodeString icuStr;
126         IcuFieldPosition icuPos = _LocaleData::GetIcuFieldPosition(pos);
127         icuStr = __pIcuNumberFormatter->format((int64_t)number, icuStr, icuPos);
128         str = _LocaleData::GetOspString(icuStr);
129         return E_SUCCESS;
130 }
131
132 result
133 _NumberFormatterImpl::Format(double number, String& str, _FieldPosition pos) const
134 {
135         /*TODO: ICU 4.8 did not replace "," by a locale. So, it returns NaN even if a number is not NaN.
136         We are setting and restoring a system locale to "C".
137         It should be removed if ICU version is up.*/
138         setlocale(LC_ALL, "C");
139         IcuUnicodeString icuStr;
140         IcuFieldPosition icuPos = _LocaleData::GetIcuFieldPosition(pos);
141         icuStr = __pIcuNumberFormatter->format(number, icuStr, icuPos);
142         setlocale(LC_ALL, "");
143         str = _LocaleData::GetOspString(icuStr);
144         return E_SUCCESS;
145 }
146
147 const Currency*
148 _NumberFormatterImpl::GetCurrency(void)
149 {
150         return &__currency;
151 }
152
153 void
154 _NumberFormatterImpl::SetCurrency(const Currency& newValue)
155 {
156         __currency.Construct(newValue.GetCurrencyCode());
157         __pIcuNumberFormatter->setCurrency(_LocaleData::GetIcuString(newValue.GetCurrencyCode()).getBuffer());
158 }
159
160 int
161 _NumberFormatterImpl::GetMaxIntegerDigits(void) const
162 {
163         return __pIcuNumberFormatter->getMaximumIntegerDigits();
164 }
165
166 void
167 _NumberFormatterImpl::SetMaxIntegerDigits(int newValue)
168 {
169         __pIcuNumberFormatter->setMaximumIntegerDigits(newValue);
170 }
171
172 int
173 _NumberFormatterImpl::GetMinIntegerDigits(void) const
174 {
175         return __pIcuNumberFormatter->getMinimumIntegerDigits();
176 }
177
178 void
179 _NumberFormatterImpl::SetMinIntegerDigits(int newValue)
180 {
181         __pIcuNumberFormatter->setMinimumIntegerDigits(newValue);
182 }
183
184 int
185 _NumberFormatterImpl::GetMaxFractionDigits(void) const
186 {
187         return __pIcuNumberFormatter->getMaximumFractionDigits();
188 }
189
190 void
191 _NumberFormatterImpl::SetMaxFractionDigits(int newValue)
192 {
193         __pIcuNumberFormatter->setMaximumFractionDigits(newValue);
194 }
195
196 int
197 _NumberFormatterImpl::GetMinFractionDigits(void) const
198 {
199         return __pIcuNumberFormatter->getMinimumFractionDigits();
200 }
201
202 void
203 _NumberFormatterImpl::SetMinFractionDigits(int newValue)
204 {
205         __pIcuNumberFormatter->setMinimumFractionDigits(newValue);
206 }
207
208 bool
209 _NumberFormatterImpl::IsGroupingUsed(void) const
210 {
211         return __pIcuNumberFormatter->isGroupingUsed();
212 }
213
214 void
215 _NumberFormatterImpl::SetGroupingUsed(bool newValue)
216 {
217         __pIcuNumberFormatter->setGroupingUsed(newValue);
218 }
219
220 String
221 _NumberFormatterImpl::GetPositivePrefix(void) const
222 {
223         IcuUnicodeString icuStr;
224         return _LocaleData::GetOspString(__pIcuNumberFormatter->getPositivePrefix(icuStr));
225 }
226
227 void
228 _NumberFormatterImpl::SetPositivePrefix(const String& newValue)
229 {
230         __pIcuNumberFormatter->setPositivePrefix(_LocaleData::GetIcuString(newValue));
231 }
232
233 String
234 _NumberFormatterImpl::GetNegativePrefix(void) const
235 {
236         IcuUnicodeString icuStr;
237         return _LocaleData::GetOspString(__pIcuNumberFormatter->getNegativePrefix(icuStr));
238 }
239
240 void
241 _NumberFormatterImpl::SetNegativePrefix(const String& newValue)
242 {
243         __pIcuNumberFormatter->setNegativePrefix(_LocaleData::GetIcuString(newValue));
244 }
245
246 String
247 _NumberFormatterImpl::GetPositiveSuffix(void) const
248 {
249         IcuUnicodeString icuStr;
250         return _LocaleData::GetOspString(__pIcuNumberFormatter->getPositiveSuffix(icuStr));
251 }
252
253 void
254 _NumberFormatterImpl::SetPositiveSuffix(const String& newValue)
255 {
256         __pIcuNumberFormatter->setPositiveSuffix(_LocaleData::GetIcuString(newValue));
257 }
258
259 String
260 _NumberFormatterImpl::GetNegativeSuffix(void) const
261 {
262         IcuUnicodeString icuStr;
263         return _LocaleData::GetOspString(__pIcuNumberFormatter->getNegativeSuffix(icuStr));
264 }
265
266 void
267 _NumberFormatterImpl::SetNegativeSuffix(const String& newValue)
268 {
269         __pIcuNumberFormatter->setNegativeSuffix(_LocaleData::GetIcuString(newValue));
270 }
271
272 int
273 _NumberFormatterImpl::GetMultiplier(void) const
274 {
275         return __pIcuNumberFormatter->getMultiplier();
276 }
277
278 result
279 _NumberFormatterImpl::SetMultiplier(int newValue)
280 {
281         __pIcuNumberFormatter->setMultiplier(newValue);
282         return E_SUCCESS;
283 }
284
285 int
286 _NumberFormatterImpl::GetGroupingSize(void) const
287 {
288         return __pIcuNumberFormatter->getGroupingSize();
289 }
290
291 result
292 _NumberFormatterImpl::SetGroupingSize(int newValue)
293 {
294         __pIcuNumberFormatter->setGroupingSize(newValue);
295         return E_SUCCESS;
296 }
297
298 bool
299 _NumberFormatterImpl::IsDecimalSeparatorAlwaysShown(void) const
300 {
301         return __pIcuNumberFormatter->isDecimalSeparatorAlwaysShown();
302 }
303
304 void
305 _NumberFormatterImpl::SetDecimalSeparatorAlwaysShown(bool newValue)
306 {
307         __pIcuNumberFormatter->setDecimalSeparatorAlwaysShown(newValue);
308 }
309
310 bool
311 _NumberFormatterImpl::IsPositiveSignAlwaysShown(void) const
312 {
313         IcuUnicodeString ps("+");
314         IcuUnicodeString pp;
315         pp = __pIcuNumberFormatter->getPositivePrefix(pp);
316
317         return (pp == ps);
318 }
319
320 void
321 _NumberFormatterImpl::SetPositiveSignAlwaysShown(bool newValue)
322 {
323         IcuUnicodeString ps("+");
324         IcuUnicodeString pp;
325         pp = __pIcuNumberFormatter->getPositivePrefix(pp);
326
327         if (newValue)
328         {
329                 __pIcuNumberFormatter->setPositivePrefix(ps);
330         }
331         else
332         {
333                 if (pp == ps)
334                 {
335                         __pIcuNumberFormatter->setPositivePrefix("");
336                 }
337         }
338 }
339
340 } } // Tizen::Locales