Related: tdf#159343 Handle TableRef separator in brackets for Function Wizard

... not breaking to next argument of a function parameter.

Change-Id: Ibc7a64c4ea64c415098a213f0ff3d96b8a9dd73c
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/171085
Tested-by: Jenkins
Reviewed-by: Eike Rathke <erack@redhat.com>
This commit is contained in:
Eike Rathke
2024-07-26 22:43:47 +02:00
parent ed2d890d69
commit 0b683547bb
5 changed files with 63 additions and 3 deletions

View File

@ -68,6 +68,8 @@ FormulaHelper::FormulaHelper(const IFunctionManager* _pFunctionManager)
,sep(_pFunctionManager->getSingleToken(IFunctionManager::eSep))
,arrayOpen(_pFunctionManager->getSingleToken(IFunctionManager::eArrayOpen))
,arrayClose(_pFunctionManager->getSingleToken(IFunctionManager::eArrayClose))
,tableRefOpen(_pFunctionManager->getSingleToken(IFunctionManager::eTableRefOpen))
,tableRefClose(_pFunctionManager->getSingleToken(IFunctionManager::eTableRefClose))
{
}
@ -306,14 +308,37 @@ sal_Int32 FormulaHelper::GetFunctionEnd( std::u16string_view rStr, sal_Int32 nS
return nStart;
short nParCount = 0;
short nTableRefCount = 0;
bool bInArray = false;
bool bFound = false;
bool bTickEscaped = false;
while ( !bFound && (nStart < nStrLen) )
{
sal_Unicode c = rStr[nStart];
if ( c == '"' )
if (nTableRefCount > 0)
{
// Column names may contain anything, skip. Also skip separator
// between item specifier and column name or whatever in a
// TableRef [[...]; [...]]
// But keep track of apostrophe ' tick escaped brackets.
if (c == '\'')
bTickEscaped = !bTickEscaped;
else
{
if (c == tableRefOpen && !bTickEscaped)
++nTableRefCount;
else if (c == tableRefClose && !bTickEscaped)
--nTableRefCount;
bTickEscaped = false;
}
}
else if (c == tableRefOpen)
{
++nTableRefCount;
}
else if ( c == '"' )
{
nStart++;
while ( (nStart < nStrLen) && rStr[nStart] != '"' )
@ -365,14 +390,37 @@ sal_Int32 FormulaHelper::GetArgStart( std::u16string_view rStr, sal_Int32 nStart
return nStart;
short nParCount = 0;
short nTableRefCount = 0;
bool bInArray = false;
bool bFound = false;
bool bTickEscaped = false;
while ( !bFound && (nStart < nStrLen) )
{
sal_Unicode c = rStr[nStart];
if ( c == '"' )
if (nTableRefCount > 0)
{
// Column names may contain anything, skip. Also skip separator
// between item specifier and column name or whatever in a
// TableRef [[...]; [...]]
// But keep track of apostrophe ' tick escaped brackets.
if (c == '\'')
bTickEscaped = !bTickEscaped;
else
{
if (c == tableRefOpen && !bTickEscaped)
++nTableRefCount;
else if (c == tableRefClose && !bTickEscaped)
--nTableRefCount;
bTickEscaped = false;
}
}
else if (c == tableRefOpen)
{
++nTableRefCount;
}
else if ( c == '"' )
{
nStart++;
while ( (nStart < nStrLen) && rStr[nStart] != '"' )

View File

@ -53,7 +53,9 @@ namespace formula
eClose,
eSep,
eArrayOpen,
eArrayClose
eArrayClose,
eTableRefOpen,
eTableRefClose
};
virtual sal_uInt32 getCount() const = 0;
virtual const IFunctionCategory* getCategory(sal_uInt32 nPos) const = 0;

View File

@ -44,6 +44,8 @@ namespace formula
const sal_Unicode sep;
const sal_Unicode arrayOpen;
const sal_Unicode arrayClose;
const sal_Unicode tableRefOpen;
const sal_Unicode tableRefClose;
public:
FormulaHelper(const IFunctionManager* _pFunctionManager);

View File

@ -51,6 +51,10 @@ sal_Unicode FunctionManager::getSingleToken(const formula::IFunctionManager::ETo
return '{';
case eArrayClose:
return '}';
case eTableRefOpen:
return '[';
case eTableRefClose:
return ']';
}
return 0;
}

View File

@ -1178,6 +1178,10 @@ sal_Unicode ScFunctionMgr::getSingleToken(const formula::IFunctionManager::EToke
return ScCompiler::GetNativeSymbolChar(ocArrayOpen);
case eArrayClose:
return ScCompiler::GetNativeSymbolChar(ocArrayClose);
case eTableRefOpen:
return ScCompiler::GetNativeSymbolChar(ocTableRefOpen);
case eTableRefClose:
return ScCompiler::GetNativeSymbolChar(ocTableRefClose);
}
return 0;
}