Version 7.6.3.2-android, tag libreoffice-7.6.3.2-android
[LibreOffice.git] / sw / qa / core / frmedt / frmedt.cxx
blobf5a12e9392f1e656bcfb1e20fa508c6c0d2ee73c
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 */
10 #include <swmodeltestbase.hxx>
12 #include <com/sun/star/text/VertOrientation.hpp>
13 #include <com/sun/star/drawing/XDrawPageSupplier.hpp>
15 #include <svx/svdpage.hxx>
17 #include <wrtsh.hxx>
18 #include <fmtanchr.hxx>
19 #include <IDocumentDrawModelAccess.hxx>
20 #include <drawdoc.hxx>
21 #include <dcontact.hxx>
22 #include <frameformats.hxx>
23 #include <unotxdoc.hxx>
24 #include <docsh.hxx>
25 #include <swdtflvr.hxx>
26 #include <caption.hxx>
27 #include <view.hxx>
28 #include <formatflysplit.hxx>
30 /// Covers sw/source/core/frmedt/ fixes.
31 class SwCoreFrmedtTest : public SwModelTestBase
33 public:
34 SwCoreFrmedtTest()
35 : SwModelTestBase("/sw/qa/core/frmedt/data/")
40 CPPUNIT_TEST_FIXTURE(SwCoreFrmedtTest, testTextboxReanchor)
42 // Load a document with a textframe and a textbox(shape+textframe).
43 createSwDoc("textbox-reanchor.odt");
44 SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument*>(mxComponent.get());
45 SwDoc* pDoc = pTextDoc->GetDocShell()->GetDoc();
46 SdrPage* pDrawPage = pDoc->getIDocumentDrawModelAccess().GetDrawModel()->GetPage(0);
47 SdrObject* pDrawShape = pDrawPage->GetObj(1);
48 CPPUNIT_ASSERT_EQUAL(OUString("draw shape"), pDrawShape->GetName());
50 // Select the shape of the textbox.
51 Point aPoint;
52 SwWrtShell* pShell = pDoc->GetDocShell()->GetWrtShell();
53 pShell->SelectObj(aPoint, /*nFlag=*/0, pDrawShape);
55 // Anchor the shape of the textbox into its own textframe.
56 SdrObject* pTextFrameObj = pDrawPage->GetObj(2);
57 SwFrameFormat* pTextFrameFormat = FindFrameFormat(pTextFrameObj);
58 CPPUNIT_ASSERT_EQUAL(OUString("Frame2"), pTextFrameFormat->GetName());
59 SwFrameFormat* pDrawShapeFormat = FindFrameFormat(pDrawShape);
60 SwNodeOffset nOldAnchor = pDrawShapeFormat->GetAnchor().GetAnchorNode()->GetIndex();
61 pShell->FindAnchorPos(pTextFrameObj->GetLastBoundRect().Center(), true);
62 SwNodeOffset nNewAnchor = pDrawShapeFormat->GetAnchor().GetAnchorNode()->GetIndex();
63 // Without the accompanying fix in place, this test would have failed with:
64 // - Expected: 6
65 // - Actual : 9
66 // i.e. SwFEShell allowed to anchor the textframe of a textbox into itself.
67 CPPUNIT_ASSERT_EQUAL(nOldAnchor, nNewAnchor);
70 CPPUNIT_TEST_FIXTURE(SwCoreFrmedtTest, testVertPosFromBottomBoundingBox)
72 // Insert a shape and anchor it vertically in a way, so its position is from the top of the page
73 // bottom margin area.
74 createSwDoc();
75 uno::Reference<css::lang::XMultiServiceFactory> xFactory(mxComponent, uno::UNO_QUERY);
76 uno::Reference<drawing::XShape> xShape(
77 xFactory->createInstance("com.sun.star.drawing.RectangleShape"), uno::UNO_QUERY);
78 xShape->setSize(awt::Size(10000, 10000));
79 uno::Reference<beans::XPropertySet> xShapeProps(xShape, uno::UNO_QUERY);
80 xShapeProps->setPropertyValue("AnchorType", uno::Any(text::TextContentAnchorType_AT_CHARACTER));
81 xShapeProps->setPropertyValue("VertOrient", uno::Any(text::VertOrientation::NONE));
82 xShapeProps->setPropertyValue("VertOrientRelation",
83 uno::Any(text::RelOrientation::PAGE_PRINT_AREA_BOTTOM));
84 xShapeProps->setPropertyValue("VertOrientPosition", uno::Any(static_cast<sal_Int32>(-11000)));
85 uno::Reference<drawing::XDrawPageSupplier> xDrawPageSupplier(mxComponent, uno::UNO_QUERY);
86 xDrawPageSupplier->getDrawPage()->add(xShape);
88 // Get the absolute position of the top of the page bottom margin area.
89 xmlDocUniquePtr pXmlDoc = parseLayoutDump();
90 SwTwips nPagePrintAreaBottom = getXPath(pXmlDoc, "//page/infos/prtBounds", "bottom").toInt32();
92 // Calculate the allowed bounding box of the shape, e.g. the shape's position & size dialog uses
93 // this to limit the vertical position to sensible values.
94 SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument*>(mxComponent.get());
95 SwWrtShell* pWrtShell = pTextDoc->GetDocShell()->GetWrtShell();
96 SwRect aBoundRect;
97 RndStdIds eAnchorType = RndStdIds::FLY_AT_CHAR;
98 SwDoc* pDoc = pTextDoc->GetDocShell()->GetDoc();
99 const auto& rFrameFormats = *pDoc->GetFrameFormats();
100 const SwFormatAnchor* pFormatAhchor = &rFrameFormats[0]->GetAnchor();
101 sal_Int16 eHoriRelOrient = text::RelOrientation::PAGE_FRAME;
102 sal_Int16 eVertRelOrient = text::RelOrientation::PAGE_PRINT_AREA_BOTTOM;
103 bool bFollowTextFlow = false;
104 bool bMirror = false;
105 Size aPercentSize;
106 pWrtShell->CalcBoundRect(aBoundRect, eAnchorType, eHoriRelOrient, eVertRelOrient, pFormatAhchor,
107 bFollowTextFlow, bMirror, nullptr, &aPercentSize);
109 // Without the accompanying fix in place, this test would have failed with:
110 // - Expected: -14705
111 // - Actual : -1134
112 // i.e. UI did not allow anchoring a shape 10cm above the bottom of the page due to wrong
113 // bounding box.
114 CPPUNIT_ASSERT_EQUAL(-1 * nPagePrintAreaBottom, aBoundRect.Pos().getY());
117 CPPUNIT_TEST_FIXTURE(SwCoreFrmedtTest, testPasteFlyInTextBox)
119 // Given a document that contains a textbox, which contains an sw image (fly frame)
120 createSwDoc("paste-fly-in-textbox.docx");
121 SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument*>(mxComponent.get());
122 SwDocShell* pDocShell = pTextDoc->GetDocShell();
123 SwWrtShell* pWrtShell = pDocShell->GetWrtShell();
124 SwDoc* pDoc = pDocShell->GetDoc();
125 SdrPage* pPage = pDoc->getIDocumentDrawModelAccess().GetDrawModel()->GetPage(0);
126 SdrObject* pObject = pPage->GetObj(0);
127 pWrtShell->SelectObj(Point(), 0, pObject);
128 CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(3), pDoc->GetSpzFrameFormats()->GetFormatCount());
129 rtl::Reference<SwTransferable> pTransfer = new SwTransferable(*pWrtShell);
130 pTransfer->Cut();
131 CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(0), pDoc->GetSpzFrameFormats()->GetFormatCount());
132 TransferableDataHelper aHelper(pTransfer);
134 // When pasting that to an empty document.
135 SwTransferable::Paste(*pWrtShell, aHelper);
137 // Then we should have the image only once: 3 formats (draw+fly formats for the textbox and a
138 // fly format for the image).
139 // Without the accompanying fix in place, this test would have failed with:
140 // - Expected: 3
141 // - Actual : 4
142 // i.e. the image was pasted twice.
143 CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(3), pDoc->GetSpzFrameFormats()->GetFormatCount());
146 CPPUNIT_TEST_FIXTURE(SwCoreFrmedtTest, testTextBoxSelectCursorPos)
148 // Given a document with a fly+draw format pair (textbox):
149 createSwDoc("paste-fly-in-textbox.docx");
151 // When selecting the fly format:
152 SwDoc* pDoc = getSwDoc();
153 SdrPage* pPage = pDoc->getIDocumentDrawModelAccess().GetDrawModel()->GetPage(0);
154 SdrObject* pFlyObject = pPage->GetObj(1);
155 SwContact* pFlyContact = static_cast<SwContact*>(pFlyObject->GetUserCall());
156 CPPUNIT_ASSERT_EQUAL(static_cast<sal_uInt16>(RES_FLYFRMFMT), pFlyContact->GetFormat()->Which());
157 SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
158 pWrtShell->SelectObj(Point(), 0, pFlyObject);
160 // Then make sure the cursor is the anchor of the draw format:
161 SdrObject* pDrawObject = pPage->GetObj(0);
162 SwDrawContact* pDrawContact = static_cast<SwDrawContact*>(pDrawObject->GetUserCall());
163 SwFrameFormat* pDrawFormat = pDrawContact->GetFormat();
164 CPPUNIT_ASSERT_EQUAL(static_cast<sal_uInt16>(RES_DRAWFRMFMT), pDrawFormat->Which());
165 SwNodeOffset nAnchor = pDrawFormat->GetAnchor().GetContentAnchor()->GetNode().GetIndex();
166 SwNodeOffset nCursor = pWrtShell->GetCurrentShellCursor().GetPointNode().GetIndex();
167 // Without the accompanying fix in place, this test would have failed with:
168 // - Expected: 15 (anchor of draw format)
169 // - Actual : 6 (in-fly-format position)
170 // i.e. the cursor had a broken position after trying to select the fly format.
171 CPPUNIT_ASSERT_EQUAL(nAnchor, nCursor);
174 CPPUNIT_TEST_FIXTURE(SwCoreFrmedtTest, testSplitFlyInsertCaption)
176 // Given a document with a full-page floating table:
177 createSwDoc("floating-table-caption.docx");
179 // When trying to insert a caption below that table:
180 SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
181 pWrtShell->GotoTable("Table1");
182 InsCaptionOpt aOpt;
183 SwView& rView = pWrtShell->GetView();
184 aOpt.SetCategory("Table");
185 aOpt.SetCaption("Numbers English-German");
186 // After, not before.
187 aOpt.SetPos(1);
188 // Without the accompanying fix in place, this call never finished, layout didn't handle content
189 // after the table in a floating table.
190 rView.InsertCaption(&aOpt);
192 // Then make sure the insertion finishes and now this is just a plain table-in-frame:
193 SwDoc* pDoc = getSwDoc();
194 sw::SpzFrameFormats& rFlys = *pDoc->GetSpzFrameFormats();
195 sw::SpzFrameFormat* pFly = rFlys[0];
196 CPPUNIT_ASSERT(!pFly->GetAttrSet().GetFlySplit().GetValue());
199 CPPUNIT_PLUGIN_IMPLEMENT();
201 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */