Kaydet (Commit) 1f335701 authored tarafından Eike Rathke's avatar Eike Rathke

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
üst 8af13dd1
......@@ -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";
......
......@@ -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);
}
......
......@@ -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; }
......
......@@ -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;
};
}; }; }; };
......
......@@ -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;
};
}; }; }; };
......
......@@ -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;}
......
......@@ -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
......
......@@ -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
......
......@@ -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);
......
......@@ -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)
......
......@@ -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;
......
......@@ -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;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment