Version 6.4.0.3, tag libreoffice-6.4.0.3
[LibreOffice.git] / sc / qa / extras / anchor.cxx
blob83553c802291e9b258a1842c9995e09fed83ef03
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 <sfx2/dispatch.hxx>
11 #include <svx/svdograf.hxx>
12 #include <svx/svdpage.hxx>
13 #include <test/calc_unoapi_test.hxx>
15 #include <com/sun/star/sheet/XSpreadsheet.hpp>
16 #include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
17 #include <com/sun/star/text/XText.hpp>
19 #include <docsh.hxx>
20 #include <drwlayer.hxx>
21 #include <scitems.hxx>
22 #include <svx/svdocirc.hxx>
23 #include <vcl/scheduler.hxx>
24 #include <tabvwsh.hxx>
26 #include <sc.hrc>
28 using namespace css;
30 namespace sc_apitest
32 class ScAnchorTest : public CalcUnoApiTest
34 public:
35 ScAnchorTest();
37 virtual void tearDown() override;
39 void testUndoAnchor();
40 void testTdf76183();
41 void testODFAnchorTypes();
42 void testCopyColumnWithImages();
43 void testCutWithImages();
44 void testTdf129552();
46 CPPUNIT_TEST_SUITE(ScAnchorTest);
47 CPPUNIT_TEST(testUndoAnchor);
48 CPPUNIT_TEST(testTdf76183);
49 CPPUNIT_TEST(testODFAnchorTypes);
50 CPPUNIT_TEST(testCopyColumnWithImages);
51 CPPUNIT_TEST(testCutWithImages);
52 CPPUNIT_TEST(testTdf129552);
53 CPPUNIT_TEST_SUITE_END();
55 private:
56 uno::Reference<lang::XComponent> mxComponent;
59 ScAnchorTest::ScAnchorTest()
60 : CalcUnoApiTest("sc/qa/unit/data/ods")
64 void ScAnchorTest::testUndoAnchor()
66 OUString aFileURL;
67 createFileURL("document_with_linked_graphic.ods", aFileURL);
68 // open the document with graphic included
69 uno::Reference<css::lang::XComponent> xComponent = loadFromDesktop(aFileURL);
70 CPPUNIT_ASSERT(xComponent.is());
72 // Get the document model
73 SfxObjectShell* pFoundShell = SfxObjectShell::GetShellFromComponent(xComponent);
74 CPPUNIT_ASSERT_MESSAGE("Failed to access document shell", pFoundShell);
76 ScDocShell* pDocSh = dynamic_cast<ScDocShell*>(pFoundShell);
77 CPPUNIT_ASSERT(pDocSh);
79 // Check whether graphic imported well
80 ScDocument& rDoc = pDocSh->GetDocument();
81 ScDrawLayer* pDrawLayer = rDoc.GetDrawLayer();
82 CPPUNIT_ASSERT(pDrawLayer);
84 const SdrPage* pPage = pDrawLayer->GetPage(0);
85 CPPUNIT_ASSERT(pPage);
87 SdrGrafObj* pObject = dynamic_cast<SdrGrafObj*>(pPage->GetObj(0));
88 CPPUNIT_ASSERT(pObject);
89 CPPUNIT_ASSERT(pObject->IsLinkedGraphic());
91 const GraphicObject& rGraphicObj = pObject->GetGraphicObject(true);
92 CPPUNIT_ASSERT_EQUAL(int(GraphicType::Bitmap), int(rGraphicObj.GetGraphic().GetType()));
93 CPPUNIT_ASSERT_EQUAL(sal_uLong(864900), rGraphicObj.GetGraphic().GetSizeBytes());
95 // Get the document controller
96 ScTabViewShell* pViewShell = pDocSh->GetBestViewShell(false);
97 CPPUNIT_ASSERT(pViewShell);
99 // Get the draw view of the document
100 ScDrawView* pDrawView = pViewShell->GetViewData().GetScDrawView();
101 CPPUNIT_ASSERT(pDrawView);
103 // Select graphic object
104 pDrawView->MarkNextObj();
105 CPPUNIT_ASSERT(pDrawView->AreObjectsMarked());
107 // Set Cell Anchor
108 ScDrawLayer::SetCellAnchoredFromPosition(*pObject, rDoc, 0, false);
109 // Check state
110 ScAnchorType oldType = ScDrawLayer::GetAnchorType(*pObject);
111 CPPUNIT_ASSERT_EQUAL(SCA_CELL, oldType);
113 // Change all selected objects to page anchor
114 pViewShell->GetViewData().GetDispatcher().Execute(SID_ANCHOR_PAGE);
115 // Check state
116 ScAnchorType newType = ScDrawLayer::GetAnchorType(*pObject);
117 CPPUNIT_ASSERT_EQUAL(SCA_PAGE, newType);
119 // Undo and check its result.
120 SfxUndoManager* pUndoMgr = rDoc.GetUndoManager();
121 CPPUNIT_ASSERT(pUndoMgr);
122 pUndoMgr->Undo();
124 // Check anchor type
125 CPPUNIT_ASSERT_EQUAL(oldType, ScDrawLayer::GetAnchorType(*pObject));
126 CPPUNIT_ASSERT_EQUAL(int(GraphicType::Bitmap), int(rGraphicObj.GetGraphic().GetType()));
127 CPPUNIT_ASSERT_EQUAL(sal_uLong(864900), rGraphicObj.GetGraphic().GetSizeBytes());
129 pUndoMgr->Redo();
131 // Check anchor type
132 CPPUNIT_ASSERT_EQUAL(newType, ScDrawLayer::GetAnchorType(*pObject));
133 CPPUNIT_ASSERT_EQUAL(int(GraphicType::Bitmap), int(rGraphicObj.GetGraphic().GetType()));
134 CPPUNIT_ASSERT_EQUAL(sal_uLong(864900), rGraphicObj.GetGraphic().GetSizeBytes());
136 ScDrawLayer::SetPageAnchored(*pObject);
137 // Check state
138 oldType = ScDrawLayer::GetAnchorType(*pObject);
139 CPPUNIT_ASSERT_EQUAL(SCA_PAGE, oldType);
141 // Change all selected objects to cell anchor
142 pViewShell->GetViewData().GetDispatcher().Execute(SID_ANCHOR_CELL);
143 // Check state
144 newType = ScDrawLayer::GetAnchorType(*pObject);
145 CPPUNIT_ASSERT_EQUAL(SCA_CELL, newType);
147 pUndoMgr->Undo();
149 // Check anchor type
150 CPPUNIT_ASSERT_EQUAL(oldType, ScDrawLayer::GetAnchorType(*pObject));
151 CPPUNIT_ASSERT_EQUAL(int(GraphicType::Bitmap), int(rGraphicObj.GetGraphic().GetType()));
152 CPPUNIT_ASSERT_EQUAL(sal_uLong(864900), rGraphicObj.GetGraphic().GetSizeBytes());
154 pUndoMgr->Redo();
156 // Check anchor type
157 CPPUNIT_ASSERT_EQUAL(newType, ScDrawLayer::GetAnchorType(*pObject));
158 CPPUNIT_ASSERT_EQUAL(int(GraphicType::Bitmap), int(rGraphicObj.GetGraphic().GetType()));
159 CPPUNIT_ASSERT_EQUAL(sal_uLong(864900), rGraphicObj.GetGraphic().GetSizeBytes());
161 xComponent->dispose();
164 void ScAnchorTest::testTdf76183()
166 uno::Reference<lang::XComponent> xComponent = loadFromDesktop("private:factory/scalc");
167 SfxObjectShell* pFoundShell = SfxObjectShell::GetShellFromComponent(xComponent);
168 ScDocShell* pDocSh = dynamic_cast<ScDocShell*>(pFoundShell);
169 ScDocument& rDoc = pDocSh->GetDocument();
170 ScDrawLayer* pDrawLayer = rDoc.GetDrawLayer();
171 SdrPage* pPage = pDrawLayer->GetPage(0);
173 // Add a circle somewhere below first row.
174 const tools::Rectangle aOrigRect(1000, 1000, 1200, 1200);
175 SdrCircObj* pObj = new SdrCircObj(*pDrawLayer, SdrCircKind::Full, aOrigRect);
176 pPage->InsertObject(pObj);
177 // Anchor to cell
178 ScDrawLayer::SetCellAnchoredFromPosition(*pObj, rDoc, 0, false);
179 const tools::Rectangle& rNewRect = pObj->GetLogicRect();
181 // Set word wrap to true
182 rDoc.ApplyAttr(0, 0, 0, SfxBoolItem(ATTR_LINEBREAK, true));
183 // Add multi-line text to cell to initiate optimal height change
184 uno::Reference<sheet::XSpreadsheetDocument> xDoc(xComponent, uno::UNO_QUERY_THROW);
185 uno::Reference<container::XIndexAccess> xIA(xDoc->getSheets(), uno::UNO_QUERY_THROW);
186 uno::Reference<sheet::XSpreadsheet> xSheet(xIA->getByIndex(0), uno::UNO_QUERY_THROW);
187 uno::Reference<text::XText> xText(xSheet->getCellByPosition(0, 0), uno::UNO_QUERY_THROW);
188 xText->setString("first\nsecond\nthird");
190 // The resize of first row must have moved the object down after its anchor cell
191 CPPUNIT_ASSERT(aOrigRect.Top() < rNewRect.Top());
193 pDocSh->DoClose();
196 void ScAnchorTest::testODFAnchorTypes()
198 OUString aFileURL;
199 createFileURL("3AnchorTypes.ods", aFileURL);
200 // open the document with graphic included
201 uno::Reference<css::lang::XComponent> xComponent = loadFromDesktop(aFileURL);
202 CPPUNIT_ASSERT(xComponent.is());
204 // Get the document model
205 SfxObjectShell* pFoundShell = SfxObjectShell::GetShellFromComponent(xComponent);
206 CPPUNIT_ASSERT_MESSAGE("Failed to access document shell", pFoundShell);
208 ScDocShell* pDocSh = dynamic_cast<ScDocShell*>(pFoundShell);
209 CPPUNIT_ASSERT(pDocSh);
211 // Check whether graphic imported well
212 ScDocument& rDoc = pDocSh->GetDocument();
213 ScDrawLayer* pDrawLayer = rDoc.GetDrawLayer();
214 CPPUNIT_ASSERT(pDrawLayer);
216 const SdrPage* pPage = pDrawLayer->GetPage(0);
217 CPPUNIT_ASSERT(pPage);
219 // Check 1st object: Page anchored
220 SdrGrafObj* pObject = dynamic_cast<SdrGrafObj*>(pPage->GetObj(0));
221 CPPUNIT_ASSERT(pObject);
222 ScAnchorType anchorType = ScDrawLayer::GetAnchorType(*pObject);
223 CPPUNIT_ASSERT_EQUAL(SCA_PAGE, anchorType);
225 // Check 2nd object: Cell anchored, resize with cell
226 pObject = dynamic_cast<SdrGrafObj*>(pPage->GetObj(1));
227 CPPUNIT_ASSERT(pObject);
228 anchorType = ScDrawLayer::GetAnchorType(*pObject);
229 CPPUNIT_ASSERT_EQUAL(SCA_CELL_RESIZE, anchorType);
231 // Check 3rd object: Cell anchored
232 pObject = dynamic_cast<SdrGrafObj*>(pPage->GetObj(2));
233 CPPUNIT_ASSERT(pObject);
234 anchorType = ScDrawLayer::GetAnchorType(*pObject);
235 CPPUNIT_ASSERT_EQUAL(SCA_CELL, anchorType);
237 pDocSh->DoClose();
240 /// Test that copying a column with an image anchored to it also copies the image
241 void ScAnchorTest::testCopyColumnWithImages()
243 OUString aFileURL;
244 createFileURL("3AnchorTypes.ods", aFileURL);
245 // open the document with graphic included
246 uno::Reference<css::lang::XComponent> xComponent = loadFromDesktop(aFileURL);
247 CPPUNIT_ASSERT(xComponent.is());
249 // Get the document model
250 SfxObjectShell* pFoundShell = SfxObjectShell::GetShellFromComponent(xComponent);
251 CPPUNIT_ASSERT_MESSAGE("Failed to access document shell", pFoundShell);
253 ScDocShell* pDocSh = dynamic_cast<ScDocShell*>(pFoundShell);
254 CPPUNIT_ASSERT(pDocSh);
256 ScDocument* pDoc = &(pDocSh->GetDocument());
257 ScDrawLayer* pDrawLayer = pDoc->GetDrawLayer();
258 CPPUNIT_ASSERT(pDrawLayer);
260 // Get the document controller
261 ScTabViewShell* pViewShell = pDocSh->GetBestViewShell(false);
262 CPPUNIT_ASSERT(pViewShell != nullptr);
264 ScDocument aClipDoc(SCDOCMODE_CLIP);
266 // Copy whole column
268 // 1. Copy source range
269 ScRange aSrcRange;
270 aSrcRange.Parse("A1:A11", pDoc, pDoc->GetAddressConvention());
271 pViewShell->GetViewData().GetMarkData().SetMarkArea(aSrcRange);
272 pViewShell->GetViewData().GetView()->CopyToClip(&aClipDoc, false, false, true, false);
274 // 2. Paste to target range
275 ScRange aDstRange;
276 aDstRange.Parse("D1:D11", pDoc, pDoc->GetAddressConvention());
277 pViewShell->GetViewData().GetMarkData().SetMarkArea(aDstRange);
278 pViewShell->GetViewData().GetView()->PasteFromClip(InsertDeleteFlags::ALL, &aClipDoc);
280 // 3. Make sure the images have been copied too
281 std::map<SCROW, std::vector<SdrObject*>> aRowObjects
282 = pDrawLayer->GetObjectsAnchoredToRange(0, 3, 0, 11);
283 CPPUNIT_ASSERT_EQUAL_MESSAGE("There should be an image anchored to D3", 1,
284 static_cast<int>(aRowObjects[2].size()));
285 CPPUNIT_ASSERT_EQUAL_MESSAGE("There should be an image anchored to D11", 1,
286 static_cast<int>(aRowObjects[10].size()));
289 // Copy individual cells
291 // 1. Copy source cells
292 ScRange aSrcRange;
293 aSrcRange.Parse("A3:B3", pDoc, pDoc->GetAddressConvention());
294 pViewShell->GetViewData().GetMarkData().SetMarkArea(aSrcRange);
295 pViewShell->GetViewData().GetView()->CopyToClip(&aClipDoc, false, false, true, false);
297 // 2. Paste to target cells
298 ScRange aDstRange;
299 aDstRange.Parse("G3:H3", pDoc, pDoc->GetAddressConvention());
300 pViewShell->GetViewData().GetMarkData().SetMarkArea(aDstRange);
301 pViewShell->GetViewData().GetView()->PasteFromClip(InsertDeleteFlags::ALL, &aClipDoc);
303 // 3. Make sure the image has been copied too
304 std::map<SCROW, std::vector<SdrObject*>> aRowObjects
305 = pDrawLayer->GetObjectsAnchoredToRange(0, 6, 2, 2);
306 CPPUNIT_ASSERT_EQUAL_MESSAGE("There should be an image anchored to G3", 1,
307 static_cast<int>(aRowObjects[2].size()));
310 pDocSh->DoClose();
313 void ScAnchorTest::testCutWithImages()
315 OUString aFileURL;
316 createFileURL("3AnchorTypes.ods", aFileURL);
317 // open the document with graphic included
318 uno::Reference<css::lang::XComponent> xComponent = loadFromDesktop(aFileURL);
319 CPPUNIT_ASSERT(xComponent.is());
321 // Get the document model
322 SfxObjectShell* pFoundShell = SfxObjectShell::GetShellFromComponent(xComponent);
323 CPPUNIT_ASSERT_MESSAGE("Failed to access document shell", pFoundShell);
325 ScDocShell* pDocSh = dynamic_cast<ScDocShell*>(pFoundShell);
326 CPPUNIT_ASSERT(pDocSh);
328 ScDocument* pDoc = &(pDocSh->GetDocument());
329 ScDrawLayer* pDrawLayer = pDoc->GetDrawLayer();
330 CPPUNIT_ASSERT(pDrawLayer);
332 // Get the document controller
333 ScTabViewShell* pViewShell = pDocSh->GetBestViewShell(false);
334 CPPUNIT_ASSERT(pViewShell != nullptr);
336 // Cut whole column
338 // Cut source range
339 ScRange aSrcRange;
340 aSrcRange.Parse("A1:A11", pDoc, pDoc->GetAddressConvention());
341 pViewShell->GetViewData().GetMarkData().SetMarkArea(aSrcRange);
342 pViewShell->GetViewData().GetView()->CutToClip();
344 std::map<SCROW, std::vector<SdrObject*>> aRowObjects
345 = pDrawLayer->GetObjectsAnchoredToRange(0, 0, 0, 11);
347 // Images should have been removed from the cells
348 CPPUNIT_ASSERT_EQUAL_MESSAGE("There should be no image anchored to A3", 0,
349 static_cast<int>(aRowObjects[2].size()));
350 CPPUNIT_ASSERT_EQUAL_MESSAGE("There should be no image anchored to A11", 0,
351 static_cast<int>(aRowObjects[10].size()));
354 // Cut individual cells
356 // Cut source cells
357 ScRange aSrcRange;
358 aSrcRange.Parse("A3:B3", pDoc, pDoc->GetAddressConvention());
359 pViewShell->GetViewData().GetMarkData().SetMarkArea(aSrcRange);
360 pViewShell->GetViewData().GetView()->CutToClip();
362 // Image should have been removed from the cell
363 std::map<SCROW, std::vector<SdrObject*>> aRowObjects
364 = pDrawLayer->GetObjectsAnchoredToRange(0, 0, 2, 2);
365 CPPUNIT_ASSERT_EQUAL_MESSAGE("There should be no image anchored to A3", 0,
366 static_cast<int>(aRowObjects[2].size()));
369 pDocSh->DoClose();
372 void ScAnchorTest::testTdf129552()
374 OUString aFileURL;
375 createFileURL("tdf129552.fods", aFileURL);
376 uno::Reference<css::lang::XComponent> xComponent = loadFromDesktop(aFileURL);
377 CPPUNIT_ASSERT(xComponent.is());
379 // Without the accompanying fix in place, this test would have never returned due to an infinite
380 // invalidation loop, where ScGridWindow::Paint() invalidated itself.
381 Scheduler::ProcessEventsToIdle();
383 xComponent->dispose();
386 void ScAnchorTest::tearDown()
388 if (mxComponent.is())
390 closeDocument(mxComponent);
393 CalcUnoApiTest::tearDown();
396 CPPUNIT_TEST_SUITE_REGISTRATION(ScAnchorTest);
399 CPPUNIT_PLUGIN_IMPLEMENT();
401 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */