summaryrefslogtreecommitdiff
path: root/sc
diff options
context:
space:
mode:
authorMarkus Mohrhard <markus.mohrhard@googlemail.com>2011-12-20 06:53:52 +0100
committerMarkus Mohrhard <markus.mohrhard@googlemail.com>2011-12-20 06:56:29 +0100
commitb5363b8cedf09ce7e8c75022041f4dafda4b699f (patch)
treef31a9d3820580c9fc4defdfe01625172c2b0fe6d /sc
parent2b995d9f9a4f5b99a1c6e80be77a0a6dea2c968a (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.hxx4
-rw-r--r--sc/inc/tokenarray.hxx11
-rw-r--r--sc/source/core/data/cell.cxx2
-rw-r--r--sc/source/core/data/document.cxx121
-rw-r--r--sc/source/core/tool/token.cxx54
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() )
{