Index: inc/cell.hxx =================================================================== --- inc/cell.hxx (revision 1384195) +++ inc/cell.hxx (working copy) @@ -19,8 +19,6 @@ * *************************************************************/ - - #ifndef SC_CELL_HXX #define SC_CELL_HXX @@ -309,6 +307,7 @@ sal_Bool bInChangeTrack : 1; // Cell is in ChangeTrack sal_Bool bTableOpDirty : 1; // Dirty flag for TableOp sal_Bool bNeedListening : 1; // Listeners need to be re-established after UpdateReference + ScToken* pValidRefToken; // i120962, get the valid reference token if the cell was applied a reference formula enum ScInterpretTailParameter { @@ -485,6 +484,7 @@ /** Determines whether or not the result string contains more than one paragraph */ bool IsMultilineResult(); + ScToken* GetValidRefToken() { return pValidRefToken; } // i120962 }; // Iterator fuer Referenzen in einer Formelzelle Index: source/core/data/cell.cxx =================================================================== --- source/core/data/cell.cxx (revision 1384195) +++ source/core/data/cell.cxx (working copy) @@ -19,8 +19,6 @@ * *************************************************************/ - - // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_sc.hxx" @@ -644,7 +642,8 @@ bInChangeTrack( sal_False ), bTableOpDirty( sal_False ), bNeedListening( sal_False ), - aPos(0,0,0) + aPos(0,0,0), + pValidRefToken( NULL ) { } @@ -673,7 +672,8 @@ bInChangeTrack( sal_False ), bTableOpDirty( sal_False ), bNeedListening( sal_False ), - aPos( rPos ) + aPos( rPos ), + pValidRefToken( NULL ) { Compile( rFormula, sal_True, eGrammar ); // bNoListening, Insert does that } @@ -704,7 +704,8 @@ bInChangeTrack( sal_False ), bTableOpDirty( sal_False ), bNeedListening( sal_False ), - aPos( rPos ) + aPos( rPos ), + pValidRefToken( NULL ) { // UPN-Array erzeugen if( pCode->GetLen() && !pCode->GetCodeError() && !pCode->GetCodeLen() ) @@ -745,7 +746,8 @@ bInChangeTrack( sal_False ), bTableOpDirty( sal_False ), bNeedListening( sal_False ), - aPos( rPos ) + aPos( rPos ), + pValidRefToken( rCell.pValidRefToken ) { pCode = (rCell.pCode) ? rCell.pCode->Clone() : NULL; @@ -823,6 +825,7 @@ #ifdef DBG_UTIL eCellType = CELLTYPE_DESTROYED; #endif + DELETEZ(pValidRefToken); } void ScFormulaCell::GetFormula( rtl::OUStringBuffer& rBuffer, @@ -1556,6 +1559,12 @@ return; } bRunning = bOldRunning; +//-> i120962: If the cell was applied reference formula, get the valid token + if (pValidRefToken) + DELETEZ(pValidRefToken); + if (p->IsReferenceFunc() && p->GetLastStackRefToken()) + pValidRefToken = static_cast(p->GetLastStackRefToken()->Clone()); +//<- i120962 // #i102616# For single-sheet saving consider only content changes, not format type, // because format type isn't set on loading (might be changed later) Index: source/core/inc/interpre.hxx =================================================================== --- source/core/inc/interpre.hxx (revision 1384195) +++ source/core/inc/interpre.hxx (working copy) @@ -19,8 +19,6 @@ * *************************************************************/ - - #ifndef SC_INTERPRE_HXX #define SC_INTERPRE_HXX @@ -146,7 +144,7 @@ ScMatrixRef GetNewMat(SCSIZE nC, SCSIZE nR); private: static ScTokenStack* pGlobalStack; - static sal_Bool bGlobalStackInUse; + static sal_Bool bGlobalStackInUse; formula::FormulaTokenIterator aCode; ScAddress aPos; @@ -160,6 +158,8 @@ const formula::FormulaToken* pCur; // current token + ScToken* pLastStackRefToken; // i120962: current valid reference token + bool bRefFunc; // i120962: is a reference function String aTempStr; // for GetString() ScTokenStack* pStackObj; // contains the stacks formula::FormulaToken** pStack; // the current stack @@ -812,14 +812,16 @@ void SetError(sal_uInt16 nError) { if (nError && !nGlobalError) nGlobalError = nError; } - sal_uInt16 GetError() const { return nGlobalError; } + sal_uInt16 GetError() const { return nGlobalError; } formula::StackVar GetResultType() const { return xResult->GetType(); } const String& GetStringResult() const { return xResult->GetString(); } double GetNumResult() const { return xResult->GetDouble(); } formula::FormulaTokenRef GetResultToken() const { return xResult; } short GetRetFormatType() const { return nRetFmtType; } - sal_uLong GetRetFormatIndex() const { return nRetFmtIndex; } + sal_uLong GetRetFormatIndex() const { return nRetFmtIndex; } + ScToken* GetLastStackRefToken() { return pLastStackRefToken; } + bool IsReferenceFunc() { return bRefFunc; } }; Index: source/core/tool/interpr4.cxx =================================================================== --- source/core/tool/interpr4.cxx (revision 1384195) +++ source/core/tool/interpr4.cxx (working copy) @@ -19,8 +19,6 @@ * *************************************************************/ - - // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_sc.hxx" // INCLUDE --------------------------------------------------------------- @@ -62,6 +60,7 @@ #include "parclass.hxx" #include "externalrefmgr.hxx" #include "doubleref.hxx" +#include "token.hxx" #include #include @@ -1170,6 +1169,9 @@ SingleRefToVars( static_cast(p)->GetSingleRef(), rCol, rRow, rTab); if ( pDok->aTableOpList.Count() > 0 ) ReplaceCell( rCol, rRow, rTab ); + DELETEZ(pLastStackRefToken); + pLastStackRefToken = static_cast(p->Clone()); + ((ScSingleRefToken*)pLastStackRefToken)->GetSingleRef().SetFlag3D(sal_True); break; default: SetError( errIllegalParameter); @@ -1201,6 +1203,9 @@ rAdr.Set( nCol, nRow, nTab ); if ( pDok->aTableOpList.Count() > 0 ) ReplaceCell( rAdr ); + DELETEZ(pLastStackRefToken); + pLastStackRefToken = static_cast(p->Clone()); + ((ScSingleRefToken*)pLastStackRefToken)->GetSingleRef().SetFlag3D(sal_True); } break; default: @@ -1283,6 +1288,9 @@ case svDoubleRef: DoubleRefToVars( static_cast(p), rCol1, rRow1, rTab1, rCol2, rRow2, rTab2, bDontCheckForTableOp); + DELETEZ(pLastStackRefToken); + pLastStackRefToken = static_cast(p->Clone()); + ((ScDoubleRefToken*)pLastStackRefToken)->GetSingleRef().SetFlag3D(sal_True); break; default: SetError( errIllegalParameter); @@ -1327,6 +1335,9 @@ case svDoubleRef: --sp; DoubleRefToRange( p->GetDoubleRef(), rRange); + DELETEZ(pLastStackRefToken); + pLastStackRefToken = static_cast(p->Clone()); + ((ScDoubleRefToken*)pLastStackRefToken)->GetSingleRef().SetFlag3D(sal_True); break; case svRefList: { @@ -1373,6 +1384,9 @@ break; case svDoubleRef: DoubleRefToRange( static_cast(p)->GetDoubleRef(), rRange, bDontCheckForTableOp); + DELETEZ(pLastStackRefToken); + pLastStackRefToken = static_cast(p->Clone()); + ((ScDoubleRefToken*)pLastStackRefToken)->GetSingleRef().SetFlag3D(sal_True); break; default: SetError( errIllegalParameter); @@ -3286,6 +3300,8 @@ pMyFormulaCell( pCell ), pFormatter( pDoc->GetFormatTable() ), mnStringNoValueError( errNoValue), + pLastStackRefToken( NULL ), + bRefFunc( false ), bCalcAsShown( pDoc->GetDocOptions().IsCalcAsShown() ) { RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScTTT" ); @@ -3317,6 +3333,7 @@ delete pStackObj; if (pTokenMatrixMap) delete pTokenMatrixMap; + DELETEZ(pLastStackRefToken); } @@ -3865,6 +3882,7 @@ // End: obtain result + bRefFunc = false; if( sp ) { pCur = pStack[ sp-1 ]; @@ -3891,6 +3909,7 @@ break; case svSingleRef : { + bRefFunc = true; ScAddress aAdr; PopSingleRef( aAdr ); if( !nGlobalError ) @@ -3911,6 +3930,7 @@ } else { + bRefFunc = true; ScRange aRange; PopDoubleRef( aRange ); ScAddress aAdr; Index: source/ui/unoobj/chart2uno.cxx =================================================================== --- source/ui/unoobj/chart2uno.cxx (revision 1384195) +++ source/ui/unoobj/chart2uno.cxx (working copy) @@ -19,8 +19,6 @@ * *************************************************************/ - - // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_sc.hxx" @@ -39,6 +37,7 @@ #include "compiler.hxx" #include "reftokenhelper.hxx" #include "chartlis.hxx" +#include "rangenam.hxx" #include #include @@ -2035,6 +2034,53 @@ vector aRefTokens; ScRefTokenHelper::compileRangeRepresentation(aRefTokens, aRangeRepresentation, m_pDocument); + if (aRefTokens.empty()) // i120962: If haven't get reference, that means aRangeRepresentation is not a simple address, then try formulas + { + ScRangeName aLocalRangeName(*(m_pDocument->GetRangeName())); + sal_uInt16 nCurPos = 0; + sal_Bool bFindName = aLocalRangeName.SearchName(aRangeRepresentation, nCurPos); // Find global name first + + for (SCTAB Scope = 0; Scope < MAXTABCOUNT && !bFindName; Scope++ ) // Find name in sheet scope + bFindName = aLocalRangeName.SearchName(aRangeRepresentation, nCurPos, Scope); + + if (bFindName) + { + ScRangeData* pData =(ScRangeData*)(aLocalRangeName.At(nCurPos)); + ScTokenArray* pArray = pData->GetCode(); + sal_uInt16 nLen = pArray->GetLen(); + if (!nLen) + ; + else if (nLen == 1) // range names + { + pArray->Reset(); + const FormulaToken* p = pArray->GetNextReference(); + if (p) + aRefTokens.push_back( + ScSharedTokenRef(static_cast(p->Clone()))); + } + else // formulas + { + String aSymbol; + pData->GetSymbol(aSymbol, FormulaGrammar::GRAM_ENGLISH); + + String aFormulaStr('='); + aFormulaStr += aSymbol; + + ScAddress aAddr; + ScFormulaCell* pCell = new ScFormulaCell(m_pDocument, aAddr, aFormulaStr, FormulaGrammar::GRAM_ENGLISH); + pCell->Interpret(); + + if (pCell->GetValidRefToken()) + { + aRefTokens.push_back( + ScSharedTokenRef(static_cast(pCell->GetValidRefToken()->Clone()))); + } + + DELETEZ( pCell ); + } + } + } + if (aRefTokens.empty()) return xResult;