[Libreoffice-commits] .: sc/inc sc/source

Markus Mohrhard mmohrhard at kemper.freedesktop.org
Mon Aug 15 22:01:08 PDT 2011


 sc/inc/rangenam.hxx              |    2 
 sc/inc/token.hxx                 |    5 +-
 sc/source/core/data/cell.cxx     |   97 +++++++++++++++++++++++++++++++++++++++
 sc/source/core/data/table2.cxx   |    6 ++
 sc/source/core/tool/rangenam.cxx |    4 -
 sc/source/core/tool/token.cxx    |    5 ++
 6 files changed, 113 insertions(+), 6 deletions(-)

New commits:
commit 04d2e6469529b6187900659517d6f6dd5ea2cca5
Author: Markus Mohrhard <markus.mohrhard at googlemail.com>
Date:   Tue Aug 16 06:50:15 2011 +0200

    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

diff --git a/sc/inc/rangenam.hxx b/sc/inc/rangenam.hxx
index 4411b48..5d65bf5 100644
--- a/sc/inc/rangenam.hxx
+++ b/sc/inc/rangenam.hxx
@@ -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();
 
diff --git a/sc/inc/token.hxx b/sc/inc/token.hxx
index d7cefab..cec672f 100644
--- a/sc/inc/token.hxx
+++ b/sc/inc/token.hxx
@@ -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); }
 };
diff --git a/sc/source/core/data/cell.cxx b/sc/source/core/data/cell.cxx
index 89f4cdb..1eb4433 100644
--- a/sc/source/core/data/cell.cxx
+++ b/sc/source/core/data/cell.cxx
@@ -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();
diff --git a/sc/source/core/data/table2.cxx b/sc/source/core/data/table2.cxx
index 1954fc6..a11d0c6 100644
--- a/sc/source/core/data/table2.cxx
+++ b/sc/source/core/data/table2.cxx
@@ -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);
diff --git a/sc/source/core/tool/rangenam.cxx b/sc/source/core/tool/rangenam.cxx
index 14c1833..2437eb4 100644
--- a/sc/source/core/tool/rangenam.cxx
+++ b/sc/source/core/tool/rangenam.cxx
@@ -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),
diff --git a/sc/source/core/tool/token.cxx b/sc/source/core/tool/token.cxx
index baee145..e9c4e67 100644
--- a/sc/source/core/tool/token.cxx
+++ b/sc/source/core/tool/token.cxx
@@ -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;


More information about the Libreoffice-commits mailing list