summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiklos Vajna <vmiklos@collabora.com>2019-03-13 21:35:42 +0100
committerMiklos Vajna <vmiklos@collabora.com>2019-03-14 09:05:50 +0100
commit2f83055cdbd915d5036a7b4374b4ad10e6efc65f (patch)
treef8eb88d7030a771076345d6a2e9ad29d2d6520b9
parent00f96e88a7c6feea98d446e82a2718c5aae6256c (diff)
sw btlr writing mode shell: fix cursor selection
All changes are about not assuming logical top is a lower y value than logical bottom, by going via the SwRectFnSet abstraction, which already does the right thing. Change-Id: I94a9881b018ad14b02e97425f60af01aa3fd9269 Reviewed-on: https://gerrit.libreoffice.org/69226 Tested-by: Jenkins Reviewed-by: Miklos Vajna <vmiklos@collabora.com>
-rw-r--r--sw/inc/swrect.hxx3
-rw-r--r--sw/qa/extras/layout/layout.cxx24
-rw-r--r--sw/source/core/layout/ssfrm.cxx9
-rw-r--r--sw/source/core/layout/trvlfrm.cxx3
4 files changed, 33 insertions, 6 deletions
diff --git a/sw/inc/swrect.hxx b/sw/inc/swrect.hxx
index c4b1889ae4ae..a09b38e81a8c 100644
--- a/sw/inc/swrect.hxx
+++ b/sw/inc/swrect.hxx
@@ -23,6 +23,7 @@
#include <sal/log.hxx>
#include <tools/gen.hxx>
+#include "swdllapi.h"
class SvStream;
@@ -30,7 +31,7 @@ class SvStream;
/// This is half-open so m_Point.X() + m_Size.getWidth() is *not* included.
/// Note the tools Rectangle is (usually? sometimes?) closed so there's a
/// SVRect() to subtract 1 for the conversion.
-class SAL_WARN_UNUSED SwRect
+class SAL_WARN_UNUSED SW_DLLPUBLIC SwRect
{
Point m_Point;
Size m_Size;
diff --git a/sw/qa/extras/layout/layout.cxx b/sw/qa/extras/layout/layout.cxx
index 8fa2b9b821bc..daca397a4d05 100644
--- a/sw/qa/extras/layout/layout.cxx
+++ b/sw/qa/extras/layout/layout.cxx
@@ -2894,6 +2894,30 @@ void SwLayoutWriter::testBtlrCell()
// Without the accompanying fix in place, this test would have failed: character position was 5,
// i.e. cursor was at the end of the paragraph.
CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(0), aPosition.nContent.GetIndex());
+
+ // Test that the selection rectangles are inside the cell frame if we select all the cell
+ // content.
+ SwTwips nCellLeft
+ = getXPath(pXmlDoc, "/root/page/body/tab/row/cell[1]/infos/bounds", "left").toInt32();
+ SwTwips nCellWidth
+ = getXPath(pXmlDoc, "/root/page/body/tab/row/cell[1]/infos/bounds", "width").toInt32();
+ SwTwips nCellTop
+ = getXPath(pXmlDoc, "/root/page/body/tab/row/cell[1]/infos/bounds", "top").toInt32();
+ SwTwips nCellHeight
+ = getXPath(pXmlDoc, "/root/page/body/tab/row/cell[1]/infos/bounds", "height").toInt32();
+ SwRect aCellRect(Point(nCellLeft, nCellTop), Size(nCellWidth, nCellHeight));
+ pWrtShell->SelAll();
+ SwShellCursor* pShellCursor = pWrtShell->getShellCursor(/*bBlock=*/false);
+ CPPUNIT_ASSERT(!pShellCursor->empty());
+ // Without the accompanying fix in place, this test would have failed with:
+ // selection rectangle 269x2573@(1970,2172) is not inside cell rectangle 3207x1134@(1593,1701)
+ // i.e. the selection went past the bottom border of the cell frame.
+ for (const auto& rRect : *pShellCursor)
+ {
+ std::stringstream ss;
+ ss << "selection rectangle " << rRect << " is not inside cell rectangle " << aCellRect;
+ CPPUNIT_ASSERT_MESSAGE(ss.str(), aCellRect.IsInside(rRect));
+ }
#endif
}
diff --git a/sw/source/core/layout/ssfrm.cxx b/sw/source/core/layout/ssfrm.cxx
index 46cf019acbc4..e1c8ec770646 100644
--- a/sw/source/core/layout/ssfrm.cxx
+++ b/sw/source/core/layout/ssfrm.cxx
@@ -680,14 +680,15 @@ const SwRect SwFrame::UnionFrame( bool bBorder ) const
long nWidth = (getFrameArea().*fnRect->fnGetWidth)();
long nPrtLeft = (getFramePrintArea().*fnRect->fnGetLeft)();
long nPrtWidth = (getFramePrintArea().*fnRect->fnGetWidth)();
- if( nPrtLeft + nPrtWidth > nWidth )
+ SwRectFnSet aRectFnSet(this);
+ if (aRectFnSet.XInc(nPrtLeft, nPrtWidth) > nWidth)
nWidth = nPrtLeft + nPrtWidth;
if( nPrtLeft < 0 )
{
nLeft += nPrtLeft;
nWidth -= nPrtLeft;
}
- SwTwips nRight = nLeft + nWidth;
+ SwTwips nRight = aRectFnSet.XInc(nLeft, nWidth);
long nAdd = 0;
if( bBorder )
{
@@ -715,9 +716,9 @@ const SwRect SwFrame::UnionFrame( bool bBorder ) const
if( nTmp > nAdd )
nAdd = nTmp;
}
- nWidth = nRight + nAdd - nLeft;
+ nWidth = aRectFnSet.XDiff(aRectFnSet.XInc(nRight, nAdd), nLeft);
SwRect aRet( getFrameArea() );
- (aRet.*fnRect->fnSetPosX)( nLeft );
+ (aRet.*fnRect->fnSetLeft)(nLeft);
(aRet.*fnRect->fnSetWidth)( nWidth );
return aRet;
}
diff --git a/sw/source/core/layout/trvlfrm.cxx b/sw/source/core/layout/trvlfrm.cxx
index 912cbafbb43e..45d22ab72a29 100644
--- a/sw/source/core/layout/trvlfrm.cxx
+++ b/sw/source/core/layout/trvlfrm.cxx
@@ -2138,6 +2138,7 @@ void SwRootFrame::CalcFrameRects(SwShellCursor &rCursor)
SwRectFnSet aRectFnSet(pStartFrame);
const bool bR2L = pStartFrame->IsRightToLeft();
const bool bEndR2L = pEndFrame->IsRightToLeft();
+ const bool bB2T = pStartFrame->IsVertLRBT();
// If there's no doubleline portion involved or start and end are both
// in the same doubleline portion, all works fine, but otherwise
@@ -2370,7 +2371,7 @@ void SwRootFrame::CalcFrameRects(SwShellCursor &rCursor)
{
Point aTmpSt( aStRect.Pos() );
Point aTmpEnd( aEndRect.Right(), aEndRect.Bottom() );
- if( bSameRotatedOrBidi || bR2L )
+ if (bSameRotatedOrBidi || bR2L || bB2T)
{
if( aTmpSt.Y() > aTmpEnd.Y() )
{