summaryrefslogtreecommitdiff
path: root/unotools
diff options
context:
space:
mode:
authorEike Rathke <erack@redhat.com>2012-08-29 20:49:01 +0200
committerCaolán McNamara <caolanm@redhat.com>2012-09-07 10:27:47 +0000
commitcfbfa26deb2776e5c07463e59517eaf68c1d5d6d (patch)
tree089961fb8b4c56f68d888f5cdbe622cc799199cc /unotools
parenta3044d50775afd105db322ab79a08e218ddc8ff7 (diff)
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@googlemail.com> Reviewed-by: Petr Mladek <pmladek@suse.cz> Tested-by: Petr Mladek <pmladek@suse.cz> Reviewed-by: Caolán McNamara <caolanm@redhat.com>
Diffstat (limited to 'unotools')
-rw-r--r--unotools/inc/unotools/localedatawrapper.hxx6
-rw-r--r--unotools/inc/unotools/syslocaleoptions.hxx18
-rw-r--r--unotools/source/config/syslocaleoptions.cxx68
-rw-r--r--unotools/source/i18n/localedatawrapper.cxx59
-rw-r--r--unotools/source/misc/syslocale.cxx31
5 files changed, 174 insertions, 8 deletions
diff --git a/unotools/inc/unotools/localedatawrapper.hxx b/unotools/inc/unotools/localedatawrapper.hxx
index 14ba39e69694..fef87d9b2032 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 d05383506e87..0c03a58e532f 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 eced74b60487..db30aa1b22bf 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 1e2ee1562465..de88414546dc 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 79aaa3945ff0..eb2740f941f3 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);
+ }
}
// ====================================================================