summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEike Rathke <erack@redhat.com>2014-05-17 02:33:42 +0200
committerEike Rathke <erack@redhat.com>2014-05-17 03:11:22 +0200
commit8e71f81f47c20320c4de7a7aadb7d524f0d8ea76 (patch)
treedd642a1e16db07f857e3e40488b4e88b08fca268
parent8c8de51cc954aaae07f76732e6202398e33afeb7 (diff)
resolved fdo#41166 match month and day name word instead of substring
Change-Id: I897dbcee47de574d91ba3e3b40a39a35b779fef8
-rw-r--r--svl/source/numbers/zforfind.cxx59
-rw-r--r--svl/source/numbers/zforfind.hxx7
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