summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEike Rathke <erack@redhat.com>2016-02-23 23:18:47 +0100
committerEike Rathke <erack@redhat.com>2016-02-23 23:25:15 +0100
commit1f3357013ba1f319a3bcddf4c9a658c46e8c0390 (patch)
treef170f7bbe5759119e80ae09eafb0f9e8409dd58e
parent8af13dd19d589c9996848fab7f4967f9018751d6 (diff)
SearchFlags::WILD_MATCH_SELECTION, SearchOptions2::WildcardEscapeCharacter
At least '\' (search in Word) and '~' (search in Excel) should be supported as escape character. Being able to restrict a match to entire selection instead of substring speeds up the Calc match whole cell scenario. Change-Id: Ice242b9cd59009f172b724e03c2cc08feda4cd3c
-rw-r--r--i18npool/qa/cppunit/test_textsearch.cxx3
-rw-r--r--i18npool/source/search/textsearch.cxx7
-rw-r--r--include/unotools/textsearch.hxx11
-rw-r--r--offapi/com/sun/star/util/SearchFlags.idl14
-rw-r--r--offapi/com/sun/star/util/SearchOptions2.idl14
-rw-r--r--sc/inc/queryentry.hxx3
-rw-r--r--sc/source/core/data/dpcache.cxx2
-rw-r--r--sc/source/core/data/table3.cxx4
-rw-r--r--sc/source/core/tool/compare.cxx5
-rw-r--r--sc/source/core/tool/interpr1.cxx2
-rw-r--r--sc/source/core/tool/queryentry.cxx5
-rw-r--r--unotools/source/i18n/textsearch.cxx18
12 files changed, 71 insertions, 17 deletions
diff --git a/i18npool/qa/cppunit/test_textsearch.cxx b/i18npool/qa/cppunit/test_textsearch.cxx
index 1cb14f6a14a6..893bed5f1bb9 100644
--- a/i18npool/qa/cppunit/test_textsearch.cxx
+++ b/i18npool/qa/cppunit/test_textsearch.cxx
@@ -145,6 +145,9 @@ void TestTextSearch::testWildcardSearch()
util::SearchResult aRes;
aOptions.AlgorithmType2 = util::SearchAlgorithms2::WILDCARD ;
+ aOptions.WildcardEscapeCharacter = '~';
+ // aOptions.searchFlag = ::css::util::SearchFlags::WILD_MATCH_SELECTION;
+ // is not set, so substring match is allowed.
aOptions.transliterateFlags = ::css::i18n::TransliterationModules::TransliterationModules_IGNORE_CASE;
aText = "abAca";
diff --git a/i18npool/source/search/textsearch.cxx b/i18npool/source/search/textsearch.cxx
index 9d000021c0fd..dab32d11b1a5 100644
--- a/i18npool/source/search/textsearch.cxx
+++ b/i18npool/source/search/textsearch.cxx
@@ -113,8 +113,6 @@ TextSearch::TextSearch(const Reference < XComponentContext > & rxContext)
, pJumpTable2( nullptr )
, pRegexMatcher( nullptr )
, pWLD( nullptr )
- , mcWildcardEscapeChar('~') /* TODO: make this option available through API */
- , mbWildcardAllowSubstring(true) /* TODO: make this option available through API */
{
SearchOptions2 aOpt;
aOpt.AlgorithmType2 = SearchAlgorithms2::ABSOLUTE;
@@ -245,6 +243,8 @@ void TextSearch::setOptions2( const SearchOptions2& rOptions ) throw( RuntimeExc
break;
case SearchAlgorithms2::WILDCARD:
+ mcWildcardEscapeChar = static_cast<sal_uInt32>(aSrchPara.WildcardEscapeCharacter);
+ mbWildcardAllowSubstring = ((aSrchPara.searchFlag & SearchFlags::WILD_MATCH_SELECTION) == 0);
fnForward = &TextSearch::WildcardSrchFrwrd;
fnBackward = &TextSearch::WildcardSrchBkwrd;
break;
@@ -289,7 +289,8 @@ void TextSearch::setOptions( const SearchOptions& rOptions ) throw( RuntimeExcep
rOptions.deletedChars,
rOptions.insertedChars,
rOptions.transliterateFlags,
- nAlgorithmType2
+ nAlgorithmType2,
+ 0 // no wildcard search, no escape character..
);
setOptions2( aOptions2);
}
diff --git a/include/unotools/textsearch.hxx b/include/unotools/textsearch.hxx
index 1847aab2baec..3a24aac648df 100644
--- a/include/unotools/textsearch.hxx
+++ b/include/unotools/textsearch.hxx
@@ -96,9 +96,12 @@ private:
SearchType m_eSrchType; // search normal/regular/LevDist
+ sal_uInt32 m_cWildEscChar; // wildcard escape character
+
bool m_bWordOnly : 1; // used by normal search
bool m_bSrchInSel : 1; // search only in the selection
bool m_bCaseSense : 1;
+ bool m_bWildMatchSel : 1; // wildcard pattern must match entire selection
// values for the "weight Levenshtein-Distance"
bool bLEV_Relaxed : 1;
@@ -114,7 +117,9 @@ public:
SearchType eSrchType = SearchParam::SRCH_NORMAL,
bool bCaseSensitive = true,
bool bWordOnly = false,
- bool bSearchInSelection = false );
+ bool bSearchInSelection = false,
+ sal_uInt32 cWildEscChar = '\\',
+ bool bWildMatchSel = false );
SearchParam( const SearchParam& );
@@ -127,6 +132,10 @@ public:
bool IsCaseSensitive() const { return m_bCaseSense; }
bool IsSrchInSelection() const { return m_bSrchInSel; }
bool IsSrchWordOnly() const { return m_bWordOnly; }
+ bool IsWildMatchSel() const { return m_bWildMatchSel; }
+
+ // signed return for API use
+ sal_Int32 GetWildEscChar() const { return static_cast<sal_Int32>(m_cWildEscChar); }
bool IsSrchRelaxed() const { return bLEV_Relaxed; }
int GetLEVOther() const { return nLEV_OtherX; }
diff --git a/offapi/com/sun/star/util/SearchFlags.idl b/offapi/com/sun/star/util/SearchFlags.idl
index f0c03e277a21..964f836962c1 100644
--- a/offapi/com/sun/star/util/SearchFlags.idl
+++ b/offapi/com/sun/star/util/SearchFlags.idl
@@ -121,6 +121,20 @@ published constants SearchFlags
positives, but meets user expectation better. </p>
*/
const long LEV_RELAXED = 0x00010000;
+
+ /** Flag for wildcards search if entire selection must match the
+ pattern.
+
+ <p> If com::sun::star::util::SearchOptions2::AlgorithmType2 is
+ com::sun::star::util::SearchAlgorithms2::WILDCARD specifies
+ whether a wildcard pattern must match the entire selected range
+ of the string from start position to end position or a substring
+ match is allowed. </p>
+
+ <p> If set, the entire selection must match. If not set, a
+ substring match is allowed. </p>
+ */
+ const long WILD_MATCH_SELECTION = 0x00100000;
};
}; }; }; };
diff --git a/offapi/com/sun/star/util/SearchOptions2.idl b/offapi/com/sun/star/util/SearchOptions2.idl
index a7f16e59b109..5dcd47e9fa41 100644
--- a/offapi/com/sun/star/util/SearchOptions2.idl
+++ b/offapi/com/sun/star/util/SearchOptions2.idl
@@ -29,6 +29,20 @@ published struct SearchOptions2 : com::sun::star::util::SearchOptions {
SearchAlgorithms SearchOptions::algorithmType enum field.
*/
short AlgorithmType2;
+
+ /** The escape character to be used with a
+ com::sun::star::util::SearchAlgorithms2::WILDCARD search.
+
+ <p> A Unicode character, if not 0 escapes the special meaning of
+ a question mark, asterisk or escape character that follows
+ immediately after the escape character. If 0 defines no escape
+ character is used. </p>
+
+ <p> Common values are '\' (U+005C REVERSE SOLIDUS) aka backslash
+ in text processing context, or '~' (U+007E TILDE) in spreadsheet
+ processing context. </p>
+ */
+ long WildcardEscapeCharacter;
};
}; }; }; };
diff --git a/sc/inc/queryentry.hxx b/sc/inc/queryentry.hxx
index 1669f6cc3e75..ab1a36fc5d9e 100644
--- a/sc/inc/queryentry.hxx
+++ b/sc/inc/queryentry.hxx
@@ -59,7 +59,8 @@ struct SC_DLLPUBLIC ScQueryEntry
~ScQueryEntry();
/// creates pSearchParam and pSearchText if necessary
- utl::TextSearch* GetSearchTextPtr( utl::SearchParam::SearchType eSearchType, bool bCaseSens ) const;
+ utl::TextSearch* GetSearchTextPtr( utl::SearchParam::SearchType eSearchType, bool bCaseSens,
+ bool bWildMatchSel ) const;
QueryItemsType& GetQueryItems() { return maQueryItems;}
const QueryItemsType& GetQueryItems() const { return maQueryItems;}
diff --git a/sc/source/core/data/dpcache.cxx b/sc/source/core/data/dpcache.cxx
index b60e9c778cbe..9fdf5a2dfbad 100644
--- a/sc/source/core/data/dpcache.cxx
+++ b/sc/source/core/data/dpcache.cxx
@@ -537,7 +537,7 @@ bool ScDPCache::ValidQuery( SCROW nRow, const ScQueryParam &rParam) const
sal_Int32 nStart = 0;
sal_Int32 nEnd = aCellStr.getLength();
- bool bMatch = (bool) rEntry.GetSearchTextPtr( rParam.eSearchType, rParam.bCaseSens )
+ bool bMatch = (bool) rEntry.GetSearchTextPtr( rParam.eSearchType, rParam.bCaseSens, bMatchWholeCell )
->SearchForward( aCellStr, &nStart, &nEnd );
// from 614 on, nEnd is behind the found text
if (bMatch && bMatchWholeCell
diff --git a/sc/source/core/data/table3.cxx b/sc/source/core/data/table3.cxx
index b3974f5a0a7e..e1842c883704 100644
--- a/sc/source/core/data/table3.cxx
+++ b/sc/source/core/data/table3.cxx
@@ -2423,12 +2423,12 @@ public:
{
nEnd = 0;
nStart = aCellStr.getLength();
- bMatch = rEntry.GetSearchTextPtr( mrParam.eSearchType, mrParam.bCaseSens )
+ bMatch = rEntry.GetSearchTextPtr( mrParam.eSearchType, mrParam.bCaseSens, bMatchWholeCell )
->SearchBackward(aCellStr.getString(), &nStart, &nEnd);
}
else
{
- bMatch = rEntry.GetSearchTextPtr( mrParam.eSearchType, mrParam.bCaseSens )
+ bMatch = rEntry.GetSearchTextPtr( mrParam.eSearchType, mrParam.bCaseSens, bMatchWholeCell )
->SearchForward(aCellStr.getString(), &nStart, &nEnd);
}
if ( bMatch && bMatchWholeCell
diff --git a/sc/source/core/tool/compare.cxx b/sc/source/core/tool/compare.cxx
index cf5c0ff69903..a1dd6026ce17 100644
--- a/sc/source/core/tool/compare.cxx
+++ b/sc/source/core/tool/compare.cxx
@@ -140,9 +140,8 @@ double CompareFunc( const Compare& rComp, CompareOptions* pOptions )
{
sal_Int32 nStart = 0;
sal_Int32 nStop = rCell1.maStr.getLength();
- bool bMatch = rEntry.GetSearchTextPtr( pOptions->eSearchType,
- !rComp.mbIgnoreCase)->SearchForward(
- rCell1.maStr.getString(), &nStart, &nStop);
+ bool bMatch = rEntry.GetSearchTextPtr( pOptions->eSearchType, !rComp.mbIgnoreCase,
+ pOptions->bMatchWholeCell)->SearchForward( rCell1.maStr.getString(), &nStart, &nStop);
if (bMatch && pOptions->bMatchWholeCell && (nStart != 0 || nStop != rCell1.maStr.getLength()))
bMatch = false; // RegEx must match entire string.
fRes = (bMatch ? 0 : 1);
diff --git a/sc/source/core/tool/interpr1.cxx b/sc/source/core/tool/interpr1.cxx
index a35a9762eb67..8d2636f0ccb9 100644
--- a/sc/source/core/tool/interpr1.cxx
+++ b/sc/source/core/tool/interpr1.cxx
@@ -8148,7 +8148,7 @@ void ScInterpreter::ScSearch()
else
{
utl::SearchParam::SearchType eSearchType = DetectSearchType( SearchStr, pDok );
- utl::SearchParam sPar(SearchStr, eSearchType, false, false, false);
+ utl::SearchParam sPar(SearchStr, eSearchType, false, false, false, '~', false);
utl::TextSearch sT( sPar, *ScGlobal::pCharClass );
bool bBool = sT.SearchForward(sStr, &nPos, &nEndPos);
if (!bBool)
diff --git a/sc/source/core/tool/queryentry.cxx b/sc/source/core/tool/queryentry.cxx
index 17529c52a4b8..e628baaffb47 100644
--- a/sc/source/core/tool/queryentry.cxx
+++ b/sc/source/core/tool/queryentry.cxx
@@ -164,13 +164,14 @@ bool ScQueryEntry::operator==( const ScQueryEntry& r ) const
// do not compare pSearchParam and pSearchText!
}
-utl::TextSearch* ScQueryEntry::GetSearchTextPtr( utl::SearchParam::SearchType eSearchType, bool bCaseSens ) const
+utl::TextSearch* ScQueryEntry::GetSearchTextPtr( utl::SearchParam::SearchType eSearchType, bool bCaseSens,
+ bool bWildMatchSel ) const
{
if ( !pSearchParam )
{
OUString aStr = maQueryItems[0].maString.getString();
pSearchParam = new utl::SearchParam(
- aStr, eSearchType, bCaseSens, false, false);
+ aStr, eSearchType, bCaseSens, false, false, '~', bWildMatchSel);
pSearchText = new utl::TextSearch( *pSearchParam, *ScGlobal::pCharClass );
}
return pSearchText;
diff --git a/unotools/source/i18n/textsearch.cxx b/unotools/source/i18n/textsearch.cxx
index ed6a58fa26a1..7e0d5a4ae3a8 100644
--- a/unotools/source/i18n/textsearch.cxx
+++ b/unotools/source/i18n/textsearch.cxx
@@ -41,14 +41,19 @@ SearchParam::SearchParam( const OUString &rText,
SearchType eType,
bool bCaseSensitive,
bool bWrdOnly,
- bool bSearchInSel )
+ bool bSearchInSel,
+ sal_uInt32 cWildEscChar,
+ bool bWildMatchSel )
{
sSrchStr = rText;
m_eSrchType = eType;
+ m_cWildEscChar = cWildEscChar;
+
m_bWordOnly = bWrdOnly;
m_bSrchInSel = bSearchInSel;
m_bCaseSense = bCaseSensitive;
+ m_bWildMatchSel = bWildMatchSel;
nTransliterationFlags = 0;
@@ -65,9 +70,12 @@ SearchParam::SearchParam( const SearchParam& rParam )
sReplaceStr = rParam.sReplaceStr;
m_eSrchType = rParam.m_eSrchType;
+ m_cWildEscChar = rParam.m_cWildEscChar;
+
m_bWordOnly = rParam.m_bWordOnly;
m_bSrchInSel = rParam.m_bSrchInSel;
m_bCaseSense = rParam.m_bCaseSense;
+ m_bWildMatchSel = rParam.m_bWildMatchSel;
bLEV_Relaxed = rParam.bLEV_Relaxed;
nLEV_OtherX = rParam.nLEV_OtherX;
@@ -83,6 +91,7 @@ static bool lcl_Equals( const SearchOptions2& rSO1, const SearchOptions2& rSO2 )
{
return
rSO1.AlgorithmType2 == rSO2.AlgorithmType2 &&
+ rSO1.WildcardEscapeCharacter == rSO2.WildcardEscapeCharacter &&
rSO1.algorithmType == rSO2.algorithmType &&
rSO1.searchFlag == rSO2.searchFlag &&
rSO1.searchString.equals(rSO2.searchString) &&
@@ -175,7 +184,8 @@ css::util::SearchOptions2 TextSearch::UpgradeToSearchOptions2( const css::util::
rOptions.deletedChars,
rOptions.insertedChars,
rOptions.transliterateFlags,
- nAlgorithmType2
+ nAlgorithmType2,
+ 0 // no wildcard search, no escape character..
);
return aOptions2;
}
@@ -190,6 +200,9 @@ void TextSearch::Init( const SearchParam & rParam,
{
case SearchParam::SRCH_WILDCARD:
aSOpt.AlgorithmType2 = SearchAlgorithms2::WILDCARD;
+ aSOpt.WildcardEscapeCharacter = rParam.GetWildEscChar();
+ if (rParam.IsWildMatchSel())
+ aSOpt.searchFlag |= SearchFlags::WILD_MATCH_SELECTION;
aSOpt.algorithmType = static_cast<SearchAlgorithms>(-1); // no old enum for that
break;
@@ -237,7 +250,6 @@ void TextSearch::Init( const SearchParam & rParam,
void TextSearch::SetLocale( const css::util::SearchOptions2& rOptions,
const css::lang::Locale& rLocale )
{
- // convert SearchParam to the UNO SearchOptions2
SearchOptions2 aSOpt( rOptions );
aSOpt.Locale = rLocale;