summaryrefslogtreecommitdiff
path: root/unotools
diff options
context:
space:
mode:
authorEike Rathke <erack@redhat.com>2012-08-29 20:49:01 +0200
committerEike Rathke <erack@redhat.com>2012-08-29 21:17:46 +0200
commitcda156257003df673fa853a0a5ffcd1cb4848d43 (patch)
tree5fcd7aa0c1c8e5de2da387e069423530500b15b4 /unotools
parent332451bea5ebe08136de2d51e0e29cac88f89e8c (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 Change-Id: I9e20fcb168578b02d0f0248a0e209942e0f27113
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 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);
+ }
}
// ====================================================================