21 #include <osl/diagnose.h>
24 #include <document.hxx>
30 #include <compiler.hxx>
33 using ::formula::FormulaGrammar;
47 bool bSuccess =
false;
48 sal_Int32 nPointPos = rAreaStr.indexOf(
'.');
49 sal_Int32 nColonPos = rAreaStr.indexOf(
':');
50 OUString aStrArea( rAreaStr );
54 if ( nColonPos == -1 && nPointPos != -1 )
56 aStrArea += OUString::Concat(
":") + rAreaStr.subView( nPointPos+1 );
59 bSuccess =
ConvertDoubleRef( rDoc, aStrArea, nTab, startPos, endPos, rDetails );
63 startPos.
Col(), startPos.
Row(),
64 endPos.
Col(), endPos.
Row() );
76 sal_Int32 nColonPos = theAreaStr.indexOf(
':');
78 if ( nColonPos != -1 )
79 aPosStr = theAreaStr.copy( 0, nColonPos );
88 std::unique_ptr<
ScArea[]>* ppAreas,
89 sal_uInt16* pAreaCount,
93 OSL_ENSURE( pDoc,
"No document given!" );
111 OUString aTempAreaStr(rAreaStr);
113 if ( -1 == aTempAreaStr.indexOf(
':') )
115 aTempAreaStr +=
":" + rAreaStr;
118 sal_Int32 nColonPos = aTempAreaStr.indexOf(
':');
121 && -1 != aTempAreaStr.indexOf(
'.') )
125 OUString aStartPosStr = aTempAreaStr.copy( 0, nColonPos );
126 OUString aEndPosStr = aTempAreaStr.copy( nColonPos+1 );
142 if ( ppAreas && pAreaCount )
146 sal_uInt16 nTabCount =
static_cast<sal_uInt16
>(nEndTab-nStartTab+1);
147 ppAreas->reset(
new ScArea[nTabCount]);
151 aEndPos.
Col(), aEndPos.
Row() );
154 for ( i=0; i<nTabCount; i++ )
156 (*ppAreas)[i] = theArea;
157 (*ppAreas)[i].
nTab = nTab;
160 *pAreaCount = nTabCount;
172 OUString* pCompleteStr,
180 bool bIsAbsArea =
ConvertDoubleRef( rDoc, rAreaStr, nTab, startPos, endPos, rDetails );
194 *pCompleteStr +=
":";
195 *pCompleteStr += endPos.
GetRefString( rDoc, nTab, rDetails );
198 if ( pStartPos && pEndPos )
200 *pStartPos = startPos;
211 OUString* pCompleteStr,
225 *pPosTripel = thePos;
234 const OUString& rName,
241 bool bResult =
false;
251 OUString
aName(rName);
252 sal_Int32 nEndPos = aName.lastIndexOf(
')');
253 sal_Int32 nStartPos = aName.lastIndexOf(
" (");
254 SCTAB nTable = nCurTab;
255 if (nEndPos != -1 && nStartPos != -1)
257 OUString aSheetName = aName.copy(nStartPos+2, nEndPos-nStartPos-2);
258 if (rDoc.
GetTable(aSheetName, nTable))
260 aName = aName.copy(0, nStartPos);
282 nullptr, &aStartPos, &aEndPos, rDetails ) )
284 nTab = aStartPos.
Tab();
285 nColStart = aStartPos.
Col();
286 nRowStart = aStartPos.
Row();
287 nColEnd = aEndPos.
Col();
288 nRowEnd = aEndPos.
Row();
295 if (
IsAbsPos( aStrArea, rDoc, nTable,
296 nullptr, &aStartPos, rDetails ) )
298 nTab = aStartPos.
Tab();
299 nColStart = nColEnd = aStartPos.
Col();
300 nRowStart = nRowEnd = aStartPos.
Row();
312 pData->
GetArea(nTab, nColStart, nRowStart, nColEnd, nRowEnd);
318 OSL_FAIL(
"ScRangeUtil::MakeRangeFromName" );
323 rRange =
ScRange( nColStart, nRowStart, nTab, nColEnd, nRowEnd, nTab );
331 const OUString& rNewStr,
337 if( !rNewStr.isEmpty() )
339 if( !rString.isEmpty() )
340 rString += OUStringChar(cSeparator);
349 const OUString& rString,
354 sal_Int32
nLength = rString.getLength();
355 sal_Int32
nIndex = nOffset;
356 bool bQuoted =
false;
357 bool bExitLoop =
false;
359 while( !bExitLoop && (nIndex >= 0 && nIndex < nLength) )
362 bExitLoop = (cCode == cSearchChar) && !bQuoted;
363 bQuoted = (bQuoted != (cCode == cQuote));
367 return (nIndex < nLength) ? nIndex : -1;
371 const OUString& rString,
375 sal_Int32
nLength = rString.getLength();
376 sal_Int32
nIndex = nOffset;
377 bool bExitLoop =
false;
379 while( !bExitLoop && (nIndex >= 0 && nIndex < nLength) )
381 bExitLoop = (rString[ nIndex ] != cSearchChar);
385 return (nIndex < nLength) ? nIndex : -1;
390 const OUString& rString,
395 sal_Int32
nLength = rString.getLength();
396 if( nOffset == -1 || nOffset >= nLength )
403 sal_Int32 nTokenEnd =
IndexOf( rString, cSeparator, nOffset, cQuote );
406 rToken = rString.copy( nOffset, nTokenEnd - nOffset );
409 nOffset = (nNextBegin < 0) ? nLength : nNextBegin;
416 OUString aQuotedTab(rTabName);
418 rBuf.append(aQuotedTab);
425 sal_Int32 nOffset = 0;
426 while( nOffset >= 0 )
437 const OUString& rAddressStr,
439 FormulaGrammar::AddressConvention eConv,
451 if (eConv != eConvUI)
459 const OUString& rRangeStr,
461 FormulaGrammar::AddressConvention eConv,
472 OUString aUIString(sToken);
476 if ( aUIString[0] ==
'.' )
477 aUIString = aUIString.copy( 1 );
481 if (!bResult && eConv != eConvUI)
488 if ( aUIString[0] ==
'.' )
490 aUIString = aUIString.copy( 1 );
494 if ( nIndex < aUIString.getLength() - 1 &&
495 aUIString[ nIndex + 1 ] ==
'.' )
496 aUIString = aUIString.replaceAt( nIndex + 1, 1,
"" );
505 bResult = ((rRange.
aStart.
Parse( aUIString.copy(0, nIndex), rDocument, eConv)
508 ((rRange.
aEnd.
Parse( aUIString.copy(nIndex+1), rDocument, eConv)
512 if (!bResult && eConv != eConvUI)
514 bResult = ((rRange.
aStart.
Parse( aUIString.copy(0, nIndex), rDocument, eConvUI)
517 ((rRange.
aEnd.
Parse( aUIString.copy(nIndex+1), rDocument, eConvUI)
528 const OUString& rRangeListStr,
530 FormulaGrammar::AddressConvention eConv,
535 OSL_ENSURE( !rRangeListStr.isEmpty(),
"ScXMLConverter::GetRangeListFromString - empty string!" );
536 sal_Int32 nOffset = 0;
537 while( nOffset >= 0 )
541 GetRangeFromString( aRange, rRangeListStr, rDocument, eConv, nOffset, cSeparator, cQuote ) &&
547 else if (nOffset > -1)
555 const OUString& rRangeStr,
557 FormulaGrammar::AddressConvention eConv,
563 if(
GetRangeFromString( aScRange, rRangeStr, rDocument, eConv, nOffset, cSeparator ) && (nOffset >= 0) )
576 table::CellRangeAddress& rRange,
577 const OUString& rRangeStr,
579 FormulaGrammar::AddressConvention eConv,
585 if(
GetRangeFromString( aScRange, rRangeStr, rDocument, eConv, nOffset, cSeparator ) && (nOffset >= 0) )
597 FormulaGrammar::AddressConvention eConv,
602 if (pDocument && pDocument->
HasTable(rAddress.
Tab()))
604 OUString sAddress(rAddress.
Format(nFormatFlags, pDocument, eConv));
605 AssignString( rString, sAddress, bAppendStr, cSeparator );
613 FormulaGrammar::AddressConvention eConv,
622 OUString sStartAddress(aStartAddress.Format(nFormatFlags, pDocument, eConv));
623 OUString sEndAddress(aEndAddress.Format(nFormatFlags, pDocument, eConv));
625 rString, sStartAddress +
":" + sEndAddress, bAppendStr, cSeparator);
633 FormulaGrammar::AddressConvention eConv,
636 OUString sRangeListStr;
639 for(
size_t nIndex = 0, nCount = pRangeList->
size(); nIndex <
nCount; nIndex++ )
641 const ScRange & rRange = (*pRangeList)[nIndex];
645 rString = sRangeListStr;
652 FormulaGrammar::AddressConvention eConv,
658 GetStringFromRange( rString, aRange, pDocument, eConv, cSeparator, bAppendStr, nFormatFlags );
663 const table::CellAddress& rAddress,
665 FormulaGrammar::AddressConvention eConv,
669 ScAddress aScAddress( static_cast<SCCOL>(rAddress.Column), static_cast<SCROW>(rAddress.Row), rAddress.Sheet );
675 const table::CellRangeAddress& rRange,
677 FormulaGrammar::AddressConvention eConv,
682 ScRange aScRange( static_cast<SCCOL>(rRange.StartColumn), static_cast<SCROW>(rRange.StartRow), rRange.Sheet,
683 static_cast<SCCOL>(rRange.EndColumn), static_cast<SCROW>(rRange.EndRow), rRange.Sheet );
684 GetStringFromRange( rString, aScRange, pDocument, eConv, cSeparator, bAppendStr, nFormatFlags );
689 const uno::Sequence< table::CellRangeAddress >& rRangeSeq,
691 FormulaGrammar::AddressConvention eConv,
694 OUString sRangeListStr;
695 for(
const table::CellRangeAddress& rRange : rRangeSeq )
699 rString = sRangeListStr;
715 rBuf.append(*pFilePath);
738 OSL_ENSURE(rExtInfo2.
mbExternal,
"2nd address is not external!?");
739 OSL_ENSURE(rExtInfo1.
mnFileId == rExtInfo2.
mnFileId,
"File IDs do not match between 1st and 2nd addresses.");
748 rBuf.append(*pFilePath);
774 aRange.
aEnd = rCell2;
785 OUStringBuffer aRetStr;
786 sal_Int32 nOffset = 0;
796 sal_Int32 nSepPos =
IndexOf(aToken,
':', 0);
800 OUString aBeginCell = aToken.copy(0, nSepPos);
801 OUString aEndCell = aToken.copy(nSepPos+1);
803 if (aBeginCell.isEmpty() || aEndCell.isEmpty())
807 sal_Int32 nEndCellDotPos = aEndCell.indexOf(
'.');
808 if (nEndCellDotPos <= 0)
811 sal_Int32 nDotPos =
IndexOf(aBeginCell,
'.', 0);
812 OUStringBuffer
aBuf = aBeginCell.copy(0, nDotPos);
814 if (nEndCellDotPos == 0)
818 aBuf.append(aEndCell);
820 else if (nEndCellDotPos < 0)
824 aBuf.append(aEndCell);
826 aEndCell = aBuf.makeStringAndClear();
831 ScRefFlags nRet = aCell1.
Parse(aBeginCell, rDoc, FormulaGrammar::CONV_OOO, &aExtInfo1);
835 if (eConv == FormulaGrammar::CONV_OOO)
838 nRet = aCell1.
Parse(aBeginCell, rDoc, eConv, &aExtInfo1);
844 nRet = aCell2.
Parse(aEndCell, rDoc, FormulaGrammar::CONV_OOO, &aExtInfo2);
848 if (eConv == FormulaGrammar::CONV_OOO)
851 nRet = aCell2.
Parse(aEndCell, rDoc, eConv, &aExtInfo2);
866 aRetStr.append(cSepNew);
878 nRet = aCell.
Parse(aToken, rDoc, eConv, &aExtInfo);
888 aRetStr.append(cSepNew);
894 rString = aRetStr.makeStringAndClear();
905 sal_Int32 nIndex = -1;
906 if (eConv == FormulaGrammar::CONV_OOO || eConv == FormulaGrammar::CONV_A1_XL_A1)
908 if (nIndex < 0 && (eConv == FormulaGrammar::CONV_A1_XL_A1
909 || eConv == FormulaGrammar::CONV_XL_A1
910 || eConv == FormulaGrammar::CONV_XL_R1C1
911 || eConv == FormulaGrammar::CONV_XL_OOX))
919 OUString aTab( rString.copy( 0, nIndex));
922 if (!rDoc.
GetTable( aTab, nLocalTab))
926 if (!pLocalRangeName)
929 const OUString
aName( rString.copy( nIndex+1));
943 if (pGlobalRangeName)
955 nColStart( colStart ), nRowStart( rowStart ),
956 nColEnd ( colEnd ), nRowEnd ( rowEnd )
970 pRangeName(rDoc.GetRangeName()),
971 pDBCollection(rDoc.GetDBCollection()),
bool Next(OUString &rName, ScRange &rRange)
SC_DLLPUBLIC void Format(OStringBuffer &r, ScRefFlags nFlags, const ScDocument *pDocument=nullptr, const Details &rDetails=detailsOOOa1) const
static void UpdateInsertTab(ScAddress &rAddr, const sc::RefUpdateInsertTabContext &rCxt)
SC_DLLPUBLIC ScDBCollection * GetDBCollection() const
void IncTab(SCTAB nDelta=1)
static bool GetAddressFromString(ScAddress &rAddress, const OUString &rAddressStr, const ScDocument &rDocument, formula::FormulaGrammar::AddressConvention eConv, sal_Int32 &nOffset, sal_Unicode cSeparator= ' ', sal_Unicode cQuote= '\'')
String to Range core.
static void lcl_appendCellRangeAddress(OUStringBuffer &rBuf, const ScDocument &rDoc, const ScAddress &rCell1, const ScAddress &rCell2, const ScAddress::ExternalInfo &rExtInfo1, const ScAddress::ExternalInfo &rExtInfo2)
std::unique_ptr< ContentProperties > pData
static void GetStringFromRange(OUString &rString, const ScRange &rRange, const ScDocument *pDocument, formula::FormulaGrammar::AddressConvention eConv, sal_Unicode cSeparator= ' ', bool bAppendStr=false, ScRefFlags nFormatFlags=ScRefFlags::VALID|ScRefFlags::TAB_3D)
bool ConvertSingleRef(const ScDocument &rDoc, const OUString &rRefString, SCTAB nDefTab, ScRefAddress &rRefAddress, const ScAddress::Details &rDetails, ScAddress::ExternalInfo *pExtInfo)
void SetRelTab(bool bNewRelTab)
SC_DLLPUBLIC ScRangeName * GetRangeName(SCTAB nTab) const
const ContentProperties & rData
SC_DLLPUBLIC formula::FormulaGrammar::AddressConvention GetAddressConvention() const
static ScRangeData * GetRangeDataFromString(const OUString &rString, const SCTAB nTab, const ScDocument &rDoc, formula::FormulaGrammar::AddressConvention eConv)
String to RangeData core.
static SC_DLLPUBLIC sal_Int32 FindUnquoted(const OUString &rString, sal_Unicode cChar, sal_Int32 nStart=0)
Finds an unquoted instance of cChar in rString, starting at offset nStart.
static bool GetAreaFromString(ScArea &rArea, const OUString &rRangeStr, const ScDocument &rDocument, formula::FormulaGrammar::AddressConvention eConv, sal_Int32 &nOffset, sal_Unicode cSeparator= ' ')
static void GetStringFromAddress(OUString &rString, const ScAddress &rAddress, const ScDocument *pDocument, formula::FormulaGrammar::AddressConvention eConv, sal_Unicode cSeparator= ' ', bool bAppendStr=false, ScRefFlags nFormatFlags=ScRefFlags::VALID|ScRefFlags::TAB_3D)
Range to String core.
const OUString * getExternalFileName(sal_uInt16 nFileId, bool bForceOriginal=false)
It returns a pointer to the name of the URI associated with a given external file ID...
ScArea(SCTAB tab=0, SCCOL colStart=0, SCROW rowStart=0, SCCOL colEnd=0, SCROW rowEnd=0)
static SC_DLLPUBLIC void EraseQuotes(OUString &rString, sal_Unicode cQuote, bool bUnescapeEmbedded=true)
Erases the character cQuote from rString, if it exists at beginning AND end.
SC_DLLPUBLIC bool GetTable(const OUString &rName, SCTAB &rTab) const
SC_DLLPUBLIC ScExternalRefManager * GetExternalRefManager() const
void push_back(const ScRange &rRange)
bool operator==(const ScArea &r) const
SC_DLLPUBLIC bool HasTable(SCTAB nTab) const
SC_DLLPUBLIC const_iterator begin() const
void GetName(OUString &rName) const
static sal_Int32 GetTokenCount(const OUString &rString, sal_Unicode cSeparator= ' ')
static bool GetRangeFromString(ScRange &rRange, const OUString &rRangeStr, const ScDocument &rDocument, formula::FormulaGrammar::AddressConvention eConv, sal_Int32 &nOffset, sal_Unicode cSeparator= ' ', sal_Unicode cQuote= '\'')
static void GetStringFromArea(OUString &rString, const ScArea &rArea, const ScDocument *pDocument, formula::FormulaGrammar::AddressConvention eConv, sal_Unicode cSeparator, bool bAppendStr=false, ScRefFlags nFormatFlags=ScRefFlags::VALID|ScRefFlags::TAB_3D)
static void AssignString(OUString &rString, const OUString &rNewStr, bool bAppendStr, sal_Unicode cSeparator= ' ')
helper methods
SC_DLLPUBLIC ScRangeData * findByUpperName(const OUString &rName)
SC_DLLPUBLIC const_iterator end() const
static bool MakeArea(const OUString &rAreaStr, ScArea &rArea, const ScDocument &rDoc, SCTAB nTab, ScAddress::Details const &rDetails)
ScRangeName::const_iterator maRNPos
SC_DLLPUBLIC void GetSymbol(OUString &rSymbol, const formula::FormulaGrammar::Grammar eGrammar=formula::FormulaGrammar::GRAM_DEFAULT) const
SC_DLLPUBLIC OUString Format(const ScDocument &rDocument, ScRefFlags nFlags=ScRefFlags::ZERO, const ScAddress::Details &rDetails=ScAddress::detailsOOOa1, bool bFullAddressNotation=false) const
Returns string with formatted cell range from aStart to aEnd, according to provided address conventio...
static void GetStringFromRangeList(OUString &rString, const ScRangeList *pRangeList, const ScDocument *pDocument, formula::FormulaGrammar::AddressConvention eConv, sal_Unicode cSeparator= ' ')
static bool IsAbsArea(const OUString &rAreaStr, const ScDocument &rDoc, SCTAB nTab, OUString *pCompleteStr, ScRefAddress *pStartPos=nullptr, ScRefAddress *pEndPos=nullptr, ScAddress::Details const &rDetails=ScAddress::detailsOOOa1)
static bool IsAbsPos(const OUString &rPosStr, const ScDocument &rDoc, SCTAB nTab, OUString *pCompleteStr, ScRefAddress *pPosTripel=nullptr, ScAddress::Details const &rDetails=ScAddress::detailsOOOa1)
OUString uppercase(const OUString &rStr, sal_Int32 nPos, sal_Int32 nCount) const
static sal_Int32 IndexOfDifferent(const OUString &rString, sal_Unicode cSearchChar, sal_Int32 nOffset)
const OUString & GetName() const
static bool IsAbsTabArea(const OUString &rAreaStr, const ScDocument *pDoc, std::unique_ptr< ScArea[]> *ppAreas, sal_uInt16 *pAreaCount, bool bAcceptCellRef=false, ScAddress::Details const &rDetails=ScAddress::detailsOOOa1)
void GetArea(SCTAB &rTab, SCCOL &rCol1, SCROW &rRow1, SCCOL &rCol2, SCROW &rRow2) const
static bool MakeRangeFromName(const OUString &rName, const ScDocument &rDoc, SCTAB nCurTab, ScRange &rRange, RutlNameScope eScope=RUTL_NAMES, ScAddress::Details const &rDetails=ScAddress::detailsOOOa1)
ScDBCollection * pDBCollection
ScDBData * findByUpperName(const OUString &rName)
ScRangeName::const_iterator maRNEnd
Stores global named database ranges.
ScDBCollection::NamedDBs::const_iterator maDBPos
static void AppendTableName(OUStringBuffer &rBuf, const OUString &rTabName)
ScAreaNameIterator(const ScDocument &rDoc)
static void UpdateDeleteTab(ScAddress &rAddr, const sc::RefUpdateDeleteTabContext &rCxt)
ScDBCollection::NamedDBs::const_iterator maDBEnd
SC_DLLPUBLIC ScRefFlags Parse(const OUString &, const ScDocument &, const ScAddress::Details &rDetails=ScAddress::detailsOOOa1, ScAddress::ExternalInfo *pExtInfo=nullptr, const css::uno::Sequence< css::sheet::ExternalLinkInfo > *pExternalLinks=nullptr, const OUString *pErrRef=nullptr)
static SC_DLLPUBLIC const CharClass * getCharClassPtr()
SC_DLLPUBLIC bool IsValidReference(ScRange &rRef) const
static bool GetRangeListFromString(ScRangeList &rRangeList, const OUString &rRangeListStr, const ScDocument &rDocument, formula::FormulaGrammar::AddressConvention eConv, sal_Unicode cSeparator= ' ', sal_Unicode cQuote= '\'')
void SetRelCol(bool bNewRelCol)
bool ConvertDoubleRef(const ScDocument &rDoc, const OUString &rRefString, SCTAB nDefTab, ScRefAddress &rStartRefAddress, ScRefAddress &rEndRefAddress, const ScAddress::Details &rDetails, ScAddress::ExternalInfo *pExtInfo)
static void FillApiRange(css::table::CellRangeAddress &rApiRange, const ScRange &rScRange)
static sal_Int32 IndexOf(const OUString &rString, sal_Unicode cSearchChar, sal_Int32 nOffset, sal_Unicode cQuote= '\'')
SC_DLLPUBLIC ScRefFlags Parse(const OUString &, const ScDocument &, const Details &rDetails=detailsOOOa1, ExternalInfo *pExtInfo=nullptr, const css::uno::Sequence< css::sheet::ExternalLinkInfo > *pExternalLinks=nullptr, sal_Int32 *pSheetEndPos=nullptr, const OUString *pErrRef=nullptr)
OUString GetRefString(const ScDocument &rDocument, SCTAB nActTab, const ScAddress::Details &rDetails=ScAddress::detailsOOOa1) const
static void lcl_appendCellAddress(OUStringBuffer &rBuf, const ScDocument &rDoc, const ScAddress &rCell, const ScAddress::ExternalInfo &rExtInfo)
static void GetStringFromXMLRangeString(OUString &rString, const OUString &rXMLRange, const ScDocument &rDoc)
XML Range to Calc Range.
static void CheckTabQuotes(OUString &aTabName, const formula::FormulaGrammar::AddressConvention eConv=formula::FormulaGrammar::CONV_OOO)
all
static void GetTokenByOffset(OUString &rToken, const OUString &rString, sal_Int32 &nOffset, sal_Unicode cSeparator= ' ', sal_Unicode cQuote= '\'')
static void CutPosString(const OUString &theAreaStr, OUString &thePosStr)
void SetRelRow(bool bNewRelRow)