1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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/.
10 #include <officecfg/Office/Common.hxx>
12 #include "sdmodeltestbase.hxx"
14 #include <com/sun/star/uno/Reference.hxx>
16 #include <com/sun/star/awt/Gradient.hpp>
17 #include <com/sun/star/drawing/FillStyle.hpp>
18 #include <com/sun/star/drawing/TextVerticalAdjust.hpp>
19 #include <com/sun/star/drawing/XDrawPagesSupplier.hpp>
20 #include <com/sun/star/drawing/XDrawPages.hpp>
21 #include <com/sun/star/drawing/XDrawPage.hpp>
22 #include <com/sun/star/drawing/XShapes.hpp>
23 #include <com/sun/star/graphic/XGraphic.hpp>
24 #include <com/sun/star/container/XIndexAccess.hpp>
25 #include <com/sun/star/table/XTable.hpp>
26 #include <com/sun/star/table/XMergeableCellRange.hpp>
27 #include <com/sun/star/lang/XSingleServiceFactory.hpp>
29 #include <DrawDocShell.hxx>
30 #include <drawdoc.hxx>
31 #include <vcl/scheduler.hxx>
32 #include <svx/sdr/table/tablecontroller.hxx>
33 #include <sfx2/request.hxx>
34 #include <svx/svdpagv.hxx>
35 #include <svx/svxids.hrc>
36 #include <editeng/eeitem.hxx>
37 #include <editeng/adjustitem.hxx>
38 #include <editeng/outlobj.hxx>
39 #include <editeng/editobj.hxx>
40 #include <comphelper/base64.hxx>
41 #include <docmodel/uno/UnoGradientTools.hxx>
42 #include <undo/undomanager.hxx>
43 #include <GraphicViewShell.hxx>
45 #include <LayerTabBar.hxx>
46 #include <vcl/event.hxx>
47 #include <vcl/keycodes.hxx>
48 #include <svx/svdoashp.hxx>
49 #include <tools/gen.hxx>
50 #include <svx/view3d.hxx>
51 #include <svx/scene3d.hxx>
52 #include <svx/sdmetitm.hxx>
53 #include <unomodel.hxx>
55 using namespace ::com::sun::star
;
57 /// Impress miscellaneous tests.
58 class SdMiscTest
: public SdModelTestBase
62 : SdModelTestBase("/sd/qa/unit/data/")
67 void testTableObjectUndoTest();
68 void testFillGradient();
71 void testTdf101242_ODF_no_settings();
72 void testTdf101242_ODF_add_settings();
73 void testTdf101242_settings_keep();
74 void testTdf101242_settings_remove();
79 void testTextColumns();
80 void testTdf98839_ShearVFlipH();
83 void testTdf129898LayerDrawnInSlideshow();
85 void testEncodedTableStyles();
87 CPPUNIT_TEST_SUITE(SdMiscTest
);
88 CPPUNIT_TEST(testTdf99396
);
89 CPPUNIT_TEST(testTableObjectUndoTest
);
90 CPPUNIT_TEST(testFillGradient
);
91 CPPUNIT_TEST(testTdf44774
);
92 CPPUNIT_TEST(testTdf38225
);
93 CPPUNIT_TEST(testTdf101242_ODF_no_settings
);
94 CPPUNIT_TEST(testTdf101242_ODF_add_settings
);
95 CPPUNIT_TEST(testTdf101242_settings_keep
);
96 CPPUNIT_TEST(testTdf101242_settings_remove
);
97 CPPUNIT_TEST(testTdf119392
);
98 CPPUNIT_TEST(testTdf67248
);
99 CPPUNIT_TEST(testTdf119956
);
100 CPPUNIT_TEST(testTdf120527
);
101 CPPUNIT_TEST(testTextColumns
);
102 CPPUNIT_TEST(testTdf98839_ShearVFlipH
);
103 CPPUNIT_TEST(testTdf130988
);
104 CPPUNIT_TEST(testTdf131033
);
105 CPPUNIT_TEST(testTdf129898LayerDrawnInSlideshow
);
106 CPPUNIT_TEST(testTdf136956
);
107 CPPUNIT_TEST(testEncodedTableStyles
);
108 CPPUNIT_TEST_SUITE_END();
111 void SdMiscTest::testTdf99396()
113 // Load the document and select the table.
114 createSdImpressDoc("tdf99396.odp");
116 SdXImpressDocument
* pXImpressDocument
= dynamic_cast<SdXImpressDocument
*>(mxComponent
.get());
117 CPPUNIT_ASSERT(pXImpressDocument
);
118 sd::ViewShell
* pViewShell
= pXImpressDocument
->GetDocShell()->GetViewShell();
120 SdPage
* pPage
= pViewShell
->GetActualPage();
121 SdrObject
* pObject
= pPage
->GetObj(0);
122 SdrView
* pView
= pViewShell
->GetView();
123 pView
->MarkObj(pObject
, pView
->GetSdrPageView());
125 SdDrawDocument
* pDoc
= pXImpressDocument
->GetDoc();
126 // Make sure that the undo stack is empty.
127 CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(0), pDoc
->GetUndoManager()->GetUndoActionCount());
129 // Set the vertical alignment of the cells to bottom.
130 sdr::table::SvxTableController
* pTableController
131 = dynamic_cast<sdr::table::SvxTableController
*>(pView
->getSelectionController().get());
132 CPPUNIT_ASSERT(pTableController
);
133 SfxRequest
aRequest(*pViewShell
->GetViewFrame(), SID_TABLE_VERT_BOTTOM
);
134 pTableController
->Execute(aRequest
);
135 // This was 0, it wasn't possible to undo a vertical alignment change.
136 CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), pDoc
->GetUndoManager()->GetUndoActionCount());
139 void SdMiscTest::testTableObjectUndoTest()
141 // See tdf#99396 for the issue
143 // Load the document and select the table.
144 createSdImpressDoc("tdf99396.odp");
145 SdXImpressDocument
* pXImpressDocument
= dynamic_cast<SdXImpressDocument
*>(mxComponent
.get());
146 CPPUNIT_ASSERT(pXImpressDocument
);
147 sd::ViewShell
* pViewShell
= pXImpressDocument
->GetDocShell()->GetViewShell();
148 SdPage
* pPage
= pViewShell
->GetActualPage();
149 auto pTableObject
= dynamic_cast<sdr::table::SdrTableObj
*>(pPage
->GetObj(0));
150 CPPUNIT_ASSERT(pTableObject
);
151 SdrView
* pView
= pViewShell
->GetView();
152 pView
->MarkObj(pTableObject
, pView
->GetSdrPageView());
154 SdDrawDocument
* pDoc
= pXImpressDocument
->GetDoc();
155 // Make sure that the undo stack is empty.
156 CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(0), pDoc
->GetUndoManager()->GetUndoActionCount());
158 // Set horizontal and vertical adjustment during text edit.
159 pView
->SdrBeginTextEdit(pTableObject
);
160 CPPUNIT_ASSERT(pView
->GetTextEditObject());
162 SfxRequest
aRequest(*pViewShell
->GetViewFrame(), SID_ATTR_PARA_ADJUST_RIGHT
);
163 SfxItemSet
aEditAttr(pDoc
->GetPool());
164 pView
->GetAttributes(aEditAttr
);
165 SfxItemSet
aNewAttr(*(aEditAttr
.GetPool()), aEditAttr
.GetRanges());
166 aNewAttr
.Put(SvxAdjustItem(SvxAdjust::Right
, EE_PARA_JUST
));
167 aRequest
.Done(aNewAttr
);
168 const SfxItemSet
* pArgs
= aRequest
.GetArgs();
169 pView
->SetAttributes(*pArgs
);
171 const auto& pLocalUndoManager
= pView
->getViewLocalUndoManager();
172 CPPUNIT_ASSERT_EQUAL(size_t(1), pLocalUndoManager
->GetUndoActionCount());
173 CPPUNIT_ASSERT_EQUAL(OUString("Apply attributes"), pLocalUndoManager
->GetUndoActionComment());
175 auto pTableController
176 = dynamic_cast<sdr::table::SvxTableController
*>(pView
->getSelectionController().get());
177 CPPUNIT_ASSERT(pTableController
);
178 SfxRequest
aRequest(*pViewShell
->GetViewFrame(), SID_TABLE_VERT_BOTTOM
);
179 pTableController
->Execute(aRequest
);
181 // Global change "Format cell" is applied only - Change the vertical alignment to "Bottom"
182 CPPUNIT_ASSERT_EQUAL(size_t(1), pDoc
->GetUndoManager()->GetUndoActionCount());
183 CPPUNIT_ASSERT_EQUAL(OUString("Format cell"), pDoc
->GetUndoManager()->GetUndoActionComment());
185 pView
->SdrEndTextEdit();
187 // End of text edit, so the text edit action is added to the undo stack
188 CPPUNIT_ASSERT_EQUAL(size_t(2), pDoc
->GetUndoManager()->GetUndoActionCount());
189 CPPUNIT_ASSERT_EQUAL(OUString("Edit text of Table"),
190 pDoc
->GetUndoManager()->GetUndoActionComment(0));
191 CPPUNIT_ASSERT_EQUAL(OUString("Format cell"), pDoc
->GetUndoManager()->GetUndoActionComment(1));
193 // Check that the result is what we expect.
195 uno::Reference
<table::XTable
> xTable
= pTableObject
->getTable();
196 uno::Reference
<beans::XPropertySet
> xCell(xTable
->getCellByPosition(0, 0), uno::UNO_QUERY
);
197 drawing::TextVerticalAdjust eAdjust
198 = xCell
->getPropertyValue("TextVerticalAdjust").get
<drawing::TextVerticalAdjust
>();
199 CPPUNIT_ASSERT_EQUAL(int(drawing::TextVerticalAdjust_BOTTOM
), static_cast<int>(eAdjust
));
202 const EditTextObject
& rEdit
203 = pTableObject
->getText(0)->GetOutlinerParaObject()->GetTextObject();
204 const SfxItemSet
& rParaAttribs
= rEdit
.GetParaAttribs(0);
205 auto pAdjust
= rParaAttribs
.GetItem(EE_PARA_JUST
);
206 CPPUNIT_ASSERT_EQUAL(SvxAdjust::Right
, pAdjust
->GetAdjust());
210 pXImpressDocument
->GetDocShell()->GetUndoManager()->Undo();
212 // Undoing the last action - one left
213 CPPUNIT_ASSERT_EQUAL(size_t(1), pDoc
->GetUndoManager()->GetUndoActionCount());
214 CPPUNIT_ASSERT_EQUAL(OUString("Format cell"), pDoc
->GetUndoManager()->GetUndoActionComment(0));
216 // Check again that the result is what we expect.
218 uno::Reference
<table::XTable
> xTable
= pTableObject
->getTable();
219 uno::Reference
<beans::XPropertySet
> xCell(xTable
->getCellByPosition(0, 0), uno::UNO_QUERY
);
220 drawing::TextVerticalAdjust eAdjust
221 = xCell
->getPropertyValue("TextVerticalAdjust").get
<drawing::TextVerticalAdjust
>();
222 // This failed: Undo() did not change it from drawing::TextVerticalAdjust_BOTTOM.
223 CPPUNIT_ASSERT_EQUAL(int(drawing::TextVerticalAdjust_TOP
), static_cast<int>(eAdjust
));
226 const EditTextObject
& rEdit
227 = pTableObject
->getText(0)->GetOutlinerParaObject()->GetTextObject();
228 const SfxItemSet
& rParaAttribs
= rEdit
.GetParaAttribs(0);
229 auto pAdjust
= rParaAttribs
.GetItem(EE_PARA_JUST
);
230 CPPUNIT_ASSERT_EQUAL(SvxAdjust::Center
, pAdjust
->GetAdjust());
233 Scheduler::ProcessEventsToIdle();
234 CPPUNIT_ASSERT_EQUAL(size_t(1), pDoc
->GetUndoManager()->GetUndoActionCount());
235 CPPUNIT_ASSERT_EQUAL(OUString("Format cell"), pDoc
->GetUndoManager()->GetUndoActionComment(0));
238 * now test tdf#103950 - Undo does not revert bundled font size changes for table cells
240 pTableObject
= dynamic_cast<sdr::table::SdrTableObj
*>(pPage
->GetObj(0));
241 pView
->MarkObj(pTableObject
, pView
->GetSdrPageView()); // select table
243 SfxRequest
aRequest(*pViewShell
->GetViewFrame(), SID_GROW_FONT_SIZE
);
244 static_cast<sd::DrawViewShell
*>(pViewShell
)->ExecChar(aRequest
);
246 Scheduler::ProcessEventsToIdle();
247 CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(3), pDoc
->GetUndoManager()->GetUndoActionCount());
248 CPPUNIT_ASSERT_EQUAL(OUString("Apply attributes to Table"),
249 pDoc
->GetUndoManager()->GetUndoActionComment(0));
250 CPPUNIT_ASSERT_EQUAL(OUString("Grow font size"),
251 pDoc
->GetUndoManager()->GetUndoActionComment(1));
252 CPPUNIT_ASSERT_EQUAL(OUString("Format cell"), pDoc
->GetUndoManager()->GetUndoActionComment(2));
255 void SdMiscTest::testFillGradient()
257 createSdImpressDoc();
258 uno::Reference
<drawing::XDrawPagesSupplier
> xDrawPagesSupplier(mxComponent
, uno::UNO_QUERY
);
259 uno::Reference
<drawing::XDrawPages
> xDrawPages
= xDrawPagesSupplier
->getDrawPages();
260 // Insert a new page.
261 uno::Reference
<drawing::XDrawPage
> xDrawPage(xDrawPages
->insertNewByIndex(0),
263 uno::Reference
<drawing::XShapes
> xShapes(xDrawPage
, uno::UNO_QUERY_THROW
);
264 // Create a rectangle
265 uno::Reference
<lang::XMultiServiceFactory
> xFactory(mxComponent
, uno::UNO_QUERY
);
266 CPPUNIT_ASSERT(xFactory
.is());
267 uno::Reference
<drawing::XShape
> xShape1(
268 xFactory
->createInstance("com.sun.star.drawing.RectangleShape"), uno::UNO_QUERY_THROW
);
269 uno::Reference
<beans::XPropertySet
> xPropSet(xShape1
, uno::UNO_QUERY_THROW
);
270 // Set FillStyle and FillGradient
271 awt::Gradient aGradient
;
272 aGradient
.StartColor
= sal_Int32(Color(255, 0, 0));
273 aGradient
.EndColor
= sal_Int32(Color(0, 255, 0));
274 xPropSet
->setPropertyValue("FillStyle", uno::Any(drawing::FillStyle_GRADIENT
));
275 xPropSet
->setPropertyValue("FillGradient", uno::Any(aGradient
));
276 // Add the rectangle to the page.
277 xShapes
->add(xShape1
);
279 // Retrieve the shape and check FillStyle and FillGradient
280 uno::Reference
<container::XIndexAccess
> xIndexAccess(xDrawPage
, uno::UNO_QUERY_THROW
);
281 uno::Reference
<beans::XPropertySet
> xPropSet2(xIndexAccess
->getByIndex(0),
282 uno::UNO_QUERY_THROW
);
283 drawing::FillStyle eFillStyle
;
284 awt::Gradient2 aGradient2
;
285 CPPUNIT_ASSERT(xPropSet2
->getPropertyValue("FillStyle") >>= eFillStyle
);
286 CPPUNIT_ASSERT_EQUAL(int(drawing::FillStyle_GRADIENT
), static_cast<int>(eFillStyle
));
287 CPPUNIT_ASSERT(xPropSet2
->getPropertyValue("FillGradient") >>= aGradient2
);
289 // MCGR: Use the completely imported gradient to check for correctness
290 const basegfx::BColorStops aColorStops
291 = model::gradient::getColorStopsFromUno(aGradient2
.ColorStops
);
293 CPPUNIT_ASSERT_EQUAL(size_t(2), aColorStops
.size());
294 CPPUNIT_ASSERT(basegfx::fTools::equal(aColorStops
[0].getStopOffset(), 0.0));
295 CPPUNIT_ASSERT_EQUAL(aColorStops
[0].getStopColor(), basegfx::BColor(1.0, 0.0, 0.0));
296 CPPUNIT_ASSERT(basegfx::fTools::equal(aColorStops
[1].getStopOffset(), 1.0));
297 CPPUNIT_ASSERT_EQUAL(aColorStops
[1].getStopColor(), basegfx::BColor(0.0, 1.0, 0.0));
300 void SdMiscTest::testTdf44774()
303 SdXImpressDocument
* pXImpressDocument
= dynamic_cast<SdXImpressDocument
*>(mxComponent
.get());
304 CPPUNIT_ASSERT(pXImpressDocument
);
305 sd::DrawDocShell
* pDocShell
= pXImpressDocument
->GetDocShell();
307 SfxStyleSheetBasePool
* pSSPool
= pDocShell
->GetStyleSheetPool();
309 // Create a new style with an empty name, like what happens in UI when creating a new style
310 SfxStyleSheetBase
& rStyleA
311 = pSSPool
->Make("", SfxStyleFamily::Para
, SfxStyleSearchBits::UserDefined
);
312 // Assign a new name, which does not yet set its ApiName
313 rStyleA
.SetName("StyleA");
314 // Create another style
315 SfxStyleSheetBase
& rStyleB
316 = pSSPool
->Make("StyleB", SfxStyleFamily::Para
, SfxStyleSearchBits::UserDefined
);
317 // ... and set its parent to the first one
318 rStyleB
.SetParent("StyleA");
320 // Now save the file and reload
321 saveAndReload("draw8");
322 pXImpressDocument
= dynamic_cast<SdXImpressDocument
*>(mxComponent
.get());
323 CPPUNIT_ASSERT(pXImpressDocument
);
324 pDocShell
= pXImpressDocument
->GetDocShell();
325 pSSPool
= pDocShell
->GetStyleSheetPool();
327 SfxStyleSheetBase
* pStyle
= pSSPool
->Find("StyleB", SfxStyleFamily::Para
);
328 CPPUNIT_ASSERT(pStyle
);
329 // The parent set in StyleB used to reset, because parent style's msApiName was empty
330 CPPUNIT_ASSERT_EQUAL(OUString("StyleA"), pStyle
->GetParent());
333 void SdMiscTest::testTdf38225()
335 createSdImpressDoc();
336 SdXImpressDocument
* pXImpressDocument
= dynamic_cast<SdXImpressDocument
*>(mxComponent
.get());
337 CPPUNIT_ASSERT(pXImpressDocument
);
338 sd::DrawDocShell
* pDocShell
= pXImpressDocument
->GetDocShell();
340 SfxStyleSheetBasePool
* pSSPool
= pDocShell
->GetStyleSheetPool();
342 // Create a new style with a name
343 pSSPool
->Make("StyleWithName1", SfxStyleFamily::Para
, SfxStyleSearchBits::UserDefined
);
345 // Now save the file and reload
346 saveAndReload("draw8");
347 pXImpressDocument
= dynamic_cast<SdXImpressDocument
*>(mxComponent
.get());
348 CPPUNIT_ASSERT(pXImpressDocument
);
349 pDocShell
= pXImpressDocument
->GetDocShell();
350 pSSPool
= pDocShell
->GetStyleSheetPool();
352 SfxStyleSheetBase
* pStyle
= pSSPool
->Find("StyleWithName1", SfxStyleFamily::Para
);
353 CPPUNIT_ASSERT(pStyle
);
356 CPPUNIT_ASSERT(pStyle
->SetName("StyleWithName2"));
358 // Save the file and reload again
359 saveAndReload("draw8");
360 pXImpressDocument
= dynamic_cast<SdXImpressDocument
*>(mxComponent
.get());
361 CPPUNIT_ASSERT(pXImpressDocument
);
362 pDocShell
= pXImpressDocument
->GetDocShell();
363 pSSPool
= pDocShell
->GetStyleSheetPool();
365 // The problem was that the style kept the old name upon reloading
366 pStyle
= pSSPool
->Find("StyleWithName1", SfxStyleFamily::Para
);
367 CPPUNIT_ASSERT(!pStyle
);
368 pStyle
= pSSPool
->Find("StyleWithName2", SfxStyleFamily::Para
);
369 CPPUNIT_ASSERT(pStyle
);
372 void SdMiscTest::testTdf120527()
374 createSdImpressDoc();
376 // Load a bitmap into the bitmap table.
377 uno::Reference
<lang::XMultiServiceFactory
> xFactory(mxComponent
, uno::UNO_QUERY
);
378 CPPUNIT_ASSERT(xFactory
.is());
379 uno::Reference
<container::XNameContainer
> xBitmaps(
380 xFactory
->createInstance("com.sun.star.drawing.BitmapTable"), uno::UNO_QUERY
);
381 CPPUNIT_ASSERT(xBitmaps
.is());
382 OUString aGraphicURL
= createFileURL(u
"tdf120527.jpg");
383 xBitmaps
->insertByName("test", uno::Any(aGraphicURL
));
386 uno::Reference
<drawing::XShape
> xShape(
387 xFactory
->createInstance("com.sun.star.drawing.GraphicObjectShape"), uno::UNO_QUERY
);
388 CPPUNIT_ASSERT(xShape
.is());
389 uno::Reference
<beans::XPropertySet
> xShapeProperySet(xShape
, uno::UNO_QUERY
);
390 CPPUNIT_ASSERT(xShapeProperySet
.is());
391 xShapeProperySet
->setPropertyValue("GraphicURL", xBitmaps
->getByName("test"));
394 uno::Reference
<drawing::XDrawPagesSupplier
> xDrawPagesSupplier(mxComponent
, uno::UNO_QUERY
);
395 CPPUNIT_ASSERT(xDrawPagesSupplier
.is());
396 uno::Reference
<drawing::XDrawPages
> xDrawPages
= xDrawPagesSupplier
->getDrawPages();
397 CPPUNIT_ASSERT(xDrawPages
.is());
398 uno::Reference
<drawing::XDrawPage
> xDrawPage(xDrawPages
->getByIndex(0), uno::UNO_QUERY
);
399 CPPUNIT_ASSERT(xDrawPage
.is());
400 // This failed with a lang.IllegalArgumentException.
401 xDrawPage
->add(xShape
);
403 // Verify that the graphic was actually consumed.
404 uno::Reference
<graphic::XGraphic
> xGraphic
;
405 xShapeProperySet
->getPropertyValue("Graphic") >>= xGraphic
;
406 CPPUNIT_ASSERT(xGraphic
.is());
409 // Testing document model part of editengine-columns
410 void SdMiscTest::testTextColumns()
412 createSdImpressDoc();
413 uno::Reference
<drawing::XDrawPagesSupplier
> xDrawPagesSupplier(mxComponent
, uno::UNO_QUERY
);
414 uno::Reference
<drawing::XDrawPages
> xDrawPages
= xDrawPagesSupplier
->getDrawPages();
415 // Insert a new page.
416 uno::Reference
<drawing::XDrawPage
> xDrawPage(xDrawPages
->insertNewByIndex(0),
418 uno::Reference
<drawing::XShapes
> xShapes(xDrawPage
, uno::UNO_QUERY_THROW
);
421 // Create a text shape
422 uno::Reference
<lang::XMultiServiceFactory
> xFactory(mxComponent
, uno::UNO_QUERY
);
423 CPPUNIT_ASSERT(xFactory
.is());
424 uno::Reference
<drawing::XShape
> xShape(
425 xFactory
->createInstance("com.sun.star.drawing.TextShape"), uno::UNO_QUERY_THROW
);
426 uno::Reference
<beans::XPropertySet
> xPropSet(xShape
, uno::UNO_QUERY_THROW
);
428 // Add the shape to the page.
429 xShapes
->add(xShape
);
432 auto pTextObj
= DynCastSdrTextObj(SdrObject::getSdrObjectFromXShape(xShape
));
433 CPPUNIT_ASSERT(pTextObj
);
434 pTextObj
->SetMergedItem(SfxInt16Item(SDRATTR_TEXTCOLUMNS_NUMBER
, 2));
435 pTextObj
->SetMergedItem(SdrMetricItem(SDRATTR_TEXTCOLUMNS_SPACING
, 1000));
439 // Retrieve the shape and check columns
440 uno::Reference
<container::XIndexAccess
> xIndexAccess(xDrawPage
, uno::UNO_QUERY_THROW
);
441 uno::Reference
<drawing::XShape
> xShape(xIndexAccess
->getByIndex(0), uno::UNO_QUERY_THROW
);
443 auto pTextObj
= DynCastSdrTextObj(SdrObject::getSdrObjectFromXShape(xShape
));
444 CPPUNIT_ASSERT(pTextObj
);
446 CPPUNIT_ASSERT_EQUAL(sal_Int16(2), pTextObj
->GetTextColumnsNumber());
447 CPPUNIT_ASSERT_EQUAL(sal_Int32(1000), pTextObj
->GetTextColumnsSpacing());
451 /// Draw miscellaneous tests.
453 // Since LO 6.2 the visible/printable/locked information for layers is always
454 // written as ODF attributes draw:display and draw:protected. It is only read from
455 // there, if the config items VisibleLayers, PrintableLayers and LockedLayers do
456 // not exist. The user option WriteLayerStateAsConfigItem can be set to 'true' to
457 // write these config items in addition to the ODF attributes for to produce
458 // documents for older LO versions or Apache OpenOffice. With value 'false' no
459 // config items are written. The 'testTdf101242_xyz' tests combine source
460 // files with and without config items with option values 'true' and 'false'.
462 void SdMiscTest::testTdf101242_ODF_add_settings()
464 // Loads a document, which has the visible/printable/locked information for layers
465 // only in the ODF attributes draw:display and draw:protected. The resaved document
466 // should still have the ODF attributes and in addition the config items in settings.xml.
467 // "Load" is needed for to handle layers, simple "loadURL" does not work.
468 createSdDrawDoc("tdf101242_ODF.odg");
470 // Saving including items in settings.xml
471 std::shared_ptr
<comphelper::ConfigurationChanges
> pBatch(
472 comphelper::ConfigurationChanges::create());
473 officecfg::Office::Common::Misc::WriteLayerStateAsConfigItem::set(true, pBatch
);
477 // Verify, that the saved document still has the ODF attributes
478 xmlDocUniquePtr pXmlDoc
= parseExport("styles.xml");
479 CPPUNIT_ASSERT_MESSAGE("Failed to get 'styles.xml'", pXmlDoc
);
480 const OString
sPathStart(
481 "/office:document-styles/office:master-styles/draw:layer-set/draw:layer");
483 sPathStart
+ "[@draw:name='backgroundobjects' and @draw:protected='true']");
484 assertXPath(pXmlDoc
, sPathStart
+ "[@draw:name='controls' and @draw:display='screen']");
485 assertXPath(pXmlDoc
, sPathStart
+ "[@draw:name='measurelines' and @draw:display='printer']");
487 // Verify, that the saved document has got the items in settings.xml
488 xmlDocUniquePtr pXmlDoc2
= parseExport("settings.xml");
489 CPPUNIT_ASSERT_MESSAGE("Failed to get 'settings.xml'", pXmlDoc2
);
490 const OString
sPathStart2("/office:document-settings/office:settings/"
491 "config:config-item-set[@config:name='ooo:view-settings']/"
492 "config:config-item-map-indexed[@config:name='Views']/"
493 "config:config-item-map-entry");
494 // Value is a bitfield with first Byte in order '* * * measurelines controls backgroundobjects background layout'
495 // The first three bits depend on initialization and may change. The values in file are Base64 encoded.
497 uno::Sequence
<sal_Int8
> aDecodedSeq
;
498 sBase64
= getXPathContent(pXmlDoc2
,
499 sPathStart2
+ "/config:config-item[@config:name='VisibleLayers']");
500 CPPUNIT_ASSERT_MESSAGE("Item VisibleLayers does not exists.", !sBase64
.isEmpty());
501 comphelper::Base64::decode(aDecodedSeq
, sBase64
);
502 CPPUNIT_ASSERT_EQUAL(0x0F, static_cast<sal_uInt8
>(aDecodedSeq
[0]) & 0x1F);
504 sBase64
= getXPathContent(pXmlDoc2
,
505 sPathStart2
+ "/config:config-item[@config:name='PrintableLayers']");
506 CPPUNIT_ASSERT_MESSAGE("Item PrintableLayers does not exists.", !sBase64
.isEmpty());
507 comphelper::Base64::decode(aDecodedSeq
, sBase64
);
508 CPPUNIT_ASSERT_EQUAL(0x17, static_cast<sal_uInt8
>(aDecodedSeq
[0]) & 0x1F);
510 sBase64
= getXPathContent(pXmlDoc2
,
511 sPathStart2
+ "/config:config-item[@config:name='LockedLayers']");
512 CPPUNIT_ASSERT_MESSAGE("Item LockedLayers does not exists.", !sBase64
.isEmpty());
513 comphelper::Base64::decode(aDecodedSeq
, sBase64
);
514 CPPUNIT_ASSERT_EQUAL(0x04, static_cast<sal_uInt8
>(aDecodedSeq
[0]) & 0x1F);
517 void SdMiscTest::testTdf101242_ODF_no_settings()
519 // Loads a document, which has the visible/printable/locked information for layers
520 // only in the ODF attributes draw:display and draw:protected. The resave document
521 // should have only the ODF attributes and no config items in settings.xml.
522 createSdDrawDoc("tdf101242_ODF.odg");
524 // Saving without items in settings.xml
525 std::shared_ptr
<comphelper::ConfigurationChanges
> pBatch(
526 comphelper::ConfigurationChanges::create());
527 officecfg::Office::Common::Misc::WriteLayerStateAsConfigItem::set(false, pBatch
);
531 // Verify, that the saved document still has the ODF attributes
532 xmlDocUniquePtr pXmlDoc
= parseExport("styles.xml");
533 CPPUNIT_ASSERT_MESSAGE("Failed to get 'styles.xml'", pXmlDoc
);
534 const OString
sPathStart(
535 "/office:document-styles/office:master-styles/draw:layer-set/draw:layer");
537 sPathStart
+ "[@draw:name='backgroundobjects' and @draw:protected='true']");
538 assertXPath(pXmlDoc
, sPathStart
+ "[@draw:name='controls' and @draw:display='screen']");
539 assertXPath(pXmlDoc
, sPathStart
+ "[@draw:name='measurelines' and @draw:display='printer']");
541 // Verify, that the saved document has no layer items in settings.xml
542 xmlDocUniquePtr pXmlDoc2
= parseExport("settings.xml");
543 CPPUNIT_ASSERT_MESSAGE("Failed to get 'settings.xml'", pXmlDoc2
);
544 const OString
sPathStart2("/office:document-settings/office:settings/"
545 "config:config-item-set[@config:name='ooo:view-settings']/"
546 "config:config-item-map-indexed[@config:name='Views']/"
547 "config:config-item-map-entry");
548 assertXPath(pXmlDoc2
, sPathStart2
+ "/config:config-item[@config:name='VisibleLayers']", 0);
549 assertXPath(pXmlDoc2
, sPathStart2
+ "/config:config-item[@config:name='PrintableLayers']", 0);
550 assertXPath(pXmlDoc2
, sPathStart2
+ "/config:config-item[@config:name='LockedLayers']", 0);
553 void SdMiscTest::testTdf101242_settings_keep()
555 // Loads a document, which has the visible/printable/locked information for layers
556 // only in the config items in settings.xml. That is the case for all old documents.
557 // The resaved document should have the ODF attributes draw:display and draw:protected
558 // and should still have these config items in settings.xml.
559 createSdDrawDoc("tdf101242_settings.odg");
561 // Saving including items in settings.xml
562 std::shared_ptr
<comphelper::ConfigurationChanges
> pBatch(
563 comphelper::ConfigurationChanges::create());
564 officecfg::Office::Common::Misc::WriteLayerStateAsConfigItem::set(true, pBatch
);
568 // Verify, that the saved document has the ODF attributes
569 xmlDocUniquePtr pXmlDoc
= parseExport("styles.xml");
570 CPPUNIT_ASSERT_MESSAGE("Failed to get 'styles.xml'", pXmlDoc
);
571 const OString
sPathStart(
572 "/office:document-styles/office:master-styles/draw:layer-set/draw:layer");
574 sPathStart
+ "[@draw:name='backgroundobjects' and @draw:protected='true']");
575 assertXPath(pXmlDoc
, sPathStart
+ "[@draw:name='controls' and @draw:display='screen']");
576 assertXPath(pXmlDoc
, sPathStart
+ "[@draw:name='measurelines' and @draw:display='printer']");
578 // Verify, that the saved document still has the items in settings.xml
579 xmlDocUniquePtr pXmlDoc2
= parseExport("settings.xml");
580 CPPUNIT_ASSERT_MESSAGE("Failed to get 'settings.xml'", pXmlDoc2
);
581 const OString
sPathStart2("/office:document-settings/office:settings/"
582 "config:config-item-set[@config:name='ooo:view-settings']/"
583 "config:config-item-map-indexed[@config:name='Views']/"
584 "config:config-item-map-entry");
585 // Value is a bitfield with first Byte in order '* * * measurelines controls backgroundobjects background layout'
586 // The first three bits depend on initialization and may change. The values in file are Base64 encoded.
588 uno::Sequence
<sal_Int8
> aDecodedSeq
;
589 sBase64
= getXPathContent(pXmlDoc2
,
590 sPathStart2
+ "/config:config-item[@config:name='VisibleLayers']");
591 CPPUNIT_ASSERT_MESSAGE("Item VisibleLayers does not exists.", !sBase64
.isEmpty());
592 comphelper::Base64::decode(aDecodedSeq
, sBase64
);
593 CPPUNIT_ASSERT_EQUAL(0x0F, static_cast<sal_uInt8
>(aDecodedSeq
[0]) & 0x1F);
595 sBase64
= getXPathContent(pXmlDoc2
,
596 sPathStart2
+ "/config:config-item[@config:name='PrintableLayers']");
597 CPPUNIT_ASSERT_MESSAGE("Item PrintableLayers does not exists.", !sBase64
.isEmpty());
598 comphelper::Base64::decode(aDecodedSeq
, sBase64
);
599 CPPUNIT_ASSERT_EQUAL(0x17, static_cast<sal_uInt8
>(aDecodedSeq
[0]) & 0x1F);
601 sBase64
= getXPathContent(pXmlDoc2
,
602 sPathStart2
+ "/config:config-item[@config:name='LockedLayers']");
603 CPPUNIT_ASSERT_MESSAGE("Item LockedLayers does not exists.", !sBase64
.isEmpty());
604 comphelper::Base64::decode(aDecodedSeq
, sBase64
);
605 CPPUNIT_ASSERT_EQUAL(0x04, static_cast<sal_uInt8
>(aDecodedSeq
[0]) & 0x1F);
608 void SdMiscTest::testTdf101242_settings_remove()
610 // Loads a document, which has the visible/printable/locked information for layers
611 // only in the config items in settings.xml. That is the case for all old documents.
612 // The resaved document should have only the ODF attributes draw:display and draw:protected
613 // and should have no config items in settings.xml.
614 createSdDrawDoc("tdf101242_settings.odg");
616 // Saving without config items in settings.xml
617 std::shared_ptr
<comphelper::ConfigurationChanges
> pBatch(
618 comphelper::ConfigurationChanges::create());
619 officecfg::Office::Common::Misc::WriteLayerStateAsConfigItem::set(false, pBatch
);
623 // Verify, that the saved document has the ODF attributes
624 xmlDocUniquePtr pXmlDoc
= parseExport("styles.xml");
625 CPPUNIT_ASSERT_MESSAGE("Failed to get 'styles.xml'", pXmlDoc
);
626 const OString
sPathStart(
627 "/office:document-styles/office:master-styles/draw:layer-set/draw:layer");
629 sPathStart
+ "[@draw:name='backgroundobjects' and @draw:protected='true']");
630 assertXPath(pXmlDoc
, sPathStart
+ "[@draw:name='controls' and @draw:display='screen']");
631 assertXPath(pXmlDoc
, sPathStart
+ "[@draw:name='measurelines' and @draw:display='printer']");
633 // Verify, that the saved document has no layer items in settings.xml
634 xmlDocUniquePtr pXmlDoc2
= parseExport("settings.xml");
635 CPPUNIT_ASSERT_MESSAGE("Failed to get 'settings.xml'", pXmlDoc2
);
636 const OString
sPathStart2("/office:document-settings/office:settings/"
637 "config:config-item-set[@config:name='ooo:view-settings']/"
638 "config:config-item-map-indexed[@config:name='Views']/"
639 "config:config-item-map-entry");
640 assertXPath(pXmlDoc2
, sPathStart2
+ "/config:config-item[@config:name='VisibleLayers']", 0);
641 assertXPath(pXmlDoc2
, sPathStart2
+ "/config:config-item[@config:name='PrintableLayers']", 0);
642 assertXPath(pXmlDoc2
, sPathStart2
+ "/config:config-item[@config:name='LockedLayers']", 0);
645 void SdMiscTest::testTdf119392()
647 // Loads a document which has two user layers "V--" and "V-L". Inserts a new layer "-P-" between them.
648 // Checks, that the bitfields in the saved file have the bits in the correct order, in case
649 // option WriteLayerAsConfigItem is true and the config items are written.
650 std::shared_ptr
<comphelper::ConfigurationChanges
> batch(
651 comphelper::ConfigurationChanges::create());
652 officecfg::Office::Common::Misc::WriteLayerStateAsConfigItem::set(true, batch
);
655 createSdDrawDoc("tdf119392_InsertLayer.odg");
656 SdXImpressDocument
* pXImpressDocument
= dynamic_cast<SdXImpressDocument
*>(mxComponent
.get());
657 CPPUNIT_ASSERT(pXImpressDocument
);
658 // Insert layer "-P-", not visible, printable, not locked
659 sd::ViewShell
* pViewShell
= pXImpressDocument
->GetDocShell()->GetViewShell();
660 SdrView
* pView
= pViewShell
->GetView();
661 pView
->InsertNewLayer("-P-", 6); // 0..4 standard layer, 5 layer "V--"
662 SdrPageView
* pPageView
= pView
->GetSdrPageView();
663 pPageView
->SetLayerVisible("-P-", false);
664 pPageView
->SetLayerPrintable("-P-", true);
665 pPageView
->SetLayerLocked("-P-", false);
668 // Verify correct bit order in bitfield in the config items in settings.xml
669 xmlDocUniquePtr pXmlDoc
= parseExport("settings.xml");
670 CPPUNIT_ASSERT_MESSAGE("Failed to get 'settings.xml'", pXmlDoc
);
671 const OString
sPathStart("/office:document-settings/office:settings/"
672 "config:config-item-set[@config:name='ooo:view-settings']/"
673 "config:config-item-map-indexed[@config:name='Views']/"
674 "config:config-item-map-entry");
675 // First Byte is in order 'V-L -P- V-- measurelines controls backgroundobjects background layout'
676 // Bits need to be: visible=10111111=0xbf=191 printable=01011111=0x5f=95 locked=10000000=0x80=128
677 // The values in file are Base64 encoded.
679 uno::Sequence
<sal_Int8
> aDecodedSeq
;
680 sBase64
= getXPathContent(pXmlDoc
,
681 sPathStart
+ "/config:config-item[@config:name='VisibleLayers']");
682 CPPUNIT_ASSERT_MESSAGE("Item VisibleLayers does not exists.", !sBase64
.isEmpty());
683 comphelper::Base64::decode(aDecodedSeq
, sBase64
);
684 CPPUNIT_ASSERT_EQUAL(0xbF,
685 static_cast<sal_uInt8
>(aDecodedSeq
[0])
686 & 0xff); // & 0xff forces unambiguous types for CPPUNIT_ASSERT_EQUAL
688 sBase64
= getXPathContent(pXmlDoc
,
689 sPathStart
+ "/config:config-item[@config:name='PrintableLayers']");
690 CPPUNIT_ASSERT_MESSAGE("Item PrintableLayers does not exists.", !sBase64
.isEmpty());
691 comphelper::Base64::decode(aDecodedSeq
, sBase64
);
692 CPPUNIT_ASSERT_EQUAL(0x5f, static_cast<sal_uInt8
>(aDecodedSeq
[0]) & 0xff);
695 = getXPathContent(pXmlDoc
, sPathStart
+ "/config:config-item[@config:name='LockedLayers']");
696 CPPUNIT_ASSERT_MESSAGE("Item LockedLayers does not exists.", !sBase64
.isEmpty());
697 comphelper::Base64::decode(aDecodedSeq
, sBase64
);
698 CPPUNIT_ASSERT_EQUAL(0x80, static_cast<sal_uInt8
>(aDecodedSeq
[0]) & 0xff);
701 void SdMiscTest::testTdf67248()
703 // The document tdf67248.odg has been created with a German UI. It has a user layer named "Background".
704 // On opening the user layer must still exists. The error was, that it was merged into the standard
705 // layer "background".
706 createSdDrawDoc("tdf67248.odg");
707 SdXImpressDocument
* pXImpressDocument
= dynamic_cast<SdXImpressDocument
*>(mxComponent
.get());
708 CPPUNIT_ASSERT(pXImpressDocument
);
709 SdDrawDocument
* pDoc
= pXImpressDocument
->GetDoc();
710 SdrLayerAdmin
& rLayerAdmin
= pDoc
->GetLayerAdmin();
711 CPPUNIT_ASSERT_EQUAL(sal_uInt16(6), rLayerAdmin
.GetLayerCount());
714 void SdMiscTest::testTdf119956()
716 createSdDrawDoc("tdf119956.odg");
717 SdXImpressDocument
* pXImpressDocument
= dynamic_cast<SdXImpressDocument
*>(mxComponent
.get());
718 CPPUNIT_ASSERT(pXImpressDocument
);
719 sd::ViewShell
* pViewShell
= pXImpressDocument
->GetDocShell()->GetViewShell();
721 sd::GraphicViewShell
* pGraphicViewShell
= static_cast<sd::GraphicViewShell
*>(pViewShell
);
722 CPPUNIT_ASSERT(pGraphicViewShell
);
723 sd::LayerTabBar
* pLayerTabBar
= pGraphicViewShell
->GetLayerTabControl();
724 CPPUNIT_ASSERT(pLayerTabBar
);
725 pLayerTabBar
->StateChanged(StateChangedType::InitShow
);
727 // Alt+Click sets a tab in edit mode, so that you can rename it.
728 // The error was, that Alt+Click on a tab, which was not the current tab, did not set the clicked tab
729 // as current tab. As a result, the entered text was applied to the wrong tab.
731 // The test document has the layer tabs "layout", "controls", "measurelines" and "Layer4" in this order
732 // The "pagePos" is 0, 1, 2, 3
733 // Make sure, that tab "layout" is the current tab.
734 MouseEvent aSyntheticMouseEvent
;
735 if (pLayerTabBar
->GetCurPagePos() != 0)
737 sal_uInt16
nIdOfTabPos0(pLayerTabBar
->GetPageId(0));
738 tools::Rectangle
aTabPos0Rect(pLayerTabBar
->GetPageRect(nIdOfTabPos0
));
740 = MouseEvent(aTabPos0Rect
.Center(), 1, MouseEventModifiers::SYNTHETIC
, MOUSE_LEFT
, 0);
741 pLayerTabBar
->MouseButtonDown(aSyntheticMouseEvent
);
743 CPPUNIT_ASSERT_EQUAL(sal_uInt16(0), pLayerTabBar
->GetCurPagePos());
745 // Alt+Click on tab "Layer4"
746 sal_uInt16
nIdOfTabPos3(pLayerTabBar
->GetPageId(3));
747 tools::Rectangle
aTabPos3Rect(pLayerTabBar
->GetPageRect(nIdOfTabPos3
));
748 aSyntheticMouseEvent
= MouseEvent(aTabPos3Rect
.Center(), 1, MouseEventModifiers::SYNTHETIC
,
749 MOUSE_LEFT
, KEY_MOD2
);
750 pLayerTabBar
->MouseButtonDown(aSyntheticMouseEvent
);
752 // Make sure, tab 3 is current tab now.
753 CPPUNIT_ASSERT_EQUAL(sal_uInt16(3), pLayerTabBar
->GetCurPagePos());
756 void SdMiscTest::testTdf98839_ShearVFlipH()
758 // Loads a document with a sheared shape and mirrors it
759 createSdDrawDoc("tdf98839_ShearVFlipH.odg");
760 SdXImpressDocument
* pXImpressDocument
= dynamic_cast<SdXImpressDocument
*>(mxComponent
.get());
761 CPPUNIT_ASSERT(pXImpressDocument
);
762 sd::ViewShell
* pViewShell
= pXImpressDocument
->GetDocShell()->GetViewShell();
763 SdPage
* pPage
= pViewShell
->GetActualPage();
764 SdrObjCustomShape
* pShape
= static_cast<SdrObjCustomShape
*>(pPage
->GetObj(0));
765 pShape
->Mirror(Point(4000, 2000), Point(4000, 10000));
767 // Save and examine attribute draw:transform
769 xmlDocUniquePtr pXmlDoc
= parseExport("content.xml");
770 CPPUNIT_ASSERT_MESSAGE("Failed to get 'content.xml'", pXmlDoc
);
771 const OString
sPathStart("/office:document-content/office:body/office:drawing/draw:page");
772 assertXPath(pXmlDoc
, sPathStart
);
773 const OUString sTransform
= getXPath(pXmlDoc
, sPathStart
+ "/draw:custom-shape", "transform");
775 // Error was, that the shear angle had a wrong sign.
776 CPPUNIT_ASSERT_MESSAGE("expected: draw:transform='skewX (-0.64350...)",
777 sTransform
.startsWith("skewX (-"));
780 void SdMiscTest::testTdf130988()
782 createSdDrawDoc("tdf130988_3D_create_lathe.odg");
783 SdXImpressDocument
* pXImpressDocument
= dynamic_cast<SdXImpressDocument
*>(mxComponent
.get());
784 CPPUNIT_ASSERT(pXImpressDocument
);
786 //emulate command .uno:ConvertInto3DLathe
787 sd::ViewShell
* pViewShell
= pXImpressDocument
->GetDocShell()->GetViewShell();
788 E3dView
* pView
= pViewShell
->GetView();
789 pView
->MarkNextObj();
790 pView
->ConvertMarkedObjTo3D(false, basegfx::B2DPoint(8000.0, -3000.0),
791 basegfx::B2DPoint(3000.0, -8000.0));
792 E3dScene
* pObj
= dynamic_cast<E3dScene
*>(pView
->GetMarkedObjectByIndex(0));
793 CPPUNIT_ASSERT(pObj
);
795 // Error was, that the created 3D object had a wrong path. Instead examining
796 // the path directly, I use the scene distance, because that is easier. The
797 // scene distance is calculated from the object while creating.
798 const double fDistance
= pObj
->GetDistance();
799 CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("D3DSceneDistance", 7071.0, fDistance
, 0.5);
802 void SdMiscTest::testTdf131033()
804 createSdDrawDoc("tdf131033_3D_SceneSizeIn2d.odg");
805 SdXImpressDocument
* pXImpressDocument
= dynamic_cast<SdXImpressDocument
*>(mxComponent
.get());
806 CPPUNIT_ASSERT(pXImpressDocument
);
808 // The document contains a polygon, so that emulate command .uno:ConvertInto3DLathe
809 // by direct call of ConvertMarkedObjTo3D works.
810 // It produces a rotation around a vertical axis, which is far away from the
812 sd::ViewShell
* pViewShell
= pXImpressDocument
->GetDocShell()->GetViewShell();
813 E3dView
* pView
= pViewShell
->GetView();
814 pView
->MarkNextObj();
815 pView
->ConvertMarkedObjTo3D(false, basegfx::B2DPoint(11000.0, -5000.0),
816 basegfx::B2DPoint(11000.0, -9000.0));
817 E3dScene
* pObj
= dynamic_cast<E3dScene
*>(pView
->GetMarkedObjectByIndex(0));
818 CPPUNIT_ASSERT(pObj
);
820 // Error was, that the 2D representation of the scene did not contain the default 20°
821 // rotation of the new scene around x-axis and therefore was not high enough.
822 const double fSnapRectHeight
= pObj
->GetSnapRect().getOpenHeight();
823 CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("2D height", 7096.0, fSnapRectHeight
, 1.0);
826 void SdMiscTest::testTdf129898LayerDrawnInSlideshow()
828 // Versions LO 6.2 to 6.4 have produced files, where the layer DrawnInSlideshow has
829 // got visible=false and printable=false attributes. Those files should be repaired now.
830 createSdImpressDoc("tdf129898_faulty_DrawnInSlideshow.odp");
831 SdXImpressDocument
* pXImpressDocument
= dynamic_cast<SdXImpressDocument
*>(mxComponent
.get());
832 CPPUNIT_ASSERT(pXImpressDocument
);
833 SdDrawDocument
* pDoc
= pXImpressDocument
->GetDoc();
836 static const OUStringLiteral sName
= u
"DrawnInSlideshow";
837 SdrLayerAdmin
& rLayerAdmin
= pDoc
->GetLayerAdmin();
838 SdrLayer
* pLayer
= rLayerAdmin
.GetLayer(sName
);
839 CPPUNIT_ASSERT_MESSAGE("No layer DrawnInSlideshow", pLayer
);
840 CPPUNIT_ASSERT(pLayer
->IsVisibleODF());
841 CPPUNIT_ASSERT(pLayer
->IsPrintableODF());
844 sd::ViewShell
* pViewShell
= pXImpressDocument
->GetDocShell()->GetViewShell();
845 SdrPageView
* pPageView
= pViewShell
->GetView()->GetSdrPageView();
846 CPPUNIT_ASSERT(pPageView
->IsLayerVisible(sName
));
847 CPPUNIT_ASSERT(pPageView
->IsLayerPrintable(sName
));
850 void SdMiscTest::testTdf136956()
852 createSdImpressDoc("odp/cellspan.odp");
853 SdXImpressDocument
* pXImpressDocument
= dynamic_cast<SdXImpressDocument
*>(mxComponent
.get());
854 CPPUNIT_ASSERT(pXImpressDocument
);
856 SdDrawDocument
* pDoc
= pXImpressDocument
->GetDoc();
857 const SdrPage
* pPage
= pDoc
->GetPage(1);
858 sdr::table::SdrTableObj
* pTableObj
= dynamic_cast<sdr::table::SdrTableObj
*>(pPage
->GetObj(0));
859 CPPUNIT_ASSERT(pTableObj
);
860 uno::Reference
<table::XTable
> xTable(pTableObj
->getTable(), uno::UNO_SET_THROW
);
862 uno::Reference
<css::table::XMergeableCellRange
> xRange(
863 xTable
->createCursorByRange(xTable
->getCellRangeByPosition(0, 0, 3, 2)),
864 uno::UNO_QUERY_THROW
);
866 // 4x3 Table before merge.
867 CPPUNIT_ASSERT_EQUAL(sal_Int32(4), xTable
->getColumnCount());
868 CPPUNIT_ASSERT_EQUAL(sal_Int32(3), xTable
->getRowCount());
872 // 1x1 Table after merge.
873 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xTable
->getColumnCount());
874 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xTable
->getRowCount());
876 pXImpressDocument
->GetDocShell()->GetUndoManager()->Undo();
878 // 4x3 Table after undo. Undo crashed before.
879 CPPUNIT_ASSERT_EQUAL(sal_Int32(4), xTable
->getColumnCount());
880 CPPUNIT_ASSERT_EQUAL(sal_Int32(3), xTable
->getRowCount());
883 void SdMiscTest::testEncodedTableStyles()
885 // Silence unrelated failure:
886 // Error: element "table:table-template" is missing "first-row-start-column" attribute
892 uno::Reference
<style::XStyleFamiliesSupplier
> xStyleFamiliesSupplier(mxComponent
,
893 uno::UNO_QUERY_THROW
);
894 uno::Reference
<css::lang::XSingleServiceFactory
> xTableStyleFamily(
895 xStyleFamiliesSupplier
->getStyleFamilies()->getByName("table"), uno::UNO_QUERY_THROW
);
896 uno::Reference
<css::lang::XSingleServiceFactory
> xCellStyleFamily(
897 xStyleFamiliesSupplier
->getStyleFamilies()->getByName("cell"), uno::UNO_QUERY_THROW
);
899 uno::Reference
<style::XStyle
> xTableStyle(xTableStyleFamily
->createInstance(),
900 uno::UNO_QUERY_THROW
);
901 uno::Reference
<style::XStyle
> xCellStyle(xCellStyleFamily
->createInstance(),
902 uno::UNO_QUERY_THROW
);
904 uno::Reference
<container::XNameContainer
>(xTableStyleFamily
, uno::UNO_QUERY_THROW
)
905 ->insertByName("table_1", uno::Any(xTableStyle
));
906 uno::Reference
<container::XNameContainer
>(xCellStyleFamily
, uno::UNO_QUERY_THROW
)
907 ->insertByName("table-body_1", uno::Any(xCellStyle
));
908 uno::Reference
<container::XNameReplace
>(xTableStyle
, uno::UNO_QUERY_THROW
)
909 ->replaceByName("body", uno::Any(xCellStyle
));
912 saveAndReload("draw8");
915 uno::Reference
<style::XStyleFamiliesSupplier
> xStyleFamiliesSupplier(mxComponent
,
916 uno::UNO_QUERY_THROW
);
917 uno::Reference
<container::XNameAccess
> xTableStyleFamily(
918 xStyleFamiliesSupplier
->getStyleFamilies()->getByName("table"), uno::UNO_QUERY_THROW
);
919 // Such style used to be exported as "table_5f_1" instead.
920 CPPUNIT_ASSERT(xTableStyleFamily
->hasByName("table_1"));
922 uno::Reference
<container::XNameAccess
> xTableStyle(xTableStyleFamily
->getByName("table_1"),
923 uno::UNO_QUERY_THROW
);
924 uno::Reference
<style::XStyle
> xCellStyle(xTableStyle
->getByName("body"), uno::UNO_QUERY
);
925 // Such style used to not be found by the table style, as it was
926 // searching for "table-body_5f_1" instead of "table-body_1".
927 CPPUNIT_ASSERT(xCellStyle
.is());
928 CPPUNIT_ASSERT_EQUAL(OUString("table-body_1"), xCellStyle
->getName());
932 CPPUNIT_TEST_SUITE_REGISTRATION(SdMiscTest
);
934 CPPUNIT_PLUGIN_IMPLEMENT();
936 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */