1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_i18npool.hxx"
30 
31 #include <numberformatcode.hxx>
32 #include <com/sun/star/i18n/KNumberFormatUsage.hpp>
33 #include <com/sun/star/i18n/KNumberFormatType.hpp>
34 
35 
36 
37 NumberFormatCodeMapper::NumberFormatCodeMapper(
38 			const ::com::sun::star::uno::Reference <
39 				::com::sun::star::lang::XMultiServiceFactory >& rxMSF )
40 		:
41 		xMSF( rxMSF ),
42 		bFormatsValid( sal_False )
43 {
44 }
45 
46 
47 NumberFormatCodeMapper::~NumberFormatCodeMapper()
48 {
49 }
50 
51 
52 ::com::sun::star::i18n::NumberFormatCode SAL_CALL
53 NumberFormatCodeMapper::getDefault( sal_Int16 formatType, sal_Int16 formatUsage, const ::com::sun::star::lang::Locale& rLocale ) throw(::com::sun::star::uno::RuntimeException)
54 {
55 
56 	::rtl::OUString elementType	= mapElementTypeShortToString(formatType);
57 	::rtl::OUString elementUsage = mapElementUsageShortToString(formatUsage);
58 
59 	getFormats( rLocale );
60 
61 	for(sal_Int32 i = 0; i < aFormatSeq.getLength(); i++) {
62 		if(aFormatSeq[i].isDefault && aFormatSeq[i].formatType == elementType &&
63 			aFormatSeq[i].formatUsage == elementUsage) {
64 			com::sun::star::i18n::NumberFormatCode anumberFormatCode(formatType,
65 																	formatUsage,
66 																	aFormatSeq[i].formatCode,
67 																	aFormatSeq[i].formatName,
68 																	aFormatSeq[i].formatKey,
69 																	aFormatSeq[i].formatIndex,
70 																	sal_True);
71 			return anumberFormatCode;
72 		}
73 	}
74 	com::sun::star::i18n::NumberFormatCode defaultNumberFormatCode;
75 	return defaultNumberFormatCode;
76 }
77 
78 
79 
80 ::com::sun::star::i18n::NumberFormatCode SAL_CALL
81 NumberFormatCodeMapper::getFormatCode( sal_Int16 formatIndex, const ::com::sun::star::lang::Locale& rLocale ) throw(::com::sun::star::uno::RuntimeException)
82 {
83 	getFormats( rLocale );
84 
85 	for(sal_Int32 i = 0; i < aFormatSeq.getLength(); i++) {
86 		if(aFormatSeq[i].formatIndex == formatIndex) {
87 			com::sun::star::i18n::NumberFormatCode anumberFormatCode(mapElementTypeStringToShort(aFormatSeq[i].formatType),
88 																	mapElementUsageStringToShort(aFormatSeq[i].formatUsage),
89 																	aFormatSeq[i].formatCode,
90 																	aFormatSeq[i].formatName,
91 																	aFormatSeq[i].formatKey,
92 																	aFormatSeq[i].formatIndex,
93 																	aFormatSeq[i].isDefault);
94 			return anumberFormatCode;
95 		}
96 	}
97 	com::sun::star::i18n::NumberFormatCode defaultNumberFormatCode;
98 	return defaultNumberFormatCode;
99 
100 }
101 
102 
103 
104 ::com::sun::star::uno::Sequence< ::com::sun::star::i18n::NumberFormatCode > SAL_CALL
105 NumberFormatCodeMapper::getAllFormatCode( sal_Int16 formatUsage, const ::com::sun::star::lang::Locale& rLocale ) throw(::com::sun::star::uno::RuntimeException)
106 {
107 	getFormats( rLocale );
108 
109 	sal_Int32 i, count;
110 	count = 0;
111 	for(i = 0; i < aFormatSeq.getLength(); i++) {
112 		sal_Int16 elementUsage = mapElementUsageStringToShort(aFormatSeq[i].formatUsage);
113 		if( elementUsage == formatUsage)
114 			count++;
115 	}
116 
117 	::com::sun::star::uno::Sequence<com::sun::star::i18n::NumberFormatCode> seq(count);
118 	sal_Int32 j = 0;
119 	for(i = 0; i < aFormatSeq.getLength(); i++) {
120 		sal_Int16 elementUsage = mapElementUsageStringToShort(aFormatSeq[i].formatUsage);
121 		if( elementUsage == formatUsage) {
122 			seq[j] = com::sun::star::i18n::NumberFormatCode(mapElementTypeStringToShort(aFormatSeq[i].formatType),
123 															formatUsage,
124 															aFormatSeq[i].formatCode,
125 															aFormatSeq[i].formatName,
126 															aFormatSeq[i].formatKey,
127 															aFormatSeq[i].formatIndex,
128 															aFormatSeq[i].isDefault);
129 			j++;
130 		}
131 	}
132 	return seq;
133 
134 }
135 
136 
137 ::com::sun::star::uno::Sequence< ::com::sun::star::i18n::NumberFormatCode > SAL_CALL
138 NumberFormatCodeMapper::getAllFormatCodes( const ::com::sun::star::lang::Locale& rLocale ) throw(::com::sun::star::uno::RuntimeException)
139 {
140 	getFormats( rLocale );
141 
142 	::com::sun::star::uno::Sequence<com::sun::star::i18n::NumberFormatCode> seq(aFormatSeq.getLength());
143 	for(sal_Int32 i = 0; i < aFormatSeq.getLength(); i++)
144 	{
145 		seq[i] = com::sun::star::i18n::NumberFormatCode(mapElementTypeStringToShort(aFormatSeq[i].formatType),
146 														mapElementUsageStringToShort(aFormatSeq[i].formatUsage),
147 														aFormatSeq[i].formatCode,
148 														aFormatSeq[i].formatName,
149 														aFormatSeq[i].formatKey,
150 														aFormatSeq[i].formatIndex,
151 														aFormatSeq[i].isDefault);
152 	}
153 	return seq;
154 }
155 
156 
157 // --- private implementation -----------------------------------------
158 
159 void NumberFormatCodeMapper::setupLocale( const ::com::sun::star::lang::Locale& rLocale )
160 {
161 	if ( aLocale.Country	!= rLocale.Country
162 	  || aLocale.Language	!= rLocale.Language
163 	  || aLocale.Variant	!= rLocale.Variant )
164 	{
165 		bFormatsValid = sal_False;
166 		aLocale = rLocale;
167 	}
168 }
169 
170 
171 void NumberFormatCodeMapper::getFormats( const ::com::sun::star::lang::Locale& rLocale )
172 {
173 	setupLocale( rLocale );
174 	if ( !bFormatsValid )
175 	{
176 		createLocaleDataObject();
177 		if( !xlocaleData.is() )
178 			aFormatSeq = ::com::sun::star::uno::Sequence< ::com::sun::star::i18n::FormatElement > (0);
179 		else
180 			aFormatSeq = xlocaleData->getAllFormats( aLocale );
181 		bFormatsValid = sal_True;
182 	}
183 }
184 
185 
186 ::rtl::OUString
187 NumberFormatCodeMapper::mapElementTypeShortToString(sal_Int16 formatType)
188 {
189 
190 	switch ( formatType )
191 	{
192 		case com::sun::star::i18n::KNumberFormatType::SHORT :
193 			return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "short" ) );
194 		case com::sun::star::i18n::KNumberFormatType::MEDIUM :
195 			return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "medium" ) );
196 		case com::sun::star::i18n::KNumberFormatType::LONG :
197 			return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "long" ) );
198 	}
199 	return ::rtl::OUString();
200 }
201 
202 sal_Int16
203 NumberFormatCodeMapper::mapElementTypeStringToShort(const ::rtl::OUString& formatType)
204 {
205 	if(formatType.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "short" ) ))
206 		return com::sun::star::i18n::KNumberFormatType::SHORT;
207 	if(formatType.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "medium" ) ))
208 		return com::sun::star::i18n::KNumberFormatType::MEDIUM;
209 	if(formatType.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "long" ) ))
210 		return com::sun::star::i18n::KNumberFormatType::LONG;
211 
212 	return com::sun::star::i18n::KNumberFormatType::SHORT;
213 }
214 
215 ::rtl::OUString
216 NumberFormatCodeMapper::mapElementUsageShortToString(sal_Int16 formatUsage)
217 {
218 	switch ( formatUsage )
219 	{
220 		case com::sun::star::i18n::KNumberFormatUsage::DATE :
221 			return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DATE" ) );
222 		case com::sun::star::i18n::KNumberFormatUsage::TIME :
223 			return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "TIME" ) );
224 		case com::sun::star::i18n::KNumberFormatUsage::DATE_TIME :
225 			return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DATE_TIME" ) );
226 		case com::sun::star::i18n::KNumberFormatUsage::FIXED_NUMBER :
227 			return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "FIXED_NUMBER" ) );
228 		case com::sun::star::i18n::KNumberFormatUsage::FRACTION_NUMBER :
229 			return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "FRACTION_NUMBER" ) );
230 		case com::sun::star::i18n::KNumberFormatUsage::PERCENT_NUMBER :
231 			return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PERCENT_NUMBER" ) );
232 		case com::sun::star::i18n::KNumberFormatUsage::CURRENCY :
233 			return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "CURRENCY" ) );
234 		case com::sun::star::i18n::KNumberFormatUsage::SCIENTIFIC_NUMBER :
235 			return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "SCIENTIFIC_NUMBER" ) );
236 	}
237 	return ::rtl::OUString();
238 }
239 
240 
241 sal_Int16
242 NumberFormatCodeMapper::mapElementUsageStringToShort(const ::rtl::OUString& formatUsage)
243 {
244 	if(formatUsage.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "DATE" ) ))
245 		return com::sun::star::i18n::KNumberFormatUsage::DATE;
246 	if(formatUsage.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "TIME" ) ))
247 		return com::sun::star::i18n::KNumberFormatUsage::TIME;
248 	if(formatUsage.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "DATE_TIME" ) ))
249 		return com::sun::star::i18n::KNumberFormatUsage::DATE_TIME;
250 	if(formatUsage.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "FIXED_NUMBER" ) ))
251 		return com::sun::star::i18n::KNumberFormatUsage::FIXED_NUMBER;
252 	if(formatUsage.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "FRACTION_NUMBER" ) ))
253 		return com::sun::star::i18n::KNumberFormatUsage::FRACTION_NUMBER;
254 	if(formatUsage.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "PERCENT_NUMBER" ) ))
255 		return  com::sun::star::i18n::KNumberFormatUsage::PERCENT_NUMBER;
256 	if(formatUsage.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "CURRENCY" ) ))
257 		return com::sun::star::i18n::KNumberFormatUsage::CURRENCY;
258 	if(formatUsage.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "SCIENTIFIC_NUMBER" ) ))
259 		return com::sun::star::i18n::KNumberFormatUsage::SCIENTIFIC_NUMBER;
260 
261 	return 0;
262 }
263 
264 
265 void
266 NumberFormatCodeMapper::createLocaleDataObject() {
267 
268 	if(xlocaleData.is())
269 		return;
270 
271 	::com::sun::star::uno::Reference < ::com::sun::star::uno::XInterface >
272 		xI = xMSF->createInstance(
273 		::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.i18n.LocaleData" ) ));
274 
275 	if ( xI.is() ) {
276 		::com::sun::star::uno::Any x = xI->queryInterface( ::getCppuType((const ::com::sun::star::uno::Reference< ::com::sun::star::i18n::XLocaleData >*)0) );
277 			x >>= xlocaleData;
278 	}
279 }
280 
281 ::rtl::OUString SAL_CALL
282 NumberFormatCodeMapper::getImplementationName(void)
283                 throw( ::com::sun::star::uno::RuntimeException )
284 {
285     return ::rtl::OUString::createFromAscii("com.sun.star.i18n.NumberFormatCodeMapper");
286 }
287 
288 const sal_Char cNumFormat[] = "com.sun.star.i18n.NumberFormatMapper";
289 
290 sal_Bool SAL_CALL
291 NumberFormatCodeMapper::supportsService(const rtl::OUString& rServiceName)
292                 throw( ::com::sun::star::uno::RuntimeException )
293 {
294     return !rServiceName.compareToAscii(cNumFormat);
295 }
296 
297 ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL
298 NumberFormatCodeMapper::getSupportedServiceNames(void) throw( ::com::sun::star::uno::RuntimeException )
299 {
300     ::com::sun::star::uno::Sequence< ::rtl::OUString > aRet(1);
301     aRet[0] = ::rtl::OUString::createFromAscii(cNumFormat);
302     return aRet;
303 }
304 
305