[Libreoffice-commits] core.git: Branch 'libreoffice-4-2' - svl/source

Eike Rathke erack at redhat.com
Sun May 18 09:52:28 PDT 2014


 svl/source/numbers/zforfind.cxx |   64 ++++++++++++++++++++++++++++++++++------
 svl/source/numbers/zforfind.hxx |    7 ++++
 2 files changed, 62 insertions(+), 9 deletions(-)

New commits:
commit 41b9ab0375f455f504c66b4870e817aba0f990d2
Author: Eike Rathke <erack at redhat.com>
Date:   Sat May 17 02:33:42 2014 +0200

    resolved fdo#41166 match month and day name word instead of substring
    
    (cherry picked from commit 8e71f81f47c20320c4de7a7aadb7d524f0d8ea76)
    (cherry picked from commit 3885b5d4b00ebb31adabc36c507abd642c03d0d4)
    
    Change-Id: I897dbcee47de574d91ba3e3b40a39a35b779fef8
    Reviewed-on: https://gerrit.libreoffice.org/9387
    Reviewed-by: Kohei Yoshida <libreoffice at kohei.us>
    Tested-by: Kohei Yoshida <libreoffice at kohei.us>

diff --git a/svl/source/numbers/zforfind.cxx b/svl/source/numbers/zforfind.cxx
index 840af0c..9c8bb1c 100644
--- a/svl/source/numbers/zforfind.cxx
+++ b/svl/source/numbers/zforfind.cxx
@@ -438,6 +438,52 @@ 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? */
+
+        // Check simple ASCII first before invoking i18n or anything else.
+        if (rtl::isAsciiAlphanumeric( rString[nPos] ))
+            return false;   // Alpha or numeric is not word gap.
+
+        sal_Int32 nIndex = nPos;
+        const 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);
+        using namespace ::com::sun::star::i18n;
+
+        if ((nType & (KCharacterType::UPPER | KCharacterType::LOWER | KCharacterType::DIGIT)) != 0)
+            return false;   // Alpha or numeric is not word gap.
+
+        if ((nType & (KCharacterType::LETTER)) != 0)
+            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,
@@ -575,7 +621,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)
@@ -584,7 +630,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)
@@ -593,7 +639,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)
@@ -602,7 +648,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)
@@ -611,7 +657,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)
@@ -620,7 +666,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)
@@ -630,7 +676,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)
@@ -665,13 +711,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 6e24040..002db24 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


More information about the Libreoffice-commits mailing list