diff options
Diffstat (limited to 'sc/source/core/tool/address.cxx')
-rw-r--r-- | sc/source/core/tool/address.cxx | 91 |
1 files changed, 64 insertions, 27 deletions
diff --git a/sc/source/core/tool/address.cxx b/sc/source/core/tool/address.cxx index ef2e492a55ee..c016102f2649 100644 --- a/sc/source/core/tool/address.cxx +++ b/sc/source/core/tool/address.cxx @@ -704,8 +704,12 @@ static ScRefFlags lcl_ScRange_Parse_XL_R1C1( ScRange& r, ScDocument* pDoc, const ScAddress::Details& rDetails, bool bOnlyAcceptSingle, - ScAddress::ExternalInfo* pExtInfo ) + ScAddress::ExternalInfo* pExtInfo, + sal_Int32* pSheetEndPos ) { + const sal_Unicode* const pStart = p; + if (pSheetEndPos) + *pSheetEndPos = 0; const sal_Unicode* pTmp = nullptr; OUString aExternDocName, aStartTabName, aEndTabName; ScRefFlags nFlags = ScRefFlags::VALID | ScRefFlags::TAB_VALID; @@ -715,6 +719,13 @@ static ScRefFlags lcl_ScRange_Parse_XL_R1C1( ScRange& r, p = r.Parse_XL_Header( p, pDoc, aExternDocName, aStartTabName, aEndTabName, nFlags, bOnlyAcceptSingle ); + ScRefFlags nBailOutFlags = ScRefFlags::ZERO; + if (pSheetEndPos && pStart < p && (nFlags & ScRefFlags::TAB_VALID) && (nFlags & ScRefFlags::TAB_3D)) + { + *pSheetEndPos = p - pStart; + nBailOutFlags = ScRefFlags::TAB_VALID | ScRefFlags::TAB_3D; + } + if (!aExternDocName.isEmpty()) lcl_ScRange_External_TabSpan( r, nFlags, pExtInfo, aExternDocName, aStartTabName, aEndTabName, pDoc); @@ -725,7 +736,7 @@ static ScRefFlags lcl_ScRange_Parse_XL_R1C1( ScRange& r, if( *p == 'R' || *p == 'r' ) { if( nullptr == (p = lcl_r1c1_get_row( p, rDetails, &r.aStart, &nFlags )) ) - return ScRefFlags::ZERO; + return nBailOutFlags; if( *p != 'C' && *p != 'c' ) // full row R# { @@ -800,7 +811,7 @@ static ScRefFlags lcl_ScRange_Parse_XL_R1C1( ScRange& r, else if( *p == 'C' || *p == 'c' ) // full col C# { if( nullptr == (p = lcl_r1c1_get_col( p, rDetails, &r.aStart, &nFlags ))) - return ScRefFlags::ZERO; + return nBailOutFlags; if( p[0] != ':' || (p[1] != 'C' && p[1] != 'c') || nullptr == (pTmp = lcl_r1c1_get_col( p+1, rDetails, &r.aEnd, &nFlags2 ))) @@ -831,7 +842,7 @@ static ScRefFlags lcl_ScRange_Parse_XL_R1C1( ScRange& r, return bOnlyAcceptSingle ? ScRefFlags::ZERO : nFlags; } - return ScRefFlags::ZERO; + return nBailOutFlags; } static inline const sal_Unicode* lcl_a1_get_col( const sal_Unicode* p, @@ -897,8 +908,12 @@ static ScRefFlags lcl_ScRange_Parse_XL_A1( ScRange& r, ScDocument* pDoc, bool bOnlyAcceptSingle, ScAddress::ExternalInfo* pExtInfo, - const uno::Sequence<sheet::ExternalLinkInfo>* pExternalLinks ) + const uno::Sequence<sheet::ExternalLinkInfo>* pExternalLinks, + sal_Int32* pSheetEndPos ) { + const sal_Unicode* const pStart = p; + if (pSheetEndPos) + *pSheetEndPos = 0; const sal_Unicode* tmp1, *tmp2; OUString aExternDocName, aStartTabName, aEndTabName; // for external link table ScRefFlags nFlags = ScRefFlags::VALID | ScRefFlags::TAB_VALID, nFlags2 = ScRefFlags::TAB_VALID; @@ -906,29 +921,36 @@ static ScRefFlags lcl_ScRange_Parse_XL_A1( ScRange& r, p = r.Parse_XL_Header( p, pDoc, aExternDocName, aStartTabName, aEndTabName, nFlags, bOnlyAcceptSingle, pExternalLinks ); + ScRefFlags nBailOutFlags = ScRefFlags::ZERO; + if (pSheetEndPos && pStart < p && (nFlags & ScRefFlags::TAB_VALID) && (nFlags & ScRefFlags::TAB_3D)) + { + *pSheetEndPos = p - pStart; + nBailOutFlags = ScRefFlags::TAB_VALID | ScRefFlags::TAB_3D; + } + if (!aExternDocName.isEmpty()) lcl_ScRange_External_TabSpan( r, nFlags, pExtInfo, aExternDocName, aStartTabName, aEndTabName, pDoc); if( nullptr == p ) - return ScRefFlags::ZERO; + return nBailOutFlags; tmp1 = lcl_a1_get_col( p, &r.aStart, &nFlags ); if( tmp1 == nullptr ) // Is it a row only reference 3:5 { if( bOnlyAcceptSingle ) // by definition full row refs are ranges - return ScRefFlags::ZERO; + return nBailOutFlags; tmp1 = lcl_a1_get_row( p, &r.aStart, &nFlags ); tmp1 = lcl_eatWhiteSpace( tmp1 ); if( !tmp1 || *tmp1++ != ':' ) // Even a singleton requires ':' (eg 2:2) - return ScRefFlags::ZERO; + return nBailOutFlags; tmp1 = lcl_eatWhiteSpace( tmp1 ); tmp2 = lcl_a1_get_row( tmp1, &r.aEnd, &nFlags2 ); if( !tmp2 || *tmp2 != 0 ) // Must have fully parsed a singleton. - return ScRefFlags::ZERO; + return nBailOutFlags; r.aStart.SetCol( 0 ); r.aEnd.SetCol( MAXCOL ); nFlags |= @@ -942,16 +964,16 @@ static ScRefFlags lcl_ScRange_Parse_XL_A1( ScRange& r, if( tmp2 == nullptr ) // check for col only reference F:H { if( bOnlyAcceptSingle ) // by definition full col refs are ranges - return ScRefFlags::ZERO; + return nBailOutFlags; tmp1 = lcl_eatWhiteSpace( tmp1 ); if( *tmp1++ != ':' ) // Even a singleton requires ':' (eg F:F) - return ScRefFlags::ZERO; + return nBailOutFlags; tmp1 = lcl_eatWhiteSpace( tmp1 ); tmp2 = lcl_a1_get_col( tmp1, &r.aEnd, &nFlags2 ); if( !tmp2 || *tmp2 != 0 ) // Must have fully parsed a singleton. - return ScRefFlags::ZERO; + return nBailOutFlags; r.aStart.SetRow( 0 ); r.aEnd.SetRow( MAXROW ); nFlags |= @@ -1047,8 +1069,13 @@ static ScRefFlags lcl_ScRange_Parse_XL_A1( ScRange& r, */ static ScRefFlags lcl_ScAddress_Parse_OOo( const sal_Unicode* p, ScDocument* pDoc, ScAddress& rAddr, ScRefFlags& rRawRes, - ScAddress::ExternalInfo* pExtInfo = nullptr, ScRange* pRange = nullptr ) + ScAddress::ExternalInfo* pExtInfo, + ScRange* pRange, + sal_Int32* pSheetEndPos ) { + const sal_Unicode* const pStart = p; + if (pSheetEndPos) + *pSheetEndPos = 0; ScRefFlags nRes = ScRefFlags::ZERO; rRawRes = ScRefFlags::ZERO; OUString aDocName; // the pure Document Name @@ -1061,7 +1088,6 @@ static ScRefFlags lcl_ScAddress_Parse_OOo( const sal_Unicode* p, ScDocument* pDo // document name is always quoted and has a trailing #. if (*p == '\'') { - const sal_Unicode* pStart = p; OUString aTmp; p = parseQuotedName(p, aTmp); aDocName = aTmp; @@ -1081,7 +1107,8 @@ static ScRefFlags lcl_ScAddress_Parse_OOo( const sal_Unicode* p, ScDocument* pDo SCCOL nCol = 0; SCROW nRow = 0; SCTAB nTab = 0; - ScRefFlags nBits = ScRefFlags::TAB_VALID; + ScRefFlags nBailOutFlags = ScRefFlags::ZERO; + ScRefFlags nBits = ScRefFlags::TAB_VALID; const sal_Unicode* q; if ( ScGlobal::FindUnquoted( p, '.') ) { @@ -1121,6 +1148,12 @@ static ScRefFlags lcl_ScAddress_Parse_OOo( const sal_Unicode* p, ScDocument* pDo if( *p++ != '.' ) nBits = ScRefFlags::ZERO; + if (pSheetEndPos && (nBits & ScRefFlags::TAB_VALID)) + { + *pSheetEndPos = p - pStart; + nBailOutFlags = ScRefFlags::TAB_VALID | ScRefFlags::TAB_3D; + } + if (!bExtDoc && (!pDoc || !pDoc->GetTable( aTab, nTab ))) { // Specified table name is not found in this document. Assume this is an external document. @@ -1305,14 +1338,15 @@ static ScRefFlags lcl_ScAddress_Parse_OOo( const sal_Unicode* p, ScDocument* pDo nRes |= ScRefFlags::VALID; } else - nRes = ScRefFlags::ZERO; + nRes = nBailOutFlags; return nRes; } static ScRefFlags lcl_ScAddress_Parse ( const sal_Unicode* p, ScDocument* pDoc, ScAddress& rAddr, const ScAddress::Details& rDetails, ScAddress::ExternalInfo* pExtInfo = nullptr, - const uno::Sequence<sheet::ExternalLinkInfo>* pExternalLinks = nullptr ) + const uno::Sequence<sheet::ExternalLinkInfo>* pExternalLinks = nullptr, + sal_Int32* pSheetEndPos = nullptr ) { if( !*p ) return ScRefFlags::ZERO; @@ -1324,15 +1358,16 @@ static ScRefFlags lcl_ScAddress_Parse ( const sal_Unicode* p, ScDocument* pDoc, { ScRange rRange = rAddr; ScRefFlags nFlags = lcl_ScRange_Parse_XL_A1( - rRange, p, pDoc, true, pExtInfo, - (rDetails.eConv == formula::FormulaGrammar::CONV_XL_OOX ? pExternalLinks : nullptr) ); + rRange, p, pDoc, true, pExtInfo, + (rDetails.eConv == formula::FormulaGrammar::CONV_XL_OOX ? pExternalLinks : nullptr), + pSheetEndPos); rAddr = rRange.aStart; return nFlags; } case formula::FormulaGrammar::CONV_XL_R1C1: { ScRange rRange = rAddr; - ScRefFlags nFlags = lcl_ScRange_Parse_XL_R1C1( rRange, p, pDoc, rDetails, true, pExtInfo ); + ScRefFlags nFlags = lcl_ScRange_Parse_XL_R1C1( rRange, p, pDoc, rDetails, true, pExtInfo, pSheetEndPos); rAddr = rRange.aStart; return nFlags; } @@ -1340,7 +1375,7 @@ static ScRefFlags lcl_ScAddress_Parse ( const sal_Unicode* p, ScDocument* pDoc, case formula::FormulaGrammar::CONV_OOO: { ScRefFlags nRawRes = ScRefFlags::ZERO; - return lcl_ScAddress_Parse_OOo( p, pDoc, rAddr, nRawRes, pExtInfo ); + return lcl_ScAddress_Parse_OOo( p, pDoc, rAddr, nRawRes, pExtInfo, nullptr, pSheetEndPos); } } } @@ -1396,9 +1431,10 @@ bool ConvertDoubleRef( ScDocument* pDoc, const OUString& rRefString, SCTAB nDefT ScRefFlags ScAddress::Parse( const OUString& r, ScDocument* pDoc, const Details& rDetails, ExternalInfo* pExtInfo, - const uno::Sequence<sheet::ExternalLinkInfo>* pExternalLinks ) + const uno::Sequence<sheet::ExternalLinkInfo>* pExternalLinks, + sal_Int32* pSheetEndPos ) { - return lcl_ScAddress_Parse( r.getStr(), pDoc, *this, rDetails, pExtInfo, pExternalLinks ); + return lcl_ScAddress_Parse( r.getStr(), pDoc, *this, rDetails, pExtInfo, pExternalLinks, pSheetEndPos ); } bool ScRange::Intersects( const ScRange& rRange ) const @@ -1476,13 +1512,14 @@ static ScRefFlags lcl_ScRange_Parse_OOo( ScRange& rRange, aTmp[nPos] = 0; const sal_Unicode* p = aTmp.getStr(); ScRefFlags nRawRes1 = ScRefFlags::ZERO; - if (((nRes1 = lcl_ScAddress_Parse_OOo( p, pDoc, rRange.aStart, nRawRes1, pExtInfo)) != ScRefFlags::ZERO) || + nRes1 = lcl_ScAddress_Parse_OOo( p, pDoc, rRange.aStart, nRawRes1, pExtInfo, nullptr, nullptr); + if ((nRes1 != ScRefFlags::ZERO) || ((nRawRes1 & (ScRefFlags::COL_VALID | ScRefFlags::ROW_VALID)) && (nRawRes1 & ScRefFlags::TAB_VALID))) { rRange.aEnd = rRange.aStart; // sheet must be initialized identical to first sheet ScRefFlags nRawRes2 = ScRefFlags::ZERO; - nRes2 = lcl_ScAddress_Parse_OOo( p + nPos+ 1, pDoc, rRange.aEnd, nRawRes2, pExtInfo, &rRange); + nRes2 = lcl_ScAddress_Parse_OOo( p + nPos+ 1, pDoc, rRange.aEnd, nRawRes2, pExtInfo, &rRange, nullptr); if (!((nRes1 & ScRefFlags::VALID) && (nRes2 & ScRefFlags::VALID)) && // If not fully valid addresses, check if both have a valid // column or row, and both have valid (or omitted) sheet references. @@ -1596,12 +1633,12 @@ ScRefFlags ScRange::Parse( const OUString& rString, ScDocument* pDoc, case formula::FormulaGrammar::CONV_XL_OOX: { return lcl_ScRange_Parse_XL_A1( *this, rString.getStr(), pDoc, false, pExtInfo, - (rDetails.eConv == formula::FormulaGrammar::CONV_XL_OOX ? pExternalLinks : nullptr) ); + (rDetails.eConv == formula::FormulaGrammar::CONV_XL_OOX ? pExternalLinks : nullptr), nullptr ); } case formula::FormulaGrammar::CONV_XL_R1C1: { - return lcl_ScRange_Parse_XL_R1C1( *this, rString.getStr(), pDoc, rDetails, false, pExtInfo ); + return lcl_ScRange_Parse_XL_R1C1( *this, rString.getStr(), pDoc, rDetails, false, pExtInfo, nullptr ); } default: |