Kaydet (Commit) 04d2e646 authored tarafından Markus Mohrhard's avatar Markus Mohrhard

update range names/database ranges in formulas cells

we need to update range names/database ranges when we copy/paste formula
cells otherwise the ScNameToken may point to a different entry
üst ade0d4b4
......@@ -104,7 +104,7 @@ public:
const String& rName,
const ScAddress& rTarget );
// rTarget is ABSPOS jump label
ScRangeData(const ScRangeData& rScRangeData);
ScRangeData(const ScRangeData& rScRangeData, ScDocument* pDocument = NULL);
SC_DLLPUBLIC ~ScRangeData();
......
......@@ -247,8 +247,9 @@ public:
ScNameToken(sal_uInt16 nIndex, bool bGlobal, OpCode eOpCode = ocName);
ScNameToken(const ScNameToken& r);
virtual ~ScNameToken();
virtual sal_uInt8 GetByte() const;
virtual sal_uInt16 GetIndex() const;
virtual sal_uInt8 GetByte() const;
virtual void SetByte(sal_uInt8 aGlobal);
virtual sal_uInt16 GetIndex() const;
virtual bool operator==( const formula::FormulaToken& rToken ) const;
virtual FormulaToken* Clone() const { return new ScNameToken(*this); }
};
......
......@@ -131,6 +131,88 @@ ScBaseCell* lclCloneCell( const ScBaseCell& rSrcCell, ScDocument& rDestDoc, cons
return 0;
}
void adjustRangeName(ScToken* pToken, ScDocument& aNewDoc, ScDocument* pOldDoc, ScAddress aNewPos, ScAddress aOldPos)
{
bool bOldGlobal = static_cast<bool>(pToken->GetByte());
SCTAB aOldTab = aOldPos.Tab();
rtl::OUString aRangeName;
int nOldIndex = pToken->GetIndex();
ScRangeData* pOldRangeData = NULL;
//search the name of the RangeName
if (!bOldGlobal)
{
pOldRangeData = pOldDoc->GetRangeName(aOldTab)->findByIndex(nOldIndex);
if (!pOldRangeData)
return; //might be an error in the formula array
aRangeName = pOldRangeData->GetName();
}
else
{
pOldRangeData = pOldDoc->GetRangeName()->findByIndex(nOldIndex);
if (!pOldRangeData)
return; //might be an error in the formula array
aRangeName = pOldRangeData->GetName();
}
//find corresponding range name in new document
//first search for local range name then global range names
SCTAB aNewTab = aNewPos.Tab();
ScRangeName* pRangeName = aNewDoc.GetRangeName(aNewTab);
ScRangeData* pRangeData = NULL;
bool bNewGlobal = false;
//search local range names
if (pRangeName)
{
pRangeData = pRangeName->findByUpperName(aRangeName.toAsciiUpperCase());
}
//search global range names
if (!pRangeData)
{
//even if it is not in the global scope we'll have a global range name
bNewGlobal = true;
pRangeName = aNewDoc.GetRangeName();
if (pRangeName)
pRangeData = pRangeName->findByUpperName(aRangeName.toAsciiUpperCase());
}
//if no range name was found copy it
if (!pRangeData)
{
pRangeData = new ScRangeData(*pOldRangeData, &aNewDoc);
aNewDoc.GetRangeName()->insert(pRangeData);
}
sal_Int32 nIndex = pRangeData->GetIndex();
pToken->SetIndex(nIndex);
pToken->SetByte(bNewGlobal);
}
void adjustDBRange(ScToken* pToken, ScDocument& aNewDoc, ScDocument* pOldDoc)
{
ScDBCollection* pOldDBCollection = pOldDoc->GetDBCollection();
if (!pOldDBCollection)
return;//strange error case, don't do anything
ScDBCollection::NamedDBs& aOldNamedDBs = pOldDBCollection->getNamedDBs();
ScDBData* pDBData = aOldNamedDBs.findByIndex(pToken->GetIndex());
if (!pDBData)
return; //invalid index
rtl::OUString aDBName = pDBData->GetName();
//search in new document
ScDBCollection* pNewDBCollection = aNewDoc.GetDBCollection();
if (!pNewDBCollection)
{
pNewDBCollection = new ScDBCollection(&aNewDoc);
}
ScDBCollection::NamedDBs& aNewNamedDBs = pNewDBCollection->getNamedDBs();
ScDBData* pNewDBData = aNewNamedDBs.findByName(aDBName);
if (!pNewDBData)
{
pNewDBData = new ScDBData(*pNewDBData);
aNewNamedDBs.insert(pNewDBData);
}
pToken->SetIndex(pNewDBData->GetIndex());
}
} // namespace
ScBaseCell* ScBaseCell::CloneWithoutNote( ScDocument& rDestDoc, int nCloneFlags ) const
......@@ -771,6 +853,21 @@ ScFormulaCell::ScFormulaCell( const ScFormulaCell& rCell, ScDocument& rDoc, cons
//! Compile ColRowNames on URM_MOVE/URM_COPY _after_ UpdateReference
sal_Bool bCompileLater = false;
sal_Bool bClipMode = rCell.pDocument->IsClipboard();
//update ScNameTokens
if (!pDocument->IsClipboard())
{
ScToken* pToken = NULL;
while((pToken = static_cast<ScToken*>(pCode->GetNextName()))!= NULL)
{
OpCode eOpCode = pToken->GetOpCode();
if (eOpCode == ocName)
adjustRangeName(pToken, rDoc, rCell.pDocument, aPos, rCell.aPos);
else if (eOpCode == ocDBArea)
adjustDBRange(pToken, rDoc, rCell.pDocument);
}
}
if( !bCompile )
{ // Name references with references and ColRowNames
pCode->Reset();
......
......@@ -463,7 +463,10 @@ void ScTable::CopyToClip(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
{
if (ValidColRow(nCol1, nRow1) && ValidColRow(nCol2, nRow2))
{
// Inhalte kopieren
// copy content
//local range names need to be copied first for formula cells
if (!pTable->mpRangeName)
pTable->mpRangeName = new ScRangeName(*mpRangeName);
SCCOL i;
for ( i = nCol1; i <= nCol2; i++)
......@@ -481,6 +484,7 @@ void ScTable::CopyToClip(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
if (pDBDataNoName)
pTable->SetAnonymousDBData(new ScDBData(*pDBDataNoName));
if (pRowFlags && pTable->pRowFlags && mpRowHeights && pTable->mpRowHeights)
{
pTable->pRowFlags->CopyFromAnded( *pRowFlags, 0, nRow2, CR_MANUALSIZE);
......
......@@ -167,13 +167,13 @@ ScRangeData::ScRangeData( ScDocument* pDok,
eType |= RT_ABSPOS;
}
ScRangeData::ScRangeData(const ScRangeData& rScRangeData) :
ScRangeData::ScRangeData(const ScRangeData& rScRangeData, ScDocument* pDocument) :
aName (rScRangeData.aName),
aUpperName (rScRangeData.aUpperName),
pCode (rScRangeData.pCode ? rScRangeData.pCode->Clone() : new ScTokenArray()), // echte Kopie erzeugen (nicht copy-ctor)
aPos (rScRangeData.aPos),
eType (rScRangeData.eType),
pDoc (rScRangeData.pDoc),
pDoc (pDocument ? pDocument : rScRangeData.pDoc),
nIndex (rScRangeData.nIndex),
bModified (rScRangeData.bModified),
mnMaxRow (rScRangeData.mnMaxRow),
......
......@@ -972,6 +972,11 @@ sal_uInt8 ScNameToken::GetByte() const
return static_cast<sal_uInt8>(mbGlobal);
}
void ScNameToken::SetByte(sal_uInt8 aGlobal)
{
mbGlobal = static_cast<bool>(aGlobal);
}
sal_uInt16 ScNameToken::GetIndex() const
{
return mnIndex;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment