[Libreoffice-commits] .: Branch 'libreoffice-3-6' - cui/source officecfg/registry svl/inc svl/source unotools/inc unotools/source

Libreoffice Gerrit user logerrit at kemper.freedesktop.org
Fri Sep 7 03:28:09 PDT 2012


 cui/source/options/optgdlg.cxx                     |  128 ++++++++++++++++++++-
 cui/source/options/optgdlg.hrc                     |    3 
 cui/source/options/optgdlg.hxx                     |    4 
 cui/source/options/optgdlg.src                     |   52 +++++---
 officecfg/registry/schema/org/openoffice/Setup.xcs |    8 +
 svl/inc/svl/zforlist.hxx                           |    4 
 svl/source/numbers/zforfind.cxx                    |   55 +++++++--
 svl/source/numbers/zforfind.hxx                    |    2 
 svl/source/numbers/zforlist.cxx                    |   37 +++---
 unotools/inc/unotools/localedatawrapper.hxx        |    6 
 unotools/inc/unotools/syslocaleoptions.hxx         |   18 ++
 unotools/source/config/syslocaleoptions.cxx        |   68 ++++++++++-
 unotools/source/i18n/localedatawrapper.cxx         |   59 +++++++++
 unotools/source/misc/syslocale.cxx                 |   31 +++++
 14 files changed, 429 insertions(+), 46 deletions(-)

New commits:
commit cfbfa26deb2776e5c07463e59517eaf68c1d5d6d
Author: Eike Rathke <erack at redhat.com>
Date:   Wed Aug 29 20:49:01 2012 +0200

    resolved fdo#52240 fdo#52137 fdo#52288 user editable date patterns
    
    Implemented user editable date acceptance patterns.
    
    The introduction of strict date parsing using locale dependent date
    acceptance patterns in 3.6.0 wasn't always welcomed. Besides that not
    every locale had patterns for incomplete (only day and month) date
    input, users also complained about not being able to key in dates on
    numeric keypads if the locale's date separator wasn't '/' or '-'
    
    This commit implements a "Date acceptance patterns" edit field under
    Tools->Options->LanguageSettings->Languages that follows the selected
    locale and enables the user to add patterns.
    
    Example de-DE locale:
    * default patterns: D.M.Y;D.M.
    * to enable additional input on numeric keypad: D.M.Y;D.M.;D-M-Y;D-M
      * if 3-4 shall not result in a date, D-M- could be used instead of D-M
      * note that to enter an ISO 8601 Y-M-D date with a D-M-Y pattern
        active one needs to enter a year >31 or with at least 3 digits, e.g.
        011
    
    (cherry picked from commit bf10f4d62a5fe308ea47f9a0aac4f6f7e264ae3e)
    
    Conflicts:
    
    	cui/source/options/optgdlg.hrc
    	svl/source/numbers/zforfind.cxx
    	unotools/source/config/syslocaleoptions.cxx
    
    Change-Id: Ic1ce91b1f9d29f1837d56b45ba0ae16f6d9cb17c
    Reviewed-on: https://gerrit.libreoffice.org/511
    Reviewed-by: Markus Mohrhard <markus.mohrhard at googlemail.com>
    Reviewed-by: Petr Mladek <pmladek at suse.cz>
    Tested-by: Petr Mladek <pmladek at suse.cz>
    Reviewed-by: Caolán McNamara <caolanm at redhat.com>

diff --git a/cui/source/options/optgdlg.cxx b/cui/source/options/optgdlg.cxx
index 72e66d2..8826a09 100644
--- a/cui/source/options/optgdlg.cxx
+++ b/cui/source/options/optgdlg.cxx
@@ -1248,6 +1248,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();
+    rtl::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      )),
@@ -1261,6 +1277,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      )),
@@ -1383,6 +1402,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 );
@@ -1579,6 +1600,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();
@@ -1730,6 +1756,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;
@@ -1913,14 +1955,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 2ccc503..59e89e4 100644
--- a/cui/source/options/optgdlg.hrc
+++ b/cui/source/options/optgdlg.hrc
@@ -203,6 +203,9 @@
 #define FT_USERINTERFACE        30
 #define LB_USERINTERFACE        31
 #define STR_IB_LANGCHANGE_TITLE 32
+#define FI_DATEPATTERNS         33
+#define FT_DATEPATTERNS         34
+#define ED_DATEPATTERNS         35
 
 #define FL_FILEDLG                  53
 #define FI_FILEDLG_RO               54
diff --git a/cui/source/options/optgdlg.hxx b/cui/source/options/optgdlg.hxx
index 4b7f571..8b832ed 100644
--- a/cui/source/options/optgdlg.hxx
+++ b/cui/source/options/optgdlg.hxx
@@ -180,6 +180,9 @@ class OfaLanguagesTabPage : public SfxTabPage
     CheckBox        aDecimalSeparatorCB;
     FixedText       aCurrencyFT;
     ListBox         aCurrencyLB;
+    ReadOnlyImage   aDatePatternsFI;
+    FixedText       aDatePatternsFT;
+    Edit            aDatePatternsED;
 
     FixedLine       aLinguLanguageGB;
     ReadOnlyImage   aWesternLanguageFI;
@@ -208,6 +211,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 75af383..6e5f3ed 100644
--- a/cui/source/options/optgdlg.src
+++ b/cui/source/options/optgdlg.src
@@ -578,21 +578,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";
     };
@@ -600,7 +620,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 ;
@@ -609,20 +629,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 ;
@@ -631,20 +651,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 ;
@@ -654,39 +674,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 2f14b7a..c818cd3 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 7012164..2dfa273 100644
--- a/svl/inc/svl/zforlist.hxx
+++ b/svl/inc/svl/zforlist.hxx
@@ -953,6 +953,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 31f9c2c..eae56da 100644
--- a/svl/source/numbers/zforfind.cxx
+++ b/svl/source/numbers/zforfind.cxx
@@ -1021,12 +1021,6 @@ bool ImpSvNumberInputScan::CanForceToIso8601( DateFormat eDateFormat )
                 break;
             }
 
-            if (pFormatter->GetDateSep() != '-')
-            {
-                nCanForceToIso8601 = 2; // date separator does not interfere
-                break;
-            }
-
             sal_Int32 n;
             switch (eDateFormat)
             {
@@ -1300,6 +1294,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");
@@ -1440,8 +1446,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 );
@@ -2233,6 +2261,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?
@@ -2240,6 +2269,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);
@@ -2310,6 +2341,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)))
@@ -2877,6 +2910,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 7c2e8eb..233b012 100644
--- a/svl/source/numbers/zforfind.hxx
+++ b/svl/source/numbers/zforfind.hxx
@@ -83,6 +83,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 7c8a49c..8cd59f8 100644
--- a/svl/source/numbers/zforlist.cxx
+++ b/svl/source/numbers/zforlist.cxx
@@ -151,19 +151,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();
+    }
 }
 
 
@@ -3183,6 +3188,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 14ba39e..fef87d9 100644
--- a/unotools/inc/unotools/localedatawrapper.hxx
+++ b/unotools/inc/unotools/localedatawrapper.hxx
@@ -72,6 +72,7 @@ class UNOTOOLS_DLLPUBLIC LocaleDataWrapper
     ::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
     String                      aLocaleItem[::com::sun::star::i18n::LocaleItem::COUNT];
@@ -163,6 +164,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 d053835..0c03a58 100644
--- a/unotools/inc/unotools/syslocaleoptions.hxx
+++ b/unotools/inc/unotools/syslocaleoptions.hxx
@@ -40,10 +40,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;
@@ -63,7 +64,8 @@ public:
     {
         E_LOCALE,
         E_UILOCALE,
-        E_CURRENCY
+        E_CURRENCY,
+        E_DATEPATTERNS
     };
                                 SvtSysLocaleOptions();
                                 virtual ~SvtSysLocaleOptions();
@@ -117,6 +119,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 eced74b..db30aa1 100644
--- a/unotools/source/config/syslocaleoptions.cxx
+++ b/unotools/source/config/syslocaleoptions.cxx
@@ -87,11 +87,13 @@ class SvtSysLocaleOptions_Impl : public utl::ConfigItem
         OUString                m_aUILocaleString;    // en-US or de-DE or empty for SYSTEM
         OUString                m_aCurrencyString;  // USD-en-US or EUR-de-DE
         sal_uLong                   m_nBlockedHint;     // pending hints
+        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();
@@ -117,6 +119,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);
 
@@ -134,13 +140,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()
 {
@@ -149,7 +157,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;
@@ -164,6 +173,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)
 
 {
@@ -232,6 +242,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!" );
                     }
@@ -301,6 +323,11 @@ sal_Bool SvtSysLocaleOptions_Impl::IsReadOnly( SvtSysLocaleOptions::EOption eOpt
                 bReadOnly = m_bROCurrency;
                 break;
             }
+        case SvtSysLocaleOptions::E_DATEPATTERNS :
+            {
+                bReadOnly = m_bRODatePatterns;
+                break;
+            }
     }
     return bReadOnly;
 }
@@ -360,6 +387,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" );
         }
@@ -410,6 +445,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)
@@ -458,6 +503,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 );
@@ -563,6 +615,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 1e2ee15..de88414 100644
--- a/unotools/source/i18n/localedatawrapper.cxx
+++ b/unotools/source/i18n/localedatawrapper.cxx
@@ -133,6 +133,8 @@ void LocaleDataWrapper::invalidateData()
     xDefaultCalendar.reset();
     if (aGrouping.getLength())
         aGrouping[0] = 0;
+    if (aDateAcceptancePatterns.getLength())
+        aDateAcceptancePatterns = Sequence<rtl::OUString>();
     // dummies
     cCurrZeroChar = '0';
 }
@@ -1866,10 +1868,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)
     {
@@ -1878,4 +1891,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< rtl::OUString > aTmp( rPatterns.getLength() + 1 );
+        rtl::OUString* pArray1 = aTmp.getArray();
+        const rtl::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 79aaa39..eb2740f 100644
--- a/unotools/source/misc/syslocale.cxx
+++ b/unotools/source/misc/syslocale.cxx
@@ -35,6 +35,7 @@
 #include <rtl/tencinfo.h>
 #include <rtl/locale.h>
 #include <osl/nlsupport.h>
+#include <vector>
 
 using namespace osl;
 using namespace com::sun::star;
@@ -56,6 +57,9 @@ public:
 
     CharClass*                      GetCharClass();
     virtual void                    ConfigurationChanged( utl::ConfigurationBroadcaster*, sal_uInt32 );
+
+private:
+    void                            setDateAcceptancePatternsConfig();
 };
 
 // -----------------------------------------------------------------------
@@ -63,6 +67,7 @@ public:
 SvtSysLocale_Impl::SvtSysLocale_Impl() : pCharClass(NULL)
 {
     pLocaleData = new LocaleDataWrapper( ::comphelper::getProcessServiceFactory(), aSysLocaleOptions.GetRealLocale() );
+    setDateAcceptancePatternsConfig();
 
     // listen for further changes
     aSysLocaleOptions.AddListener( this );
@@ -86,12 +91,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()
+{
+    rtl::OUString aStr( aSysLocaleOptions.GetDatePatternsConfigString());
+    if (aStr.isEmpty())
+        pLocaleData->setDateAcceptancePatterns( uno::Sequence<rtl::OUString>());     // reset
+    else
+    {
+        ::std::vector< rtl::OUString > aVec;
+        for (sal_Int32 nIndex = 0; nIndex >= 0; /*nop*/)
+        {
+            rtl::OUString aTok( aStr.getToken( 0, ';', nIndex));
+            if (!aTok.isEmpty())
+                aVec.push_back( aTok);
+        }
+        uno::Sequence< rtl::OUString > aSeq( aVec.size());
+        for (sal_Int32 i=0; i < aSeq.getLength(); ++i)
+            aSeq[i] = aVec[i];
+        pLocaleData->setDateAcceptancePatterns( aSeq);
+    }
 }
 
 // ====================================================================


More information about the Libreoffice-commits mailing list