summaryrefslogtreecommitdiff
path: root/sw
diff options
context:
space:
mode:
authorMiklos Vajna <vmiklos@collabora.com>2023-04-13 08:12:29 +0200
committerMiklos Vajna <vmiklos@collabora.com>2023-04-13 09:22:03 +0200
commit17367a67cd39109006060176b04bc2b174a17e48 (patch)
tree3302f6c5587d887ccd8d289328acba65d754b0fb /sw
parent852af3af0dde3810e323afc3d42d7bd1cd4e67bc (diff)
sw floattable: restrict selection of follow flys
Select a follow flys that is at the top of the page, drag it towards the bottom of the page, release it, it'll jump back to its original position, which is frustrating. The reason for this is that the layout ignores the vertical offset for follow flys on purpose, but this is communicated to the user poorly. Fix the problem by selecting the master fly on fly selection (for split flys), this allows changing the horizontal position for all flys in the chain and changing the vertical position for the master flys. This is now less confusing, since the indicator of the new position is also drawn for the master fly. This is somewhat similar to what 7596e26fd259ce5445212949403e7cd32303b2bd (Add SwTextBoxHelper::findShapes, 2014-06-24) did for textboxes, but there we selected the owning draw shape of the fly frame. Change-Id: Ie8171d32a306bfb5d28cc750db5bbae6021ef72f Reviewed-on: https://gerrit.libreoffice.org/c/core/+/150310 Reviewed-by: Miklos Vajna <vmiklos@collabora.com> Tested-by: Jenkins
Diffstat (limited to 'sw')
-rw-r--r--sw/qa/core/layout/flycnt.cxx33
-rw-r--r--sw/source/core/frmedt/feshview.cxx22
-rw-r--r--sw/source/core/inc/dflyobj.hxx4
3 files changed, 58 insertions, 1 deletions
diff --git a/sw/qa/core/layout/flycnt.cxx b/sw/qa/core/layout/flycnt.cxx
index c72f9fff0459..72591730bfb2 100644
--- a/sw/qa/core/layout/flycnt.cxx
+++ b/sw/qa/core/layout/flycnt.cxx
@@ -9,6 +9,8 @@
#include <swmodeltestbase.hxx>
+#include <svx/svdview.hxx>
+
#include <IDocumentLayoutAccess.hxx>
#include <anchoredobject.hxx>
#include <flyfrms.hxx>
@@ -26,6 +28,7 @@
#include <frameformats.hxx>
#include <cellfrm.hxx>
#include <ndtxt.hxx>
+#include <dflyobj.hxx>
namespace
{
@@ -654,6 +657,36 @@ CPPUNIT_TEST_FIXTURE(Test, testSplitFly3rdRowDelete)
// Without the accompanying fix in place, this test would have failed, page 3 was not deleted.
CPPUNIT_ASSERT(!pPage2->GetNext());
}
+
+CPPUNIT_TEST_FIXTURE(Test, testSplitFly2ndRowSelect)
+{
+ // Given a document with a multi-page floating table:
+ createSwDoc("floattable.docx");
+
+ // When selecting the second row:
+ SwDoc* pDoc = getSwDoc();
+ SwRootFrame* pLayout = pDoc->getIDocumentLayoutAccess().GetCurrentLayout();
+ auto pPage1 = dynamic_cast<SwPageFrame*>(pLayout->Lower());
+ CPPUNIT_ASSERT(pPage1);
+ auto pPage2 = dynamic_cast<SwPageFrame*>(pPage1->GetNext());
+ SwSortedObjs& rPage2Objs = *pPage2->GetSortedObjs();
+ auto pPage2Fly = dynamic_cast<SwFlyAtContentFrame*>(rPage2Objs[0]);
+ const SwRect& aFollowArea = pPage2Fly->getFrameArea();
+ Point aTopCenter((aFollowArea.Left() + aFollowArea.Right()) / 2, aFollowArea.Top());
+ SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
+ pWrtShell->SelectObj(aTopCenter);
+
+ // Then make sure the first row is selected:
+ const SdrMarkList& rMarkList = pWrtShell->GetDrawView()->GetMarkedObjectList();
+ SdrObject* pSelectedObj = rMarkList.GetMark(0)->GetMarkedSdrObj();
+ auto pSelectedVirtObj = dynamic_cast<SwVirtFlyDrawObj*>(pSelectedObj);
+ auto pSelected = static_cast<SwFlyAtContentFrame*>(pSelectedVirtObj->GetFlyFrame());
+ // Without the accompanying fix in place, this test would have failed with:
+ // - Expected: 5
+ // - Actual : 17
+ // i.e. a follow fly was possible to select (instead of its master)
+ CPPUNIT_ASSERT_EQUAL(pPage2Fly->GetPrecede()->GetFrameId(), pSelected->GetFrameId());
+}
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/frmedt/feshview.cxx b/sw/source/core/frmedt/feshview.cxx
index be160057093e..ef9497b53f38 100644
--- a/sw/source/core/frmedt/feshview.cxx
+++ b/sw/source/core/frmedt/feshview.cxx
@@ -90,6 +90,7 @@
#include <sfx2/lokhelper.hxx>
#include <LibreOfficeKit/LibreOfficeKitEnums.h>
#include <calbck.hxx>
+#include <flyfrms.hxx>
#include <basegfx/polygon/b2dpolygontools.hxx>
#include <svx/svxids.hrc>
#include <osl/diagnose.h>
@@ -277,6 +278,27 @@ bool SwFEShell::SelectObj( const Point& rPt, sal_uInt8 nFlag, SdrObject *pObj )
}
}
+ if (rMrkList.GetMarkCount() == 1)
+ {
+ SwFlyFrame* pSelFly = ::GetFlyFromMarked(&rMrkList, this);
+ if (pSelFly && pSelFly->IsFlySplitAllowed())
+ {
+ auto pMaster = static_cast<SwFlyAtContentFrame*>(pSelFly);
+ while (pMaster->IsFollow())
+ {
+ pMaster = pMaster->GetPrecede();
+ }
+ if (pMaster != pSelFly)
+ {
+ // A follow fly frame is selected, select the master instead. Selection of a follow
+ // would not be ideal, since one can't customize its vertical position (always
+ // starts at the top of the page).
+ pDView->UnmarkAll();
+ pDView->MarkObj(pMaster->DrawObj(), Imp()->GetPageView(), bAddSelect, bEnterGroup);
+ }
+ }
+ }
+
if ( rMrkList.GetMarkCount() == 1 )
{
SwFlyFrame *pSelFly = ::GetFlyFromMarked( &rMrkList, this );
diff --git a/sw/source/core/inc/dflyobj.hxx b/sw/source/core/inc/dflyobj.hxx
index 96b12dcf49f8..fe43f24c9045 100644
--- a/sw/source/core/inc/dflyobj.hxx
+++ b/sw/source/core/inc/dflyobj.hxx
@@ -23,6 +23,8 @@
#include <svx/svdovirt.hxx>
#include <svx/svdobj.hxx>
+#include <swdllapi.h>
+
namespace drawinglayer::geometry { class ViewInformation2D; }
class SwFlyFrame;
@@ -62,7 +64,7 @@ public:
// shown multiple times if needed (header/footer).
// For example, if an SwFlyFrameFormat is anchored in a header, then all pages will have a separate
// SwVirtFlyDrawObj in their headers.
-class SwVirtFlyDrawObj final : public SdrVirtObj
+class SW_DLLPUBLIC SwVirtFlyDrawObj final : public SdrVirtObj
{
private:
SwFlyFrame *m_pFlyFrame;