[Libreoffice-commits] core.git: 3 commits - sw/inc sw/source

Miklos Vajna vmiklos at collabora.co.uk
Fri Jun 13 01:58:53 PDT 2014


 sw/inc/textboxhelper.hxx             |   17 ++++++++++
 sw/source/core/doc/doclay.cxx        |    9 ++++-
 sw/source/core/doc/textboxhelper.cxx |   58 +++++++++++++++++++++++++++++++++++
 sw/source/core/docnode/ndcopy.cxx    |   28 +++-------------
 4 files changed, 87 insertions(+), 25 deletions(-)

New commits:
commit da22fb668d21d20432232034cd54af509ded1bbf
Author: Miklos Vajna <vmiklos at collabora.co.uk>
Date:   Fri Jun 13 10:32:46 2014 +0200

    SwTextBoxHelper::syncProperty: handle FN_TEXT_RANGE
    
    The TextRange property of a shape is its anchor position: if that's
    adjusted, then also set the textbox's RES_ANCHOR to the new position.
    
    Without this, e.g. shapes anchored in headers have their textboxes
    anchored in the body text, CppunitTest_sw_ooxmlexport's testfdo78420 is
    a reproducer.
    
    Change-Id: I83ed09875c3f0360c581c331507ad2b9d05ffb3a

diff --git a/sw/source/core/doc/textboxhelper.cxx b/sw/source/core/doc/textboxhelper.cxx
index eac7e57..06bc0e0 100644
--- a/sw/source/core/doc/textboxhelper.cxx
+++ b/sw/source/core/doc/textboxhelper.cxx
@@ -10,6 +10,7 @@
 #include <textboxhelper.hxx>
 #include <frmfmt.hxx>
 #include <fmtcntnt.hxx>
+#include <fmtanchr.hxx>
 #include <doc.hxx>
 #include <docsh.hxx>
 #include <docary.hxx>
@@ -19,6 +20,7 @@
 #include <unotextbodyhf.hxx>
 #include <unotextrange.hxx>
 #include <unomid.h>
+#include <cmdid.h>
 #include <unoprnms.hxx>
 #include <dflyobj.hxx>
 #include <mvsave.hxx>
@@ -336,6 +338,19 @@ void SwTextBoxHelper::syncProperty(SwFrmFmt* pShape, sal_uInt16 nWID, sal_uInt8
                 break;
             }
             break;
+        case FN_TEXT_RANGE:
+            {
+                uno::Reference<text::XTextRange> xRange;
+                rValue >>= xRange;
+                SwUnoInternalPaM aInternalPaM(*pFmt->GetDoc());
+                if (sw::XTextRangeToSwPaM(aInternalPaM, xRange))
+                {
+                    SwFmtAnchor aAnchor(pFmt->GetAnchor());
+                    aAnchor.SetAnchor(aInternalPaM.Start());
+                    pFmt->SetFmtAttr(aAnchor);
+                }
+            }
+            break;
         }
 
         if (!aPropertyName.isEmpty())
commit 02f2d886c897a286b875f9053052061fe0b357fd
Author: Miklos Vajna <vmiklos at collabora.co.uk>
Date:   Fri Jun 13 09:29:12 2014 +0200

    SwDoc::CopyFlyInFlyImpl: factor out textbox code into SwTextBoxHelper
    
    Also, let the new SwTextBoxHelper::restoreLinks() restore also the
    RES_CNTNT of the *old* draw formats, not only the link between the new
    draw and fly formats.
    
    This allows properly preserving the link between draw and fly formats,
    when they are in the header (and so copied in and out variously).
    
    Change-Id: I101ff06533e2ea27abea8bed171ed69c9649ebe8

diff --git a/sw/inc/textboxhelper.hxx b/sw/inc/textboxhelper.hxx
index 2bb791f..50024e1 100644
--- a/sw/inc/textboxhelper.hxx
+++ b/sw/inc/textboxhelper.hxx
@@ -11,6 +11,9 @@
 #define INCLUDED_SW_INC_TEXTBOXHELPER_HXX
 
 #include <list>
+#include <map>
+#include <set>
+#include <vector>
 
 #include <com/sun/star/drawing/XShape.hpp>
 #include <com/sun/star/uno/Any.h>
@@ -21,8 +24,11 @@
 
 class SdrPage;
 class SwFrmFmt;
+class SwFrmFmts;
+class SwFmtCntnt;
 class SwDoc;
 class Rectangle;
