diff options
author | Eike Rathke <erack@redhat.com> | 2014-05-17 02:33:42 +0200 |
---|---|---|
committer | Eike Rathke <erack@redhat.com> | 2014-05-17 03:11:22 +0200 |
commit | 8e71f81f47c20320c4de7a7aadb7d524f0d8ea76 (patch) | |
tree | dd642a1e16db07f857e3e40488b4e88b08fca268 | |
parent | 8c8de51cc954aaae07f76732e6202398e33afeb7 (diff) |
resolved fdo#41166 match month and day name word instead of substring
Change-Id: I897dbcee47de574d91ba3e3b40a39a35b779fef8
-rw-r--r-- | svl/source/numbers/zforfind.cxx | 59 | ||||
-rw-r--r-- | svl/source/numbers/zforfind.hxx | 7 |
2 files changed, 57 insertions, 9 deletions
diff --git a/svl/source/numbers/zforfind.cxx b/svl/source/numbers/zforfind.cxx index c77bb0a05462..0cf62fd68dd7 100644 --- a/svl/source/numbers/zforfind.cxx +++ b/svl/source/numbers/zforfind.cxx @@ -439,6 +439,47 @@ bool ImpSvNumberInputScan::StringPtrContainsImpl( const OUString& rWhat, /** + * Whether rString contains word rWhat at nPos + */ +bool ImpSvNumberInputScan::StringContainsWord( const OUString& rWhat, + const OUString& rString, sal_Int32 nPos ) +{ + if (rWhat.isEmpty() || rString.getLength() < nPos + rWhat.getLength()) + return false; + + if (StringPtrContainsImpl( rWhat, rString.getStr(), nPos)) + { + nPos += rWhat.getLength(); + if (nPos == rString.getLength()) + return true; // word at end of string + + /* TODO: we COULD invoke bells and whistles word break iterator to find + * the next boundary, but really ... this is called for date input, so + * how many languages do not separate the day and month names in some + * form? */ + + sal_Int32 nIndex = nPos; + sal_uInt32 c = rString.iterateCodePoints( &nIndex); + if (nPos+1 < nIndex) + return true; // Surrogate, assume these to be new words. + (void)c; + + const sal_Int32 nType = pFormatter->GetCharClass()->getCharacterType( rString, nPos); + + if (CharClass::isAlphaNumericType( nType)) + return false; // Alpha or numeric is not word gap. + + if (CharClass::isLetterType( nType)) + return true; // Letter other than alpha is new word. (Is it?) + + return true; // Catch all remaining as gap until we know better. + } + + return false; +} + + +/** * Skips the supplied char */ inline bool ImpSvNumberInputScan::SkipChar( sal_Unicode c, const OUString& rString, @@ -577,7 +618,7 @@ short ImpSvNumberInputScan::GetMonth( const OUString& rString, sal_Int32& nPos ) // if we stopped at the first match. for ( sal_Int16 i = 0; i < nMonths; i++ ) { - if ( bScanGenitiveMonths && StringContains( pUpperGenitiveMonthText[i], rString, nPos ) ) + if ( bScanGenitiveMonths && StringContainsWord( pUpperGenitiveMonthText[i], rString, nPos ) ) { // genitive full names first const int nMonthLen = pUpperGenitiveMonthText[i].getLength(); if (nMonthLen > nMatchLen) @@ -586,7 +627,7 @@ short ImpSvNumberInputScan::GetMonth( const OUString& rString, sal_Int32& nPos ) res = i + 1; } } - else if ( bScanGenitiveMonths && StringContains( pUpperGenitiveAbbrevMonthText[i], rString, nPos ) ) + else if ( bScanGenitiveMonths && StringContainsWord( pUpperGenitiveAbbrevMonthText[i], rString, nPos ) ) { // genitive abbreviated const int nMonthLen = pUpperGenitiveAbbrevMonthText[i].getLength(); if (nMonthLen > nMatchLen) @@ -595,7 +636,7 @@ short ImpSvNumberInputScan::GetMonth( const OUString& rString, sal_Int32& nPos ) res = sal::static_int_cast< short >(-(i+1)); // negative } } - else if ( bScanPartitiveMonths && StringContains( pUpperPartitiveMonthText[i], rString, nPos ) ) + else if ( bScanPartitiveMonths && StringContainsWord( pUpperPartitiveMonthText[i], rString, nPos ) ) { // partitive full names const int nMonthLen = pUpperPartitiveMonthText[i].getLength(); if (nMonthLen > nMatchLen) @@ -604,7 +645,7 @@ short ImpSvNumberInputScan::GetMonth( const OUString& rString, sal_Int32& nPos ) res = i+1; } } - else if ( bScanPartitiveMonths && StringContains( pUpperPartitiveAbbrevMonthText[i], rString, nPos ) ) + else if ( bScanPartitiveMonths && StringContainsWord( pUpperPartitiveAbbrevMonthText[i], rString, nPos ) ) { // partitive abbreviated const int nMonthLen = pUpperPartitiveAbbrevMonthText[i].getLength(); if (nMonthLen > nMatchLen) @@ -613,7 +654,7 @@ short ImpSvNumberInputScan::GetMonth( const OUString& rString, sal_Int32& nPos ) res = sal::static_int_cast< short >(-(i+1)); // negative } } - else if ( StringContains( pUpperMonthText[i], rString, nPos ) ) + else if ( StringContainsWord( pUpperMonthText[i], rString, nPos ) ) { // noun full names const int nMonthLen = pUpperMonthText[i].getLength(); if (nMonthLen > nMatchLen) @@ -622,7 +663,7 @@ short ImpSvNumberInputScan::GetMonth( const OUString& rString, sal_Int32& nPos ) res = i+1; } } - else if ( StringContains( pUpperAbbrevMonthText[i], rString, nPos ) ) + else if ( StringContainsWord( pUpperAbbrevMonthText[i], rString, nPos ) ) { // noun abbreviated const int nMonthLen = pUpperAbbrevMonthText[i].getLength(); if (nMonthLen > nMatchLen) @@ -632,7 +673,7 @@ short ImpSvNumberInputScan::GetMonth( const OUString& rString, sal_Int32& nPos ) } } else if ( i == 8 && pUpperAbbrevMonthText[i] == aSeptCorrect && - StringContains( aSepShortened, rString, nPos ) ) + StringContainsWord( aSepShortened, rString, nPos ) ) { // #102136# SEPT/SEP const int nMonthLen = aSepShortened.getLength(); if (nMonthLen > nMatchLen) @@ -667,13 +708,13 @@ int ImpSvNumberInputScan::GetDayOfWeek( const OUString& rString, sal_Int32& nPos sal_Int16 nDays = pFormatter->GetCalendar()->getNumberOfDaysInWeek(); for ( sal_Int16 i = 0; i < nDays; i++ ) { - if ( StringContains( pUpperDayText[i], rString, nPos ) ) + if ( StringContainsWord( pUpperDayText[i], rString, nPos ) ) { // full names first nPos = nPos + pUpperDayText[i].getLength(); res = i + 1; break; // for } - if ( StringContains( pUpperAbbrevDayText[i], rString, nPos ) ) + if ( StringContainsWord( pUpperAbbrevDayText[i], rString, nPos ) ) { // abbreviated nPos = nPos + pUpperAbbrevDayText[i].getLength(); res = -(i + 1); // negative diff --git a/svl/source/numbers/zforfind.hxx b/svl/source/numbers/zforfind.hxx index 5738ce60c5f6..1f03fb9e15ff 100644 --- a/svl/source/numbers/zforfind.hxx +++ b/svl/source/numbers/zforfind.hxx @@ -210,6 +210,13 @@ private: void NumberStringDivision( const OUString& rString ); + /** Whether rString contains word (!) rWhat at nPos. + rWhat will not be matched if it is a substring of a word. + */ + bool StringContainsWord( const OUString& rWhat, + const OUString& rString, + sal_Int32 nPos ); + // optimized substring versions // Whether rString contains rWhat at nPos |