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

Miklos Vajna (via logerrit) logerrit at kemper.freedesktop.org
Fri Jun 21 17:19:27 UTC 2019


 sw/inc/postithelper.hxx                |    3 -
 sw/qa/extras/unowriter/unowriter.cxx   |   14 +++++
 sw/source/core/fields/postithelper.cxx |   88 +++++++++++++++++++++++++++++++--
 sw/source/uibase/docvw/PostItMgr.cxx   |    2 
 4 files changed, 100 insertions(+), 7 deletions(-)

New commits:
commit ac246d6ea1bc43bfc82c9b4c69c9c0f1fd678129
Author:     Miklos Vajna <vmiklos at collabora.com>
AuthorDate: Fri Jun 21 17:55:01 2019 +0200
Commit:     Miklos Vajna <vmiklos at collabora.com>
CommitDate: Fri Jun 21 19:17:58 2019 +0200

    sw comments on frames: fix layout to place anchor next to the image
    
    With this, if you load
    sw/qa/extras/unowriter/data/image-comment-at-char.odt, the comment
    anchor leads to the commented image, not to the anchor of the image
    (between "aaa" and "bbb").
    
    Change-Id: I99389c9fc849269eb20d0266f8f604db89faec12
    Reviewed-on: https://gerrit.libreoffice.org/74519
    Reviewed-by: Miklos Vajna <vmiklos at collabora.com>
    Tested-by: Jenkins

diff --git a/sw/inc/postithelper.hxx b/sw/inc/postithelper.hxx
index 3c22ad9fd357..0a0523cc8e4d 100644
--- a/sw/inc/postithelper.hxx
+++ b/sw/inc/postithelper.hxx
@@ -35,6 +35,7 @@ class IDocumentRedlineAccess;
 namespace sw { namespace annotation {
     class SwAnnotationWin;
 } }
+namespace sw::mark { class IMark; }
 
 struct SwPosition;
 
@@ -78,7 +79,7 @@ namespace SwPostItHelper
     SwLayoutStatus getLayoutInfos(
         SwLayoutInfo& o_rInfo,
         const SwPosition& rAnchorPos,
-        const SwPosition* pAnnotationStartPos = nullptr );
+        const sw::mark::IMark* pAnnotationMark = nullptr );
 
     long getLayoutHeight( const SwRootFrame* pRoot );
     void setSidebarChanged( SwRootFrame* pRoot, bool bBrowseMode );
diff --git a/sw/qa/extras/unowriter/unowriter.cxx b/sw/qa/extras/unowriter/unowriter.cxx
index 38c55cfb74dd..b7b38d4a6da3 100644
--- a/sw/qa/extras/unowriter/unowriter.cxx
+++ b/sw/qa/extras/unowriter/unowriter.cxx
@@ -24,6 +24,9 @@
 #include <ndtxt.hxx>
 #include <swdtflvr.hxx>
 #include <view.hxx>
+#include <PostItMgr.hxx>
+#include <postithelper.hxx>
+#include <AnnotationWin.hxx>
 
 using namespace ::com::sun::star;
 
@@ -561,6 +564,17 @@ CPPUNIT_TEST_FIXTURE(SwUnoWriter, testImageCommentAtChar)
                          getProperty<OUString>(getRun(xPara, 4), "TextPortionType"));
     CPPUNIT_ASSERT_EQUAL(OUString("Text"),
                          getProperty<OUString>(getRun(xPara, 5), "TextPortionType"));
+
+    // Without the accompanying fix in place, this test would have failed with 'Expected:
+    // 5892; Actual: 1738', i.e. the anchor pos was between the "aaa" and "bbb" portions, not at the
+    // center of the page (horizontally) where the image is.
+    SwView* pView = pDoc->GetDocShell()->GetView();
+    SwPostItMgr* pPostItMgr = pView->GetPostItMgr();
+    for (const auto& pItem : *pPostItMgr)
+    {
+        const SwRect& rAnchor = pItem->pPostIt->GetAnchorRect();
+        CPPUNIT_ASSERT_EQUAL(static_cast<long>(5892), rAnchor.Left());
+    }
 }
 
 CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/sw/source/core/fields/postithelper.cxx b/sw/source/core/fields/postithelper.cxx
index dde8d8dcaecf..f613ae4187e7 100644
--- a/sw/source/core/fields/postithelper.cxx
+++ b/sw/source/core/fields/postithelper.cxx
@@ -36,14 +36,77 @@
 #include <scriptinfo.hxx>
 #include <editeng/charhiddenitem.hxx>
 #include <calbck.hxx>
+#include <IMark.hxx>
+#include <sortedobjs.hxx>
+#include <anchoredobject.hxx>
+#include <fmtanchr.hxx>
 #include <tools/solar.h>
 
 class Point;
 
