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

Markus Mohrhard mmohrhard at kemper.freedesktop.org
Mon Dec 19 21:57:07 PST 2011


 sc/inc/document.hxx              |    4 -
 sc/inc/externalrefmgr.hxx        |   13 ++--
 sc/inc/globstr.hrc               |    3 
 sc/inc/tokenarray.hxx            |   11 ++-
 sc/source/core/data/cell.cxx     |    2 
 sc/source/core/data/document.cxx |  121 ---------------------------------------
 sc/source/core/tool/token.cxx    |   54 +++++++++++++----
 sc/source/ui/docshell/docsh.cxx  |   15 ++++
 sc/source/ui/src/globstr.src     |    4 +
 9 files changed, 79 insertions(+), 148 deletions(-)

New commits:
commit b5363b8cedf09ce7e8c75022041f4dafda4b699f
Author: Markus Mohrhard <markus.mohrhard at googlemail.com>
Date:   Tue Dec 20 06:53:52 2011 +0100

    improve the handling of range names while copy between different docs
    
    we now behave nearly the same way as excel does

diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx
index 526ad41..83ad4a1 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 f766a46..1819de2 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 e85d984..a5d6df4 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 9796ceb..eb03a74 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 35d6358..50b3433 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() )
                 {
commit 2b995d9f9a4f5b99a1c6e80be77a0a6dea2c968a
Author: Markus Mohrhard <markus.mohrhard at googlemail.com>
Date:   Tue Dec 20 05:18:26 2011 +0100

    add a warning dialog if we have ext refs to unsaved docs

diff --git a/sc/inc/externalrefmgr.hxx b/sc/inc/externalrefmgr.hxx
index b3a640e..c44c8f1 100644
--- a/sc/inc/externalrefmgr.hxx
+++ b/sc/inc/externalrefmgr.hxx
@@ -687,6 +687,13 @@ public:
 
     virtual void Notify( SfxBroadcaster& rBC, const SfxHint& rHint );
 
+    /**
+     * If we still contain unsaved files we should warn the user before saving
+     *
+     * @return true if the document still contains references to an unsaved file
+     */
+    bool containsUnsavedReferences() { return !maUnsavedDocShells.empty(); }
+
 private:
     ScExternalRefManager();
     ScExternalRefManager(const ScExternalRefManager&);
@@ -763,12 +770,6 @@ private:
 
     sal_uInt32 getMappedNumberFormat(sal_uInt16 nFileId, sal_uInt32 nNumFmt, const ScDocument* pSrcDoc);
 
-    /**
-     * If we still contain unsaved files we should warn the user before saving
-     *
-     * @return true if the document still contains references to an unsaved file
-     */
-    bool containsUnsavedReferences() { return !maUnsavedDocShells.empty(); }
 
 private:
     /** cache of referenced ranges and names from source documents. */
diff --git a/sc/inc/globstr.hrc b/sc/inc/globstr.hrc
index 2363aaf..a545a0e 100644
--- a/sc/inc/globstr.hrc
+++ b/sc/inc/globstr.hrc
@@ -599,8 +599,9 @@
 #define STR_ERR_NAME_EXISTS         463
 #define STR_ERR_NAME_INVALID        464
 
+#define STR_UNSAVED_EXT_REF         465
 
-#define STR_COUNT                   465
+#define STR_COUNT                   466
 
 
 #endif
diff --git a/sc/source/ui/docshell/docsh.cxx b/sc/source/ui/docshell/docsh.cxx
index 26cea14..8f4f3fc 100644
--- a/sc/source/ui/docshell/docsh.cxx
+++ b/sc/source/ui/docshell/docsh.cxx
@@ -913,11 +913,25 @@ void ScDocShell::Notify( SfxBroadcaster&, const SfxHint& rHint )
                         if ( !bSuccess )
                             SetError( ERRCODE_IO_ABORT, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) ); // this error code will produce no error message, but will break the further saving process
                     }
+
+
                     if (pSheetSaveData)
                         pSheetSaveData->SetInSupportedSave(true);
                 }
                 break;
             case SFX_EVENT_SAVEASDOC:
+                {
+                    if ( GetDocument()->GetExternalRefManager()->containsUnsavedReferences() )
+                    {
+                        WarningBox aBox( GetActiveDialogParent(), WinBits( WB_YES_NO ),
+                                ScGlobal::GetRscString( STR_UNSAVED_EXT_REF ) );
+
+                        if( RET_NO == aBox.Execute())
+                        {
+                            SetError( ERRCODE_IO_ABORT, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) ); // this error code will produce no error message, but will break the further saving process
+                        }
+                    }
+                } // fall through
             case SFX_EVENT_SAVETODOC:
                 // #i108978# If no event is sent before saving, there will also be no "...DONE" event,
                 // and SAVE/SAVEAS can't be distinguished from SAVETO. So stream copying is only enabled
@@ -1557,6 +1571,7 @@ sal_Bool ScDocShell::SaveAs( SfxMedium& rMedium )
             return false;
     }
 
+
     ScRefreshTimerProtector( aDocument.GetRefreshTimerControlAddress() );
 
     PrepareSaveGuard aPrepareGuard( *this);
diff --git a/sc/source/ui/src/globstr.src b/sc/source/ui/src/globstr.src
index 464f141..8d6425d 100644
--- a/sc/source/ui/src/globstr.src
+++ b/sc/source/ui/src/globstr.src
@@ -1851,5 +1851,9 @@ Resource RID_GLOBSTR
     {
         Text [ en-US ] = "Invalid name. Only use letters, numbers and underscore.";
     };
+    String STR_UNSAVED_EXT_REF
+    {
+        Text [ en-US ] = "This Document contains external references to unsaved documents.\n\nDo you want to continue?";
+    };
 };
 


More information about the Libreoffice-commits mailing list