diff options
author | Markus Mohrhard <markus.mohrhard@googlemail.com> | 2011-12-20 06:53:52 +0100 |
---|---|---|
committer | Markus Mohrhard <markus.mohrhard@googlemail.com> | 2011-12-20 06:56:29 +0100 |
commit | b5363b8cedf09ce7e8c75022041f4dafda4b699f (patch) | |
tree | f31a9d3820580c9fc4defdfe01625172c2b0fe6d /sc | |
parent | 2b995d9f9a4f5b99a1c6e80be77a0a6dea2c968a (diff) |
improve the handling of range names while copy between different docs
we now behave nearly the same way as excel does
Diffstat (limited to 'sc')
-rw-r--r-- | sc/inc/document.hxx | 4 | ||||
-rw-r--r-- | sc/inc/tokenarray.hxx | 11 | ||||
-rw-r--r-- | sc/source/core/data/cell.cxx | 2 | ||||
-rw-r--r-- | sc/source/core/data/document.cxx | 121 | ||||
-rw-r--r-- | sc/source/core/tool/token.cxx | 54 |
5 files changed, 51 insertions, 141 deletions
diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx index 526ad41f740f..83ad4a1a6cae 100644 --- a/sc/inc/document.hxx +++ b/sc/inc/document.hxx @@ -1864,10 +1864,6 @@ private: // CLOOK-Impl-methods void CopyRangeNamesToClip(ScDocument* pClipDoc, const ScRange& rClipRange, const ScMarkData* pMarks, bool bAllTabs); void CopyRangeNamesToClip(ScDocument* pClipDoc, const ScRange& rClipRange, SCTAB nTab); - void CopyRangeNamesFromClip(ScDocument* pClipDoc, ScClipRangeNameData& rRangeNames); - void UpdateRangeNamesInFormulas( - ScClipRangeNameData& rRangeNames, const ScRangeList& rDestRanges, const ScMarkData& rMark, - SCCOL nXw, SCROW nYw); bool HasPartOfMerged( const ScRange& rRange ); diff --git a/sc/inc/tokenarray.hxx b/sc/inc/tokenarray.hxx index f766a46a66d0..1819de247647 100644 --- a/sc/inc/tokenarray.hxx +++ b/sc/inc/tokenarray.hxx @@ -96,8 +96,15 @@ public: const ScAddress& rOldPos, const ScAddress& rNewPos ); - // Make all absolute references external references pointing to the old document - void ReadjusteAbsolute3DReferences( const ScDocument* pOldDoc, const ScDocument* pNewDoc, const ScAddress& rPos ); + /** + * Make all absolute references external references pointing to the old document + * + * @param pOldDoc old document + * @param pNewDoc new document + * @param rPos position of the cell to determine if the reference is in the copied area + * @param bRangeName set for range names, range names have special handling for absolute sheet ref + relative col/row ref + */ + void ReadjusteAbsolute3DReferences( const ScDocument* pOldDoc, const ScDocument* pNewDoc, const ScAddress& rPos, bool bRangeName = false ); }; #endif // SC_TOKENARRAY_HXX diff --git a/sc/source/core/data/cell.cxx b/sc/source/core/data/cell.cxx index e85d984a98d0..a5d6df44b720 100644 --- a/sc/source/core/data/cell.cxx +++ b/sc/source/core/data/cell.cxx @@ -180,7 +180,7 @@ void adjustRangeName(ScToken* pToken, ScDocument& rNewDoc, const ScDocument* pOl bNewGlobal = bOldGlobal; pRangeData = new ScRangeData(*pOldRangeData, &rNewDoc); ScTokenArray* pRangeNameToken = pRangeData->GetCode(); - pRangeNameToken->ReadjusteAbsolute3DReferences(pOldDoc, &rNewDoc, pRangeData->GetPos()); + pRangeNameToken->ReadjusteAbsolute3DReferences(pOldDoc, &rNewDoc, pRangeData->GetPos(), true); bool bInserted; if (bNewGlobal) bInserted = rNewDoc.GetRangeName()->insert(pRangeData); diff --git a/sc/source/core/data/document.cxx b/sc/source/core/data/document.cxx index 9796cebde95a..eb03a7420b99 100644 --- a/sc/source/core/data/document.cxx +++ b/sc/source/core/data/document.cxx @@ -2184,116 +2184,6 @@ void ScDocument::MergeNumberFormatter(ScDocument* pSrcDoc) } } -void ScDocument::CopyRangeNamesFromClip(ScDocument* pClipDoc, ScClipRangeNameData& rRangeNames) -{ - if (!pClipDoc->pRangeName) - return; - - ScClipRangeNameData aClipRangeNames; - - ScRangeName::const_iterator itr = pClipDoc->pRangeName->begin(); - ScRangeName::const_iterator itrEnd = pClipDoc->pRangeName->end(); - for (; itr != itrEnd; ++itr) //! DB-Bereiche Pivot-Bereiche auch - { - /* Copy only if the name doesn't exist in this document. - If it exists we use the already existing name instead, - another possibility could be to create new names if - documents differ. - A proper solution would ask the user how to proceed. - The adjustment of the indices in the formulas is done later. - */ - const ScRangeData* pExistingData = GetRangeName()->findByUpperName(itr->first); - if (pExistingData) - { - sal_uInt16 nOldIndex = itr->second->GetIndex(); - sal_uInt16 nNewIndex = pExistingData->GetIndex(); - aClipRangeNames.insert(nOldIndex, nNewIndex); - if ( !aClipRangeNames.mbReplace ) - aClipRangeNames.mbReplace = ( nOldIndex != nNewIndex ); - } - else - { - ScRangeData* pData = new ScRangeData( *itr->second ); - pData->SetDocument(this); - if ( pRangeName->findByIndex( pData->GetIndex() ) ) - pData->SetIndex(0); // need new index, done in Insert - if ( pRangeName->insert(pData) ) - { - aClipRangeNames.mpRangeNames.push_back(pData); - sal_uInt16 nOldIndex = itr->second->GetIndex(); - sal_uInt16 nNewIndex = pData->GetIndex(); - aClipRangeNames.insert(nOldIndex, nNewIndex); - if ( !aClipRangeNames.mbReplace ) - aClipRangeNames.mbReplace = ( nOldIndex != nNewIndex ); - } - else - { // must be an overflow - pData = NULL; - aClipRangeNames.insert(itr->second->GetIndex(), 0); - aClipRangeNames.mbReplace = true; - } - } - } - rRangeNames = aClipRangeNames; -} - -void ScDocument::UpdateRangeNamesInFormulas( - ScClipRangeNameData& rRangeNames, const ScRangeList& rDestRanges, const ScMarkData& rMark, - SCCOL nXw, SCROW nYw) -{ - // nXw and nYw are the extra width and height of the destination range - // extended due to presence of merged cell(s). - - if (!rRangeNames.mbReplace) - return; - - // first update all inserted named formulas if they contain other - // range names and used indices changed - for (size_t i = 0, n = rRangeNames.mpRangeNames.size(); i < n; ++i) //! DB-Bereiche Pivot-Bereiche auch - { - rRangeNames.mpRangeNames[i]->ReplaceRangeNamesInUse(rRangeNames.maRangeMap); - } - // then update the formulas, they might need just the updated range names - for ( size_t nRange = 0, n = rDestRanges.size(); nRange < n; ++nRange ) - { - const ScRange* pRange = rDestRanges[nRange]; - SCCOL nCol1 = pRange->aStart.Col(); - SCROW nRow1 = pRange->aStart.Row(); - SCCOL nCol2 = pRange->aEnd.Col(); - SCROW nRow2 = pRange->aEnd.Row(); - - SCCOL nC1 = nCol1; - SCROW nR1 = nRow1; - SCCOL nC2 = nC1 + nXw; - if (nC2 > nCol2) - nC2 = nCol2; - SCROW nR2 = nR1 + nYw; - if (nR2 > nRow2) - nR2 = nRow2; - do - { - do - { - ScMarkData::const_iterator itr = rMark.begin(), itrEnd = rMark.end(); - for (; itr != itrEnd; ++itr) - { - if ( maTabs[*itr] ) - maTabs[*itr]->ReplaceRangeNamesInUse(nC1, nR1, - nC2, nR2, rRangeNames.maRangeMap); - } - nC1 = nC2 + 1; - nC2 = Min((SCCOL)(nC1 + nXw), nCol2); - } while (nC1 <= nCol2); - nC1 = nCol1; - nC2 = nC1 + nXw; - if (nC2 > nCol2) - nC2 = nCol2; - nR1 = nR2 + 1; - nR2 = Min((SCROW)(nR1 + nYw), nRow2); - } while (nR1 <= nRow2); - } -} - ScClipParam& ScDocument::GetClipParam() { if (!mpClipParam.get()) @@ -2498,9 +2388,6 @@ void ScDocument::CopyFromClip( const ScRange& rDestRange, const ScMarkData& rMar NumFmtMergeHandler aNumFmtMergeHdl(this, pClipDoc); - ScClipRangeNameData aClipRangeNames; - CopyRangeNamesFromClip(pClipDoc, aClipRangeNames); - SCCOL nAllCol1 = rDestRange.aStart.Col(); SCROW nAllRow1 = rDestRange.aStart.Row(); SCCOL nAllCol2 = rDestRange.aEnd.Col(); @@ -2657,8 +2544,6 @@ void ScDocument::CopyFromClip( const ScRange& rDestRange, const ScMarkData& rMar bInsertingFromOtherDoc = false; - UpdateRangeNamesInFormulas(aClipRangeNames, *pDestRanges, rMark, nXw, nYw); - // Listener aufbauen nachdem alles inserted wurde StartListeningFromClip( nAllCol1, nAllRow1, nAllCol2, nAllRow2, rMark, nInsFlag ); // nachdem alle Listener aufgebaut wurden, kann gebroadcastet werden @@ -2701,9 +2586,6 @@ void ScDocument::CopyMultiRangeFromClip( NumFmtMergeHandler aNumFmtMergeHdl(this, pClipDoc); - ScClipRangeNameData aClipRangeNames; - CopyRangeNamesFromClip(pClipDoc, aClipRangeNames); - SCCOL nCol1 = rDestPos.Col(); SCROW nRow1 = rDestPos.Row(); ScClipParam& rClipParam = pClipDoc->GetClipParam(); @@ -2798,9 +2680,6 @@ void ScDocument::CopyMultiRangeFromClip( ScRangeList aRanges; aRanges.Append(aDestRange); - SCCOL nCols = aDestRange.aEnd.Col() - aDestRange.aStart.Col() + 1; - SCROW nRows = aDestRange.aEnd.Row() - aDestRange.aStart.Row() + 1; - UpdateRangeNamesInFormulas(aClipRangeNames, aRanges, rMark, nCols-1, nRows-1); // Listener aufbauen nachdem alles inserted wurde StartListeningFromClip(aDestRange.aStart.Col(), aDestRange.aStart.Row(), diff --git a/sc/source/core/tool/token.cxx b/sc/source/core/tool/token.cxx index 35d635808cc1..50b3433e172c 100644 --- a/sc/source/core/tool/token.cxx +++ b/sc/source/core/tool/token.cxx @@ -1841,9 +1841,45 @@ bool IsInCopyRange( const ScRange& rRange, const ScDocument* pClipDoc ) return rClipParam.maRanges.In(rRange); } +bool SkipReference(ScToken* pToken, const ScAddress& rPos, const ScDocument* pOldDoc, bool bRangeName) +{ + ScRange aRange; + if (!ScRefTokenHelper::getAbsRangeFromToken(aRange, pToken, rPos)) + return true; + + if (bRangeName && aRange.aStart.Tab() == rPos.Tab()) + { + switch (pToken->GetType()) + { + case svDoubleRef: + { + ScSingleRefData& rRef = pToken->GetSingleRef2(); + if (rRef.IsColRel() || rRef.IsRowRel()) + return true; + } // fall through + case svSingleRef: + { + ScSingleRefData& rRef = pToken->GetSingleRef(); + if (rRef.IsColRel() || rRef.IsRowRel()) + return true; + } + break; + default: + break; + } + } + else + { + if (IsInCopyRange(aRange, pOldDoc)) + return true; + } + + return false; +} + } -void ScTokenArray::ReadjusteAbsolute3DReferences( const ScDocument* pOldDoc, const ScDocument* pNewDoc, const ScAddress& rPos ) +void ScTokenArray::ReadjusteAbsolute3DReferences( const ScDocument* pOldDoc, const ScDocument* pNewDoc, const ScAddress& rPos, bool bRangeName ) { for ( sal_uInt16 j=0; j<nLen; ++j ) { @@ -1855,12 +1891,8 @@ void ScTokenArray::ReadjusteAbsolute3DReferences( const ScDocument* pOldDoc, con ScSingleRefData& rRef2 = rRef.Ref2; ScSingleRefData& rRef1 = rRef.Ref1; - ScRange aRange; - if (!ScRefTokenHelper::getAbsRangeFromToken(aRange, static_cast<ScToken*>(pCode[j]), rPos)) - continue; // might be an external ref token - - if (IsInCopyRange(aRange, pOldDoc)) - continue; // don't adjust references to copied values + if (SkipReference(static_cast<ScToken*>(pCode[j]), rPos, pOldDoc, bRangeName)) + continue; if ( (rRef2.IsFlag3D() && !rRef2.IsTabRel()) || (rRef1.IsFlag3D() && !rRef1.IsTabRel()) ) { @@ -1878,12 +1910,8 @@ void ScTokenArray::ReadjusteAbsolute3DReferences( const ScDocument* pOldDoc, con { ScSingleRefData& rRef = static_cast<ScToken*>(pCode[j])->GetSingleRef(); - ScRange aRange; - if (!ScRefTokenHelper::getAbsRangeFromToken(aRange, static_cast<ScToken*>(pCode[j]), rPos)) - continue; // might be an external ref token - - if (IsInCopyRange(aRange, pOldDoc)) - continue; // don't adjust references to copied values + if (SkipReference(static_cast<ScToken*>(pCode[j]), rPos, pOldDoc, bRangeName)) + continue; if ( rRef.IsFlag3D() && !rRef.IsTabRel() ) { |