+namespace
+{
+/// Checks if pAnnotationMark covers exactly rAnchorPos (the comment anchor).
+bool AnnotationMarkCoversCommentAnchor(const sw::mark::IMark* pAnnotationMark,
+                                       const SwPosition& rAnchorPos)
+{
+    if (!pAnnotationMark)
+    {
+        return false;
+    }
+
+    const SwPosition& rMarkStart = pAnnotationMark->GetMarkStart();
+    const SwPosition& rMarkEnd = pAnnotationMark->GetMarkEnd();
+
+    if (rMarkStart != rAnchorPos)
+    {
+        return false;
+    }
+
+    if (rMarkStart.nNode != rMarkEnd.nNode)
+    {
+        return false;
+    }
+
+    return rMarkEnd.nContent.GetIndex() == rMarkStart.nContent.GetIndex() + 1;
+}
+
+/**
+ * Finds the first draw object of rTextFrame which has the same anchor position as the start of
+ * rAnnotationMark.
+ */
+SwAnchoredObject* GetAnchoredObjectOfAnnotationMark(const sw::mark::IMark& rAnnotationMark,
+                                                    const SwTextFrame& rTextFrame)
+{
+    const SwSortedObjs* pAnchored = rTextFrame.GetDrawObjs();
+    if (!pAnchored)
+    {
+        return nullptr;
+    }
+
+    for (SwAnchoredObject* pObject : *pAnchored)
+    {
+        SwFrameFormat& rFrameFormat = pObject->GetFrameFormat();
+        const SwPosition* pFrameAnchor = rFrameFormat.GetAnchor().GetContentAnchor();
+        if (!pFrameAnchor)
+        {
+            continue;
+        }
+
+        if (rAnnotationMark.GetMarkStart() == *pFrameAnchor)
+        {
+            return pObject;
+        }
+    }
+
+    return nullptr;
+}
+}
+
 SwPostItHelper::SwLayoutStatus SwPostItHelper::getLayoutInfos(
     SwLayoutInfo& o_rInfo,
     const SwPosition& rAnchorPos,
-    const SwPosition* pAnnotationStartPos )
+    const sw::mark::IMark* pAnnotationMark )
 {
     SwLayoutStatus aRet = INVISIBLE;
     SwTextNode* pTextNode = rAnchorPos.nNode.GetNode().GetTextNode();
@@ -64,12 +127,27 @@ SwPostItHelper::SwLayoutStatus SwPostItHelper::getLayoutInfos(
                 o_rInfo.mpAnchorFrame = pTextFrame;
                 {
                     DisableCallbackAction a(*pTextFrame->getRootFrame());
-                    pTextFrame->GetCharRect(o_rInfo.mPosition, rAnchorPos, nullptr, false);
+                    bool bPositionFromCommentAnchor = true;
+                    if (AnnotationMarkCoversCommentAnchor(pAnnotationMark, rAnchorPos))
+                    {
+                        SwAnchoredObject* pFrame
+                            = GetAnchoredObjectOfAnnotationMark(*pAnnotationMark, *pTextFrame);
+                        if (pFrame)
+                        {
+                            o_rInfo.mPosition = pFrame->GetObjRect();
+                            bPositionFromCommentAnchor = false;
+                        }
+                    }
+                    if (bPositionFromCommentAnchor)
+                    {
+                        pTextFrame->GetCharRect(o_rInfo.mPosition, rAnchorPos, nullptr, false);
+                    }
                 }
-                if ( pAnnotationStartPos != nullptr )
+                if (pAnnotationMark != nullptr)
                 {
-                    o_rInfo.mnStartNodeIdx = pAnnotationStartPos->nNode.GetIndex();
-                    o_rInfo.mnStartContent = pAnnotationStartPos->nContent.GetIndex();
+                    const SwPosition& rAnnotationStartPos = pAnnotationMark->GetMarkStart();
+                    o_rInfo.mnStartNodeIdx = rAnnotationStartPos.nNode.GetIndex();
+                    o_rInfo.mnStartContent = rAnnotationStartPos.nContent.GetIndex();
                 }
                 else
                 {
diff --git a/sw/source/uibase/docvw/PostItMgr.cxx b/sw/source/uibase/docvw/PostItMgr.cxx
index 3f0e6a0c1dc6..78fc9a3b317d 100644
--- a/sw/source/uibase/docvw/PostItMgr.cxx
+++ b/sw/source/uibase/docvw/PostItMgr.cxx
@@ -559,7 +559,7 @@ bool SwPostItMgr::CalcRects()
                         SwPostItHelper::getLayoutInfos(
                             pItem->maLayoutInfo,
                             pItem->GetAnchorPosition(),
-                            &pAnnotationMark->GetMarkStart() );
+                            pAnnotationMark );
                 }
                 else
                 {


More information about the Libreoffice-commits mailing list