+class _ZSortFly;
 
 /**
  * A TextBox is a TextFrame, that is tied to a drawinglayer shape.
@@ -33,6 +39,10 @@ class Rectangle;
 class SW_DLLPUBLIC SwTextBoxHelper
 {
 public:
+    /// Maps a draw format to a fly format.
+    typedef std::map<const SwFrmFmt*, const SwFrmFmt*> SavedLink;
+    /// Maps a draw format to content.
+    typedef std::map<const SwFrmFmt*, SwFmtCntnt> SavedContent;
     /// Create a TextBox for a shape.
     static void create(SwFrmFmt* pShape);
     /// Destroy a TextBox for a shape.
@@ -57,6 +67,13 @@ public:
     static sal_Int32 getCount(SdrPage* pPage, std::list<SwFrmFmt*>& rTextBoxes);
     /// Get a shape by index, excluding TextBoxes.
     static css::uno::Any getByIndex(SdrPage* pPage, sal_Int32 nIndex, std::list<SwFrmFmt*>& rTextBoxes) throw(css::lang::IndexOutOfBoundsException);
+
+    /// Saves the current shape -> textbox links in a map, so they can be restored later.
+    static void saveLinks(const SwFrmFmts& rFormats, std::map<const SwFrmFmt*, const SwFrmFmt*>& rLinks);
+    /// Reset the shape -> textbox link on the shape, and save it to the map, so it can be restored later.
+    static void resetLink(SwFrmFmt* pShape, std::map<const SwFrmFmt*, SwFmtCntnt>& rOldContent);
+    /// Undo the effect of saveLinks() + individual resetLink() calls.
+    static void restoreLinks(std::set<_ZSortFly>& rOld, std::vector<SwFrmFmt*>& rNew, SavedLink& rSavedLinks, SavedContent& rResetContent);
 };
 
 #endif // INCLUDED_SW_INC_TEXTBOXHELPER_HXX
diff --git a/sw/source/core/doc/textboxhelper.cxx b/sw/source/core/doc/textboxhelper.cxx
index 598d4b8..eac7e57 100644
--- a/sw/source/core/doc/textboxhelper.cxx
+++ b/sw/source/core/doc/textboxhelper.cxx
@@ -21,6 +21,7 @@
 #include <unomid.h>
 #include <unoprnms.hxx>
 #include <dflyobj.hxx>
+#include <mvsave.hxx>
 
 #include <editeng/unoprnms.hxx>
 #include <svx/svdoashp.hxx>
@@ -371,4 +372,46 @@ void SwTextBoxHelper::syncProperty(SwFrmFmt* pShape, sal_uInt16 nWID, sal_uInt8
     }
 }
 
+void SwTextBoxHelper::saveLinks(const SwFrmFmts& rFormats, std::map<const SwFrmFmt*, const SwFrmFmt*>& rLinks)
+{
+    for (size_t i = 0; i < rFormats.size(); ++i)
+    {
+        SwFrmFmt* pFmt = rFormats[i];
+        if (pFmt->Which() != RES_DRAWFRMFMT)
+            continue;
+        if (SwFrmFmt* pTextBox = findTextBox(pFmt))
+            rLinks[pFmt] = pTextBox;
+    }
+}
+
+void SwTextBoxHelper::resetLink(SwFrmFmt* pShape, std::map<const SwFrmFmt*, SwFmtCntnt>& rMap)
+{
+    if (pShape->Which() == RES_DRAWFRMFMT)
+    {
+        if (pShape->GetCntnt().GetCntntIdx())
+            rMap.insert(std::make_pair(pShape, pShape->GetCntnt()));
+        pShape->ResetFmtAttr(RES_CNTNT);
+    }
+}
+
+void SwTextBoxHelper::restoreLinks(std::set<_ZSortFly>& rOld, std::vector<SwFrmFmt*>& rNew, SavedLink& rSavedLinks, SavedContent& rOldContent)
+{
+    size_t i = 0;
+    for (std::set<_ZSortFly>::iterator aSetIt = rOld.begin(); aSetIt != rOld.end(); ++aSetIt, ++i)
+    {
+        SavedLink::iterator aTextBoxIt = rSavedLinks.find(aSetIt->GetFmt());
+        if (aTextBoxIt != rSavedLinks.end())
+        {
+            size_t j = 0;
+            for (std::set<_ZSortFly>::iterator aSetJt = rOld.begin(); aSetJt != rOld.end(); ++aSetJt, ++j)
+            {
+                if (aSetJt->GetFmt() == aTextBoxIt->second)
+                    rNew[i]->SetFmtAttr(rNew[j]->GetCntnt());
+            }
+        }
+        if (rOldContent.find(aSetIt->GetFmt()) != rOldContent.end())
+            const_cast<SwFrmFmt*>(aSetIt->GetFmt())->SetFmtAttr(rOldContent[aSetIt->GetFmt()]);
+    }
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/docnode/ndcopy.cxx b/sw/source/core/docnode/ndcopy.cxx
index 270e2c9..fd9f013 100644
--- a/sw/source/core/docnode/ndcopy.cxx
+++ b/sw/source/core/docnode/ndcopy.cxx
@@ -1415,17 +1415,9 @@ void SwDoc::CopyFlyInFlyImpl(
     ::std::set< _ZSortFly > aSet;
     sal_uInt16 nArrLen = GetSpzFrmFmts()->size();
 
-    // Old textbox -> old shape map.
-    std::map<const SwFrmFmt*, const SwFrmFmt*> aOldTextBoxes;
-
-    for (size_t i = 0; i < GetSpzFrmFmts()->size(); ++i)
-    {
-        SwFrmFmt* pFmt = (*GetSpzFrmFmts())[i];
-        if (pFmt->Which() != RES_DRAWFRMFMT)
-            continue;
-        if (SwFrmFmt* pTextBox = SwTextBoxHelper::findTextBox(pFmt))
-            aOldTextBoxes[pTextBox] = pFmt;
-    }
+    SwTextBoxHelper::SavedLink aOldTextBoxes;
+    SwTextBoxHelper::saveLinks(*GetSpzFrmFmts(), aOldTextBoxes);
+    SwTextBoxHelper::SavedContent aOldContent;
 
     for ( sal_uInt16 n = 0; n < nArrLen; ++n )
     {
@@ -1491,8 +1483,7 @@ void SwDoc::CopyFlyInFlyImpl(
             {
                 // Make sure draw formats don't refer to content, so that such
                 // content can be removed without problems.
-                if (pFmt->Which() == RES_DRAWFRMFMT)
-                    pFmt->ResetFmtAttr(RES_CNTNT);
+                SwTextBoxHelper::resetLink(pFmt, aOldContent);
                 aSet.insert( _ZSortFly( pFmt, pAnchor, nArrLen + aSet.size() ));
             }
         }
@@ -1649,16 +1640,7 @@ void SwDoc::CopyFlyInFlyImpl(
         // Re-create content property of draw formats, knowing how old shapes
         // were paired with old fly formats (aOldTextBoxes) and that aSet is
         // parallel with aVecSwFrmFmt.
-        size_t i = 0;
-        for (std::set<_ZSortFly>::iterator aSetIt = aSet.begin(); aSetIt != aSet.end(); ++aSetIt, ++i)
-        {
-            std::map<const SwFrmFmt*, const SwFrmFmt*>::iterator aDrawIt = aOldTextBoxes.find(aSetIt->GetFmt());
-            if (aDrawIt != aOldTextBoxes.end())
-            {
-                size_t nDrawIndex = std::distance(aOldTextBoxes.begin(), aDrawIt);
-                aVecSwFrmFmt[nDrawIndex]->SetFmtAttr(aVecSwFrmFmt[i]->GetCntnt());
-            }
-        }
+        SwTextBoxHelper::restoreLinks(aSet, aVecSwFrmFmt, aOldTextBoxes, aOldContent);
     }
 }
 
commit 11c94c170500e0bc147ff512789130c770843b1e
Author: Miklos Vajna <vmiklos at collabora.co.uk>
Date:   Fri Jun 13 08:40:18 2014 +0200

    SwDoc::DelLayoutFmt: don't delete content of a draw format
    
    In case a shape (has a draw format) has a textbox (RES_CNTNT of the draw
    format), then that's just a pointer to that content, but the draw format
    doesn't own it: the matching fly format does. So ignore that content
    when deleting the layout format in case of draw formats: that ensures
    when both the draw and the fly format is deleted, deletion is only
    performed once.
    
    Change-Id: Idb4bb19130a6b9acd8f8d3710b9982801b416dda

diff --git a/sw/source/core/doc/doclay.cxx b/sw/source/core/doc/doclay.cxx
index 942ac12..965af9a 100644
--- a/sw/source/core/doc/doclay.cxx
+++ b/sw/source/core/doc/doclay.cxx
@@ -216,7 +216,10 @@ void SwDoc::DelLayoutFmt( SwFrmFmt *pFmt )
         SetAttr( aChain, *rChain.GetNext() );
     }
 
-    const SwNodeIndex* pCntIdx = pFmt->GetCntnt().GetCntntIdx();
+    const SwNodeIndex* pCntIdx = 0;
+    // The draw format doesn't own its content, it just has a pointer to it.
+    if (pFmt->Which() != RES_DRAWFRMFMT)
+        pCntIdx = pFmt->GetCntnt().GetCntntIdx();
     if (pCntIdx && !GetIDocumentUndoRedo().DoesUndo())
     {
         // Disconnect if it's an OLE object
@@ -257,7 +260,9 @@ void SwDoc::DelLayoutFmt( SwFrmFmt *pFmt )
         if ( nWh == RES_FLYFRMFMT )
         {
             // determine frame formats of at-frame anchored objects
-            const SwNodeIndex* pCntntIdx = pFmt->GetCntnt().GetCntntIdx();
+            const SwNodeIndex* pCntntIdx = 0;
+            if (pFmt->Which() != RES_DRAWFRMFMT)
+                pFmt->GetCntnt().GetCntntIdx();
             if ( pCntntIdx )
             {
                 const SwFrmFmts* pTbl = pFmt->GetDoc()->GetSpzFrmFmts();


More information about the Libreoffice-commits mailing list