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,
240 bool bUseDetailsPos )
242 bool bResult =
false;
254 OUString
aName(rName);
255 SCTAB nTable = nCurTab;
261 const sal_Int32 nEndPos = aName.getLength() - 1;
262 if (rName[nEndPos] ==
')')
264 const sal_Int32 nStartPos = aName.indexOf(
" (");
267 OUString aSheetName = aName.copy(nStartPos+2, nEndPos-nStartPos-2);
268 if (rDoc.
GetTable(aSheetName, nTable))
270 aName = aName.copy(0, nStartPos);
308 nullptr, &aStartPos, &aEndPos, rDetails ) )
310 nTab = aStartPos.
Tab();
311 nColStart = aStartPos.
Col();
312 nRowStart = aStartPos.
Row();
313 nColEnd = aEndPos.
Col();
314 nRowEnd = aEndPos.
Row();
321 if (
IsAbsPos( aStrArea, rDoc, nTable,
322 nullptr, &aStartPos, rDetails ) )
324 nTab = aStartPos.
Tab();
325 nColStart = nColEnd = aStartPos.
Col();
326 nRowStart = nRowEnd = aStartPos.
Row();
338 pData->
GetArea(nTab, nColStart, nRowStart, nColEnd, nRowEnd);
344 OSL_FAIL(
"ScRangeUtil::MakeRangeFromName" );
349 rRange =
ScRange( nColStart, nRowStart, nTab, nColEnd, nRowEnd, nTab );
357 const OUString& rNewStr,
363 if( !rNewStr.isEmpty() )
365 if( !rString.isEmpty() )
366 rString += OUStringChar(cSeparator);
375 const OUString& rString,
380 sal_Int32
nLength = rString.getLength();
381 sal_Int32
nIndex = nOffset;
382 bool bQuoted =
false;
383 bool bExitLoop =
false;
385 while( !bExitLoop && (nIndex >= 0 && nIndex < nLength) )
388 bExitLoop = (cCode == cSearchChar) && !bQuoted;
389 bQuoted = (bQuoted != (cCode == cQuote));
393 return (nIndex < nLength) ? nIndex : -1;
397 const OUString& rString,
401 sal_Int32
nLength = rString.getLength();
402 sal_Int32
nIndex = nOffset;
403 bool bExitLoop =
false;
405 while( !bExitLoop && (nIndex >= 0 && nIndex < nLength) )
407 bExitLoop = (rString[ nIndex ] != cSearchChar);
411 return (nIndex < nLength) ? nIndex : -1;
416 const OUString& rString,
421 sal_Int32
nLength = rString.getLength();
422 if( nOffset == -1 || nOffset >= nLength )
429 sal_Int32 nTokenEnd =
IndexOf( rString, cSeparator, nOffset, cQuote );
432 rToken = rString.copy( nOffset, nTokenEnd - nOffset );
435 nOffset = (nNextBegin < 0) ? nLength : nNextBegin;
442 OUString aQuotedTab(rTabName);
444 rBuf.append(aQuotedTab);
451 sal_Int32 nOffset = 0;
452 while( nOffset >= 0 )
463 const OUString& rAddressStr,
465 FormulaGrammar::AddressConvention eConv,
477 if (eConv != eConvUI)
485 const OUString& rRangeStr,
487 FormulaGrammar::AddressConvention eConv,
498 OUString aUIString(sToken);
502 if ( aUIString[0] ==
'.' )
503 aUIString = aUIString.copy( 1 );
507 if (!bResult && eConv != eConvUI)
514 if ( aUIString[0] ==
'.' )
516 aUIString = aUIString.copy( 1 );
520 if ( nIndex < aUIString.getLength() - 1 &&
521 aUIString[ nIndex + 1 ] ==
'.' )
522 aUIString = aUIString.replaceAt( nIndex + 1, 1, u
"" );
531 bResult = ((rRange.
aStart.
Parse( aUIString.copy(0, nIndex), rDocument, eConv)
534 ((rRange.
aEnd.
Parse( aUIString.copy(nIndex+1), rDocument, eConv)
538 if (!bResult && eConv != eConvUI)
540 bResult = ((rRange.
aStart.
Parse( aUIString.copy(0, nIndex), rDocument, eConvUI)
543 ((rRange.
aEnd.
Parse( aUIString.copy(nIndex+1), rDocument, eConvUI)
554 const OUString& rRangeListStr,
556 FormulaGrammar::AddressConvention eConv,
561 OSL_ENSURE( !rRangeListStr.isEmpty(),
"ScXMLConverter::GetRangeListFromString - empty string!" );
562 sal_Int32 nOffset = 0;
563 while( nOffset >= 0 )
567 GetRangeFromString( aRange, rRangeListStr, rDocument, eConv, nOffset, cSeparator, cQuote ) &&
573 else if (nOffset > -1)
581 const OUString& rRangeStr,
583 FormulaGrammar::AddressConvention eConv,
589 if(
GetRangeFromString( aScRange, rRangeStr, rDocument, eConv, nOffset, cSeparator ) && (nOffset >= 0) )
602 table::CellRangeAddress& rRange,
603 const OUString& rRangeStr,
605 FormulaGrammar::AddressConvention eConv,
611 if(
GetRangeFromString( aScRange, rRangeStr, rDocument, eConv, nOffset, cSeparator ) && (nOffset >= 0) )
623 FormulaGrammar::AddressConvention eConv,
628 if (pDocument && pDocument->
HasTable(rAddress.
Tab()))
630 OUString sAddress(rAddress.
Format(nFormatFlags, pDocument, eConv));
631 AssignString( rString, sAddress, bAppendStr, cSeparator );
639 FormulaGrammar::AddressConvention eConv,
648 OUString sStartAddress(aStartAddress.Format(nFormatFlags, pDocument, eConv));
649 OUString sEndAddress(aEndAddress.Format(nFormatFlags, pDocument, eConv));
651 rString, sStartAddress +
":" + sEndAddress, bAppendStr, cSeparator);
659 FormulaGrammar::AddressConvention eConv,
662 OUString sRangeListStr;
665 for(
size_t nIndex = 0, nCount = pRangeList->
size(); nIndex <
nCount; nIndex++ )
667 const ScRange & rRange = (*pRangeList)[nIndex];
671 rString = sRangeListStr;
678 FormulaGrammar::AddressConvention eConv,
684 GetStringFromRange( rString, aRange, pDocument, eConv, cSeparator, bAppendStr, nFormatFlags );
689 const table::CellAddress& rAddress,
691 FormulaGrammar::AddressConvention eConv,
695 ScAddress aScAddress( static_cast<SCCOL>(rAddress.Column), static_cast<SCROW>(rAddress.Row), rAddress.Sheet );
701 const table::CellRangeAddress& rRange,
703 FormulaGrammar::AddressConvention eConv,
708 ScRange aScRange( static_cast<SCCOL>(rRange.StartColumn), static_cast<SCROW>(rRange.StartRow), rRange.Sheet,
709 static_cast<SCCOL>(rRange.EndColumn), static_cast<SCROW>(rRange.EndRow), rRange.Sheet );
710 GetStringFromRange( rString, aScRange, pDocument, eConv, cSeparator, bAppendStr, nFormatFlags );
715 const uno::Sequence< table::CellRangeAddress >& rRangeSeq,
717 FormulaGrammar::AddressConvention eConv,
720 OUString sRangeListStr;
721 for(
const table::CellRangeAddress& rRange : rRangeSeq )
725 rString = sRangeListStr;
741 rBuf.append(*pFilePath);
764 OSL_ENSURE(rExtInfo2.
mbExternal,
"2nd address is not external!?");
765 OSL_ENSURE(rExtInfo1.
mnFileId == rExtInfo2.
mnFileId,
"File IDs do not match between 1st and 2nd addresses.");
774 rBuf.append(*pFilePath);
800 aRange.
aEnd = rCell2;
811 OUStringBuffer aRetStr;
812 sal_Int32 nOffset = 0;
822 sal_Int32 nSepPos =
IndexOf(aToken,
':', 0);
826 OUString aBeginCell = aToken.copy(0, nSepPos);
827 OUString aEndCell = aToken.copy(nSepPos+1);
829 if (aBeginCell.isEmpty() || aEndCell.isEmpty())
833 sal_Int32 nEndCellDotPos = aEndCell.indexOf(
'.');
834 if (nEndCellDotPos <= 0)
837 sal_Int32 nDotPos =
IndexOf(aBeginCell,
'.', 0);
838 OUStringBuffer
aBuf(aBeginCell.subView(0, nDotPos));
840 if (nEndCellDotPos == 0)
844 aBuf.append(aEndCell);
846 else if (nEndCellDotPos < 0)
850 aBuf.append(aEndCell);
852 aEndCell =
aBuf.makeStringAndClear();
857 ScRefFlags nRet = aCell1.
Parse(aBeginCell, rDoc, FormulaGrammar::CONV_OOO, &aExtInfo1);
861 if (eConv == FormulaGrammar::CONV_OOO)
864 nRet = aCell1.
Parse(aBeginCell, rDoc, eConv, &aExtInfo1);
870 nRet = aCell2.
Parse(aEndCell, rDoc, FormulaGrammar::CONV_OOO, &aExtInfo2);
874 if (eConv == FormulaGrammar::CONV_OOO)
877 nRet = aCell2.
Parse(aEndCell, rDoc, eConv, &aExtInfo2);
892 aRetStr.append(cSepNew);
904 nRet = aCell.
Parse(aToken, rDoc, eConv, &aExtInfo);
914 aRetStr.append(cSepNew);
920 rString = aRetStr.makeStringAndClear();
931 sal_Int32 nIndex = -1;
932 if (eConv == FormulaGrammar::CONV_OOO || eConv == FormulaGrammar::CONV_A1_XL_A1)
934 if (nIndex < 0 && (eConv == FormulaGrammar::CONV_A1_XL_A1
935 || eConv == FormulaGrammar::CONV_XL_A1
936 || eConv == FormulaGrammar::CONV_XL_R1C1
937 || eConv == FormulaGrammar::CONV_XL_OOX))
945 OUString aTab( rString.copy( 0, nIndex));
948 if (!rDoc.
GetTable( aTab, nLocalTab))
952 if (!pLocalRangeName)
955 const OUString
aName( rString.copy( nIndex+1));
969 if (pGlobalRangeName)
981 nColStart( colStart ), nRowStart( rowStart ),
982 nColEnd ( colEnd ), nRowEnd ( rowEnd )
996 pRangeName(rDoc.GetRangeName()),
997 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 MakeRangeFromName(const OUString &rName, const ScDocument &rDoc, SCTAB nCurTab, ScRange &rRange, RutlNameScope eScope=RUTL_NAMES, ScAddress::Details const &rDetails=ScAddress::detailsOOOa1, bool bUseDetailsPos=false)
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)
SC_DLLPUBLIC OUString GetSymbol(const formula::FormulaGrammar::Grammar eGrammar=formula::FormulaGrammar::GRAM_DEFAULT) const
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)
std::unique_ptr< sal_Int32[]> pData
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::Grammar GetGrammar() const
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...
SC_DLLPUBLIC const_iterator end() const
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.
formula::FormulaGrammar::AddressConvention eConv
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
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)
static bool MakeArea(const OUString &rAreaStr, ScArea &rArea, const ScDocument &rDoc, SCTAB nTab, ScAddress::Details const &rDetails)
ScRangeName::const_iterator maRNPos
static SC_DLLPUBLIC const CharClass & getCharClass()
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
ScDBCollection * pDBCollection
ScDBData * findByUpperName(const OUString &rName)
SC_DLLPUBLIC const_iterator begin() const
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
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)
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)