bump product version to 4.2.0.1
[LibreOffice.git] / include / unotools / localedatawrapper.hxx
blob3f206f4cafe663a084bda9c6ffd3da933a5fb591
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #ifndef INCLUDED_UNOTOOLS_LOCALEDATAWRAPPER_HXX
21 #define INCLUDED_UNOTOOLS_LOCALEDATAWRAPPER_HXX
23 #include <boost/noncopyable.hpp>
24 #include <boost/shared_ptr.hpp>
25 #include <com/sun/star/i18n/XLocaleData4.hpp>
26 #include <com/sun/star/i18n/LocaleItem.hpp>
27 #include <com/sun/star/i18n/reservedWords.hpp>
28 #include <rtl/ustring.hxx>
29 #include <i18nlangtag/languagetag.hxx>
30 #include <unotools/readwritemutexguard.hxx>
31 #include <unotools/unotoolsdllapi.h>
33 namespace com { namespace sun { namespace star {
34 namespace uno {
35 class XComponentContext;
37 }}}
38 class Date;
39 class Time;
40 class CalendarWrapper;
43 enum DateFormat {
44 MDY,
45 DMY,
46 YMD
50 enum MeasurementSystem {
51 MEASURE_METRIC,
52 MEASURE_US
56 class UNOTOOLS_DLLPUBLIC LocaleDataWrapper : private boost::noncopyable
58 static sal_uInt8 nLocaleDataChecking; // 0:=dontknow, 1:=yes, 2:=no
60 ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext > m_xContext;
61 ::com::sun::star::uno::Reference< ::com::sun::star::i18n::XLocaleData4 > xLD;
62 LanguageTag maLanguageTag;
63 ::boost::shared_ptr< ::com::sun::star::i18n::Calendar2 > xDefaultCalendar;
64 ::com::sun::star::i18n::LocaleDataItem aLocaleDataItem;
65 ::com::sun::star::uno::Sequence< OUString > aReservedWordSeq;
66 ::com::sun::star::uno::Sequence< OUString > aDateAcceptancePatterns;
67 ::com::sun::star::uno::Sequence< sal_Int32 > aGrouping;
68 // cached items
69 OUString aLocaleItem[::com::sun::star::i18n::LocaleItem::COUNT];
70 OUString aReservedWord[::com::sun::star::i18n::reservedWords::COUNT];
71 OUString aCurrSymbol;
72 OUString aCurrBankSymbol;
73 int nDateFormat;
74 int nLongDateFormat;
75 sal_uInt16 nCurrPositiveFormat;
76 sal_uInt16 nCurrNegativeFormat;
77 sal_uInt16 nCurrDigits;
78 sal_Bool bLocaleDataItemValid;
79 sal_Bool bReservedWordValid;
80 mutable ::utl::ReadWriteMutex aMutex;
82 // dummies, to be implemented or provided by XML locale data
83 sal_Unicode cCurrZeroChar;
85 // whenever Locale changes
86 void invalidateData();
88 void getOneLocaleItemImpl( sal_Int16 nItem );
89 const OUString& getOneLocaleItem( sal_Int16 nItem ) const;
91 void getOneReservedWordImpl( sal_Int16 nWord );
92 const OUString& getOneReservedWord( sal_Int16 nWord ) const;
94 void getCurrSymbolsImpl();
95 void getCurrFormatsImpl();
97 void scanCurrFormatImpl( const OUString& rCode,
98 sal_Int32 nStart, sal_Int32& nSign,
99 sal_Int32& nPar, sal_Int32& nNum,
100 sal_Int32& nBlank, sal_Int32& nSym );
102 void getDateFormatsImpl();
103 DateFormat scanDateFormatImpl( const OUString& rCode );
105 void getDefaultCalendarImpl();
107 sal_Unicode* ImplAddFormatNum( sal_Unicode* pBuf,
108 sal_Int64 nNumber, sal_uInt16 nDecimals,
109 sal_Bool bUseThousandSep, sal_Bool bTrailingZeros ) const;
111 void getDigitGroupingImpl();
113 public:
114 LocaleDataWrapper(
115 const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext > & rxContext,
116 const LanguageTag& rLanguageTag
118 LocaleDataWrapper(
119 const LanguageTag& rLanguageTag
121 ~LocaleDataWrapper();
123 /** Get the service factory, meant to be able to create a CalendarWrapper
124 from a LocaleDataWrapper. Note that the service factory may be
125 non-existent if this LocaleDataWrapper was created without one and
126 lives "on the grassland". The CalendarWrapper ctor can handle that
127 though. */
128 const ::com::sun::star::uno::Reference<
129 ::com::sun::star::uno::XComponentContext > & getComponentContext()
130 const { return m_xContext; }
132 /// set a new Locale to request
133 void setLanguageTag( const LanguageTag& rLanguageTag );
135 /// get current requested Locale
136 const LanguageTag& getLanguageTag() const;
138 /// get current loaded Locale, which might differ from the requested Locale
139 LanguageTag getLoadedLanguageTag() const;
142 // Wrapper implementations of service LocaleData
144 ::com::sun::star::i18n::LanguageCountryInfo getLanguageCountryInfo() const;
145 ::com::sun::star::i18n::LocaleDataItem getLocaleItem() const;
146 /// NOTE: this wraps XLocaleData3::getAllCalendars2() in fact.
147 ::com::sun::star::uno::Sequence< ::com::sun::star::i18n::Calendar2 > getAllCalendars() const;
148 /// NOTE: this wraps XLocaleData2::getAllCurrencies2() in fact.
149 ::com::sun::star::uno::Sequence< ::com::sun::star::i18n::Currency2 > getAllCurrencies() const;
150 ::com::sun::star::uno::Sequence< ::com::sun::star::i18n::FormatElement > getAllFormats() const;
151 ::com::sun::star::i18n::ForbiddenCharacters getForbiddenCharacters() const;
152 ::com::sun::star::uno::Sequence< OUString > getReservedWord() const;
153 ::com::sun::star::uno::Sequence< ::com::sun::star::lang::Locale > getAllInstalledLocaleNames() const;
154 ::com::sun::star::uno::Sequence< OUString > getDateAcceptancePatterns() const;
156 /** Override locale's date acceptance patterns.
157 An empty sequence resets the patterns to the locale's pattern sequence.
159 void setDateAcceptancePatterns( const ::com::sun::star::uno::Sequence< OUString > & rPatterns );
161 /// same as the wrapper implementation but static
162 static ::com::sun::star::uno::Sequence< ::com::sun::star::lang::Locale > getInstalledLocaleNames();
164 /** Get LanguageTypes for all installed locales which are unambiguous
165 convertible back and forth between locale ISO strings and MS-LCID
166 LanguageType. Upon the first time the function is called when
167 locale data checking is enabled, messages are shown for locales not
168 matching, excluding already known problems.
169 (e.g. used in number formatter dialog init)
171 static ::com::sun::star::uno::Sequence< sal_uInt16 > getInstalledLanguageTypes();
173 /// maps the LocaleData string to the International enum
174 MeasurementSystem mapMeasurementStringToEnum( const OUString& rMS ) const;
176 /// Convenience method to obtain the default calendar.
177 const ::boost::shared_ptr< ::com::sun::star::i18n::Calendar2 > getDefaultCalendar() const;
179 /// Convenience method to obtain the day names of the default calendar.
180 const ::com::sun::star::uno::Sequence< ::com::sun::star::i18n::CalendarItem2 > getDefaultCalendarDays() const;
182 /// Convenience method to obtain the month names of the default calendar.
183 const ::com::sun::star::uno::Sequence< ::com::sun::star::i18n::CalendarItem2 > getDefaultCalendarMonths() const;
185 /** Obtain digit grouping. The usually known grouping by thousands (#,###)
186 is actually only one of possible groupings. Another one, for example,
187 used in India is group by 3 and then by 2 indefinitely (#,##,###). The
188 integer sequence returned here specifies grouping from right to left
189 (!), with a 0 entry designating the end of rules and the previous value
190 to be repeated indefinitely. Hence the sequence {3,0} specifies the
191 usual grouping by thousands, whereas the sequence {3,2,0} specifies
192 Indian grouping. The sal_Int32* getConstArray() can be passed directly
193 to the ::rtl::math::doubleToString() methods as argument for the
194 pGroups parameter. */
195 const ::com::sun::star::uno::Sequence< sal_Int32 > getDigitGrouping() const;
197 // Functionality of class International methods, LocaleItem
199 const OUString& getDateSep() const
200 { return getOneLocaleItem( ::com::sun::star::i18n::LocaleItem::DATE_SEPARATOR ); }
201 const OUString& getNumThousandSep() const
202 { return getOneLocaleItem( ::com::sun::star::i18n::LocaleItem::THOUSAND_SEPARATOR ); }
203 const OUString& getNumDecimalSep() const
204 { return getOneLocaleItem( ::com::sun::star::i18n::LocaleItem::DECIMAL_SEPARATOR ); }
205 const OUString& getTimeSep() const
206 { return getOneLocaleItem( ::com::sun::star::i18n::LocaleItem::TIME_SEPARATOR ); }
207 const OUString& getTime100SecSep() const
208 { return getOneLocaleItem( ::com::sun::star::i18n::LocaleItem::TIME_100SEC_SEPARATOR ); }
209 const OUString& getListSep() const
210 { return getOneLocaleItem( ::com::sun::star::i18n::LocaleItem::LIST_SEPARATOR ); }
211 const OUString& getQuotationMarkStart() const
212 { return getOneLocaleItem( ::com::sun::star::i18n::LocaleItem::SINGLE_QUOTATION_START ); }
213 const OUString& getQuotationMarkEnd() const
214 { return getOneLocaleItem( ::com::sun::star::i18n::LocaleItem::SINGLE_QUOTATION_END ); }
215 const OUString& getDoubleQuotationMarkStart() const
216 { return getOneLocaleItem( ::com::sun::star::i18n::LocaleItem::DOUBLE_QUOTATION_START ); }
217 const OUString& getDoubleQuotationMarkEnd() const
218 { return getOneLocaleItem( ::com::sun::star::i18n::LocaleItem::DOUBLE_QUOTATION_END ); }
219 const OUString& getMeasurementSystem() const
220 { return getOneLocaleItem( ::com::sun::star::i18n::LocaleItem::MEASUREMENT_SYSTEM ); }
221 MeasurementSystem getMeasurementSystemEnum() const
222 { return mapMeasurementStringToEnum( getOneLocaleItem( ::com::sun::star::i18n::LocaleItem::MEASUREMENT_SYSTEM ) ); }
223 const OUString& getTimeAM() const
224 { return getOneLocaleItem( ::com::sun::star::i18n::LocaleItem::TIME_AM ); }
225 const OUString& getTimePM() const
226 { return getOneLocaleItem( ::com::sun::star::i18n::LocaleItem::TIME_PM ); }
227 const OUString& getLongDateDayOfWeekSep() const
228 { return getOneLocaleItem( ::com::sun::star::i18n::LocaleItem::LONG_DATE_DAY_OF_WEEK_SEPARATOR ); }
229 const OUString& getLongDateDaySep() const
230 { return getOneLocaleItem( ::com::sun::star::i18n::LocaleItem::LONG_DATE_DAY_SEPARATOR ); }
231 const OUString& getLongDateMonthSep() const
232 { return getOneLocaleItem( ::com::sun::star::i18n::LocaleItem::LONG_DATE_MONTH_SEPARATOR ); }
233 const OUString& getLongDateYearSep() const
234 { return getOneLocaleItem( ::com::sun::star::i18n::LocaleItem::LONG_DATE_YEAR_SEPARATOR ); }
236 // currency
237 const OUString& getCurrSymbol() const;
238 const OUString& getCurrBankSymbol() const;
239 sal_uInt16 getCurrPositiveFormat() const;
240 sal_uInt16 getCurrNegativeFormat() const;
241 sal_uInt16 getCurrDigits() const;
243 // simple date and time formatting
244 DateFormat getDateFormat() const;
245 DateFormat getLongDateFormat() const;
246 /// only numerical values of Gregorian calendar
247 OUString getDate( const Date& rDate ) const;
248 OUString getTime( const Time& rTime, sal_Bool bSec = sal_True,
249 sal_Bool b100Sec = sal_False ) const;
250 OUString getDuration( const Time& rTime,
251 sal_Bool bSec = sal_True, sal_Bool b100Sec = sal_False ) const;
253 /** The CalendarWrapper already <b>MUST</b>
254 have loaded a calendar.
255 @param nDisplayDayOfWeek
256 0 := abbreviated name
257 1 := full name
258 @param bDayOfMonthWithLeadingZero
259 <FALSE/> := without leading zero
260 <TRUE/> := with leading zero if <10
261 @param nDisplayMonth
262 0 := abbreviated name
263 1 := full name
264 @param bTwoDigitYear
265 <FALSE/> := full year
266 <TRUE/> := year % 100
268 OUString getLongDate( const Date& rDate,
269 CalendarWrapper& rCal,
270 sal_Int16 nDisplayDayOfWeek = 1,
271 sal_Bool bDayOfMonthWithLeadingZero = sal_False,
272 sal_Int16 nDisplayMonth = 1,
273 sal_Bool bTwoDigitYear = sal_False
274 ) const;
276 /** Simple number formatting
277 @param nNumber
278 value * 10**nDecimals
279 @param bTrailingZeros
280 </sal_True> := always display trailing zeros in
281 decimal places, even if integer value.
282 </sal_False> := trailing zeros are only displayed
283 if the value is not an integer value.
285 OUString getNum( sal_Int64 nNumber, sal_uInt16 nDecimals,
286 sal_Bool bUseThousandSep = sal_True,
287 sal_Bool bTrailingZeros = sal_True ) const;
289 /// "Secure" currency formatted string.
290 OUString getCurr( sal_Int64 nNumber, sal_uInt16 nDecimals,
291 const OUString& rCurrencySymbol,
292 sal_Bool bUseThousandSep = sal_True ) const;
293 /** Default currency formatted string, use with
294 care as default currency may change in any
295 locale, for example, DEM -> EUR */
296 OUString getCurr( sal_Int64 nNumber, sal_uInt16 nDecimals,
297 sal_Bool bUseThousandSep = sal_True ) const
298 { return getCurr( nNumber, nDecimals,
299 getCurrSymbol(), bUseThousandSep ); }
301 // dummy returns, to be implemented
302 inline sal_Unicode getCurrZeroChar() const
303 { return cCurrZeroChar; }
304 inline sal_Bool isNumLeadingZero() const
305 { return sal_True; }
306 /// standard decimal places
307 inline sal_uInt16 getNumDigits() const
308 { return 2; }
309 inline sal_Bool isNumTrailingZeros() const
310 { return sal_True; }
313 // reserved words
315 const OUString& getTrueWord() const
316 { return getOneReservedWord( ::com::sun::star::i18n::reservedWords::TRUE_WORD ); }
317 const OUString& getFalseWord() const
318 { return getOneReservedWord( ::com::sun::star::i18n::reservedWords::FALSE_WORD ); }
319 /// return a quarter string matching nQuarter (0..3) => "1st quarter" .. "4th quarter"
320 const OUString& getQuarterWord( sal_Int16 nQuarter ) const
321 { return getOneReservedWord( ::com::sun::star::i18n::reservedWords::QUARTER1_WORD + nQuarter ); }
322 const OUString& getAboveWord() const
323 { return getOneReservedWord( ::com::sun::star::i18n::reservedWords::ABOVE_WORD ); }
324 const OUString& getBelowWord() const
325 { return getOneReservedWord( ::com::sun::star::i18n::reservedWords::BELOW_WORD ); }
326 /// return a quarter abbreviation string matching nQuarter (0..3) => "Q1" .. "Q2"
327 const OUString& getQuarterAbbreviation( sal_Int16 nQuarter ) const
328 { return getOneReservedWord( ::com::sun::star::i18n::reservedWords::QUARTER1_ABBREVIATION + nQuarter ); }
330 /** Return whether locale data checks are enabled.
331 Checks are enabled if the environment variable
332 OOO_ENABLE_LOCALE_DATA_CHECKS is set to 'Y' or 'Yes' (or any other
333 string starting with 'Y') or '1'.
334 Also used in conjunction with the number formatter. */
335 static inline bool areChecksEnabled()
337 if (nLocaleDataChecking == 0)
338 evaluateLocaleDataChecking();
339 return nLocaleDataChecking == 1;
342 /** Append locale info to string, used with locale data checking.
343 A string similar to "de_DE requested\n en_US loaded" is appended. */
344 OUString appendLocaleInfo(const OUString& rDebugMsg) const;
346 /** Ouput a message during locale data checking. The (UTF-8) string is
347 written to stderr and in a non-product build or if DBG_UTIL is enabled
348 also raised as an assertion message box. */
349 static void outputCheckMessage( const OUString& rMsg );
350 static void outputCheckMessage( const char* pStr);
352 private:
354 const ::com::sun::star::lang::Locale & getMyLocale() const;
356 static void evaluateLocaleDataChecking();
360 #endif // INCLUDED_UNOTOOLS_LOCALEDATAWRAPPER_HXX
362 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */