summaryrefslogtreecommitdiffstats
path: root/sd/qa/unit/misc-tests.cxx
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 09:06:44 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 09:06:44 +0000
commited5640d8b587fbcfed7dd7967f3de04b37a76f26 (patch)
tree7a5f7c6c9d02226d7471cb3cc8fbbf631b415303 /sd/qa/unit/misc-tests.cxx
parentInitial commit. (diff)
downloadlibreoffice-ed5640d8b587fbcfed7dd7967f3de04b37a76f26.tar.xz
libreoffice-ed5640d8b587fbcfed7dd7967f3de04b37a76f26.zip
Adding upstream version 4:7.4.7.upstream/4%7.4.7upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'sd/qa/unit/misc-tests.cxx')
-rw-r--r--sd/qa/unit/misc-tests.cxx970
1 files changed, 970 insertions, 0 deletions
diff --git a/sd/qa/unit/misc-tests.cxx b/sd/qa/unit/misc-tests.cxx
new file mode 100644
index 000000000..f864dfa6b
--- /dev/null
+++ b/sd/qa/unit/misc-tests.cxx
@@ -0,0 +1,970 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <officecfg/Office/Common.hxx>
+#include "sdmodeltestbase.hxx"
+
+#include <com/sun/star/uno/Reference.hxx>
+
+#include <comphelper/processfactory.hxx>
+#include <com/sun/star/frame/Desktop.hpp>
+#include <com/sun/star/frame/XModel2.hpp>
+
+#include <com/sun/star/awt/Gradient.hpp>
+#include <com/sun/star/awt/PosSize.hpp>
+#include <com/sun/star/drawing/FillStyle.hpp>
+#include <com/sun/star/drawing/TextVerticalAdjust.hpp>
+#include <com/sun/star/drawing/XDrawPagesSupplier.hpp>
+#include <com/sun/star/drawing/XDrawPages.hpp>
+#include <com/sun/star/drawing/XDrawPage.hpp>
+#include <com/sun/star/drawing/XShapes.hpp>
+#include <com/sun/star/graphic/XGraphic.hpp>
+#include <com/sun/star/container/XIndexAccess.hpp>
+#include <com/sun/star/frame/XLoadable.hpp>
+#include <com/sun/star/table/XTable.hpp>
+#include <com/sun/star/table/XMergeableCellRange.hpp>
+
+#include <vcl/scheduler.hxx>
+#include <osl/thread.hxx>
+#include <svx/sdr/table/tablecontroller.hxx>
+#include <sfx2/request.hxx>
+#include <svx/svdpagv.hxx>
+#include <svx/svxids.hrc>
+#include <editeng/eeitem.hxx>
+#include <editeng/adjustitem.hxx>
+#include <editeng/outlobj.hxx>
+#include <editeng/editobj.hxx>
+#include <SlideSorterViewShell.hxx>
+#include <SlideSorter.hxx>
+#include <controller/SlideSorterController.hxx>
+#include <controller/SlsClipboard.hxx>
+#include <controller/SlsPageSelector.hxx>
+#include <undo/undomanager.hxx>
+#include <GraphicViewShell.hxx>
+#include <chrono>
+#include <sdpage.hxx>
+#include <comphelper/base64.hxx>
+#include <LayerTabBar.hxx>
+#include <vcl/event.hxx>
+#include <vcl/keycodes.hxx>
+#include <svx/svdoashp.hxx>
+#include <tools/gen.hxx>
+#include <svx/view3d.hxx>
+#include <svx/scene3d.hxx>
+#include <svx/sdmetitm.hxx>
+
+using namespace ::com::sun::star;
+
+/// Impress miscellaneous tests.
+class SdMiscTest : public SdModelTestBaseXML
+{
+public:
+ void testTdf96206();
+ void testTdf96708();
+ void testTdf99396();
+ void testTableObjectUndoTest();
+ void testFillGradient();
+ void testTdf44774();
+ void testTdf38225();
+ void testTdf101242_ODF_no_settings();
+ void testTdf101242_ODF_add_settings();
+ void testTdf101242_settings_keep();
+ void testTdf101242_settings_remove();
+ void testTdf119392();
+ void testTdf67248();
+ void testTdf119956();
+ void testTdf120527();
+ void testTextColumns();
+ void testTdf98839_ShearVFlipH();
+ void testTdf130988();
+ void testTdf131033();
+ void testTdf129898LayerDrawnInSlideshow();
+ void testTdf136956();
+
+ CPPUNIT_TEST_SUITE(SdMiscTest);
+ CPPUNIT_TEST(testTdf96206);
+ CPPUNIT_TEST(testTdf96708);
+ CPPUNIT_TEST(testTdf99396);
+ CPPUNIT_TEST(testTableObjectUndoTest);
+ CPPUNIT_TEST(testFillGradient);
+ CPPUNIT_TEST(testTdf44774);
+ CPPUNIT_TEST(testTdf38225);
+ CPPUNIT_TEST(testTdf101242_ODF_no_settings);
+ CPPUNIT_TEST(testTdf101242_ODF_add_settings);
+ CPPUNIT_TEST(testTdf101242_settings_keep);
+ CPPUNIT_TEST(testTdf101242_settings_remove);
+ CPPUNIT_TEST(testTdf119392);
+ CPPUNIT_TEST(testTdf67248);
+ CPPUNIT_TEST(testTdf119956);
+ CPPUNIT_TEST(testTdf120527);
+ CPPUNIT_TEST(testTextColumns);
+ CPPUNIT_TEST(testTdf98839_ShearVFlipH);
+ CPPUNIT_TEST(testTdf130988);
+ CPPUNIT_TEST(testTdf131033);
+ CPPUNIT_TEST(testTdf129898LayerDrawnInSlideshow);
+ CPPUNIT_TEST(testTdf136956);
+ CPPUNIT_TEST_SUITE_END();
+
+virtual void registerNamespaces(xmlXPathContextPtr& pXmlXPathCtx) override
+ {
+ XmlTestTools::registerODFNamespaces(pXmlXPathCtx);
+ }
+
+private:
+ sd::DrawDocShellRef Load(const OUString& rURL, sal_Int32 nFormat);
+};
+
+sd::DrawDocShellRef SdMiscTest::Load(const OUString& rURL, sal_Int32 nFormat)
+{
+ uno::Reference< frame::XDesktop2 > xDesktop = frame::Desktop::create(::comphelper::getProcessComponentContext());
+ CPPUNIT_ASSERT(xDesktop.is());
+
+ // create a frame
+ uno::Reference< frame::XFrame > xTargetFrame = xDesktop->findFrame("_blank", 0);
+ CPPUNIT_ASSERT(xTargetFrame.is());
+
+ // This ContainerWindow corresponds to the outermost window of a running LibreOffice.
+ // It needs a non-zero size and must be shown. Otherwise visible elements like the
+ // LayerTabBar in Draw have zero size and cannot get mouse events.
+ // The here used size is freely chosen.
+ uno::Reference<awt::XWindow> xContainerWindow = xTargetFrame->getContainerWindow();
+ CPPUNIT_ASSERT(xContainerWindow.is());
+ xContainerWindow->setPosSize(0, 0, 1024, 768, awt::PosSize::SIZE);
+ xContainerWindow->setVisible(true);
+
+ // 1. Open the document
+ sd::DrawDocShellRef xDocSh = loadURL(rURL, nFormat);
+ CPPUNIT_ASSERT_MESSAGE("Failed to load file.", xDocSh.is());
+
+ uno::Reference< frame::XModel2 > xModel2 = xDocSh->GetModel();
+ CPPUNIT_ASSERT(xModel2.is());
+
+ uno::Reference< frame::XController2 > xController = xModel2->createDefaultViewController(xTargetFrame);
+ CPPUNIT_ASSERT(xController.is());
+
+ // introduce model/view/controller to each other
+ xController->attachModel(xModel2);
+ xModel2->connectController(xController);
+ xTargetFrame->setComponent(xController->getComponentWindow(), xController);
+ xController->attachFrame(xTargetFrame);
+ xModel2->setCurrentController(xController);
+
+ sd::ViewShell *pViewShell = xDocSh->GetViewShell();
+ CPPUNIT_ASSERT(pViewShell);
+
+ // Draw has no slidesorter, Impress never shows a LayerTabBar
+ if (sd::ViewShell::ST_DRAW == pViewShell->GetShellType())
+ {
+ sd::LayerTabBar* pLayerTabBar = static_cast<sd::GraphicViewShell*>(pViewShell)->GetLayerTabControl();
+ CPPUNIT_ASSERT(pLayerTabBar);
+ pLayerTabBar->StateChanged(StateChangedType::InitShow);
+ }
+ else
+ {
+ sd::slidesorter::SlideSorterViewShell* pSSVS = nullptr;
+ for (int i = 0; i < 1000; i++)
+ {
+ // Process all Tasks - slide sorter is created here
+ Scheduler::ProcessEventsToIdle();
+ if ((pSSVS = sd::slidesorter::SlideSorterViewShell::GetSlideSorter(pViewShell->GetViewShellBase())) != nullptr)
+ break;
+ osl::Thread::wait(std::chrono::milliseconds(100));
+ }
+ CPPUNIT_ASSERT(pSSVS);
+ }
+
+ return xDocSh;
+}
+
+void SdMiscTest::testTdf96206()
+{
+ // Copying/pasting slide referring to a non-default master with a text duplicated the master
+
+ sd::DrawDocShellRef xDocSh = Load(m_directories.getURLFromSrc(u"/sd/qa/unit/data/odp/tdf96206.odp"), ODP);
+ sd::ViewShell *pViewShell = xDocSh->GetViewShell();
+ auto pSSVS = sd::slidesorter::SlideSorterViewShell::GetSlideSorter(pViewShell->GetViewShellBase());
+ auto& rSSController = pSSVS->GetSlideSorter().GetController();
+
+ const sal_uInt16 nMasterPageCnt1 = xDocSh->GetDoc()->GetMasterSdPageCount(PageKind::Standard);
+ CPPUNIT_ASSERT_EQUAL(sal_uInt16(2), nMasterPageCnt1);
+ rSSController.GetClipboard().DoCopy();
+ rSSController.GetClipboard().DoPaste();
+ const sal_uInt16 nMasterPageCnt2 = xDocSh->GetDoc()->GetMasterSdPageCount(PageKind::Standard);
+ CPPUNIT_ASSERT_EQUAL(nMasterPageCnt1, nMasterPageCnt2);
+
+ xDocSh->DoClose();
+}
+
+void SdMiscTest::testTdf96708()
+{
+ sd::DrawDocShellRef xDocSh = Load(m_directories.getURLFromSrc(u"/sd/qa/unit/data/odp/tdf96708.odp"), ODP);
+ sd::ViewShell *pViewShell = xDocSh->GetViewShell();
+ auto pSSVS = sd::slidesorter::SlideSorterViewShell::GetSlideSorter(pViewShell->GetViewShellBase());
+ auto& rSSController = pSSVS->GetSlideSorter().GetController();
+ auto& rPageSelector = rSSController.GetPageSelector();
+
+ const sal_uInt16 nMasterPageCnt1 = xDocSh->GetDoc()->GetMasterSdPageCount(PageKind::Standard);
+ CPPUNIT_ASSERT_EQUAL(sal_uInt16(4), nMasterPageCnt1);
+ rPageSelector.SelectAllPages();
+ rSSController.GetClipboard().DoCopy();
+
+ // Now wait for timers to trigger creation of auto-layout
+ osl::Thread::wait(std::chrono::milliseconds(100));
+ Scheduler::ProcessEventsToIdle();
+
+ rSSController.GetClipboard().DoPaste();
+ const sal_uInt16 nMasterPageCnt2 = xDocSh->GetDoc()->GetMasterSdPageCount(PageKind::Standard);
+ CPPUNIT_ASSERT_EQUAL(nMasterPageCnt1, nMasterPageCnt2);
+
+ xDocSh->DoClose();
+}
+
+void SdMiscTest::testTdf99396()
+{
+ // Load the document and select the table.
+ sd::DrawDocShellRef xDocSh = Load(m_directories.getURLFromSrc(u"/sd/qa/unit/data/tdf99396.odp"), ODP);
+ sd::ViewShell *pViewShell = xDocSh->GetViewShell();
+ SdPage* pPage = pViewShell->GetActualPage();
+ SdrObject* pObject = pPage->GetObj(0);
+ SdrView* pView = pViewShell->GetView();
+ pView->MarkObj(pObject, pView->GetSdrPageView());
+
+ // Make sure that the undo stack is empty.
+ CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(0), xDocSh->GetDoc()->GetUndoManager()->GetUndoActionCount());
+
+ // Set the vertical alignment of the cells to bottom.
+ sdr::table::SvxTableController* pTableController = dynamic_cast<sdr::table::SvxTableController*>(pView->getSelectionController().get());
+ CPPUNIT_ASSERT(pTableController);
+ SfxRequest aRequest(pViewShell->GetViewFrame(), SID_TABLE_VERT_BOTTOM);
+ pTableController->Execute(aRequest);
+ // This was 0, it wasn't possible to undo a vertical alignment change.
+ CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), xDocSh->GetDoc()->GetUndoManager()->GetUndoActionCount());
+
+ xDocSh->DoClose();
+}
+
+void SdMiscTest::testTableObjectUndoTest()
+{
+ // See tdf#99396 for the issue
+
+ // Load the document and select the table.
+ sd::DrawDocShellRef xDocSh = Load(m_directories.getURLFromSrc(u"/sd/qa/unit/data/tdf99396.odp"), ODP);
+ sd::ViewShell* pViewShell = xDocSh->GetViewShell();
+ SdPage* pPage = pViewShell->GetActualPage();
+ auto pTableObject = dynamic_cast<sdr::table::SdrTableObj*>(pPage->GetObj(0));
+ CPPUNIT_ASSERT(pTableObject);
+ SdrView* pView = pViewShell->GetView();
+ pView->MarkObj(pTableObject, pView->GetSdrPageView());
+
+ // Make sure that the undo stack is empty.
+ CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(0), xDocSh->GetDoc()->GetUndoManager()->GetUndoActionCount());
+
+ // Set horizontal and vertical adjustment during text edit.
+ pView->SdrBeginTextEdit(pTableObject);
+ CPPUNIT_ASSERT(pView->GetTextEditObject());
+ {
+ SfxRequest aRequest(pViewShell->GetViewFrame(), SID_ATTR_PARA_ADJUST_RIGHT);
+ SfxItemSet aEditAttr(xDocSh->GetDoc()->GetPool());
+ pView->GetAttributes(aEditAttr);
+ SfxItemSet aNewAttr(*(aEditAttr.GetPool()), aEditAttr.GetRanges());
+ aNewAttr.Put(SvxAdjustItem(SvxAdjust::Right, EE_PARA_JUST));
+ aRequest.Done(aNewAttr);
+ const SfxItemSet* pArgs = aRequest.GetArgs();
+ pView->SetAttributes(*pArgs);
+ }
+ const auto& pLocalUndoManager = pView->getViewLocalUndoManager();
+ CPPUNIT_ASSERT_EQUAL(size_t(1), pLocalUndoManager->GetUndoActionCount());
+ CPPUNIT_ASSERT_EQUAL(OUString("Apply attributes"), pLocalUndoManager->GetUndoActionComment());
+ {
+ auto pTableController = dynamic_cast<sdr::table::SvxTableController*>(pView->getSelectionController().get());
+ CPPUNIT_ASSERT(pTableController);
+ SfxRequest aRequest(pViewShell->GetViewFrame(), SID_TABLE_VERT_BOTTOM);
+ pTableController->Execute(aRequest);
+ }
+ // Global change "Format cell" is applied only - Change the vertical alignment to "Bottom"
+ CPPUNIT_ASSERT_EQUAL(size_t(1), xDocSh->GetDoc()->GetUndoManager()->GetUndoActionCount());
+ CPPUNIT_ASSERT_EQUAL(OUString("Format cell"), xDocSh->GetDoc()->GetUndoManager()->GetUndoActionComment());
+
+ pView->SdrEndTextEdit();
+
+ // End of text edit, so the text edit action is added to the undo stack
+ CPPUNIT_ASSERT_EQUAL(size_t(2), xDocSh->GetDoc()->GetUndoManager()->GetUndoActionCount());
+ CPPUNIT_ASSERT_EQUAL(OUString("Edit text of Table"), xDocSh->GetDoc()->GetUndoManager()->GetUndoActionComment(0));
+ CPPUNIT_ASSERT_EQUAL(OUString("Format cell"), xDocSh->GetDoc()->GetUndoManager()->GetUndoActionComment(1));
+
+ // Check that the result is what we expect.
+ {
+ uno::Reference<table::XTable> xTable = pTableObject->getTable();
+ uno::Reference<beans::XPropertySet> xCell(xTable->getCellByPosition(0, 0), uno::UNO_QUERY);
+ drawing::TextVerticalAdjust eAdjust = xCell->getPropertyValue("TextVerticalAdjust").get<drawing::TextVerticalAdjust>();
+ CPPUNIT_ASSERT_EQUAL(int(drawing::TextVerticalAdjust_BOTTOM), static_cast<int>(eAdjust));
+ }
+ {
+ const EditTextObject& rEdit = pTableObject->getText(0)->GetOutlinerParaObject()->GetTextObject();
+ const SfxItemSet& rParaAttribs = rEdit.GetParaAttribs(0);
+ auto pAdjust = rParaAttribs.GetItem(EE_PARA_JUST);
+ CPPUNIT_ASSERT_EQUAL(SvxAdjust::Right, pAdjust->GetAdjust());
+ }
+
+ // Now undo.
+ xDocSh->GetUndoManager()->Undo();
+
+ // Undoing the last action - one left
+ CPPUNIT_ASSERT_EQUAL(size_t(1), xDocSh->GetDoc()->GetUndoManager()->GetUndoActionCount());
+ CPPUNIT_ASSERT_EQUAL(OUString("Format cell"), xDocSh->GetDoc()->GetUndoManager()->GetUndoActionComment(0));
+
+ // Check again that the result is what we expect.
+ {
+ uno::Reference<table::XTable> xTable = pTableObject->getTable();
+ uno::Reference<beans::XPropertySet> xCell(xTable->getCellByPosition(0, 0), uno::UNO_QUERY);
+ drawing::TextVerticalAdjust eAdjust = xCell->getPropertyValue("TextVerticalAdjust").get<drawing::TextVerticalAdjust>();
+ // This failed: Undo() did not change it from drawing::TextVerticalAdjust_BOTTOM.
+ CPPUNIT_ASSERT_EQUAL(int(drawing::TextVerticalAdjust_TOP), static_cast<int>(eAdjust));
+ }
+ {
+ const EditTextObject& rEdit = pTableObject->getText(0)->GetOutlinerParaObject()->GetTextObject();
+ const SfxItemSet& rParaAttribs = rEdit.GetParaAttribs(0);
+ auto pAdjust = rParaAttribs.GetItem(EE_PARA_JUST);
+ CPPUNIT_ASSERT_EQUAL(SvxAdjust::Center, pAdjust->GetAdjust());
+ }
+
+ Scheduler::ProcessEventsToIdle();
+ CPPUNIT_ASSERT_EQUAL(size_t(1), xDocSh->GetDoc()->GetUndoManager()->GetUndoActionCount());
+ CPPUNIT_ASSERT_EQUAL(OUString("Format cell"), xDocSh->GetDoc()->GetUndoManager()->GetUndoActionComment(0));
+
+ /*
+ * now test tdf#103950 - Undo does not revert bundled font size changes for table cells
+ */
+ pTableObject = dynamic_cast<sdr::table::SdrTableObj*>(pPage->GetObj(0));
+ pView->MarkObj(pTableObject, pView->GetSdrPageView()); // select table
+ {
+ SfxRequest aRequest(pViewShell->GetViewFrame(), SID_GROW_FONT_SIZE);
+ static_cast<sd::DrawViewShell*>(pViewShell)->ExecChar(aRequest);
+ }
+ Scheduler::ProcessEventsToIdle();
+ CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(3), xDocSh->GetDoc()->GetUndoManager()->GetUndoActionCount());
+ CPPUNIT_ASSERT_EQUAL(OUString("Apply attributes to Table"), xDocSh->GetDoc()->GetUndoManager()->GetUndoActionComment(0));
+ CPPUNIT_ASSERT_EQUAL(OUString("Grow font size"), xDocSh->GetDoc()->GetUndoManager()->GetUndoActionComment(1));
+ CPPUNIT_ASSERT_EQUAL(OUString("Format cell"), xDocSh->GetDoc()->GetUndoManager()->GetUndoActionComment(2));
+
+ xDocSh->DoClose();
+}
+
+void SdMiscTest::testFillGradient()
+{
+ ::sd::DrawDocShellRef xDocShRef = new ::sd::DrawDocShell(SfxObjectCreateMode::EMBEDDED, false, DocumentType::Impress);
+ uno::Reference<drawing::XDrawPagesSupplier> xDrawPagesSupplier = getDoc( xDocShRef );
+ uno::Reference<drawing::XDrawPages> xDrawPages = xDrawPagesSupplier->getDrawPages();
+ // Insert a new page.
+ uno::Reference<drawing::XDrawPage> xDrawPage(xDrawPages->insertNewByIndex(0), uno::UNO_SET_THROW );
+ uno::Reference<drawing::XShapes> xShapes(xDrawPage,uno::UNO_QUERY_THROW);
+ uno::Reference<lang::XMultiServiceFactory> const xDoc(xDocShRef->GetDoc()->getUnoModel(), uno::UNO_QUERY);
+ // Create a rectangle
+ uno::Reference<drawing::XShape> xShape1(xDoc->createInstance("com.sun.star.drawing.RectangleShape"),uno::UNO_QUERY_THROW );
+ uno::Reference<beans::XPropertySet> xPropSet(xShape1, uno::UNO_QUERY_THROW);
+ // Set FillStyle and FillGradient
+ awt::Gradient aGradient;
+ aGradient.StartColor = sal_Int32(Color(255, 0, 0));
+ aGradient.EndColor = sal_Int32(Color(0, 255, 0));
+ xPropSet->setPropertyValue("FillStyle", uno::Any(drawing::FillStyle_GRADIENT));
+ xPropSet->setPropertyValue("FillGradient", uno::Any(aGradient));
+ // Add the rectangle to the page.
+ xShapes->add(xShape1);
+
+ // Retrieve the shape and check FillStyle and FillGradient
+ uno::Reference<container::XIndexAccess> xIndexAccess(xDrawPage, uno::UNO_QUERY_THROW);
+ uno::Reference<beans::XPropertySet > xPropSet2(xIndexAccess->getByIndex(0), uno::UNO_QUERY_THROW);
+ drawing::FillStyle eFillStyle;
+ awt::Gradient aGradient2;
+ CPPUNIT_ASSERT(xPropSet2->getPropertyValue("FillStyle") >>= eFillStyle);
+ CPPUNIT_ASSERT_EQUAL(int(drawing::FillStyle_GRADIENT), static_cast<int>(eFillStyle));
+ CPPUNIT_ASSERT(xPropSet2->getPropertyValue("FillGradient") >>= aGradient2);
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(Color(255, 0, 0)),aGradient2.StartColor);
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(Color(0, 255, 0)),aGradient2.EndColor);
+
+ xDocShRef->DoClose();
+}
+
+void SdMiscTest::testTdf44774()
+{
+ sd::DrawDocShellRef xDocShRef = new sd::DrawDocShell(SfxObjectCreateMode::EMBEDDED, false,
+ DocumentType::Draw);
+ const uno::Reference<frame::XLoadable> xLoadable(xDocShRef->GetModel(), uno::UNO_QUERY_THROW);
+ xLoadable->initNew();
+ SfxStyleSheetBasePool* pSSPool = xDocShRef->GetStyleSheetPool();
+
+ // Create a new style with an empty name, like what happens in UI when creating a new style
+ SfxStyleSheetBase& rStyleA = pSSPool->Make("", SfxStyleFamily::Para, SfxStyleSearchBits::UserDefined);
+ // Assign a new name, which does not yet set its ApiName
+ rStyleA.SetName("StyleA");
+ // Create another style
+ SfxStyleSheetBase& rStyleB = pSSPool->Make("StyleB", SfxStyleFamily::Para, SfxStyleSearchBits::UserDefined);
+ // ... and set its parent to the first one
+ rStyleB.SetParent("StyleA");
+
+ // Now save the file and reload
+ xDocShRef = saveAndReload(xDocShRef.get(), ODG);
+ pSSPool = xDocShRef->GetStyleSheetPool();
+
+ SfxStyleSheetBase* pStyle = pSSPool->Find("StyleB", SfxStyleFamily::Para);
+ CPPUNIT_ASSERT(pStyle);
+ // The parent set in StyleB used to reset, because parent style's msApiName was empty
+ CPPUNIT_ASSERT_EQUAL(OUString("StyleA"), pStyle->GetParent());
+
+ xDocShRef->DoClose();
+}
+
+void SdMiscTest::testTdf38225()
+{
+ sd::DrawDocShellRef xDocShRef = new sd::DrawDocShell(SfxObjectCreateMode::EMBEDDED, false,
+ DocumentType::Draw);
+ const uno::Reference<frame::XLoadable> xLoadable(xDocShRef->GetModel(), uno::UNO_QUERY_THROW);
+ xLoadable->initNew();
+ SfxStyleSheetBasePool* pSSPool = xDocShRef->GetStyleSheetPool();
+
+ // Create a new style with a name
+ pSSPool->Make("StyleWithName1", SfxStyleFamily::Para, SfxStyleSearchBits::UserDefined);
+
+ // Now save the file and reload
+ xDocShRef = saveAndReload(xDocShRef.get(), ODG);
+ pSSPool = xDocShRef->GetStyleSheetPool();
+
+ SfxStyleSheetBase* pStyle = pSSPool->Find("StyleWithName1", SfxStyleFamily::Para);
+ CPPUNIT_ASSERT(pStyle);
+
+ // Rename the style
+ CPPUNIT_ASSERT(pStyle->SetName("StyleWithName2"));
+
+ // Save the file and reload again
+ xDocShRef = saveAndReload(xDocShRef.get(), ODG);
+ pSSPool = xDocShRef->GetStyleSheetPool();
+
+ // The problem was that the style kept the old name upon reloading
+ pStyle = pSSPool->Find("StyleWithName1", SfxStyleFamily::Para);
+ CPPUNIT_ASSERT(!pStyle);
+ pStyle = pSSPool->Find("StyleWithName2", SfxStyleFamily::Para);
+ CPPUNIT_ASSERT(pStyle);
+
+ xDocShRef->DoClose();
+}
+
+void SdMiscTest::testTdf120527()
+{
+ sd::DrawDocShellRef xDocShRef
+ = new sd::DrawDocShell(SfxObjectCreateMode::EMBEDDED, false, DocumentType::Draw);
+ uno::Reference<frame::XLoadable> xLoadable(xDocShRef->GetModel(), uno::UNO_QUERY);
+ CPPUNIT_ASSERT(xLoadable.is());
+ xLoadable->initNew();
+
+ // Load a bitmap into the bitmap table.
+ uno::Reference<lang::XMultiServiceFactory> xFactory(xDocShRef->GetModel(), uno::UNO_QUERY);
+ CPPUNIT_ASSERT(xFactory.is());
+ uno::Reference<container::XNameContainer> xBitmaps(
+ xFactory->createInstance("com.sun.star.drawing.BitmapTable"), uno::UNO_QUERY);
+ CPPUNIT_ASSERT(xBitmaps.is());
+ OUString aGraphicURL = m_directories.getURLFromSrc(u"/sd/qa/unit/data/tdf120527.jpg");
+ xBitmaps->insertByName("test", uno::Any(aGraphicURL));
+
+ // Create a graphic.
+ uno::Reference<drawing::XShape> xShape(
+ xFactory->createInstance("com.sun.star.drawing.GraphicObjectShape"), uno::UNO_QUERY);
+ CPPUNIT_ASSERT(xShape.is());
+ uno::Reference<beans::XPropertySet> xShapeProperySet(xShape, uno::UNO_QUERY);
+ CPPUNIT_ASSERT(xShapeProperySet.is());
+ xShapeProperySet->setPropertyValue("GraphicURL", xBitmaps->getByName("test"));
+
+ // Insert it.
+ uno::Reference<drawing::XDrawPagesSupplier> xDrawPagesSupplier(xDocShRef->GetModel(),
+ uno::UNO_QUERY);
+ CPPUNIT_ASSERT(xDrawPagesSupplier.is());
+ uno::Reference<drawing::XDrawPages> xDrawPages = xDrawPagesSupplier->getDrawPages();
+ CPPUNIT_ASSERT(xDrawPages.is());
+ uno::Reference<drawing::XDrawPage> xDrawPage(xDrawPages->getByIndex(0), uno::UNO_QUERY);
+ CPPUNIT_ASSERT(xDrawPage.is());
+ // This failed with a lang.IllegalArgumentException.
+ xDrawPage->add(xShape);
+
+ // Verify that the graphic was actually consumed.
+ uno::Reference<graphic::XGraphic> xGraphic;
+ xShapeProperySet->getPropertyValue("Graphic") >>= xGraphic;
+ CPPUNIT_ASSERT(xGraphic.is());
+
+ xDocShRef->DoClose();
+}
+
+// Testing document model part of editengine-columns
+void SdMiscTest::testTextColumns()
+{
+ ::sd::DrawDocShellRef xDocShRef
+ = new ::sd::DrawDocShell(SfxObjectCreateMode::EMBEDDED, false, DocumentType::Impress);
+ uno::Reference<drawing::XDrawPagesSupplier> xDrawPagesSupplier = getDoc(xDocShRef);
+ uno::Reference<drawing::XDrawPages> xDrawPages = xDrawPagesSupplier->getDrawPages();
+ // Insert a new page.
+ uno::Reference<drawing::XDrawPage> xDrawPage(xDrawPages->insertNewByIndex(0),
+ uno::UNO_SET_THROW);
+ uno::Reference<drawing::XShapes> xShapes(xDrawPage, uno::UNO_QUERY_THROW);
+ uno::Reference<lang::XMultiServiceFactory> const xDoc(xDocShRef->GetDoc()->getUnoModel(),
+ uno::UNO_QUERY);
+
+ {
+ // Create a text shape
+ uno::Reference<drawing::XShape> xShape(
+ xDoc->createInstance("com.sun.star.drawing.TextShape"), uno::UNO_QUERY_THROW);
+ uno::Reference<beans::XPropertySet> xPropSet(xShape, uno::UNO_QUERY_THROW);
+
+ // Add the shape to the page.
+ xShapes->add(xShape);
+
+ // Set up columns
+ auto pTextObj = dynamic_cast<SdrTextObj*>(SdrObject::getSdrObjectFromXShape(xShape));
+ CPPUNIT_ASSERT(pTextObj);
+ pTextObj->SetMergedItem(SfxInt16Item(SDRATTR_TEXTCOLUMNS_NUMBER, 2));
+ pTextObj->SetMergedItem(SdrMetricItem(SDRATTR_TEXTCOLUMNS_SPACING, 1000));
+ }
+
+ {
+ // Retrieve the shape and check columns
+ uno::Reference<container::XIndexAccess> xIndexAccess(xDrawPage, uno::UNO_QUERY_THROW);
+ uno::Reference<drawing::XShape> xShape(xIndexAccess->getByIndex(0), uno::UNO_QUERY_THROW);
+
+ auto pTextObj = dynamic_cast<SdrTextObj*>(SdrObject::getSdrObjectFromXShape(xShape));
+ CPPUNIT_ASSERT(pTextObj);
+
+ CPPUNIT_ASSERT_EQUAL(sal_Int16(2), pTextObj->GetTextColumnsNumber());
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(1000), pTextObj->GetTextColumnsSpacing());
+ }
+
+ xDocShRef->DoClose();
+}
+
+/// Draw miscellaneous tests.
+
+// Since LO 6.2 the visible/printable/locked information for layers is always
+// written as ODF attributes draw:display and draw:protected. It is only read from
+// there, if the config items VisibleLayers, PrintableLayers and LockedLayers do
+// not exist. The user option WriteLayerStateAsConfigItem can be set to 'true' to
+// write these config items in addition to the ODF attributes for to produce
+// documents for older LO versions or Apache OpenOffice. With value 'false' no
+// config items are written. The 'testTdf101242_xyz' tests combine source
+// files with and without config items with option values 'true' and 'false'.
+
+void SdMiscTest::testTdf101242_ODF_add_settings()
+{
+ // Loads a document, which has the visible/printable/locked information for layers
+ // only in the ODF attributes draw:display and draw:protected. The resaved document
+ // should still have the ODF attributes and in addition the config items in settings.xml.
+ // "Load" is needed for to handle layers, simple "loadURL" does not work.
+ sd::DrawDocShellRef xDocShRef = Load(m_directories.getURLFromSrc(u"/sd/qa/unit/data/tdf101242_ODF.odg"), ODG);
+ CPPUNIT_ASSERT_MESSAGE("Failed to load file.", xDocShRef.is());
+
+ // Saving including items in settings.xml
+ std::shared_ptr<comphelper::ConfigurationChanges> pBatch( comphelper::ConfigurationChanges::create() );
+ officecfg::Office::Common::Misc::WriteLayerStateAsConfigItem::set(true, pBatch);
+ pBatch->commit();
+ utl::TempFile aTempFile;
+ aTempFile.EnableKillingFile();
+ save(xDocShRef.get(), getFormat(ODG), aTempFile );
+
+ // Verify, that the saved document still has the ODF attributes
+ xmlDocUniquePtr pXmlDoc = parseExport(aTempFile, "styles.xml");
+ CPPUNIT_ASSERT_MESSAGE("Failed to get 'styles.xml'", pXmlDoc);
+ const OString sPathStart("/office:document-styles/office:master-styles/draw:layer-set/draw:layer");
+ assertXPath(pXmlDoc, sPathStart + "[@draw:name='backgroundobjects' and @draw:protected='true']");
+ assertXPath(pXmlDoc, sPathStart + "[@draw:name='controls' and @draw:display='screen']");
+ assertXPath(pXmlDoc, sPathStart + "[@draw:name='measurelines' and @draw:display='printer']");
+
+ // Verify, that the saved document has got the items in settings.xml
+ xmlDocUniquePtr pXmlDoc2 = parseExport(aTempFile, "settings.xml");
+ CPPUNIT_ASSERT_MESSAGE("Failed to get 'settings.xml'", pXmlDoc2);
+ const OString sPathStart2("/office:document-settings/office:settings/config:config-item-set[@config:name='ooo:view-settings']/config:config-item-map-indexed[@config:name='Views']/config:config-item-map-entry");
+ // Value is a bitfield with first Byte in order '* * * measurelines controls backgroundobjects background layout'
+ // The first three bits depend on initialization and may change. The values in file are Base64 encoded.
+ OUString sBase64;
+ uno::Sequence<sal_Int8> aDecodedSeq;
+ sBase64 = getXPathContent(pXmlDoc2, sPathStart2 + "/config:config-item[@config:name='VisibleLayers']");
+ CPPUNIT_ASSERT_MESSAGE( "Item VisibleLayers does not exists.", !sBase64.isEmpty());
+ comphelper::Base64::decode(aDecodedSeq, sBase64);
+ CPPUNIT_ASSERT_EQUAL( 0x0F, static_cast<sal_uInt8>(aDecodedSeq[0]) & 0x1F );
+
+ sBase64 = getXPathContent(pXmlDoc2, sPathStart2 + "/config:config-item[@config:name='PrintableLayers']");
+ CPPUNIT_ASSERT_MESSAGE( "Item PrintableLayers does not exists.", !sBase64.isEmpty());
+ comphelper::Base64::decode(aDecodedSeq, sBase64);
+ CPPUNIT_ASSERT_EQUAL( 0x17, static_cast<sal_uInt8>(aDecodedSeq[0]) & 0x1F);
+
+ sBase64 = getXPathContent(pXmlDoc2, sPathStart2 + "/config:config-item[@config:name='LockedLayers']");
+ CPPUNIT_ASSERT_MESSAGE( "Item LockedLayers does not exists.", !sBase64.isEmpty());
+ comphelper::Base64::decode(aDecodedSeq, sBase64);
+ CPPUNIT_ASSERT_EQUAL( 0x04, static_cast<sal_uInt8>(aDecodedSeq[0]) & 0x1F);
+
+ xDocShRef->DoClose();
+}
+
+void SdMiscTest::testTdf101242_ODF_no_settings()
+{
+ // Loads a document, which has the visible/printable/locked information for layers
+ // only in the ODF attributes draw:display and draw:protected. The resave document
+ // should have only the ODF attributes and no config items in settings.xml.
+ sd::DrawDocShellRef xDocShRef = Load(m_directories.getURLFromSrc(u"/sd/qa/unit/data/tdf101242_ODF.odg"), ODG);
+ CPPUNIT_ASSERT_MESSAGE("Failed to load file.", xDocShRef.is());
+
+ // Saving without items in settings.xml
+ std::shared_ptr<comphelper::ConfigurationChanges> pBatch( comphelper::ConfigurationChanges::create() );
+ officecfg::Office::Common::Misc::WriteLayerStateAsConfigItem::set(false, pBatch);
+ pBatch->commit();
+ utl::TempFile aTempFile;
+ aTempFile.EnableKillingFile();
+ save(xDocShRef.get(), getFormat(ODG), aTempFile );
+
+ // Verify, that the saved document still has the ODF attributes
+ xmlDocUniquePtr pXmlDoc = parseExport(aTempFile, "styles.xml");
+ CPPUNIT_ASSERT_MESSAGE("Failed to get 'styles.xml'", pXmlDoc);
+ const OString sPathStart("/office:document-styles/office:master-styles/draw:layer-set/draw:layer");
+ assertXPath(pXmlDoc, sPathStart + "[@draw:name='backgroundobjects' and @draw:protected='true']");
+ assertXPath(pXmlDoc, sPathStart + "[@draw:name='controls' and @draw:display='screen']");
+ assertXPath(pXmlDoc, sPathStart + "[@draw:name='measurelines' and @draw:display='printer']");
+
+ // Verify, that the saved document has no layer items in settings.xml
+ xmlDocUniquePtr pXmlDoc2 = parseExport(aTempFile, "settings.xml");
+ CPPUNIT_ASSERT_MESSAGE("Failed to get 'settings.xml'", pXmlDoc2);
+ const OString sPathStart2("/office:document-settings/office:settings/config:config-item-set[@config:name='ooo:view-settings']/config:config-item-map-indexed[@config:name='Views']/config:config-item-map-entry");
+ xmlXPathObjectPtr pXmlObj=getXPathNode(pXmlDoc2, sPathStart2 + "/config:config-item[@config:name='VisibleLayers']");
+ CPPUNIT_ASSERT_EQUAL(0, xmlXPathNodeSetGetLength(pXmlObj->nodesetval));
+ xmlXPathFreeObject(pXmlObj);
+ pXmlObj=getXPathNode(pXmlDoc2, sPathStart2 + "/config:config-item[@config:name='PrintableLayers']");
+ CPPUNIT_ASSERT_EQUAL(0, xmlXPathNodeSetGetLength(pXmlObj->nodesetval));
+ xmlXPathFreeObject(pXmlObj);
+ pXmlObj=getXPathNode(pXmlDoc2, sPathStart2 + "/config:config-item[@config:name='LockedLayers']");
+ CPPUNIT_ASSERT_EQUAL(0, xmlXPathNodeSetGetLength(pXmlObj->nodesetval));
+ xmlXPathFreeObject(pXmlObj);
+
+ xDocShRef->DoClose();
+}
+
+void SdMiscTest::testTdf101242_settings_keep()
+{
+ // Loads a document, which has the visible/printable/locked information for layers
+ // only in the config items in settings.xml. That is the case for all old documents.
+ // The resaved document should have the ODF attributes draw:display and draw:protected
+ // and should still have these config items in settings.xml.
+ sd::DrawDocShellRef xDocShRef = Load(m_directories.getURLFromSrc(u"/sd/qa/unit/data/tdf101242_settings.odg"), ODG);
+ CPPUNIT_ASSERT_MESSAGE("Failed to load file.", xDocShRef.is());
+
+ // Saving including items in settings.xml
+ std::shared_ptr<comphelper::ConfigurationChanges> pBatch( comphelper::ConfigurationChanges::create() );
+ officecfg::Office::Common::Misc::WriteLayerStateAsConfigItem::set(true, pBatch);
+ pBatch->commit();
+ utl::TempFile aTempFile;
+ aTempFile.EnableKillingFile();
+ save(xDocShRef.get(), getFormat(ODG), aTempFile );
+
+ // Verify, that the saved document has the ODF attributes
+ xmlDocUniquePtr pXmlDoc = parseExport(aTempFile, "styles.xml");
+ CPPUNIT_ASSERT_MESSAGE("Failed to get 'styles.xml'", pXmlDoc);
+ const OString sPathStart("/office:document-styles/office:master-styles/draw:layer-set/draw:layer");
+ assertXPath(pXmlDoc, sPathStart + "[@draw:name='backgroundobjects' and @draw:protected='true']");
+ assertXPath(pXmlDoc, sPathStart + "[@draw:name='controls' and @draw:display='screen']");
+ assertXPath(pXmlDoc, sPathStart + "[@draw:name='measurelines' and @draw:display='printer']");
+
+ // Verify, that the saved document still has the items in settings.xml
+ xmlDocUniquePtr pXmlDoc2 = parseExport(aTempFile, "settings.xml");
+ CPPUNIT_ASSERT_MESSAGE("Failed to get 'settings.xml'", pXmlDoc2);
+ const OString sPathStart2("/office:document-settings/office:settings/config:config-item-set[@config:name='ooo:view-settings']/config:config-item-map-indexed[@config:name='Views']/config:config-item-map-entry");
+ // Value is a bitfield with first Byte in order '* * * measurelines controls backgroundobjects background layout'
+ // The first three bits depend on initialization and may change. The values in file are Base64 encoded.
+ OUString sBase64;
+ uno::Sequence<sal_Int8> aDecodedSeq;
+ sBase64 = getXPathContent(pXmlDoc2, sPathStart2 + "/config:config-item[@config:name='VisibleLayers']");
+ CPPUNIT_ASSERT_MESSAGE( "Item VisibleLayers does not exists.", !sBase64.isEmpty());
+ comphelper::Base64::decode(aDecodedSeq, sBase64);
+ CPPUNIT_ASSERT_EQUAL( 0x0F, static_cast<sal_uInt8>(aDecodedSeq[0]) & 0x1F );
+
+ sBase64 = getXPathContent(pXmlDoc2, sPathStart2 + "/config:config-item[@config:name='PrintableLayers']");
+ CPPUNIT_ASSERT_MESSAGE( "Item PrintableLayers does not exists.", !sBase64.isEmpty());
+ comphelper::Base64::decode(aDecodedSeq, sBase64);
+ CPPUNIT_ASSERT_EQUAL( 0x17, static_cast<sal_uInt8>(aDecodedSeq[0]) & 0x1F);
+
+ sBase64 = getXPathContent(pXmlDoc2, sPathStart2 + "/config:config-item[@config:name='LockedLayers']");
+ CPPUNIT_ASSERT_MESSAGE( "Item LockedLayers does not exists.", !sBase64.isEmpty());
+ comphelper::Base64::decode(aDecodedSeq, sBase64);
+ CPPUNIT_ASSERT_EQUAL( 0x04, static_cast<sal_uInt8>(aDecodedSeq[0]) & 0x1F);
+
+ xDocShRef->DoClose();
+}
+
+void SdMiscTest::testTdf101242_settings_remove()
+{
+ // Loads a document, which has the visible/printable/locked information for layers
+ // only in the config items in settings.xml. That is the case for all old documents.
+ // The resaved document should have only the ODF attributes draw:display and draw:protected
+ // and should have no config items in settings.xml.
+ sd::DrawDocShellRef xDocShRef = Load(m_directories.getURLFromSrc(u"/sd/qa/unit/data/tdf101242_settings.odg"), ODG);
+ CPPUNIT_ASSERT_MESSAGE("Failed to load file.", xDocShRef.is());
+
+ // Saving without config items in settings.xml
+ std::shared_ptr<comphelper::ConfigurationChanges> pBatch( comphelper::ConfigurationChanges::create() );
+ officecfg::Office::Common::Misc::WriteLayerStateAsConfigItem::set(false, pBatch);
+ pBatch->commit();
+ utl::TempFile aTempFile;
+ aTempFile.EnableKillingFile();
+ save(xDocShRef.get(), getFormat(ODG), aTempFile );
+
+ // Verify, that the saved document has the ODF attributes
+ xmlDocUniquePtr pXmlDoc = parseExport(aTempFile, "styles.xml");
+ CPPUNIT_ASSERT_MESSAGE("Failed to get 'styles.xml'", pXmlDoc);
+ const OString sPathStart("/office:document-styles/office:master-styles/draw:layer-set/draw:layer");
+ assertXPath(pXmlDoc, sPathStart + "[@draw:name='backgroundobjects' and @draw:protected='true']");
+ assertXPath(pXmlDoc, sPathStart + "[@draw:name='controls' and @draw:display='screen']");
+ assertXPath(pXmlDoc, sPathStart + "[@draw:name='measurelines' and @draw:display='printer']");
+
+ // Verify, that the saved document has no layer items in settings.xml
+ xmlDocUniquePtr pXmlDoc2 = parseExport(aTempFile, "settings.xml");
+ CPPUNIT_ASSERT_MESSAGE("Failed to get 'settings.xml'", pXmlDoc2);
+ const OString sPathStart2("/office:document-settings/office:settings/config:config-item-set[@config:name='ooo:view-settings']/config:config-item-map-indexed[@config:name='Views']/config:config-item-map-entry");
+ xmlXPathObjectPtr pXmlObj=getXPathNode(pXmlDoc2, sPathStart2 + "/config:config-item[@config:name='VisibleLayers']");
+ CPPUNIT_ASSERT_EQUAL(0, xmlXPathNodeSetGetLength(pXmlObj->nodesetval));
+ xmlXPathFreeObject(pXmlObj);
+ pXmlObj=getXPathNode(pXmlDoc2, sPathStart2 + "/config:config-item[@config:name='PrintableLayers']");
+ CPPUNIT_ASSERT_EQUAL(0, xmlXPathNodeSetGetLength(pXmlObj->nodesetval));
+ xmlXPathFreeObject(pXmlObj);
+ pXmlObj=getXPathNode(pXmlDoc2, sPathStart2 + "/config:config-item[@config:name='LockedLayers']");
+ CPPUNIT_ASSERT_EQUAL(0, xmlXPathNodeSetGetLength(pXmlObj->nodesetval));
+ xmlXPathFreeObject(pXmlObj);
+
+ xDocShRef->DoClose();
+}
+
+void SdMiscTest::testTdf119392()
+{
+ // Loads a document which has two user layers "V--" and "V-L". Inserts a new layer "-P-" between them.
+ // Checks, that the bitfields in the saved file have the bits in the correct order, in case
+ // option WriteLayerAsConfigItem is true and the config items are written.
+ std::shared_ptr<comphelper::ConfigurationChanges> batch( comphelper::ConfigurationChanges::create() );
+ officecfg::Office::Common::Misc::WriteLayerStateAsConfigItem::set(true, batch);
+ batch->commit();
+
+ sd::DrawDocShellRef xDocShRef = Load(m_directories.getURLFromSrc(u"sd/qa/unit/data/tdf119392_InsertLayer.odg"), ODG);
+ CPPUNIT_ASSERT_MESSAGE("Failed to load file.", xDocShRef.is());
+ // Insert layer "-P-", not visible, printable, not locked
+ SdrView* pView = xDocShRef -> GetViewShell()->GetView();
+ pView -> InsertNewLayer("-P-", 6); // 0..4 standard layer, 5 layer "V--"
+ SdrPageView* pPageView = pView -> GetSdrPageView();
+ pPageView -> SetLayerVisible("-P-", false);
+ pPageView -> SetLayerPrintable("-P-", true);
+ pPageView -> SetLayerLocked("-P-", false);
+ utl::TempFile aTempFile;
+ aTempFile.EnableKillingFile();
+ save(xDocShRef.get(), getFormat(ODG), aTempFile );
+
+ // Verify correct bit order in bitfield in the config items in settings.xml
+ xmlDocUniquePtr pXmlDoc = parseExport(aTempFile, "settings.xml");
+ CPPUNIT_ASSERT_MESSAGE("Failed to get 'settings.xml'", pXmlDoc);
+ const OString sPathStart("/office:document-settings/office:settings/config:config-item-set[@config:name='ooo:view-settings']/config:config-item-map-indexed[@config:name='Views']/config:config-item-map-entry");
+ // First Byte is in order 'V-L -P- V-- measurelines controls backgroundobjects background layout'
+ // Bits need to be: visible=10111111=0xbf=191 printable=01011111=0x5f=95 locked=10000000=0x80=128
+ // The values in file are Base64 encoded.
+ OUString sBase64;
+ uno::Sequence<sal_Int8> aDecodedSeq;
+ sBase64 = getXPathContent(pXmlDoc, sPathStart + "/config:config-item[@config:name='VisibleLayers']");
+ CPPUNIT_ASSERT_MESSAGE( "Item VisibleLayers does not exists.", !sBase64.isEmpty());
+ comphelper::Base64::decode(aDecodedSeq, sBase64);
+ CPPUNIT_ASSERT_EQUAL( 0xbF, static_cast<sal_uInt8>(aDecodedSeq[0]) & 0xff); // & 0xff forces unambiguous types for CPPUNIT_ASSERT_EQUAL
+
+ sBase64 = getXPathContent(pXmlDoc, sPathStart + "/config:config-item[@config:name='PrintableLayers']");
+ CPPUNIT_ASSERT_MESSAGE( "Item PrintableLayers does not exists.", !sBase64.isEmpty());
+ comphelper::Base64::decode(aDecodedSeq, sBase64);
+ CPPUNIT_ASSERT_EQUAL( 0x5f, static_cast<sal_uInt8>(aDecodedSeq[0]) & 0xff);
+
+ sBase64 = getXPathContent(pXmlDoc, sPathStart + "/config:config-item[@config:name='LockedLayers']");
+ CPPUNIT_ASSERT_MESSAGE( "Item LockedLayers does not exists.", !sBase64.isEmpty());
+ comphelper::Base64::decode(aDecodedSeq, sBase64);
+ CPPUNIT_ASSERT_EQUAL( 0x80, static_cast<sal_uInt8>(aDecodedSeq[0]) & 0xff);
+
+ xDocShRef->DoClose();
+}
+
+void SdMiscTest::testTdf67248()
+{
+ // The document tdf67248.odg has been created with a German UI. It has a user layer named "Background".
+ // On opening the user layer must still exists. The error was, that it was merged into the standard
+ // layer "background".
+ sd::DrawDocShellRef xDocShRef = Load(m_directories.getURLFromSrc(u"sd/qa/unit/data/tdf67248.odg"), ODG);
+ CPPUNIT_ASSERT_MESSAGE("Failed to load file.", xDocShRef.is());
+ SdrLayerAdmin& rLayerAdmin = xDocShRef->GetDoc()->GetLayerAdmin();
+ CPPUNIT_ASSERT_EQUAL( sal_uInt16(6), rLayerAdmin.GetLayerCount());
+
+ xDocShRef->DoClose();
+}
+
+void SdMiscTest::testTdf119956()
+{
+ sd::DrawDocShellRef xDocShRef = Load(m_directories.getURLFromSrc(u"sd/qa/unit/data/tdf119956.odg"), ODG);
+ CPPUNIT_ASSERT_MESSAGE("Failed to load file.", xDocShRef.is());
+ sd::GraphicViewShell* pGraphicViewShell = static_cast<sd::GraphicViewShell*>(xDocShRef -> GetViewShell());
+ CPPUNIT_ASSERT(pGraphicViewShell);
+ sd::LayerTabBar* pLayerTabBar = pGraphicViewShell->GetLayerTabControl();
+ CPPUNIT_ASSERT(pLayerTabBar);
+
+ // Alt+Click sets a tab in edit mode, so that you can rename it.
+ // The error was, that Alt+Click on a tab, which was not the current tab, did not set the clicked tab
+ // as current tab. As a result, the entered text was applied to the wrong tab.
+
+ // The test document has the layer tabs "layout", "controls", "measurelines" and "Layer4" in this order
+ // The "pagePos" is 0, 1, 2, 3
+ // Make sure, that tab "layout" is the current tab.
+ MouseEvent aSyntheticMouseEvent;
+ if (pLayerTabBar->GetCurPagePos() != 0)
+ {
+ sal_uInt16 nIdOfTabPos0(pLayerTabBar->GetPageId(0));
+ tools::Rectangle aTabPos0Rect(pLayerTabBar->GetPageRect(nIdOfTabPos0));
+ aSyntheticMouseEvent = MouseEvent(aTabPos0Rect.Center(), 1, MouseEventModifiers::SYNTHETIC, MOUSE_LEFT, 0);
+ pLayerTabBar->MouseButtonDown(aSyntheticMouseEvent);
+ }
+ CPPUNIT_ASSERT_EQUAL(sal_uInt16(0), pLayerTabBar->GetCurPagePos());
+
+ // Alt+Click on tab "Layer4"
+ sal_uInt16 nIdOfTabPos3(pLayerTabBar->GetPageId(3));
+ tools::Rectangle aTabPos3Rect(pLayerTabBar->GetPageRect(nIdOfTabPos3));
+ aSyntheticMouseEvent = MouseEvent(aTabPos3Rect.Center(), 1, MouseEventModifiers::SYNTHETIC, MOUSE_LEFT, KEY_MOD2);
+ pLayerTabBar->MouseButtonDown(aSyntheticMouseEvent);
+
+ // Make sure, tab 3 is current tab now.
+ CPPUNIT_ASSERT_EQUAL(sal_uInt16(3), pLayerTabBar->GetCurPagePos());
+
+ xDocShRef->DoClose();
+}
+
+void SdMiscTest::testTdf98839_ShearVFlipH()
+{
+ // Loads a document with a sheared shape and mirrors it
+ sd::DrawDocShellRef xDocShRef = Load(m_directories.getURLFromSrc(u"sd/qa/unit/data/tdf98839_ShearVFlipH.odg"), ODG);
+ sd::GraphicViewShell* pViewShell = static_cast<sd::GraphicViewShell*>(xDocShRef->GetViewShell());
+ SdPage* pPage = pViewShell->GetActualPage();
+ SdrObjCustomShape* pShape = static_cast<SdrObjCustomShape*>(pPage->GetObj(0));
+ pShape->Mirror(Point(4000, 2000), Point(4000, 10000));
+
+ // Save and examine attribute draw:transform
+ utl::TempFile aTempFile;
+ aTempFile.EnableKillingFile();
+ save(xDocShRef.get(), getFormat(ODG), aTempFile);
+ xmlDocUniquePtr pXmlDoc = parseExport(aTempFile, "content.xml");
+ CPPUNIT_ASSERT_MESSAGE("Failed to get 'content.xml'", pXmlDoc);
+ const OString sPathStart("/office:document-content/office:body/office:drawing/draw:page");
+ assertXPath(pXmlDoc, sPathStart);
+ const OUString sTransform = getXPath(pXmlDoc, sPathStart + "/draw:custom-shape","transform");
+
+ // Error was, that the shear angle had a wrong sign.
+ CPPUNIT_ASSERT_MESSAGE("expected: draw:transform='skewX (-0.64350...)", sTransform.startsWith("skewX (-"));
+
+ xDocShRef->DoClose();
+}
+
+void SdMiscTest::testTdf130988()
+{
+ sd::DrawDocShellRef xDocShRef = Load(m_directories.getURLFromSrc(u"sd/qa/unit/data/tdf130988_3D_create_lathe.odg"), ODG);
+
+ //emulate command .uno:ConvertInto3DLathe
+ sd::ViewShell* pViewShell = xDocShRef->GetViewShell();
+ E3dView* pView = pViewShell->GetView();
+ pView->MarkNextObj();
+ pView->ConvertMarkedObjTo3D(false, basegfx::B2DPoint(8000.0, -3000.0), basegfx::B2DPoint(3000.0, -8000.0));
+ E3dScene* pObj = dynamic_cast<E3dScene*>(pView->GetMarkedObjectByIndex(0));
+ CPPUNIT_ASSERT(pObj);
+
+ // Error was, that the created 3D object had a wrong path. Instead examining
+ // the path directly, I use the scene distance, because that is easier. The
+ // scene distance is calculated from the object while creating.
+ const double fDistance = pObj->GetDistance();
+ CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("D3DSceneDistance", 7071.0, fDistance, 0.5);
+
+ xDocShRef->DoClose();
+}
+
+void SdMiscTest::testTdf131033()
+{
+ sd::DrawDocShellRef xDocShRef = Load(m_directories.getURLFromSrc(u"sd/qa/unit/data/tdf131033_3D_SceneSizeIn2d.odg"), ODG);
+
+ // The document contains a polygon, so that emulate command .uno:ConvertInto3DLathe
+ // by direct call of ConvertMarkedObjTo3D works.
+ // It produces a rotation around a vertical axis, which is far away from the
+ // generating shape.
+ sd::ViewShell* pViewShell = xDocShRef->GetViewShell();
+ E3dView* pView = pViewShell->GetView();
+ pView->MarkNextObj();
+ pView->ConvertMarkedObjTo3D(false, basegfx::B2DPoint(11000.0, -5000.0), basegfx::B2DPoint(11000.0, -9000.0));
+ E3dScene* pObj = dynamic_cast<E3dScene*>(pView->GetMarkedObjectByIndex(0));
+ CPPUNIT_ASSERT(pObj);
+
+ // Error was, that the 2D representation of the scene did not contain the default 20°
+ // rotation of the new scene around x-axis and therefore was not high enough.
+ const double fSnapRectHeight = pObj->GetSnapRect().getHeight();
+ CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("2D height", 7096.0, fSnapRectHeight, 1.0);
+
+ xDocShRef->DoClose();
+}
+
+void SdMiscTest::testTdf129898LayerDrawnInSlideshow()
+{
+ // Versions LO 6.2 to 6.4 have produced files, where the layer DrawnInSlideshow has
+ // got visible=false and printable=false attributes. Those files should be repaired now.
+ sd::DrawDocShellRef xDocShRef = Load(m_directories.getURLFromSrc(u"sd/qa/unit/data/tdf129898_faulty_DrawnInSlideshow.odp"), ODP);
+ CPPUNIT_ASSERT_MESSAGE("Failed to load file.", xDocShRef.is());
+
+ // Verify model
+ static const OUStringLiteral sName = u"DrawnInSlideshow";
+ SdrLayerAdmin& rLayerAdmin = xDocShRef->GetDoc()->GetLayerAdmin();
+ SdrLayer* pLayer = rLayerAdmin.GetLayer(sName);
+ CPPUNIT_ASSERT_MESSAGE("No layer DrawnInSlideshow", pLayer);
+ CPPUNIT_ASSERT(pLayer->IsVisibleODF());
+ CPPUNIT_ASSERT(pLayer->IsPrintableODF());
+
+ // Verify view
+ sd::DrawViewShell* pViewShell = static_cast<sd::DrawViewShell*>(xDocShRef->GetViewShell());
+ SdrPageView* pPageView = pViewShell->GetView()->GetSdrPageView();
+ CPPUNIT_ASSERT(pPageView->IsLayerVisible(sName));
+ CPPUNIT_ASSERT(pPageView->IsLayerPrintable(sName));
+
+ xDocShRef->DoClose();
+}
+
+void SdMiscTest::testTdf136956()
+{
+ ::sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc(u"sd/qa/unit/data/odp/cellspan.odp"), ODP);
+
+ const SdrPage *pPage = GetPage( 1, xDocShRef );
+ sdr::table::SdrTableObj *pTableObj = dynamic_cast<sdr::table::SdrTableObj*>(pPage->GetObj(0));
+ CPPUNIT_ASSERT( pTableObj );
+ uno::Reference< table::XTable > xTable(pTableObj->getTable(), uno::UNO_SET_THROW);
+
+ uno::Reference< css::table::XMergeableCellRange > xRange(
+ xTable->createCursorByRange( xTable->getCellRangeByPosition( 0, 0, 3, 2 ) ), uno::UNO_QUERY_THROW );
+
+ // 4x3 Table before merge.
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(4), xTable->getColumnCount());
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(3), xTable->getRowCount());
+
+ xRange->merge();
+
+ // 1x1 Table after merge.
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xTable->getColumnCount());
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xTable->getRowCount());
+
+ xDocShRef->GetUndoManager()->Undo();
+
+ // 4x3 Table after undo. Undo crashed before.
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(4), xTable->getColumnCount());
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(3), xTable->getRowCount());
+
+ xDocShRef->DoClose();
+}
+
+CPPUNIT_TEST_SUITE_REGISTRATION(SdMiscTest);
+
+CPPUNIT_PLUGIN_IMPLEMENT();
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */