diff options
-rw-r--r-- | cui/source/options/optgdlg.cxx | 128 | ||||
-rw-r--r-- | cui/source/options/optgdlg.hrc | 3 | ||||
-rw-r--r-- | cui/source/options/optgdlg.hxx | 4 | ||||
-rw-r--r-- | cui/source/options/optgdlg.src | 52 | ||||
-rw-r--r-- | officecfg/registry/schema/org/openoffice/Setup.xcs | 8 | ||||
-rw-r--r-- | svl/inc/svl/zforlist.hxx | 4 | ||||
-rw-r--r-- | svl/source/numbers/zforfind.cxx | 55 | ||||
-rw-r--r-- | svl/source/numbers/zforfind.hxx | 2 | ||||
-rw-r--r-- | svl/source/numbers/zforlist.cxx | 37 | ||||
-rw-r--r-- | unotools/inc/unotools/localedatawrapper.hxx | 6 | ||||
-rw-r--r-- | unotools/inc/unotools/syslocaleoptions.hxx | 18 | ||||
-rw-r--r-- | unotools/source/config/syslocaleoptions.cxx | 68 | ||||
-rw-r--r-- | unotools/source/i18n/localedatawrapper.cxx | 59 | ||||
-rw-r--r-- | unotools/source/misc/syslocale.cxx | 31 |
14 files changed, 429 insertions, 46 deletions
diff --git a/cui/source/options/optgdlg.cxx b/cui/source/options/optgdlg.cxx index 4f8336822446..5f7015bdbd37 100644 --- a/cui/source/options/optgdlg.cxx +++ b/cui/source/options/optgdlg.cxx @@ -1206,6 +1206,22 @@ static OUString sUserLocalePath(RTL_CONSTASCII_USTRINGPARAM("org.openoffice.Offi static const OUString sUserLocaleKey(RTL_CONSTASCII_USTRINGPARAM("UILocale")); static Sequence< OUString > seqInstalledLanguages; +static OUString lcl_getDatePatternsConfigString( const LocaleDataWrapper& rLocaleWrapper ) +{ + Sequence< OUString > aDateAcceptancePatterns = rLocaleWrapper.getDateAcceptancePatterns(); + sal_Int32 nPatterns = aDateAcceptancePatterns.getLength(); + OUStringBuffer aBuf( nPatterns * 6 ); // 6 := length of Y-M-D; + SAL_WARN_IF( !nPatterns, "cui.options", "No date acceptance pattern"); + if (nPatterns) + { + const OUString* pPatterns = aDateAcceptancePatterns.getConstArray(); + aBuf.append( pPatterns[0]); + for (sal_Int32 i=1; i < nPatterns; ++i) + aBuf.append(';').append( pPatterns[i]); + } + return aBuf.makeStringAndClear(); +} + OfaLanguagesTabPage::OfaLanguagesTabPage( Window* pParent, const SfxItemSet& rSet ) : SfxTabPage( pParent, CUI_RES( OFA_TP_LANGUAGES ), rSet ), aUILanguageGB(this, CUI_RES(FL_UI_LANG )), @@ -1219,6 +1235,9 @@ OfaLanguagesTabPage::OfaLanguagesTabPage( Window* pParent, const SfxItemSet& rSe aDecimalSeparatorCB(this, CUI_RES(CB_DECIMALSEPARATOR)), aCurrencyFT( this, CUI_RES(FT_CURRENCY )), aCurrencyLB( this, CUI_RES(LB_CURRENCY )), + aDatePatternsFI( this, CUI_RES(FI_DATEPATTERNS )), + aDatePatternsFT( this, CUI_RES(FT_DATEPATTERNS )), + aDatePatternsED( this, CUI_RES(ED_DATEPATTERNS )), aLinguLanguageGB(this, CUI_RES(FL_LINGU_LANG )), aWesternLanguageFI(this, CUI_RES(FI_WEST_LANG )), aWesternLanguageFT(this, CUI_RES(FT_WEST_LANG )), @@ -1341,6 +1360,8 @@ OfaLanguagesTabPage::OfaLanguagesTabPage( Window* pParent, const SfxItemSet& rSe delete pLanguageTable; aLocaleSettingLB.SetSelectHdl( LINK( this, OfaLanguagesTabPage, LocaleSettingHdl ) ); + aDatePatternsED.SetModifyHdl( LINK( this, OfaLanguagesTabPage, DatePatternsHdl ) ); + Link aLink( LINK( this, OfaLanguagesTabPage, SupportHdl ) ); aAsianSupportCB.SetClickHdl( aLink ); aCTLSupportCB.SetClickHdl( aLink ); @@ -1537,6 +1558,11 @@ sal_Bool OfaLanguagesTabPage::FillItemSet( SfxItemSet& rSet ) if ( sOldCurr != sNewCurr ) pLangConfig->aSysLocaleOptions.SetCurrencyConfigString( sNewCurr ); + // Configured date acceptance patterns, for example Y-M-D;M-D or empty for + // locale default. + if (aDatePatternsED.GetText() != aDatePatternsED.GetSavedValue()) + pLangConfig->aSysLocaleOptions.SetDatePatternsConfigString( aDatePatternsED.GetText()); + SfxObjectShell* pCurrentDocShell = SfxObjectShell::Current(); Reference< XPropertySet > xLinguProp( LinguMgr::GetLinguPropertySet(), UNO_QUERY ); sal_Bool bCurrentDocCBChecked = aCurrentDocCB.IsChecked(); @@ -1688,6 +1714,22 @@ void OfaLanguagesTabPage::Reset( const SfxItemSet& rSet ) aCurrencyFT.Enable(!bReadonly); aCurrencyFI.Show(bReadonly); + // date acceptance patterns + OUString aDatePatternsString = pLangConfig->aSysLocaleOptions.GetDatePatternsConfigString(); + if (aDatePatternsString.isEmpty()) + { + Locale aTempLocale; + SvxLanguageToLocale( aTempLocale, Application::GetSettings().GetLanguage()); + LocaleDataWrapper aLocaleWrapper( ::comphelper::getProcessServiceFactory(), aTempLocale ); + aDatePatternsString = lcl_getDatePatternsConfigString( aLocaleWrapper); + } + aDatePatternsED.SetText( aDatePatternsString); + bReadonly = pLangConfig->aSysLocaleOptions.IsReadOnly(SvtSysLocaleOptions::E_DATEPATTERNS); + aDatePatternsED.Enable(!bReadonly); + aDatePatternsFT.Enable(!bReadonly); + aDatePatternsFI.Show(bReadonly); + aDatePatternsED.SaveValue(); + //western/CJK/CLK language LanguageType eCurLang = LANGUAGE_NONE; LanguageType eCurLangCJK = LANGUAGE_NONE; @@ -1871,14 +1913,98 @@ IMPL_LINK( OfaLanguagesTabPage, LocaleSettingHdl, SvxLanguageBox*, pBox ) } aCurrencyLB.SelectEntryPos( nPos ); - //update the decimal separator key of the related CheckBox + // obtain corresponding locale data Locale aTempLocale; SvxLanguageToLocale( aTempLocale, eLang ); LocaleDataWrapper aLocaleWrapper( ::comphelper::getProcessServiceFactory(), aTempLocale ); + + // update the decimal separator key of the related CheckBox String sTempLabel(sDecimalSeparatorLabel); sTempLabel.SearchAndReplaceAscii("%1", aLocaleWrapper.getNumDecimalSep() ); aDecimalSeparatorCB.SetText(sTempLabel); + // update the date acceptance patterns + OUString aDatePatternsString = lcl_getDatePatternsConfigString( aLocaleWrapper); + aDatePatternsED.SetText( aDatePatternsString); + + return 0; +} + +IMPL_LINK( OfaLanguagesTabPage, DatePatternsHdl, Edit*, pEd ) +{ + OUString aPatterns( pEd->GetText()); + bool bValid = true; + if (!aPatterns.isEmpty()) + { + for (sal_Int32 nIndex=0; nIndex >= 0 && bValid; /*nop*/) + { + OUString aPat( aPatterns.getToken( 0, ';', nIndex)); + if (aPat.isEmpty() && nIndex < 0) + { + // Indicating failure when about to append a pattern is too + // confusing. Empty patterns are ignored anyway when sequencing + // to SvtSysLocale. + continue; // for + } + else if (aPat.getLength() < 2) + bValid = false; + else + { + bool bY, bM, bD; + bY = bM = bD = false; + bool bSep = true; + for (sal_Int32 i = 0; i < aPat.getLength() && bValid; /*nop*/) + { + sal_uInt32 c = aPat.iterateCodePoints( &i); + // Only one Y,M,D per pattern, separated by any character(s). + switch (c) + { + case 'Y': + if (bY || !bSep) + bValid = false; + bY = true; + bSep = false; + break; + case 'M': + if (bM || !bSep) + bValid = false; + bM = true; + bSep = false; + break; + case 'D': + if (bD || !bSep) + bValid = false; + bD = true; + bSep = false; + break; + default: + bSep = true; + } + } + // At least one of Y,M,D + bValid &= (bY || bM || bD); + } + } + } + if (bValid) + { + pEd->SetControlForeground(); + pEd->SetControlBackground(); + } + else + { + // color to use as foreground for an invalid pattern + #define INVALID_PATTERN_FOREGROUND_COLOR Color(COL_WHITE) + // color to use as background for an invalid pattern + #define INVALID_PATTERN_BACKGROUND_COLOR Color(0xff6563) +#if 0 + //! Gives white on white!?! + pEd->SetControlBackground( INVALID_PATTERN_BACKGROUND_COLOR); + pEd->SetControlForeground( INVALID_PATTERN_FOREGROUND_COLOR); +#else + pEd->SetControlForeground( INVALID_PATTERN_BACKGROUND_COLOR); +#endif + } return 0; } diff --git a/cui/source/options/optgdlg.hrc b/cui/source/options/optgdlg.hrc index aaa966660faf..59293806fb49 100644 --- a/cui/source/options/optgdlg.hrc +++ b/cui/source/options/optgdlg.hrc @@ -176,6 +176,9 @@ #define FI_USERINTERFACE 29 #define FT_USERINTERFACE 30 #define LB_USERINTERFACE 31 +#define FI_DATEPATTERNS 32 +#define FT_DATEPATTERNS 33 +#define ED_DATEPATTERNS 34 #define FL_FILEDLG 53 #define FI_FILEDLG_RO 54 diff --git a/cui/source/options/optgdlg.hxx b/cui/source/options/optgdlg.hxx index e38c48c90db3..b58868866e75 100644 --- a/cui/source/options/optgdlg.hxx +++ b/cui/source/options/optgdlg.hxx @@ -179,6 +179,9 @@ class OfaLanguagesTabPage : public SfxTabPage CheckBox aDecimalSeparatorCB; FixedText aCurrencyFT; ListBox aCurrencyLB; + ReadOnlyImage aDatePatternsFI; + FixedText aDatePatternsFT; + Edit aDatePatternsED; FixedLine aLinguLanguageGB; ReadOnlyImage aWesternLanguageFI; @@ -207,6 +210,7 @@ class OfaLanguagesTabPage : public SfxTabPage DECL_LINK( SupportHdl, CheckBox* ) ; DECL_LINK( LocaleSettingHdl, SvxLanguageBox* ) ; + DECL_LINK( DatePatternsHdl, Edit* ) ; public: OfaLanguagesTabPage( Window* pParent, const SfxItemSet& rSet ); diff --git a/cui/source/options/optgdlg.src b/cui/source/options/optgdlg.src index 272874429302..67abcf0aa2d2 100644 --- a/cui/source/options/optgdlg.src +++ b/cui/source/options/optgdlg.src @@ -558,21 +558,41 @@ TabPage OFA_TP_LANGUAGES TabStop = TRUE ; Sort = TRUE; }; + FixedImage FI_DATEPATTERNS + { + Pos = MAP_APPFONT ( 5 , 78 ) ; + Size = MAP_APPFONT ( 6 , 6 ) ; + Hide = TRUE; + }; + FixedText FT_DATEPATTERNS + { + Pos = MAP_APPFONT ( 12 , 76 ) ; + Size = MAP_APPFONT ( 108 , 8 ) ; + Text [ en-US ] = "Date acceptance ~patterns"; + }; + Edit ED_DATEPATTERNS + { + HelpID = "cui:Edit:OFA_TP_LANGUAGES:ED_DATEPATTERNS"; + Pos = MAP_APPFONT ( 123 , 74 ) ; + Size = MAP_APPFONT ( 125 , 12 ) ; + Border = TRUE ; + TabStop = TRUE ; + }; FixedLine FL_LINGU_LANG { - Pos = MAP_APPFONT ( 6 , 77 ) ; + Pos = MAP_APPFONT ( 6 , 92 ) ; Size = MAP_APPFONT ( 248 , 8 ) ; Text [ en-US ] = "Default languages for documents"; }; FixedImage FI_WEST_LANG { - Pos = MAP_APPFONT ( 5 , 92 ) ; + Pos = MAP_APPFONT ( 5 , 107 ) ; Size = MAP_APPFONT ( 6 , 6 ) ; Hide = TRUE; }; FixedText FT_WEST_LANG { - Pos = MAP_APPFONT ( 12 , 90 ) ; + Pos = MAP_APPFONT ( 12 , 105 ) ; Size = MAP_APPFONT ( 108 , 8 ) ; Text [ en-US ] = "Western"; }; @@ -580,7 +600,7 @@ TabPage OFA_TP_LANGUAGES ListBox LB_WEST_LANG { HelpID = "cui:ListBox:OFA_TP_LANGUAGES:LB_WEST_LANG"; - Pos = MAP_APPFONT ( 123 , 88 ) ; + Pos = MAP_APPFONT ( 123 , 103 ) ; Size = MAP_APPFONT ( 125 , 60 ) ; DropDown = TRUE ; Border = TRUE ; @@ -589,20 +609,20 @@ TabPage OFA_TP_LANGUAGES }; FixedImage FI_ASIAN_LANG { - Pos = MAP_APPFONT ( 5 , 108 ) ; + Pos = MAP_APPFONT ( 5 , 123 ) ; Size = MAP_APPFONT ( 6 , 6 ) ; Hide = TRUE; }; FixedText FT_ASIAN_LANG { - Pos = MAP_APPFONT ( 12 , 106 ) ; + Pos = MAP_APPFONT ( 12 , 121 ) ; Size = MAP_APPFONT ( 108 , 8 ) ; Text [ en-US ] = "Asian"; }; ListBox LB_ASIAN_LANG { HelpID = "cui:ListBox:OFA_TP_LANGUAGES:LB_ASIAN_LANG"; - Pos = MAP_APPFONT ( 123 , 104 ) ; + Pos = MAP_APPFONT ( 123 , 119 ) ; Size = MAP_APPFONT ( 125 , 60 ) ; DropDown = TRUE ; Border = TRUE ; @@ -611,20 +631,20 @@ TabPage OFA_TP_LANGUAGES }; FixedImage FI_COMPLEX_LANG { - Pos = MAP_APPFONT ( 5 , 124 ) ; + Pos = MAP_APPFONT ( 5 , 139 ) ; Size = MAP_APPFONT ( 6 , 6 ) ; Hide = TRUE; }; FixedText FT_COMPLEX_LANG { - Pos = MAP_APPFONT ( 12 , 122 ) ; + Pos = MAP_APPFONT ( 12 , 137 ) ; Size = MAP_APPFONT ( 108 , 8 ) ; Text [ en-US ] = "C~TL"; }; ListBox LB_COMPLEX_LANG { HelpID = "cui:ListBox:OFA_TP_LANGUAGES:LB_COMPLEX_LANG"; - Pos = MAP_APPFONT ( 123 , 120 ) ; + Pos = MAP_APPFONT ( 123 , 135 ) ; Size = MAP_APPFONT ( 125 , 60 ) ; DropDown = TRUE ; Border = TRUE ; @@ -634,39 +654,39 @@ TabPage OFA_TP_LANGUAGES CheckBox CB_CURRENT_DOC { HelpID = "cui:CheckBox:OFA_TP_LANGUAGES:CB_CURRENT_DOC"; - Pos = MAP_APPFONT ( 123 , 135 ) ; + Pos = MAP_APPFONT ( 123 , 150 ) ; Size = MAP_APPFONT ( 125 , RSC_CD_CHECKBOX_HEIGHT ) ; Text [ en-US ] = "For the current document only"; }; FixedLine FL_ENHANCED { - Pos = MAP_APPFONT ( 6 , 145 ) ; + Pos = MAP_APPFONT ( 6 , 160 ) ; Size = MAP_APPFONT ( 248 , 8 ) ; Text [ en-US ] = "Enhanced language support"; }; FixedImage FI_ASIANSUPPORT { - Pos = MAP_APPFONT ( 5 , 160 ) ; + Pos = MAP_APPFONT ( 5 , 175 ) ; Size = MAP_APPFONT ( 6 , 6 ) ; Hide = TRUE; }; CheckBox CB_ASIANSUPPORT { HelpID = "cui:CheckBox:OFA_TP_LANGUAGES:CB_ASIANSUPPORT"; - Pos = MAP_APPFONT ( 12 , 158 ) ; + Pos = MAP_APPFONT ( 12 , 173 ) ; Size = MAP_APPFONT ( 236 ,RSC_CD_CHECKBOX_HEIGHT ) ; Text [ en-US ] = "E~nabled for Asian languages"; }; FixedImage FI_CTLSUPPORT { - Pos = MAP_APPFONT ( 5 , 175 ) ; + Pos = MAP_APPFONT ( 5 , 190 ) ; Size = MAP_APPFONT ( 6 , 6 ) ; Hide = TRUE; }; CheckBox CB_CTLSUPPORT { HelpID = "cui:CheckBox:OFA_TP_LANGUAGES:CB_CTLSUPPORT"; - Pos = MAP_APPFONT ( 12 , 173 ) ; + Pos = MAP_APPFONT ( 12 , 188 ) ; Size = MAP_APPFONT ( 236 , RSC_CD_CHECKBOX_HEIGHT ) ; Text [ en-US ] = "Ena~bled for complex text layout (CTL)"; }; diff --git a/officecfg/registry/schema/org/openoffice/Setup.xcs b/officecfg/registry/schema/org/openoffice/Setup.xcs index 2f14b7a81fd0..c818cd3cef5d 100644 --- a/officecfg/registry/schema/org/openoffice/Setup.xcs +++ b/officecfg/registry/schema/org/openoffice/Setup.xcs @@ -457,6 +457,14 @@ </info> <value>true</value> </prop> + <prop oor:name="DateAcceptancePatterns" oor:type="xs:string" oor:nillable="true"> + <!-- UIHints: Tools - Options - Language Settings - Languages - Language of - Date acceptance patterns --> + <info> + <author>erAck</author> + <desc>Indicates the date acceptance patterns defined by the user. By default, this label is empty and the patterns defined in the ooSetupSystemLocale are used.</desc> + </info> + <value/> + </prop> </group> <group oor:name="Configuration"> <info> diff --git a/svl/inc/svl/zforlist.hxx b/svl/inc/svl/zforlist.hxx index 1cace08d22bf..5b7ab3861182 100644 --- a/svl/inc/svl/zforlist.hxx +++ b/svl/inc/svl/zforlist.hxx @@ -943,6 +943,10 @@ public: // called by SvNumberFormatterRegistry_Impl::Notify if the default system currency changes void ResetDefaultSystemCurrency(); + // Called by SvNumberFormatterRegistry_Impl::Notify if the system locale's + // date acceptence patterns change. + void InvalidateDateAcceptancePatterns(); + // Replace the SYSTEM language/country format codes. Called upon change of // the user configurable locale. // Old compatibility codes are replaced, user defined are converted, and diff --git a/svl/source/numbers/zforfind.cxx b/svl/source/numbers/zforfind.cxx index 6d0cbdc93551..fb5bbe3ad821 100644 --- a/svl/source/numbers/zforfind.cxx +++ b/svl/source/numbers/zforfind.cxx @@ -1012,12 +1012,6 @@ bool ImpSvNumberInputScan::CanForceToIso8601( DateFormat eDateFormat ) break; } - if (!comphelper::string::equals(pFormatter->GetDateSep(), '-')) - { - nCanForceToIso8601 = 2; // date separator does not interfere - break; - } - sal_Int32 n; switch (eDateFormat) { @@ -1292,6 +1286,18 @@ DateFormat ImpSvNumberInputScan::GetDateOrder() return DMY; } break; + default: + case 0: + switch ((nOrder & 0xff)) + { + case 'Y': + return YMD; + case 'M': + return MDY; + case 'D': + return DMY; + } + break; } } SAL_WARN( "nf.date", "ImpSvNumberInputScan::GetDateOrder: undefined, falling back to locale's default"); @@ -1432,8 +1438,30 @@ input for the following reasons: nCounter = 1; switch (nMonthPos) // where is the month { - case 0: // not found => only day entered - pCal->setValue( CalendarFieldIndex::DAY_OF_MONTH, ImplGetDay(0) ); + case 0: // not found + { + // If input matched a date pattern, use the pattern + // to determine if it is a day, month or year. The + // pattern should have only one single value then, + // 'D-', 'M-' or 'Y-'. If input did not match a + // pattern assume the usual day of current month. + sal_uInt32 nDateOrder = (bFormatTurn ? + pFormat->GetExactDateOrder() : + GetDatePatternOrder()); + switch (nDateOrder) + { + case 'Y': + pCal->setValue( CalendarFieldIndex::YEAR, ImplGetYear(0) ); + break; + case 'M': + pCal->setValue( CalendarFieldIndex::MONTH, ImplGetMonth(0) ); + break; + case 'D': + default: + pCal->setValue( CalendarFieldIndex::DAY_OF_MONTH, ImplGetDay(0) ); + break; + } + } break; case 1: // month at the beginning (Jan 01) pCal->setValue( CalendarFieldIndex::MONTH, Abs(nMonth)-1 ); @@ -2223,6 +2251,7 @@ bool ImpSvNumberInputScan::ScanEndString( const String& rString, } } + bool bSignDetectedHere = false; if ( nSign == 0 // conflict - not signed && eScannedType != NUMBERFORMAT_DATE) // and not date //!? catch time too? @@ -2230,6 +2259,8 @@ bool ImpSvNumberInputScan::ScanEndString( const String& rString, nSign = GetSign(rString, nPos); // 1- DM if (nNegCheck) // '(' as sign return MatchedReturn(); + if (nSign) + bSignDetectedHere = true; } SkipBlanks(rString, nPos); @@ -2300,6 +2331,8 @@ bool ImpSvNumberInputScan::ScanEndString( const String& rString, const String& rDate = pFormatter->GetDateSep(); bDate = SkipString( rDate, rString, nPos); // 10. 10- 10/ } + if (bDate && bSignDetectedHere) + nSign = 0; // 'D-' takes precedence over signed date if (bDate || ((MayBeIso8601() || MayBeMonthDate()) && SkipChar( '-', rString, nPos))) @@ -2866,6 +2899,12 @@ void ImpSvNumberInputScan::ChangeIntl() cDecSep == pFormatter->GetDateSep().GetChar(0) ); bTextInitialized = false; aUpperCurrSymbol.Erase(); + InvalidateDateAcceptancePatterns(); +} + + +void ImpSvNumberInputScan::InvalidateDateAcceptancePatterns() +{ if (sDateAcceptancePatterns.getLength()) sDateAcceptancePatterns = ::com::sun::star::uno::Sequence< ::rtl::OUString >(); } diff --git a/svl/source/numbers/zforfind.hxx b/svl/source/numbers/zforfind.hxx index 2f8d6ffbd1d8..7eb58c8f698f 100644 --- a/svl/source/numbers/zforfind.hxx +++ b/svl/source/numbers/zforfind.hxx @@ -74,6 +74,8 @@ public: */ bool CanForceToIso8601( DateFormat eDateFormat ); + void InvalidateDateAcceptancePatterns(); + private: SvNumberFormatter* pFormatter; String* pUpperMonthText; // Array of month names, uppercase diff --git a/svl/source/numbers/zforlist.cxx b/svl/source/numbers/zforlist.cxx index c5172a2972b9..e4596551dd44 100644 --- a/svl/source/numbers/zforlist.cxx +++ b/svl/source/numbers/zforlist.cxx @@ -141,19 +141,24 @@ void SvNumberFormatterRegistry_Impl::ConfigurationChanged( utl::ConfigurationBroadcaster*, sal_uInt32 nHint) { - if ( nHint & SYSLOCALEOPTIONS_HINT_LOCALE ) - { - ::osl::MutexGuard aGuard( SvNumberFormatter::GetMutex() ); - for( size_t i = 0, n = aFormatters.size(); i < n; ++i ) - aFormatters[ i ]->ReplaceSystemCL( eSysLanguage ); - eSysLanguage = MsLangId::getRealLanguage( LANGUAGE_SYSTEM ); - } - if ( nHint & SYSLOCALEOPTIONS_HINT_CURRENCY ) - { - ::osl::MutexGuard aGuard( SvNumberFormatter::GetMutex() ); - for( size_t i = 0, n = aFormatters.size(); i < n; ++i ) - aFormatters[ i ]->ResetDefaultSystemCurrency(); - } + ::osl::MutexGuard aGuard( SvNumberFormatter::GetMutex() ); + + if ( nHint & SYSLOCALEOPTIONS_HINT_LOCALE ) + { + for( size_t i = 0, n = aFormatters.size(); i < n; ++i ) + aFormatters[ i ]->ReplaceSystemCL( eSysLanguage ); + eSysLanguage = MsLangId::getRealLanguage( LANGUAGE_SYSTEM ); + } + if ( nHint & SYSLOCALEOPTIONS_HINT_CURRENCY ) + { + for( size_t i = 0, n = aFormatters.size(); i < n; ++i ) + aFormatters[ i ]->ResetDefaultSystemCurrency(); + } + if ( nHint & SYSLOCALEOPTIONS_HINT_DATEPATTERNS ) + { + for( size_t i = 0, n = aFormatters.size(); i < n; ++i ) + aFormatters[ i ]->InvalidateDateAcceptancePatterns(); + } } @@ -3158,6 +3163,12 @@ void SvNumberFormatter::ResetDefaultSystemCurrency() } +void SvNumberFormatter::InvalidateDateAcceptancePatterns() +{ + pStringScanner->InvalidateDateAcceptancePatterns(); +} + + sal_uInt32 SvNumberFormatter::ImpGetDefaultSystemCurrencyFormat() { if ( nDefaultSystemCurrencyFormat == NUMBERFORMAT_ENTRY_NOT_FOUND ) diff --git a/unotools/inc/unotools/localedatawrapper.hxx b/unotools/inc/unotools/localedatawrapper.hxx index 4391719eb7fc..1b6e95beae6d 100644 --- a/unotools/inc/unotools/localedatawrapper.hxx +++ b/unotools/inc/unotools/localedatawrapper.hxx @@ -62,6 +62,7 @@ class UNOTOOLS_DLLPUBLIC LocaleDataWrapper : private boost::noncopyable ::boost::shared_ptr< ::com::sun::star::i18n::Calendar2 > xDefaultCalendar; ::com::sun::star::i18n::LocaleDataItem aLocaleDataItem; ::com::sun::star::uno::Sequence< ::rtl::OUString > aReservedWordSeq; + ::com::sun::star::uno::Sequence< ::rtl::OUString > aDateAcceptancePatterns; ::com::sun::star::uno::Sequence< sal_Int32 > aGrouping; // cached items rtl::OUString aLocaleItem[::com::sun::star::i18n::LocaleItem::COUNT]; @@ -148,6 +149,11 @@ public: ::com::sun::star::uno::Sequence< ::com::sun::star::lang::Locale > getAllInstalledLocaleNames() const; ::com::sun::star::uno::Sequence< ::rtl::OUString > getDateAcceptancePatterns() const; + /** Override locale's date acceptance patterns. + An empty sequence resets the patterns to the locale's pattern sequence. + */ + void setDateAcceptancePatterns( const ::com::sun::star::uno::Sequence< ::rtl::OUString > & rPatterns ); + /// same as the wrapper implementation but static static ::com::sun::star::uno::Sequence< ::com::sun::star::lang::Locale > getInstalledLocaleNames(); diff --git a/unotools/inc/unotools/syslocaleoptions.hxx b/unotools/inc/unotools/syslocaleoptions.hxx index 6db9a0fd4349..1c62ad809492 100644 --- a/unotools/inc/unotools/syslocaleoptions.hxx +++ b/unotools/inc/unotools/syslocaleoptions.hxx @@ -31,10 +31,11 @@ #include <com/sun/star/lang/Locale.hpp> // bits for broadcasting hints of changes in a SfxSimpleHint, may be combined -const sal_uLong SYSLOCALEOPTIONS_HINT_LOCALE = 0x00000001; -const sal_uLong SYSLOCALEOPTIONS_HINT_CURRENCY = 0x00000002; -const sal_uLong SYSLOCALEOPTIONS_HINT_UILOCALE = 0x00000004; -const sal_uLong SYSLOCALEOPTIONS_HINT_DECSEP = 0x00000008; +const sal_uLong SYSLOCALEOPTIONS_HINT_LOCALE = 0x00000001; +const sal_uLong SYSLOCALEOPTIONS_HINT_CURRENCY = 0x00000002; +const sal_uLong SYSLOCALEOPTIONS_HINT_UILOCALE = 0x00000004; +const sal_uLong SYSLOCALEOPTIONS_HINT_DECSEP = 0x00000008; +const sal_uLong SYSLOCALEOPTIONS_HINT_DATEPATTERNS = 0x00000010; class SvtSysLocaleOptions_Impl; class SvtListener; @@ -54,7 +55,8 @@ public: { E_LOCALE, E_UILOCALE, - E_CURRENCY + E_CURRENCY, + E_DATEPATTERNS }; SvtSysLocaleOptions(); virtual ~SvtSysLocaleOptions(); @@ -108,6 +110,12 @@ public: /// The config string may be empty to denote the default currency of the locale const ::rtl::OUString& GetCurrencyConfigString() const; void SetCurrencyConfigString( const ::rtl::OUString& rStr ); + + /** The config string may be empty to denote the default + DateAcceptancePatterns of the locale */ + const ::rtl::OUString& GetDatePatternsConfigString() const; + void SetDatePatternsConfigString( const ::rtl::OUString& rStr ); + // determine whether the decimal separator defined in the keyboard layout is used // or the one approriate to the locale sal_Bool IsDecimalSeparatorAsLocale() const; diff --git a/unotools/source/config/syslocaleoptions.cxx b/unotools/source/config/syslocaleoptions.cxx index d790d48fdcef..604344ba66f5 100644 --- a/unotools/source/config/syslocaleoptions.cxx +++ b/unotools/source/config/syslocaleoptions.cxx @@ -77,11 +77,13 @@ class SvtSysLocaleOptions_Impl : public utl::ConfigItem OUString m_aLocaleString; // en-US or de-DE or empty for SYSTEM OUString m_aUILocaleString; // en-US or de-DE or empty for SYSTEM OUString m_aCurrencyString; // USD-en-US or EUR-de-DE + OUString m_aDatePatternsString; // "Y-M-D;M-D" sal_Bool m_bDecimalSeparator; //use decimal separator same as locale sal_Bool m_bROLocale; sal_Bool m_bROUILocale; sal_Bool m_bROCurrency; + sal_Bool m_bRODatePatterns; sal_Bool m_bRODecimalSeparator; static const Sequence< /* const */ OUString > GetPropertyNames(); @@ -107,6 +109,10 @@ public: { return m_aCurrencyString; } void SetCurrencyString( const OUString& rStr ); + const OUString& GetDatePatternsString() const + { return m_aDatePatternsString; } + void SetDatePatternsString( const OUString& rStr ); + sal_Bool IsDecimalSeparatorAsLocale() const { return m_bDecimalSeparator;} void SetDecimalSeparatorAsLocale( sal_Bool bSet); @@ -124,13 +130,15 @@ public: #define PROPERTYNAME_UILOCALE OUString(RTL_CONSTASCII_USTRINGPARAM("ooLocale")) #define PROPERTYNAME_CURRENCY OUString(RTL_CONSTASCII_USTRINGPARAM("ooSetupCurrency")) #define PROPERTYNAME_DECIMALSEPARATOR OUString(RTL_CONSTASCII_USTRINGPARAM("DecimalSeparatorAsLocale")) +#define PROPERTYNAME_DATEPATTERNS OUString(RTL_CONSTASCII_USTRINGPARAM("DateAcceptancePatterns")) #define PROPERTYHANDLE_LOCALE 0 #define PROPERTYHANDLE_UILOCALE 1 #define PROPERTYHANDLE_CURRENCY 2 #define PROPERTYHANDLE_DECIMALSEPARATOR 3 +#define PROPERTYHANDLE_DATEPATTERNS 4 -#define PROPERTYCOUNT 4 +#define PROPERTYCOUNT 5 const Sequence< OUString > SvtSysLocaleOptions_Impl::GetPropertyNames() { @@ -139,7 +147,8 @@ const Sequence< OUString > SvtSysLocaleOptions_Impl::GetPropertyNames() PROPERTYNAME_LOCALE, PROPERTYNAME_UILOCALE, PROPERTYNAME_CURRENCY, - PROPERTYNAME_DECIMALSEPARATOR + PROPERTYNAME_DECIMALSEPARATOR, + PROPERTYNAME_DATEPATTERNS }; const Sequence< OUString > seqPropertyNames( pProperties, PROPERTYCOUNT ); return seqPropertyNames; @@ -153,6 +162,7 @@ SvtSysLocaleOptions_Impl::SvtSysLocaleOptions_Impl() , m_bROLocale(CFG_READONLY_DEFAULT) , m_bROUILocale(CFG_READONLY_DEFAULT) , m_bROCurrency(CFG_READONLY_DEFAULT) + , m_bRODatePatterns(CFG_READONLY_DEFAULT) , m_bRODecimalSeparator(sal_False) { @@ -221,6 +231,18 @@ SvtSysLocaleOptions_Impl::SvtSysLocaleOptions_Impl() m_bRODecimalSeparator = pROStates[nProp]; } break; + case PROPERTYHANDLE_DATEPATTERNS : + { + OUString aStr; + if ( pValues[nProp] >>= aStr ) + m_aDatePatternsString = aStr; + else + { + SAL_WARN( "unotools.config", "Wrong property type!" ); + } + m_bRODatePatterns = pROStates[nProp]; + } + break; default: SAL_WARN( "unotools.config", "Wrong property type!" ); } @@ -290,6 +312,11 @@ sal_Bool SvtSysLocaleOptions_Impl::IsReadOnly( SvtSysLocaleOptions::EOption eOpt bReadOnly = m_bROCurrency; break; } + case SvtSysLocaleOptions::E_DATEPATTERNS : + { + bReadOnly = m_bRODatePatterns; + break; + } } return bReadOnly; } @@ -349,6 +376,14 @@ void SvtSysLocaleOptions_Impl::Commit() ++nRealCount; } break; + case PROPERTYHANDLE_DATEPATTERNS : + if (!m_bRODatePatterns) + { + pNames[nRealCount] = aOrgNames[nProp]; + pValues[nRealCount] <<= m_aDatePatternsString; + ++nRealCount; + } + break; default: SAL_WARN( "unotools.config", "invalid index to save a path" ); } @@ -399,6 +434,16 @@ void SvtSysLocaleOptions_Impl::SetCurrencyString( const OUString& rStr ) } } +void SvtSysLocaleOptions_Impl::SetDatePatternsString( const OUString& rStr ) +{ + if (!m_bRODatePatterns && rStr != m_aDatePatternsString ) + { + m_aDatePatternsString = rStr; + SetModified(); + NotifyListeners( SYSLOCALEOPTIONS_HINT_DATEPATTERNS ); + } +} + void SvtSysLocaleOptions_Impl::SetDecimalSeparatorAsLocale( sal_Bool bSet) { if(bSet != m_bDecimalSeparator) @@ -447,6 +492,13 @@ void SvtSysLocaleOptions_Impl::Notify( const Sequence< rtl::OUString >& seqPrope seqValues[nProp] >>= m_bDecimalSeparator; m_bRODecimalSeparator = seqROStates[nProp]; } + else if( seqPropertyNames[nProp] == PROPERTYNAME_DATEPATTERNS ) + { + DBG_ASSERT( seqValues[nProp].getValueTypeClass() == TypeClass_STRING, "DatePatterns property type" ); + seqValues[nProp] >>= m_aDatePatternsString; + m_bRODatePatterns = seqROStates[nProp]; + nHint |= SYSLOCALEOPTIONS_HINT_DATEPATTERNS; + } } if ( nHint ) NotifyListeners( nHint ); @@ -552,6 +604,18 @@ void SvtSysLocaleOptions::SetCurrencyConfigString( const OUString& rStr ) pOptions->SetCurrencyString( rStr ); } +const OUString& SvtSysLocaleOptions::GetDatePatternsConfigString() const +{ + MutexGuard aGuard( GetMutex() ); + return pOptions->GetDatePatternsString(); +} + +void SvtSysLocaleOptions::SetDatePatternsConfigString( const OUString& rStr ) +{ + MutexGuard aGuard( GetMutex() ); + pOptions->SetDatePatternsString( rStr ); +} + sal_Bool SvtSysLocaleOptions::IsDecimalSeparatorAsLocale() const { MutexGuard aGuard( GetMutex() ); diff --git a/unotools/source/i18n/localedatawrapper.cxx b/unotools/source/i18n/localedatawrapper.cxx index 8faab07f0cd7..db5e2b85e266 100644 --- a/unotools/source/i18n/localedatawrapper.cxx +++ b/unotools/source/i18n/localedatawrapper.cxx @@ -120,6 +120,8 @@ void LocaleDataWrapper::invalidateData() xDefaultCalendar.reset(); if (aGrouping.getLength()) aGrouping[0] = 0; + if (aDateAcceptancePatterns.getLength()) + aDateAcceptancePatterns = Sequence<OUString>(); // dummies cCurrZeroChar = '0'; } @@ -1845,10 +1847,21 @@ void LocaleDataWrapper::evaluateLocaleDataChecking() ::com::sun::star::uno::Sequence< ::rtl::OUString > LocaleDataWrapper::getDateAcceptancePatterns() const { + ::utl::ReadWriteGuard aGuard( aMutex ); + + if (aDateAcceptancePatterns.getLength()) + return aDateAcceptancePatterns; + + aGuard.changeReadToWrite(); + try { if ( xLD.is() ) - return xLD->getDateAcceptancePatterns( getLocale() ); + { + const_cast<LocaleDataWrapper*>(this)->aDateAcceptancePatterns = + xLD->getDateAcceptancePatterns( getLocale() ); + return aDateAcceptancePatterns; + } } catch (const Exception& e) { @@ -1857,4 +1870,48 @@ void LocaleDataWrapper::evaluateLocaleDataChecking() return ::com::sun::star::uno::Sequence< ::rtl::OUString >(0); } +// --- Override layer -------------------------------------------------------- + +void LocaleDataWrapper::setDateAcceptancePatterns( + const ::com::sun::star::uno::Sequence< ::rtl::OUString > & rPatterns ) +{ + ::utl::ReadWriteGuard aGuard( aMutex, ::utl::ReadWriteGuardMode::nWrite ); + + if (!aDateAcceptancePatterns.getLength() || !rPatterns.getLength()) + { + try + { + if ( xLD.is() ) + aDateAcceptancePatterns = xLD->getDateAcceptancePatterns( getLocale() ); + } + catch (const Exception& e) + { + SAL_WARN( "unotools.i18n", "setDateAcceptancePatterns: Exception caught " << e.Message ); + } + if (!rPatterns.getLength()) + return; // just a reset + if (!aDateAcceptancePatterns.getLength()) + { + aDateAcceptancePatterns = rPatterns; + return; + } + } + + // Never overwrite the locale's full date pattern! The first. + if (aDateAcceptancePatterns[0] == rPatterns[0]) + aDateAcceptancePatterns = rPatterns; // sane + else + { + // Copy existing full date pattern and append the sequence passed. + /* TODO: could check for duplicates and shrink target sequence */ + Sequence< OUString > aTmp( rPatterns.getLength() + 1 ); + OUString* pArray1 = aTmp.getArray(); + const OUString* pArray2 = rPatterns.getConstArray(); + pArray1[0] = aDateAcceptancePatterns[0]; + for (sal_Int32 i=0; i < rPatterns.getLength(); ++i) + pArray1[i+1] = pArray2[i]; + aDateAcceptancePatterns = aTmp; + } +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/unotools/source/misc/syslocale.cxx b/unotools/source/misc/syslocale.cxx index 2441a528fc40..ead6e92eeb3e 100644 --- a/unotools/source/misc/syslocale.cxx +++ b/unotools/source/misc/syslocale.cxx @@ -26,6 +26,7 @@ #include <rtl/tencinfo.h> #include <rtl/locale.h> #include <osl/nlsupport.h> +#include <vector> using namespace osl; using namespace com::sun::star; @@ -47,6 +48,9 @@ public: CharClass* GetCharClass(); virtual void ConfigurationChanged( utl::ConfigurationBroadcaster*, sal_uInt32 ); + +private: + void setDateAcceptancePatternsConfig(); }; // ----------------------------------------------------------------------- @@ -54,6 +58,7 @@ public: SvtSysLocale_Impl::SvtSysLocale_Impl() : pCharClass(NULL) { pLocaleData = new LocaleDataWrapper( ::comphelper::getProcessServiceFactory(), aSysLocaleOptions.GetRealLocale() ); + setDateAcceptancePatternsConfig(); // listen for further changes aSysLocaleOptions.AddListener( this ); @@ -77,12 +82,38 @@ CharClass* SvtSysLocale_Impl::GetCharClass() void SvtSysLocale_Impl::ConfigurationChanged( utl::ConfigurationBroadcaster*, sal_uInt32 nHint ) { MutexGuard aGuard( SvtSysLocale::GetMutex() ); + if ( nHint & SYSLOCALEOPTIONS_HINT_LOCALE ) { com::sun::star::lang::Locale aLocale( aSysLocaleOptions.GetRealLocale() ); pLocaleData->setLocale( aLocale ); GetCharClass()->setLocale( aLocale ); } + if ( nHint & SYSLOCALEOPTIONS_HINT_DATEPATTERNS ) + { + setDateAcceptancePatternsConfig(); + } +} + +void SvtSysLocale_Impl::setDateAcceptancePatternsConfig() +{ + OUString aStr( aSysLocaleOptions.GetDatePatternsConfigString()); + if (aStr.isEmpty()) + pLocaleData->setDateAcceptancePatterns( uno::Sequence<OUString>()); // reset + else + { + ::std::vector< OUString > aVec; + for (sal_Int32 nIndex = 0; nIndex >= 0; /*nop*/) + { + OUString aTok( aStr.getToken( 0, ';', nIndex)); + if (!aTok.isEmpty()) + aVec.push_back( aTok); + } + uno::Sequence< OUString > aSeq( aVec.size()); + for (sal_Int32 i=0; i < aSeq.getLength(); ++i) + aSeq[i] = aVec[i]; + pLocaleData->setDateAcceptancePatterns( aSeq); + } } // ==================================================================== |