summaryrefslogtreecommitdiffstats
path: root/sd/qa/unit/import-tests.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'sd/qa/unit/import-tests.cxx')
-rw-r--r--sd/qa/unit/import-tests.cxx3214
1 files changed, 3214 insertions, 0 deletions
diff --git a/sd/qa/unit/import-tests.cxx b/sd/qa/unit/import-tests.cxx
new file mode 100644
index 000000000..5d6157aa4
--- /dev/null
+++ b/sd/qa/unit/import-tests.cxx
@@ -0,0 +1,3214 @@
+/* -*- 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 <sal/config.h>
+
+#include <config_features.h>
+#include <config_poppler.h>
+#include <memory>
+#include <ostream>
+#include <sdpage.hxx>
+
+#include "sdmodeltestbase.hxx"
+
+#include <svl/stritem.hxx>
+#include <editeng/eeitem.hxx>
+#include <editeng/editobj.hxx>
+#include <editeng/outlobj.hxx>
+#include <editeng/ulspitem.hxx>
+#include <editeng/fhgtitem.hxx>
+#include <editeng/escapementitem.hxx>
+#include <editeng/colritem.hxx>
+#include <editeng/numitem.hxx>
+#include <editeng/unoprnms.hxx>
+#include <sfx2/app.hxx>
+#include <sfx2/sfxsids.hrc>
+#include <svl/style.hxx>
+
+#include <svx/svdotext.hxx>
+#include <svx/svdoashp.hxx>
+#include <svx/svdogrp.hxx>
+#include <svx/svdoole2.hxx>
+#include <svx/svdotable.hxx>
+#include <svx/xfillit0.hxx>
+#include <svx/xflclit.hxx>
+#include <svx/xlineit0.hxx>
+#include <svx/xlnclit.hxx>
+#include <svx/xlnwtit.hxx>
+#include <svx/sdasitm.hxx>
+#include <svx/sdmetitm.hxx>
+#include <svx/sdooitm.hxx>
+#include <animations/animationnodehelper.hxx>
+#include <sax/tools/converter.hxx>
+
+#include <com/sun/star/awt/Gradient.hpp>
+#include <com/sun/star/awt/XBitmap.hpp>
+#include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
+#include <com/sun/star/document/XEventsSupplier.hpp>
+#include <com/sun/star/presentation/ClickAction.hpp>
+#include <com/sun/star/presentation/XPresentationPage.hpp>
+#include <com/sun/star/presentation/XPresentationSupplier.hpp>
+#include <com/sun/star/drawing/BitmapMode.hpp>
+#include <com/sun/star/drawing/ColorMode.hpp>
+#include <com/sun/star/drawing/GraphicExportFilter.hpp>
+#include <com/sun/star/drawing/XDrawPage.hpp>
+#include <com/sun/star/drawing/XDrawPagesSupplier.hpp>
+#include <com/sun/star/drawing/XMasterPagesSupplier.hpp>
+#include <com/sun/star/drawing/XGluePointsSupplier.hpp>
+#include <com/sun/star/drawing/GluePoint2.hpp>
+#include <com/sun/star/container/XIdentifierAccess.hpp>
+#include <com/sun/star/animations/XAnimationNodeSupplier.hpp>
+#include <com/sun/star/animations/XAnimationNode.hpp>
+#include <com/sun/star/animations/XAnimate.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/chart/DataLabelPlacement.hpp>
+#include <com/sun/star/chart/XChartDocument.hpp>
+#include <com/sun/star/chart2/XChartDocument.hpp>
+#include <com/sun/star/chart2/XDataSeriesContainer.hpp>
+#include <com/sun/star/chart2/XCoordinateSystemContainer.hpp>
+#include <com/sun/star/chart2/XChartTypeContainer.hpp>
+#include <com/sun/star/chart2/data/XLabeledDataSequence.hpp>
+#include <com/sun/star/chart2/data/XDataSequence.hpp>
+#include <com/sun/star/chart2/data/XNumericalDataSequence.hpp>
+#include <com/sun/star/graphic/XGraphic.hpp>
+#include <com/sun/star/table/BorderLineStyle.hpp>
+#include <com/sun/star/table/BorderLine2.hpp>
+#include <com/sun/star/style/ParagraphAdjust.hpp>
+#include <com/sun/star/style/LineSpacing.hpp>
+#include <com/sun/star/style/LineSpacingMode.hpp>
+#include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
+#include <com/sun/star/table/XTableRows.hpp>
+#include <com/sun/star/style/NumberingType.hpp>
+#include <com/sun/star/frame/Desktop.hpp>
+#include <com/sun/star/text/GraphicCrop.hpp>
+#include <com/sun/star/text/XTextCursor.hpp>
+#include <com/sun/star/xml/dom/XDocument.hpp>
+
+#include <stlpool.hxx>
+#include <comphelper/processfactory.hxx>
+#include <comphelper/sequenceashashmap.hxx>
+#include <comphelper/graphicmimetype.hxx>
+#include <comphelper/lok.hxx>
+#include <vcl/pngread.hxx>
+#include <vcl/bitmapaccess.hxx>
+#include <vcl/dibtools.hxx>
+#include <svx/svdograf.hxx>
+
+using namespace ::com::sun::star;
+
+namespace com::sun::star::uno {
+
+template<class T>
+static std::ostream& operator<<(std::ostream& rStrm, const uno::Reference<T>& xRef)
+{
+ rStrm << xRef.get();
+ return rStrm;
+}
+
+}
+
+
+/// Impress import filters tests.
+class SdImportTest : public SdModelTestBase
+{
+public:
+ virtual void setUp() override;
+
+ void testDocumentLayout();
+ void testSmoketest();
+ void testN759180();
+ void testN778859();
+ void testMasterPageStyleParent();
+ void testGradientAngle();
+ void testTdf97808();
+ void testFillStyleNone();
+ void testFdo64512();
+ void testFdo71075();
+ void testN828390_2();
+ void testN828390_3();
+ void testFdo68594();
+ void testPlaceholderPriority();
+ void testFdo72998();
+ void testFdo77027();
+ void testStrictOOXML();
+ void testN862510_1();
+ void testN862510_2();
+ void testN862510_4();
+ void testBnc870237();
+ void testBnc887225();
+ void testPredefinedTableStyle();
+ void testBnc591147();
+ void testCreationDate();
+ void testMultiColTexts();
+ void testBnc584721_1();
+ void testBnc584721_2();
+ void testBnc584721_4();
+ void testBnc904423();
+ void testShapeLineStyle();
+ void testTableBorderLineStyle();
+ void testBnc862510_6();
+ void testBnc862510_7();
+#if ENABLE_PDFIMPORT
+#if HAVE_FEATURE_PDFIUM
+ void testPDFImportShared();
+#endif
+#if defined(IMPORT_PDF_ELEMENTS)
+ void testPDFImport();
+ void testPDFImportSkipImages();
+#endif
+#endif
+ void testBulletSuffix();
+ void testBnc910045();
+ void testRowHeight();
+ void testTdf93830();
+ void testTdf127129();
+ void testTdf93097();
+ void testTdf62255();
+ void testTdf93124();
+ void testTdf99729();
+ void testTdf89927();
+ void testTdf93868();
+ void testTdf95932();
+ void testTdf99030();
+ void testTdf49561();
+ void testTdf103473();
+ void testAoo124143();
+ void testTdf103567();
+ void testTdf103792();
+ void testTdf103876();
+ void testTdf79007();
+ void testTdf129686();
+ void testTdf104015();
+ void testTdf104201();
+ void testTdf103477();
+ void testTdf104445();
+ void testTdf105150();
+ void testTdf105150PPT();
+ void testTdf123684();
+ void testTdf100926();
+ void testTdf89064();
+ void testTdf108925();
+ void testTdf109067();
+ void testTdf109187();
+ void testTdf108926();
+ void testTdf100065();
+ void testTdf90626();
+ void testTdf114488();
+ void testTdf134174();
+ void testTdf114913();
+ void testTdf114821();
+ void testTdf115394();
+ void testTdf115394PPT();
+ void testTdf51340();
+ void testTdf116899();
+ void testTdf77747();
+ void testTdf116266();
+ void testTdf128684();
+ void testTdf119187();
+ void testShapeGlowEffectPPTXImpoer();
+
+ bool checkPattern(sd::DrawDocShellRef const & rDocRef, int nShapeNumber, std::vector<sal_uInt8>& rExpected);
+ void testPatternImport();
+ void testPptCrop();
+ void testTdf120028();
+ void testTdf120028b();
+ void testDescriptionImport();
+ void testTdf83247();
+ void testTdf47365();
+ void testTdf122899();
+ void testOOXTheme();
+ void testCropToShape();
+ void testTdf127964();
+ void testTdf106638();
+ void testTdf113198();
+
+ CPPUNIT_TEST_SUITE(SdImportTest);
+
+ CPPUNIT_TEST(testDocumentLayout);
+ CPPUNIT_TEST(testSmoketest);
+ CPPUNIT_TEST(testN759180);
+ CPPUNIT_TEST(testN778859);
+ CPPUNIT_TEST(testMasterPageStyleParent);
+ CPPUNIT_TEST(testGradientAngle);
+ CPPUNIT_TEST(testTdf97808);
+ CPPUNIT_TEST(testFillStyleNone);
+ CPPUNIT_TEST(testFdo64512);
+ CPPUNIT_TEST(testFdo71075);
+ CPPUNIT_TEST(testN828390_2);
+ CPPUNIT_TEST(testN828390_3);
+ CPPUNIT_TEST(testFdo68594);
+ CPPUNIT_TEST(testPlaceholderPriority);
+ CPPUNIT_TEST(testFdo72998);
+ CPPUNIT_TEST(testFdo77027);
+ CPPUNIT_TEST(testStrictOOXML);
+ CPPUNIT_TEST(testN862510_1);
+ CPPUNIT_TEST(testN862510_2);
+ CPPUNIT_TEST(testN862510_4);
+ CPPUNIT_TEST(testBnc870237);
+ CPPUNIT_TEST(testBnc887225);
+ CPPUNIT_TEST(testPredefinedTableStyle);
+ CPPUNIT_TEST(testBnc591147);
+ CPPUNIT_TEST(testCreationDate);
+ CPPUNIT_TEST(testMultiColTexts);
+ CPPUNIT_TEST(testBnc584721_1);
+ CPPUNIT_TEST(testBnc584721_2);
+ CPPUNIT_TEST(testBnc584721_4);
+ CPPUNIT_TEST(testBnc904423);
+ CPPUNIT_TEST(testShapeLineStyle);
+ CPPUNIT_TEST(testTableBorderLineStyle);
+ CPPUNIT_TEST(testBnc862510_6);
+ CPPUNIT_TEST(testBnc862510_7);
+#if ENABLE_PDFIMPORT
+#if HAVE_FEATURE_PDFIUM
+ CPPUNIT_TEST(testPDFImportShared);
+#endif
+#if defined(IMPORT_PDF_ELEMENTS)
+ CPPUNIT_TEST(testPDFImport);
+ CPPUNIT_TEST(testPDFImportSkipImages);
+#endif
+#endif
+ CPPUNIT_TEST(testBulletSuffix);
+ CPPUNIT_TEST(testBnc910045);
+ CPPUNIT_TEST(testRowHeight);
+ CPPUNIT_TEST(testTdf93830);
+ CPPUNIT_TEST(testTdf127129);
+ CPPUNIT_TEST(testTdf93097);
+ CPPUNIT_TEST(testTdf62255);
+ CPPUNIT_TEST(testTdf93124);
+ CPPUNIT_TEST(testTdf99729);
+ CPPUNIT_TEST(testTdf89927);
+ CPPUNIT_TEST(testTdf93868);
+ CPPUNIT_TEST(testTdf95932);
+ CPPUNIT_TEST(testTdf99030);
+ CPPUNIT_TEST(testTdf49561);
+ CPPUNIT_TEST(testTdf103473);
+ CPPUNIT_TEST(testAoo124143);
+ CPPUNIT_TEST(testTdf103567);
+ CPPUNIT_TEST(testTdf103792);
+ CPPUNIT_TEST(testTdf103876);
+ CPPUNIT_TEST(testTdf79007);
+ CPPUNIT_TEST(testTdf129686);
+ CPPUNIT_TEST(testTdf104015);
+ CPPUNIT_TEST(testTdf104201);
+ CPPUNIT_TEST(testTdf103477);
+ CPPUNIT_TEST(testTdf104445);
+ CPPUNIT_TEST(testTdf105150);
+ CPPUNIT_TEST(testTdf105150PPT);
+ CPPUNIT_TEST(testTdf123684);
+ CPPUNIT_TEST(testTdf100926);
+ CPPUNIT_TEST(testPatternImport);
+ CPPUNIT_TEST(testTdf89064);
+ CPPUNIT_TEST(testTdf108925);
+ CPPUNIT_TEST(testTdf109067);
+ CPPUNIT_TEST(testTdf109187);
+ CPPUNIT_TEST(testTdf108926);
+ CPPUNIT_TEST(testTdf100065);
+ CPPUNIT_TEST(testTdf90626);
+ CPPUNIT_TEST(testTdf114488);
+ CPPUNIT_TEST(testTdf134174);
+ CPPUNIT_TEST(testTdf114913);
+ CPPUNIT_TEST(testTdf114821);
+ CPPUNIT_TEST(testTdf115394);
+ CPPUNIT_TEST(testTdf115394PPT);
+ CPPUNIT_TEST(testTdf51340);
+ CPPUNIT_TEST(testTdf116899);
+ CPPUNIT_TEST(testTdf77747);
+ CPPUNIT_TEST(testTdf116266);
+ CPPUNIT_TEST(testPptCrop);
+ CPPUNIT_TEST(testTdf120028);
+ CPPUNIT_TEST(testTdf120028b);
+ CPPUNIT_TEST(testDescriptionImport);
+ CPPUNIT_TEST(testTdf83247);
+ CPPUNIT_TEST(testTdf47365);
+ CPPUNIT_TEST(testTdf122899);
+ CPPUNIT_TEST(testOOXTheme);
+ CPPUNIT_TEST(testCropToShape);
+ CPPUNIT_TEST(testTdf127964);
+ CPPUNIT_TEST(testTdf106638);
+ CPPUNIT_TEST(testTdf128684);
+ CPPUNIT_TEST(testTdf113198);
+ CPPUNIT_TEST(testTdf119187);
+ CPPUNIT_TEST(testShapeGlowEffectPPTXImpoer);
+
+ CPPUNIT_TEST_SUITE_END();
+};
+
+void SdImportTest::setUp()
+{
+ SdModelTestBase::setUp();
+ mxDesktop.set(frame::Desktop::create(getComponentContext()));
+}
+
+/** Test document against a reference XML dump of shapes.
+
+If you want to update one of these tests, or add a new one, set the nUpdateMe
+to the index of the test, and the dump XML's will be created (or rewritten)
+instead of checking. Use with care - when the test is failing, first find out
+why, instead of just updating .xml's blindly.
+
+Example: Let's say you are adding a test called fdoABCD.pptx. You'll place it
+to the data/ subdirectory, and will add an entry to aFilesToCompare below,
+the 3rd parameter is for export test - can be -1 (don't export), ODP, PPT or PPTX
+like:
+
+ { "fdoABCD.pptx", "xml/fdoABCD_", PPTX },
+
+and will count the index in the aFilesToCompare structure (1st is 0, 2nd is 1,
+etc.) Temporarily you'll set nUpdateMe to this index (instead of -1), and run
+
+make sd
+
+This will generate the sd/qa/unit/data/xml/fdoABCD_*.xml for you. Now you
+will change nUpdateMe back to -1, and commit your fdoABCD.pptx test, the
+xml/fdoABCD_*.xml dumps, and the aFilesToCompare addition in one commit.
+
+As the last step, you will revert your fix and do 'make sd' again, to check
+that without your fix, the unit test breaks. Then clean up, and push :-)
+
+NOTE: This approach is suitable only for tests of fixes that actually change
+the layout - best to check by reverting your fix locally after having added
+the test, and re-running; it should break.
+*/
+void SdImportTest::testDocumentLayout()
+{
+ static const struct { const char *pInput, *pDump; sal_Int32 nFormat; sal_Int32 nExportType; } aFilesToCompare[] =
+ {
+ { "odp/shapes-test.odp", "xml/shapes-test_page", ODP, -1 },
+ { "fdo47434.pptx", "xml/fdo47434_", PPTX, -1 },
+ { "n758621.ppt", "xml/n758621_", PPT, -1 },
+ { "fdo64586.ppt", "xml/fdo64586_", PPT, -1 },
+ { "n819614.pptx", "xml/n819614_", PPTX, -1 },
+ { "n820786.pptx", "xml/n820786_", PPTX, -1 },
+ { "n762695.pptx", "xml/n762695_", PPTX, -1 },
+ { "n593612.pptx", "xml/n593612_", PPTX, -1 },
+ { "fdo71434.pptx", "xml/fdo71434_", PPTX, -1 },
+ { "n902652.pptx", "xml/n902652_", PPTX, -1 },
+ { "tdf90403.pptx", "xml/tdf90403_", PPTX, -1 },
+ { "tdf90338.odp", "xml/tdf90338_", ODP, PPTX },
+ { "tdf92001.odp", "xml/tdf92001_", ODP, PPTX },
+// GCC -mfpmath=387 rounding issues in lclPushMarkerProperties
+// (oox/source/drawingml/lineproperties.cxx); see mail sub-thread starting at
+// <https://lists.freedesktop.org/archives/libreoffice/2016-September/
+// 075211.html> "Re: Test File: sc/qa/unit/data/functions/fods/chiinv.fods:
+// fails with Assertion" for how "-mfpmath=sse -msse2" would fix that:
+#if !(defined LINUX && defined X86)
+ { "tdf100491.pptx", "xml/tdf100491_", PPTX, -1 },
+#endif
+ { "tdf109317.pptx", "xml/tdf109317_", PPTX, ODP},
+ // { "pptx/n828390.pptx", "pptx/xml/n828390_", PPTX, PPTX }, // Example
+ };
+
+ for ( int i = 0; i < static_cast< int >( SAL_N_ELEMENTS( aFilesToCompare ) ); ++i )
+ {
+ int const nUpdateMe = -1; // index of test we want to update; supposedly only when the test is created
+
+ sd::DrawDocShellRef xDocShRef = loadURL( m_directories.getURLFromSrc( "/sd/qa/unit/data/" ) + OUString::createFromAscii( aFilesToCompare[i].pInput ), aFilesToCompare[i].nFormat );
+ if( aFilesToCompare[i].nExportType >= 0 )
+ xDocShRef = saveAndReload( xDocShRef.get(), aFilesToCompare[i].nExportType );
+ compareWithShapesDump( xDocShRef,
+ m_directories.getPathFromSrc( "/sd/qa/unit/data/" ) + OUString::createFromAscii( aFilesToCompare[i].pDump ),
+ i == nUpdateMe );
+ }
+}
+
+void SdImportTest::testSmoketest()
+{
+ sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc("/sd/qa/unit/data/smoketest.pptx"), PPTX);
+
+ SdDrawDocument *pDoc = xDocShRef->GetDoc();
+ CPPUNIT_ASSERT_MESSAGE( "no document", pDoc != nullptr );
+
+ // cf. SdrModel svx/svdmodel.hxx ...
+
+ CPPUNIT_ASSERT_EQUAL_MESSAGE( "wrong page count", static_cast<sal_uInt16>(3), pDoc->GetPageCount());
+
+ const SdrPage *pPage = pDoc->GetPage (1);
+ CPPUNIT_ASSERT_MESSAGE( "no page", pPage != nullptr );
+
+ CPPUNIT_ASSERT_MESSAGE( "changed", !pDoc->IsChanged() );
+
+ xDocShRef->DoClose();
+}
+
+void SdImportTest::testN759180()
+{
+ sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc("/sd/qa/unit/data/n759180.pptx"), PPTX);
+
+ const SdrPage *pPage = GetPage( 1, xDocShRef );
+
+ //sal_uIntPtr nObjs = pPage->GetObjCount();
+ //for (sal_uIntPtr i = 0; i < nObjs; i++)
+ {
+ // Get the object
+ SdrObject *pObj = pPage->GetObj(0);
+ SdrTextObj *pTxtObj = dynamic_cast<SdrTextObj *>( pObj );
+ CPPUNIT_ASSERT(pTxtObj);
+ std::vector<EECharAttrib> rLst;
+ const EditTextObject& aEdit = pTxtObj->GetOutlinerParaObject()->GetTextObject();
+ const SvxULSpaceItem *pULSpace = aEdit.GetParaAttribs(0).GetItem(EE_PARA_ULSPACE);
+ CPPUNIT_ASSERT(pULSpace);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE( "Para bottom spacing is wrong!", static_cast<sal_uInt16>(0), pULSpace->GetLower());
+ aEdit.GetCharAttribs(1, rLst);
+ auto it = std::find_if(rLst.rbegin(), rLst.rend(),
+ [](const EECharAttrib& rCharAttr) { return dynamic_cast<const SvxFontHeightItem *>(rCharAttr.pAttr) != nullptr; });
+ if (it != rLst.rend())
+ {
+ const SvxFontHeightItem * pFontHeight = dynamic_cast<const SvxFontHeightItem *>((*it).pAttr);
+ // nStart == 9
+ // font height = 5 => 5*2540/72
+ CPPUNIT_ASSERT_EQUAL_MESSAGE( "Font height is wrong", static_cast<sal_uInt32>(176), pFontHeight->GetHeight() );
+ }
+ }
+
+ xDocShRef->DoClose();
+}
+
+void SdImportTest::testN862510_1()
+{
+ sd::DrawDocShellRef xDocShRef = loadURL( m_directories.getURLFromSrc("/sd/qa/unit/data/pptx/n862510_1.pptx"), PPTX );
+
+ const SdrPage *pPage = GetPage( 1, xDocShRef );
+ {
+ std::vector<EECharAttrib> rLst;
+ SdrObject *pObj = pPage->GetObj( 0 );
+ SdrTextObj *pTxtObj = dynamic_cast<SdrTextObj *>( pObj );
+ CPPUNIT_ASSERT( pTxtObj );
+ const EditTextObject& aEdit = pTxtObj->GetOutlinerParaObject()->GetTextObject();
+ aEdit.GetCharAttribs( 0, rLst );
+ for( std::vector<EECharAttrib>::reverse_iterator it = rLst.rbegin(); it!=rLst.rend(); ++it)
+ {
+ const SvxEscapementItem *pFontEscapement = dynamic_cast<const SvxEscapementItem *>( (*it).pAttr );
+ CPPUNIT_ASSERT_MESSAGE( "Baseline attribute not handled properly", !(pFontEscapement && pFontEscapement->GetProportionalHeight() != 100) );
+ }
+ }
+
+ xDocShRef->DoClose();
+}
+
+void SdImportTest::testN862510_2()
+{
+ sd::DrawDocShellRef xDocShRef = loadURL( m_directories.getURLFromSrc("/sd/qa/unit/data/pptx/n862510_2.pptx"), PPTX );
+
+ const SdrPage *pPage = GetPage( 1, xDocShRef );
+ {
+ CPPUNIT_ASSERT_EQUAL(size_t(1), pPage->GetObjCount());
+ SdrObjGroup *pGrpObj = dynamic_cast<SdrObjGroup *>( pPage->GetObj( 0 ) );
+ CPPUNIT_ASSERT( pGrpObj );
+ SdrObjCustomShape *pObj = dynamic_cast<SdrObjCustomShape *>( pGrpObj->GetSubList()->GetObj( 1 ) );
+ CPPUNIT_ASSERT( pObj );
+ CPPUNIT_ASSERT_EQUAL_MESSAGE( "Wrong Text Rotation!", 90.0, pObj->GetExtraTextRotation( true ) );
+ }
+
+ xDocShRef->DoClose();
+}
+
+void SdImportTest::testN862510_4()
+{
+ sd::DrawDocShellRef xDocShRef = loadURL( m_directories.getURLFromSrc("/sd/qa/unit/data/pptx/n862510_4.pptx"), PPTX );
+
+ const SdrPage *pPage = GetPage( 1, xDocShRef );
+ {
+ std::vector<EECharAttrib> rLst;
+ SdrObject *pObj = pPage->GetObj( 0 );
+ SdrTextObj *pTxtObj = dynamic_cast<SdrTextObj *>( pObj );
+ CPPUNIT_ASSERT( pTxtObj );
+ const EditTextObject& aEdit = pTxtObj->GetOutlinerParaObject()->GetTextObject();
+ aEdit.GetCharAttribs( 0, rLst );
+ for( std::vector<EECharAttrib>::reverse_iterator it = rLst.rbegin(); it != rLst.rend(); ++it )
+ {
+ const SvxColorItem *pC = dynamic_cast<const SvxColorItem *>( (*it).pAttr );
+ CPPUNIT_ASSERT_MESSAGE( "gradfill for text color not handled!", !( pC && pC->GetValue() == Color(0) ) );
+ }
+ }
+
+ xDocShRef->DoClose();
+}
+
+void SdImportTest::testN828390_2()
+{
+ sd::DrawDocShellRef xDocShRef = loadURL( m_directories.getURLFromSrc("/sd/qa/unit/data/pptx/n828390_2.pptx"), PPTX );
+ const SdrPage *pPage = GetPage( 1, xDocShRef );
+
+ SdrObject *pObj = pPage->GetObj(0);
+ SdrTextObj *pTxtObj = dynamic_cast<SdrTextObj *>( pObj );
+ CPPUNIT_ASSERT( pTxtObj );
+ const EditTextObject& aEdit = pTxtObj->GetOutlinerParaObject()->GetTextObject();
+ CPPUNIT_ASSERT_EQUAL(OUString("Linux "), aEdit.GetText(0));
+ CPPUNIT_ASSERT_EQUAL(OUString("Standard Platform"), aEdit.GetText(1));
+
+ xDocShRef->DoClose();
+}
+
+void SdImportTest::testN828390_3()
+{
+ sd::DrawDocShellRef xDocShRef = loadURL( m_directories.getURLFromSrc("/sd/qa/unit/data/pptx/n828390_3.pptx"), PPTX );
+ const SdrPage *pPage = GetPage( 1, xDocShRef );
+
+ SdrObject *pObj = pPage->GetObj(0);
+ SdrTextObj *pTxtObj = dynamic_cast<SdrTextObj *>( pObj );
+ CPPUNIT_ASSERT( pTxtObj );
+ const EditTextObject& aEdit = pTxtObj->GetOutlinerParaObject()->GetTextObject();
+ std::vector<EECharAttrib> rLst;
+ aEdit.GetCharAttribs(1, rLst);
+ bool bPassed = std::none_of(rLst.rbegin(), rLst.rend(),
+ [](const EECharAttrib& rCharAttr) {
+ const SvxEscapementItem *pFontEscapement = dynamic_cast<const SvxEscapementItem *>(rCharAttr.pAttr);
+ return pFontEscapement && (pFontEscapement->GetEsc() != 0);
+ });
+ CPPUNIT_ASSERT_MESSAGE("CharEscapment not imported properly", bPassed);
+
+ xDocShRef->DoClose();
+}
+
+void SdImportTest::testMasterPageStyleParent()
+{
+ sd::DrawDocShellRef xDocShRef = loadURL( m_directories.getURLFromSrc("/sd/qa/unit/data/odp/masterpage_style_parent.odp"), ODP );
+ SdDrawDocument *pDoc = xDocShRef->GetDoc();
+ CPPUNIT_ASSERT_MESSAGE( "no document", pDoc != nullptr );
+
+ SdStyleSheetPool *const pPool(pDoc->GetSdStyleSheetPool());
+
+ int parents(0);
+ SfxStyleSheetIterator iter(pPool, SfxStyleFamily::Page);
+ for (SfxStyleSheetBase * pStyle = iter.First(); pStyle; pStyle = iter.Next())
+ {
+ OUString const name(pStyle->GetName());
+ OUString const parent(pStyle->GetParent());
+ if (!parent.isEmpty())
+ {
+ ++parents;
+ // check that parent exists
+ SfxStyleSheetBase *const pParentStyle(
+ pPool->Find(parent, SfxStyleFamily::Page));
+ CPPUNIT_ASSERT(pParentStyle);
+ CPPUNIT_ASSERT_EQUAL(pParentStyle->GetName(), parent);
+ // check that parent has the same master page as pStyle
+ CPPUNIT_ASSERT(parent.indexOf(SD_LT_SEPARATOR) != -1);
+ CPPUNIT_ASSERT(name.indexOf(SD_LT_SEPARATOR) != -1);
+ CPPUNIT_ASSERT_EQUAL(
+ parent.copy(0, parent.indexOf(SD_LT_SEPARATOR)),
+ name.copy(0, name.indexOf(SD_LT_SEPARATOR)));
+ }
+ }
+ // check that there are actually parents...
+ CPPUNIT_ASSERT_EQUAL(16, parents);
+
+ xDocShRef->DoClose();
+}
+
+void SdImportTest::testGradientAngle()
+{
+ sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc("/sd/qa/unit/data/odg/gradient-angle.fodg"), FODG);
+
+ uno::Reference<lang::XMultiServiceFactory> const xDoc(
+ xDocShRef->GetDoc()->getUnoModel(), uno::UNO_QUERY);
+
+ awt::Gradient gradient;
+ uno::Reference<container::XNameAccess> const xGradients(
+ xDoc->createInstance("com.sun.star.drawing.GradientTable"),
+ uno::UNO_QUERY);
+
+ CPPUNIT_ASSERT(xGradients->getByName("Gradient 38") >>= gradient);
+ CPPUNIT_ASSERT_EQUAL(sal_Int16(0), gradient.Angle); // was: 3600
+
+ CPPUNIT_ASSERT(xGradients->getByName("Gradient 10") >>= gradient);
+ CPPUNIT_ASSERT_EQUAL(sal_Int16(270), gradient.Angle); // 27deg
+
+ CPPUNIT_ASSERT(xGradients->getByName("Gradient 11") >>= gradient);
+ CPPUNIT_ASSERT_EQUAL(sal_Int16(1145), gradient.Angle); // 2rad
+
+ CPPUNIT_ASSERT(xGradients->getByName("Gradient 12") >>= gradient);
+ CPPUNIT_ASSERT_EQUAL(sal_Int16(900), gradient.Angle); // 100grad
+
+ CPPUNIT_ASSERT(xGradients->getByName("Gradient 13") >>= gradient);
+ CPPUNIT_ASSERT_EQUAL(sal_Int16(3599), gradient.Angle); // -1
+
+ CPPUNIT_ASSERT(xGradients->getByName("Gradient 14") >>= gradient);
+ CPPUNIT_ASSERT_EQUAL(sal_Int16(3028), gradient.Angle); // -1rad
+
+ CPPUNIT_ASSERT(xGradients->getByName("Gradient 15") >>= gradient);
+ CPPUNIT_ASSERT_EQUAL(sal_Int16(300), gradient.Angle); // 3900
+
+ CPPUNIT_ASSERT(xGradients->getByName("Gradient 16") >>= gradient);
+ CPPUNIT_ASSERT_EQUAL(sal_Int16(105), gradient.Angle); // 10.5deg
+
+ CPPUNIT_ASSERT(xGradients->getByName("Gradient 17") >>= gradient);
+ CPPUNIT_ASSERT_EQUAL(sal_Int16(1800), gradient.Angle); // \pi rad
+
+ uno::Reference<container::XNameAccess> const xTranspGradients(
+ xDoc->createInstance("com.sun.star.drawing.TransparencyGradientTable"),
+ uno::UNO_QUERY);
+
+ CPPUNIT_ASSERT(xTranspGradients->getByName("Transparency 2") >>= gradient);
+ CPPUNIT_ASSERT_EQUAL(sal_Int16(10), gradient.Angle); // 1
+
+ CPPUNIT_ASSERT(xTranspGradients->getByName("Transparency 1") >>= gradient);
+ CPPUNIT_ASSERT_EQUAL(sal_Int16(900), gradient.Angle); // 90deg
+
+ CPPUNIT_ASSERT(xTranspGradients->getByName("Transparency 3") >>= gradient);
+ CPPUNIT_ASSERT_EQUAL(sal_Int16(572), gradient.Angle); // 1.0rad
+
+ CPPUNIT_ASSERT(xTranspGradients->getByName("Transparency 4") >>= gradient);
+ CPPUNIT_ASSERT_EQUAL(sal_Int16(1800), gradient.Angle); // 1000grad
+
+ xDocShRef->DoClose();
+}
+
+void SdImportTest::testN778859()
+{
+ sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc("/sd/qa/unit/data/pptx/n778859.pptx"), PPTX);
+
+ const SdrPage *pPage = GetPage( 1, xDocShRef );
+ {
+ // Get the object
+ SdrObject *pObj = pPage->GetObj(1);
+ SdrTextObj *pTxtObj = dynamic_cast<SdrTextObj *>( pObj );
+ CPPUNIT_ASSERT_MESSAGE( "no text object", pTxtObj != nullptr);
+ CPPUNIT_ASSERT(!pTxtObj->IsAutoFit());
+ }
+
+ xDocShRef->DoClose();
+}
+
+void SdImportTest::testFdo68594()
+{
+ sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc("/sd/qa/unit/data/ppt/fdo68594.ppt"), PPT);
+
+ const SdrPage *pPage = &(GetPage( 1, xDocShRef )->TRG_GetMasterPage());
+ SdrObject *pObj = pPage->GetObj(1);
+ SdrTextObj *pTxtObj = dynamic_cast<SdrTextObj *>( pObj );
+ CPPUNIT_ASSERT_MESSAGE( "no text object", pTxtObj != nullptr);
+ const SvxColorItem *pC = &pTxtObj->GetMergedItem(EE_CHAR_COLOR);
+ CPPUNIT_ASSERT_MESSAGE( "no color item", pC != nullptr);
+ // Color should be black
+ CPPUNIT_ASSERT_EQUAL_MESSAGE( "Placeholder color mismatch", sal_uInt32(0), sal_uInt32(pC->GetValue()) );
+
+ xDocShRef->DoClose();
+}
+
+void SdImportTest::testPlaceholderPriority()
+{
+ sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc("/sd/qa/unit/data/ppt/placeholder-priority.pptx"), PPTX);
+
+ const SdrPage* pPage = GetPage( 1, xDocShRef );
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Missing placeholder", sal_uInt32(2), sal_uInt32(pPage->GetObjCount()));
+
+ tools::Rectangle pObj1Rect(9100, 3500, 29619, 4038);
+ SdrObject *pObj1 = pPage->GetObj(0);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Placeholder position is wrong, check the placeholder priority", pObj1Rect, pObj1->GetCurrentBoundRect());
+
+ tools::Rectangle pObj2Rect(9102, 8643, 29619, 12642);
+ SdrObject *pObj2 = pPage->GetObj(1);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Placeholder position is wrong, check the placeholder priority", pObj2Rect, pObj2->GetCurrentBoundRect());
+
+ // If the placeholder positions are wrong, please check placeholder priority in Placeholders class.
+}
+
+void SdImportTest::testPptCrop()
+{
+ sd::DrawDocShellRef xDocShRef
+ = loadURL(m_directories.getURLFromSrc("/sd/qa/unit/data/ppt/crop.ppt"), PPT);
+
+ uno::Reference<beans::XPropertySet> xPropertySet(
+ getShapeFromPage(/*nShape=*/1, /*nPage=*/0, xDocShRef));
+ text::GraphicCrop aCrop;
+ xPropertySet->getPropertyValue("GraphicCrop") >>= aCrop;
+ // These were all 0, lazy-loading broke cropping.
+ CPPUNIT_ASSERT_GREATER(static_cast<sal_Int32>(0), aCrop.Top);
+ CPPUNIT_ASSERT_GREATER(static_cast<sal_Int32>(0), aCrop.Bottom);
+ CPPUNIT_ASSERT_GREATER(static_cast<sal_Int32>(0), aCrop.Left);
+ CPPUNIT_ASSERT_GREATER(static_cast<sal_Int32>(0), aCrop.Right);
+
+ xDocShRef->DoClose();
+}
+
+void SdImportTest::testFdo72998()
+{
+ sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc("/sd/qa/unit/data/pptx/cshapes.pptx"), PPTX);
+
+ const SdrPage *pPage = GetPage( 1, xDocShRef );
+ {
+ SdrObjCustomShape *pObj = dynamic_cast<SdrObjCustomShape *>(pPage->GetObj(2));
+ CPPUNIT_ASSERT( pObj );
+ const SdrCustomShapeGeometryItem& rGeometryItem = pObj->GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY );
+ const css::uno::Any* pViewBox = const_cast<SdrCustomShapeGeometryItem&>(rGeometryItem).GetPropertyValueByName( OUString( "ViewBox" ) );
+ CPPUNIT_ASSERT_MESSAGE( "Missing ViewBox", pViewBox );
+ css::awt::Rectangle aViewBox;
+ CPPUNIT_ASSERT( (*pViewBox >>= aViewBox ) );
+ CPPUNIT_ASSERT_MESSAGE( "Width should be zero - for forcing scale to 1", !aViewBox.Width );
+ CPPUNIT_ASSERT_MESSAGE( "Height should be zero - for forcing scale to 1", !aViewBox.Height );
+ }
+
+ xDocShRef->DoClose();
+}
+
+void SdImportTest::testFdo77027()
+{
+ sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc("/sd/qa/unit/data/odp/fdo77027.odp"), ODP);
+
+ const SdrPage *pPage = GetPage( 1, xDocShRef );
+ {
+ SdrOle2Obj *const pObj = dynamic_cast<SdrOle2Obj*>(pPage->GetObj(0));
+ CPPUNIT_ASSERT(pObj);
+
+ // check that the fill style/color was actually imported
+ const XFillStyleItem& rStyleItem = dynamic_cast<const XFillStyleItem&>(
+ pObj->GetMergedItem(XATTR_FILLSTYLE));
+ CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_SOLID, rStyleItem.GetValue());
+ const XFillColorItem& rColorItem = dynamic_cast<const XFillColorItem&>(
+ pObj->GetMergedItem(XATTR_FILLCOLOR));
+ CPPUNIT_ASSERT_EQUAL(Color(0xff6600), rColorItem.GetColorValue());
+ }
+
+ xDocShRef->DoClose();
+}
+
+void SdImportTest::testTdf97808()
+{
+ sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc("/sd/qa/unit/data/tdf97808.fodp"), FODP);
+
+ uno::Reference<style::XStyleFamiliesSupplier> xStyleFamiliesSupplier(
+ xDocShRef->GetModel(), uno::UNO_QUERY);
+ uno::Reference<container::XNameAccess> xStyleFamilies = xStyleFamiliesSupplier->getStyleFamilies();
+ uno::Reference<container::XNameAccess> xStyleFamily(xStyleFamilies->getByName("graphics"), uno::UNO_QUERY);
+ uno::Reference<beans::XPropertySet> xStyle(xStyleFamily->getByName("objectwithoutfill"), uno::UNO_QUERY);
+ OUString lineend;
+ CPPUNIT_ASSERT(xStyle->getPropertyValue("LineEndName") >>= lineend);
+ CPPUNIT_ASSERT_EQUAL(OUString("Arrow"), lineend);
+
+ // the draw:marker-end="" did not override the style
+ uno::Reference<drawing::XDrawPagesSupplier> xDoc(
+ xDocShRef->GetDoc()->getUnoModel(), uno::UNO_QUERY_THROW);
+ uno::Reference<drawing::XDrawPage> xPage(
+ xDoc->getDrawPages()->getByIndex(0), uno::UNO_QUERY_THROW);
+ uno::Reference<beans::XPropertySet> xLine(
+ xPage->getByIndex(0), uno::UNO_QUERY_THROW);
+ //uno::Reference<style::XStyle> xParent;
+ uno::Reference<beans::XPropertySet> xParent;
+ CPPUNIT_ASSERT(xLine->getPropertyValue("Style") >>= xParent);
+ CPPUNIT_ASSERT_EQUAL(xStyle, xParent);
+ CPPUNIT_ASSERT(xLine->getPropertyValue("LineEndName") >>= lineend);
+ CPPUNIT_ASSERT_EQUAL(OUString(), lineend);
+
+ xDocShRef->DoClose();
+}
+void SdImportTest::testFillStyleNone()
+{
+ sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc("/sd/qa/unit/data/tdf123841.odg"), ODG);
+
+ const SdrPage* pPage = GetPage(1, xDocShRef);
+ const SdrObject* pObj = pPage->GetObj(0);
+ auto& rFillStyleItem
+ = dynamic_cast<const XFillStyleItem&>(pObj->GetMergedItem(XATTR_FILLSTYLE));
+ // Without the accompanying fix in place, this test would have failed with 'Expected: 0; Actual:
+ // 1', i.e. the shape's fill was FillStyle_SOLID, making the text of the shape unreadable.
+ CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_NONE, rFillStyleItem.GetValue());
+ xDocShRef->DoClose();
+}
+
+void SdImportTest::testFdo64512()
+{
+ sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc("/sd/qa/unit/data/fdo64512.odp"), ODP);
+
+ uno::Reference< drawing::XDrawPagesSupplier > xDoc(
+ xDocShRef->GetDoc()->getUnoModel(), uno::UNO_QUERY_THROW );
+ CPPUNIT_ASSERT_EQUAL_MESSAGE( "not exactly one page", static_cast<sal_Int32>(1), xDoc->getDrawPages()->getCount() );
+
+ uno::Reference< drawing::XDrawPage > xPage(
+ xDoc->getDrawPages()->getByIndex(0), uno::UNO_QUERY_THROW );
+ CPPUNIT_ASSERT_EQUAL_MESSAGE( "not exactly three shapes", static_cast<sal_Int32>(3), xPage->getCount() );
+
+ uno::Reference< beans::XPropertySet > xConnectorShape(
+ xPage->getByIndex(2), uno::UNO_QUERY );
+ CPPUNIT_ASSERT_MESSAGE( "no connector shape", xConnectorShape.is() );
+
+ uno::Reference< beans::XPropertySet > xSvgShape(
+ xConnectorShape->getPropertyValue("StartShape"), uno::UNO_QUERY );
+ CPPUNIT_ASSERT_MESSAGE( "no start shape", xSvgShape.is() );
+
+ uno::Reference< beans::XPropertySet > xCustomShape(
+ xConnectorShape->getPropertyValue("EndShape"), uno::UNO_QUERY );
+ CPPUNIT_ASSERT_MESSAGE( "no end shape", xCustomShape.is() );
+
+ uno::Reference< animations::XAnimationNodeSupplier > xAnimNodeSupplier(
+ xPage, uno::UNO_QUERY_THROW );
+ uno::Reference< animations::XAnimationNode > xRootNode(
+ xAnimNodeSupplier->getAnimationNode() );
+ std::vector< uno::Reference< animations::XAnimationNode > > aAnimVector;
+ anim::create_deep_vector(xRootNode, aAnimVector);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE( "not 8 animation nodes", static_cast<std::size_t>(8), aAnimVector.size() );
+
+ uno::Reference< animations::XAnimate > xNode(
+ aAnimVector[7], uno::UNO_QUERY_THROW );
+ uno::Reference< drawing::XShape > xTargetShape(
+ xNode->getTarget(), uno::UNO_QUERY_THROW );
+ CPPUNIT_ASSERT_MESSAGE( "inner node not referencing svg shape",
+ xTargetShape != xSvgShape );
+
+ xDocShRef->DoClose();
+}
+
+// Unit test for importing charts
+void SdImportTest::testFdo71075()
+{
+ double values[] = { 12.0, 13.0, 14.0 };
+ css::uno::Any aAny;
+ sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc("/sd/qa/unit/data/fdo71075.odp"), ODP);
+
+ uno::Reference< beans::XPropertySet > xPropSet( getShapeFromPage( 0, 0, xDocShRef ) );
+ aAny = xPropSet->getPropertyValue( "Model" );
+ CPPUNIT_ASSERT_MESSAGE( "The shape doesn't have the property", aAny.hasValue() );
+
+ uno::Reference< chart::XChartDocument > xChartDoc;
+ aAny >>= xChartDoc;
+ CPPUNIT_ASSERT_MESSAGE( "failed to load chart", xChartDoc.is() );
+ uno::Reference< chart2::XChartDocument > xChart2Doc( xChartDoc, uno::UNO_QUERY );
+ CPPUNIT_ASSERT_MESSAGE( "failed to load chart", xChart2Doc.is() );
+
+ uno::Reference< chart2::XCoordinateSystemContainer > xBCooSysCnt( xChart2Doc->getFirstDiagram(), uno::UNO_QUERY );
+ uno::Sequence< uno::Reference< chart2::XCoordinateSystem > > aCooSysSeq( xBCooSysCnt->getCoordinateSystems());
+ uno::Reference< chart2::XChartTypeContainer > xCTCnt( aCooSysSeq[0], uno::UNO_QUERY );
+
+ uno::Reference< chart2::XDataSeriesContainer > xDSCnt( xCTCnt->getChartTypes()[0], uno::UNO_QUERY );
+ CPPUNIT_ASSERT_MESSAGE( "failed to load data series", xDSCnt.is() );
+ uno::Sequence< uno::Reference< chart2::XDataSeries > > aSeriesSeq( xDSCnt->getDataSeries());
+ CPPUNIT_ASSERT_EQUAL_MESSAGE( "Invalid Series count", static_cast<sal_Int32>(1), aSeriesSeq.getLength() );
+ uno::Reference< chart2::data::XDataSource > xSource( aSeriesSeq[0], uno::UNO_QUERY );
+ uno::Sequence< uno::Reference< chart2::data::XLabeledDataSequence > > aSeqCnt(xSource->getDataSequences());
+ CPPUNIT_ASSERT_EQUAL_MESSAGE( "Invalid Series count", static_cast<sal_Int32>(1), aSeqCnt.getLength());
+ uno::Reference< chart2::data::XDataSequence > xValueSeq( aSeqCnt[0]->getValues() );
+ CPPUNIT_ASSERT_EQUAL_MESSAGE( "Invalid Data count", static_cast<sal_Int32>(SAL_N_ELEMENTS(values)), xValueSeq->getData().getLength());
+ uno::Reference< chart2::data::XNumericalDataSequence > xNumSeq( xValueSeq, uno::UNO_QUERY );
+ uno::Sequence< double > aValues( xNumSeq->getNumericalData());
+ for(sal_Int32 i=0;i<xValueSeq->getData().getLength();i++)
+ CPPUNIT_ASSERT_EQUAL_MESSAGE( "Invalid Series count", values[i], aValues.getConstArray()[i]);
+
+ xDocShRef->DoClose();
+}
+
+void SdImportTest::testStrictOOXML()
+{
+ sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc("/sd/qa/unit/data/strict_ooxml.pptx"), PPTX);
+
+ SdDrawDocument *pDoc = xDocShRef->GetDoc();
+ CPPUNIT_ASSERT_MESSAGE( "no document", pDoc != nullptr );
+ getShapeFromPage( 0, 0, xDocShRef );
+
+ xDocShRef->DoClose();
+}
+
+void SdImportTest::testBnc870237()
+{
+ sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc("/sd/qa/unit/data/pptx/bnc870237.pptx"), PPTX);
+ const SdrPage *pPage = GetPage( 1, xDocShRef );
+
+ // Simulate a:ext inside dsp:txXfrm with changing the lower distance
+ const SdrObjGroup* pGroupObj = dynamic_cast<SdrObjGroup*>( pPage->GetObj( 0 ) );
+ const SdrObject* pObj = pGroupObj->GetSubList()->GetObj( 1 );
+ CPPUNIT_ASSERT_MESSAGE( "no object", pObj != nullptr);
+ CPPUNIT_ASSERT_EQUAL( sal_Int32(0), pObj->GetMergedItem(SDRATTR_TEXT_UPPERDIST).GetValue());
+ CPPUNIT_ASSERT_EQUAL( sal_Int32(9919), pObj->GetMergedItem(SDRATTR_TEXT_LOWERDIST).GetValue());
+ CPPUNIT_ASSERT_EQUAL( sal_Int32(0), pObj->GetMergedItem(SDRATTR_TEXT_RIGHTDIST).GetValue());
+ CPPUNIT_ASSERT_EQUAL( sal_Int32(0), pObj->GetMergedItem(SDRATTR_TEXT_LEFTDIST).GetValue());
+
+ xDocShRef->DoClose();
+}
+
+void SdImportTest::testCreationDate()
+{
+ sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc("/sd/qa/unit/data/fdo71434.pptx"), PPTX);
+ uno::Reference<document::XDocumentPropertiesSupplier> xDocumentPropertiesSupplier(xDocShRef->GetModel(), uno::UNO_QUERY);
+ uno::Reference<document::XDocumentProperties> xDocumentProperties = xDocumentPropertiesSupplier->getDocumentProperties();
+ util::DateTime aDate = xDocumentProperties->getCreationDate();
+ OUStringBuffer aBuffer;
+ sax::Converter::convertDateTime(aBuffer, aDate, nullptr);
+ // Metadata wasn't imported, this was 0000-00-00.
+ CPPUNIT_ASSERT_EQUAL(OUString("2013-11-09T10:37:56"), aBuffer.makeStringAndClear());
+ xDocShRef->DoClose();
+}
+
+void SdImportTest::testMultiColTexts()
+{
+ sd::DrawDocShellRef xDocShRef = loadURL( m_directories.getURLFromSrc("/sd/qa/unit/data/pptx/multicol.pptx"), PPTX );
+ const SdrPage *pPage = GetPage( 1, xDocShRef );
+
+ sdr::table::SdrTableObj *pTableObj = dynamic_cast<sdr::table::SdrTableObj*>(pPage->GetObj(0));
+ CPPUNIT_ASSERT( pTableObj );
+
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(1), pTableObj->getRowCount());
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(2), pTableObj->getColumnCount());
+
+ sdr::table::SdrTableObj *pMasterTableObj = dynamic_cast<sdr::table::SdrTableObj*>(pPage->TRG_GetMasterPage().GetObj(0));
+ CPPUNIT_ASSERT( pMasterTableObj );
+
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(1), pMasterTableObj->getRowCount());
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(2), pMasterTableObj->getColumnCount());
+
+ uno::Reference< table::XCellRange > xTable(pMasterTableObj->getTable(), uno::UNO_QUERY_THROW);
+ uno::Reference< beans::XPropertySet > xCell;
+ xCell.set(xTable->getCellByPosition(0, 0), uno::UNO_QUERY_THROW);
+ uno::Reference<text::XTextRange> xParagraph(getParagraphFromShape(0, xCell));
+ uno::Reference<text::XTextRange> xRun( getRunFromParagraph (0, xParagraph ) );
+ OUString sText = xRun->getString();
+
+ CPPUNIT_ASSERT_EQUAL(OUString(""), sText); //We don't import master table text for multicolumn case.
+}
+
+void SdImportTest::testPredefinedTableStyle()
+{
+ // 073A0DAA-6AF3-43AB-8588-CEC1D06C72B9 (Medium Style 2)
+ sd::DrawDocShellRef xDocShRef = loadURL( m_directories.getURLFromSrc("/sd/qa/unit/data/pptx/predefined-table-style.pptx"), PPTX );
+ const SdrPage *pPage = GetPage( 1, xDocShRef );
+
+ sdr::table::SdrTableObj *pTableObj = dynamic_cast<sdr::table::SdrTableObj*>(pPage->GetObj(0));
+ CPPUNIT_ASSERT( pTableObj );
+
+ uno::Reference< table::XCellRange > xTable(pTableObj->getTable(), uno::UNO_QUERY_THROW);
+ uno::Reference< beans::XPropertySet > xCell;
+ sal_Int32 nColor;
+
+ xCell.set(xTable->getCellByPosition(0, 0), uno::UNO_QUERY_THROW);
+ xCell->getPropertyValue("FillColor") >>= nColor;
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(0), nColor);
+
+ xCell.set(xTable->getCellByPosition(0, 1), uno::UNO_QUERY_THROW);
+ xCell->getPropertyValue("FillColor") >>= nColor;
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(13421772), nColor);
+
+ xCell.set(xTable->getCellByPosition(0, 2), uno::UNO_QUERY_THROW);
+ xCell->getPropertyValue("FillColor") >>= nColor;
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(15198183), nColor);
+
+ xDocShRef->DoClose();
+}
+
+void SdImportTest::testBnc887225()
+{
+ sd::DrawDocShellRef xDocShRef = loadURL( m_directories.getURLFromSrc("/sd/qa/unit/data/pptx/bnc887225.pptx"), PPTX );
+ // In the document, lastRow and lastCol table properties are used.
+ // Make sure styles are set properly for individual cells.
+
+ const SdrPage *pPage = GetPage( 1, xDocShRef );
+
+ sdr::table::SdrTableObj *pTableObj = dynamic_cast<sdr::table::SdrTableObj*>(pPage->GetObj(2));
+ CPPUNIT_ASSERT( pTableObj );
+ uno::Reference< table::XCellRange > xTable(pTableObj->getTable(), uno::UNO_QUERY_THROW);
+ uno::Reference< beans::XPropertySet > xCell;
+ sal_Int32 nColor;
+
+ xCell.set(xTable->getCellByPosition(0, 0), uno::UNO_QUERY_THROW);
+ xCell->getPropertyValue("FillColor") >>= nColor;
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(6003669), nColor);
+
+ xCell.set(xTable->getCellByPosition(0, 1), uno::UNO_QUERY_THROW);
+ xCell->getPropertyValue("FillColor") >>= nColor;
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(6003669), nColor);
+
+ xCell.set(xTable->getCellByPosition(1, 1), uno::UNO_QUERY_THROW);
+ xCell->getPropertyValue("FillColor") >>= nColor;
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(13754095), nColor);
+
+ xCell.set(xTable->getCellByPosition(1, 2), uno::UNO_QUERY_THROW);
+ xCell->getPropertyValue("FillColor") >>= nColor;
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(15331319), nColor);
+
+ xCell.set(xTable->getCellByPosition(1, 4), uno::UNO_QUERY_THROW);
+ xCell->getPropertyValue("FillColor") >>= nColor;
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(6003669), nColor);
+
+ xCell.set(xTable->getCellByPosition(3, 2), uno::UNO_QUERY_THROW);
+ xCell->getPropertyValue("FillColor") >>= nColor;
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(6003669), nColor);
+
+ xCell.set(xTable->getCellByPosition(3, 4), uno::UNO_QUERY_THROW);
+ xCell->getPropertyValue("FillColor") >>= nColor;
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(6003669), nColor);
+
+ xDocShRef->DoClose();
+}
+
+void SdImportTest::testBnc584721_1()
+{
+ // Title text shape on the master page contained wrong text.
+
+ sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc("/sd/qa/unit/data/pptx/bnc584721_1_2.pptx"), PPTX);
+
+ const SdrPage *pPage = &(GetPage( 1, xDocShRef )->TRG_GetMasterPage());
+ SdrObject *pObj = pPage->GetObj(0);
+ SdrTextObj *pTxtObj = dynamic_cast<SdrTextObj *>( pObj );
+ CPPUNIT_ASSERT_MESSAGE( "no text object", pTxtObj != nullptr);
+ const EditTextObject& aEdit = pTxtObj->GetOutlinerParaObject()->GetTextObject();
+ CPPUNIT_ASSERT_EQUAL(OUString("Click to edit Master title style"), aEdit.GetText(0));
+ xDocShRef->DoClose();
+}
+
+void SdImportTest::testBnc584721_2()
+{
+ // Import created an extra/unneeded outliner shape on the master slide next to the imported title shape.
+
+ sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc("/sd/qa/unit/data/pptx/bnc584721_1_2.pptx"), PPTX);
+
+ const SdrPage *pPage = &(GetPage( 1, xDocShRef )->TRG_GetMasterPage());
+ CPPUNIT_ASSERT_EQUAL(size_t(1), pPage->GetObjCount());
+
+ xDocShRef->DoClose();
+}
+
+void SdImportTest::testBnc591147()
+{
+ sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc("/sd/qa/unit/data/pptx/bnc591147.pptx"), PPTX);
+
+ // In the document, there are two slides with media files.
+ uno::Reference< drawing::XDrawPagesSupplier > xDoc(
+ xDocShRef->GetDoc()->getUnoModel(), uno::UNO_QUERY_THROW );
+ CPPUNIT_ASSERT_EQUAL( sal_Int32(2), xDoc->getDrawPages()->getCount() );
+
+ // First page has video file inserted
+ uno::Reference< drawing::XDrawPage > xPage(
+ xDoc->getDrawPages()->getByIndex(0), uno::UNO_QUERY_THROW );
+ CPPUNIT_ASSERT_EQUAL( sal_Int32(1), xPage->getCount() );
+
+ //uno::Reference< drawing::XShape > xShape(xPage->getByIndex(0), uno::UNO_QUERY_THROW );
+ uno::Reference< beans::XPropertySet > xPropSet( getShape( 0, xPage ) );
+ OUString sVideoURL("emptyURL");
+ bool bSuccess = xPropSet->getPropertyValue("MediaURL") >>= sVideoURL;
+ CPPUNIT_ASSERT_MESSAGE( "MediaURL property is not set", bSuccess );
+ CPPUNIT_ASSERT_MESSAGE("MediaURL is empty", !sVideoURL.isEmpty());
+
+ // Second page has audio file inserted
+ xPage.set( xDoc->getDrawPages()->getByIndex(1), uno::UNO_QUERY_THROW );
+ CPPUNIT_ASSERT_EQUAL( sal_Int32(1), xPage->getCount() );
+
+ xPropSet.set( getShape( 0, xPage ) );
+ OUString sAudioURL("emptyURL");
+ bSuccess = xPropSet->getPropertyValue("MediaURL") >>= sAudioURL;
+ CPPUNIT_ASSERT_MESSAGE( "MediaURL property is not set", bSuccess );
+ CPPUNIT_ASSERT_MESSAGE("MediaURL is empty", !sAudioURL.isEmpty());
+
+ CPPUNIT_ASSERT_MESSAGE( "sAudioURL and sVideoURL should not be equal", sAudioURL != sVideoURL );
+
+ xDocShRef->DoClose();
+}
+
+void SdImportTest::testBnc584721_4()
+{
+ // Black text was imported as white because of wrong caching mechanism
+
+ sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc("/sd/qa/unit/data/pptx/bnc584721_4.pptx"), PPTX);
+ uno::Reference< beans::XPropertySet > xShape( getShapeFromPage( 1, 1, xDocShRef ) );
+
+ // Get first paragraph of the text
+ uno::Reference<text::XTextRange> const xParagraph( getParagraphFromShape( 0, xShape ) );
+
+ // Get first run of the paragraph
+ uno::Reference<text::XTextRange> xRun( getRunFromParagraph (0, xParagraph ) );
+ uno::Reference< beans::XPropertySet > xPropSet( xRun, uno::UNO_QUERY_THROW );
+ Color nCharColor;
+ xPropSet->getPropertyValue( "CharColor" ) >>= nCharColor;
+
+ // Color should be black
+ CPPUNIT_ASSERT_EQUAL( COL_BLACK, nCharColor );
+
+ xDocShRef->DoClose();
+}
+
+void SdImportTest::testBnc904423()
+{
+ // Here the problem was that different fill properties were applied in wrong order on the shape
+ // Right order: 1) master slide fill style, 2) theme, 3) direct formatting
+ sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc("sd/qa/unit/data/pptx/bnc904423.pptx"), PPTX);
+
+ const SdrPage *pPage = GetPage( 1, xDocShRef );
+ // First shape's background color is defined on master slide
+ {
+ SdrObject *const pObj = pPage->GetObj(0);
+ CPPUNIT_ASSERT(pObj);
+
+ const XFillStyleItem& rStyleItem = dynamic_cast<const XFillStyleItem&>(
+ pObj->GetMergedItem(XATTR_FILLSTYLE));
+ CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_SOLID, rStyleItem.GetValue());
+ const XFillColorItem& rColorItem = dynamic_cast<const XFillColorItem&>(
+ pObj->GetMergedItem(XATTR_FILLCOLOR));
+ CPPUNIT_ASSERT_EQUAL(sal_uInt32(0x00CC99), sal_uInt32(rColorItem.GetColorValue()));
+ }
+
+ // Second shape's background color is defined by theme
+ {
+ SdrObject *const pObj = pPage->GetObj(1);
+ CPPUNIT_ASSERT(pObj);
+
+ const XFillStyleItem& rStyleItem = dynamic_cast<const XFillStyleItem&>(
+ pObj->GetMergedItem(XATTR_FILLSTYLE));
+ CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_SOLID, rStyleItem.GetValue());
+ const XFillColorItem& rColorItem = dynamic_cast<const XFillColorItem&>(
+ pObj->GetMergedItem(XATTR_FILLCOLOR));
+ CPPUNIT_ASSERT_EQUAL(sal_uInt32(0x3333CC), sal_uInt32(rColorItem.GetColorValue()));
+ }
+
+ // Third shape's background color is defined by direct formatting
+ {
+ SdrObject *const pObj = pPage->GetObj(2);
+ CPPUNIT_ASSERT(pObj);
+
+ const XFillStyleItem& rStyleItem = dynamic_cast<const XFillStyleItem&>(
+ pObj->GetMergedItem(XATTR_FILLSTYLE));
+ CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_SOLID, rStyleItem.GetValue());
+ const XFillColorItem& rColorItem = dynamic_cast<const XFillColorItem&>(
+ pObj->GetMergedItem(XATTR_FILLCOLOR));
+ CPPUNIT_ASSERT_EQUAL(sal_uInt32(0xFF0000), sal_uInt32(rColorItem.GetColorValue()));
+ }
+
+ xDocShRef->DoClose();
+}
+
+void SdImportTest::testShapeLineStyle()
+{
+ // Here the problem was that different line properties were applied in wrong order on the shape
+ // Right order: 1) master slide line style, 2) theme, 3) direct formatting
+ sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc("sd/qa/unit/data/pptx/ShapeLineProperties.pptx"), PPTX);
+
+ const SdrPage *pPage = GetPage( 1, xDocShRef );
+ // First shape's line style is defined on master slide
+ {
+ SdrObject *const pObj = pPage->GetObj(0);
+ CPPUNIT_ASSERT(pObj);
+
+ const XLineStyleItem& rStyleItem = dynamic_cast<const XLineStyleItem&>(
+ pObj->GetMergedItem(XATTR_LINESTYLE));
+ CPPUNIT_ASSERT_EQUAL(drawing::LineStyle_DASH, rStyleItem.GetValue());
+
+ const XLineColorItem& rColorItem = dynamic_cast<const XLineColorItem&>(
+ pObj->GetMergedItem(XATTR_LINECOLOR));
+ CPPUNIT_ASSERT_EQUAL(sal_uInt32(0xFF0000), sal_uInt32(rColorItem.GetColorValue()));
+
+ const XLineWidthItem& rWidthItem = dynamic_cast<const XLineWidthItem&>(
+ pObj->GetMergedItem(XATTR_LINEWIDTH));
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(132), rWidthItem.GetValue());
+ }
+
+ // Second shape's line style is defined by theme
+ {
+ SdrObject *const pObj = pPage->GetObj(1);
+ CPPUNIT_ASSERT(pObj);
+
+ const XLineStyleItem& rStyleItem = dynamic_cast<const XLineStyleItem&>(
+ pObj->GetMergedItem(XATTR_LINESTYLE));
+ CPPUNIT_ASSERT_EQUAL(drawing::LineStyle_SOLID, rStyleItem.GetValue());
+
+ const XLineColorItem& rColorItem = dynamic_cast<const XLineColorItem&>(
+ pObj->GetMergedItem(XATTR_LINECOLOR));
+ CPPUNIT_ASSERT_EQUAL(sal_uInt32(0x3333CC), sal_uInt32(rColorItem.GetColorValue()));
+
+ const XLineWidthItem& rWidthItem = dynamic_cast<const XLineWidthItem&>(
+ pObj->GetMergedItem(XATTR_LINEWIDTH));
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(35), rWidthItem.GetValue());
+ }
+
+ // Third shape's line style is defined by direct formatting
+ {
+ SdrObject *const pObj = pPage->GetObj(2);
+ CPPUNIT_ASSERT(pObj);
+
+ const XLineStyleItem& rStyleItem = dynamic_cast<const XLineStyleItem&>(
+ pObj->GetMergedItem(XATTR_LINESTYLE));
+ CPPUNIT_ASSERT_EQUAL(drawing::LineStyle_SOLID, rStyleItem.GetValue());
+
+ const XLineColorItem& rColorItem = dynamic_cast<const XLineColorItem&>(
+ pObj->GetMergedItem(XATTR_LINECOLOR));
+ CPPUNIT_ASSERT_EQUAL(sal_uInt32(0x7030A0), sal_uInt32(rColorItem.GetColorValue()));
+
+ const XLineWidthItem& rWidthItem = dynamic_cast<const XLineWidthItem&>(
+ pObj->GetMergedItem(XATTR_LINEWIDTH));
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(176), rWidthItem.GetValue());
+ }
+
+ xDocShRef->DoClose();
+}
+
+void SdImportTest::testTableBorderLineStyle()
+{
+ sd::DrawDocShellRef xDocShRef = loadURL( m_directories.getURLFromSrc("/sd/qa/unit/data/pptx/tableBorderLineStyle.pptx"), PPTX );
+
+ // TODO: If you are working on improvement of table border line style
+ // support, then expect this unit test to fail.
+
+ const sal_Int16 nObjBorderLineStyles[] =
+ {
+ ::table::BorderLineStyle::DASHED,
+ ::table::BorderLineStyle::DASH_DOT_DOT,
+ ::table::BorderLineStyle::DASH_DOT,
+ ::table::BorderLineStyle::DOTTED,
+ ::table::BorderLineStyle::DASHED,
+ ::table::BorderLineStyle::DOTTED,
+ ::table::BorderLineStyle::DASHED,
+ ::table::BorderLineStyle::DASH_DOT,
+ ::table::BorderLineStyle::DASH_DOT,
+ ::table::BorderLineStyle::SOLID,
+ ::table::BorderLineStyle::NONE
+ };
+
+ const SdrPage *pPage = GetPage( 1, xDocShRef );
+ CPPUNIT_ASSERT_EQUAL(SAL_N_ELEMENTS(nObjBorderLineStyles), pPage->GetObjCount());
+
+ sdr::table::SdrTableObj *pTableObj;
+ uno::Reference< table::XCellRange > xTable;
+ uno::Reference< beans::XPropertySet > xCell;
+ table::BorderLine2 aBorderLine;
+
+ for (size_t i = 0; i < SAL_N_ELEMENTS(nObjBorderLineStyles); i++)
+ {
+ pTableObj = dynamic_cast<sdr::table::SdrTableObj*>(pPage->GetObj(i));
+ CPPUNIT_ASSERT( pTableObj );
+ xTable.set(pTableObj->getTable(), uno::UNO_QUERY_THROW);
+ xCell.set(xTable->getCellByPosition(0, 0), uno::UNO_QUERY_THROW);
+ xCell->getPropertyValue("TopBorder") >>= aBorderLine;
+ if (aBorderLine.LineWidth > 0) {
+ CPPUNIT_ASSERT_EQUAL(nObjBorderLineStyles[i], aBorderLine.LineStyle);
+ }
+ }
+
+ xDocShRef->DoClose();
+}
+
+void SdImportTest::testBnc862510_6()
+{
+ // Black text was imported instead of gray
+ sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc("/sd/qa/unit/data/pptx/bnc862510_6.pptx"), PPTX);
+ uno::Reference< beans::XPropertySet > xShape( getShapeFromPage( 0, 0, xDocShRef ) );
+
+ // Get first paragraph of the text
+ uno::Reference<text::XTextRange> const xParagraph( getParagraphFromShape( 0, xShape ) );
+
+ // Get first run of the paragraph
+ uno::Reference<text::XTextRange> xRun( getRunFromParagraph( 0, xParagraph ) );
+ uno::Reference< beans::XPropertySet > xPropSet( xRun, uno::UNO_QUERY_THROW );
+ sal_Int32 nCharColor;
+ xPropSet->getPropertyValue( "CharColor" ) >>= nCharColor;
+
+ // Color should be gray
+ CPPUNIT_ASSERT_EQUAL( sal_Int32(0x8B8B8B), nCharColor );
+
+ xDocShRef->DoClose();
+}
+
+void SdImportTest::testBnc862510_7()
+{
+ // Title shape's text was aligned to left instead of center.
+ sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc("/sd/qa/unit/data/pptx/bnc862510_7.pptx"), PPTX);
+ uno::Reference< beans::XPropertySet > xShape( getShapeFromPage( 0, 0, xDocShRef ) );
+
+ // Get first paragraph
+ uno::Reference<text::XTextRange> const xParagraph( getParagraphFromShape( 0, xShape ) );
+ uno::Reference< beans::XPropertySet > xPropSet( xParagraph, uno::UNO_QUERY_THROW );
+
+ sal_Int16 nParaAdjust = 0;
+ xPropSet->getPropertyValue( "ParaAdjust" ) >>= nParaAdjust;
+ CPPUNIT_ASSERT_EQUAL(style::ParagraphAdjust_CENTER, static_cast<style::ParagraphAdjust>(nParaAdjust));
+
+ xDocShRef->DoClose();
+}
+
+#if ENABLE_PDFIMPORT
+// These tests use the old PDF-importing logic, which imports PDF elements as
+// SD elements. This suffered many issues, and therefore wasn't ideal.
+// The old PDF importer relied on an open-source project (xpdf) with an
+// incompatible license (gpl), which has to be interfaced via an out-of-process
+// library wrapper process. The resulting imported document was inaccurate
+// and often very slow and with large memory footprint.
+// Instead, PDFium offers state-of-the-art PDF importing logic,
+// which is well-maintained and renders PDFs into images with high accuracy.
+// So, the idea is to import PDFs as images using PDFium, which has a very
+// high quality (and is much faster) than importing individual editable elements.
+// So that's the "new" way of importing.
+// The user then breaks the image to editable elements (which is not perfect,
+// but very close to the old way), only if they need editing ability.
+// PDFium should overall be better, and where it isn't, we just need to improve it.
+// So these tests aren't really useful anymore. They should be modified to do
+// import+break and then check the results. But that isn't straight-forward and
+// currently await volunteering time to implement.
+
+#if HAVE_FEATURE_PDFIUM
+void SdImportTest::testPDFImportShared()
+{
+ comphelper::LibreOfficeKit::setActive();
+ sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc("/sd/qa/unit/data/pdf/multipage.pdf"), PDF);
+ SdDrawDocument *pDoc = xDocShRef->GetDoc();
+ CPPUNIT_ASSERT_MESSAGE( "no document", pDoc != nullptr );
+
+ // This test is to verify that we share the PDF stream linked to each
+ // Graphic instance in the imported document.
+ // Since we import PDFs as images, we support attaching the original
+ // PDF with each image to allow for advanced editing.
+ // Here we iterate over all Graphic instances embedded in the pages
+ // and verify that they all point to the same object in memory.
+ std::vector<Graphic> aGraphics;
+
+ for (int nPageIndex = 0; nPageIndex < pDoc->GetPageCount(); ++nPageIndex)
+ {
+ const SdrPage* pPage = GetPage(nPageIndex, xDocShRef);
+ if (pPage == nullptr)
+ break;
+
+ for (size_t nObjIndex = 0; nObjIndex < pPage->GetObjCount(); ++nObjIndex)
+ {
+ SdrObject* pObject = pPage->GetObj(nObjIndex);
+ if (pObject == nullptr)
+ continue;
+
+ SdrGrafObj* pSdrGrafObj = dynamic_cast<SdrGrafObj*>(pObject);
+ if (pSdrGrafObj == nullptr)
+ continue;
+
+ const GraphicObject& rGraphicObject = pSdrGrafObj->GetGraphicObject().GetGraphic();
+ const Graphic& rGraphic = rGraphicObject.GetGraphic();
+ CPPUNIT_ASSERT_MESSAGE("After loading, the PDF shouldn't have the primitive sequence created yet",
+ !rGraphic.getVectorGraphicData()->isPrimitiveSequenceCreated());
+ aGraphics.push_back(rGraphic);
+ }
+ }
+
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Expected more than one page.", size_t(9), aGraphics.size());
+
+ Graphic const & rFirstGraphic = aGraphics[0];
+
+ for (size_t i = 0; i < aGraphics.size(); ++i)
+ {
+ Graphic const & rGraphic = aGraphics[i];
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Expected all PDF streams to be identical.",
+ rFirstGraphic.getVectorGraphicData()->getVectorGraphicDataArray().getConstArray(),
+ rGraphic.getVectorGraphicData()->getVectorGraphicDataArray().getConstArray());
+
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Expected all GfxLinks to be identical.",
+ rFirstGraphic.GetSharedGfxLink().get(),
+ rGraphic.GetSharedGfxLink().get());
+
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Page number doesn't match expected", sal_Int32(i), rGraphic.getPageNumber());
+ }
+
+ xDocShRef->DoClose();
+ comphelper::LibreOfficeKit::setActive(false);
+}
+#endif
+
+#if defined(IMPORT_PDF_ELEMENTS)
+
+void SdImportTest::testPDFImport()
+{
+ sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc("/sd/qa/unit/data/pdf/txtpic.pdf"), PDF);
+ SdDrawDocument *pDoc = xDocShRef->GetDoc();
+ CPPUNIT_ASSERT_MESSAGE( "no document", pDoc != nullptr );
+ uno::Reference< drawing::XDrawPagesSupplier > xDoc(xDocShRef->GetDoc()->getUnoModel(), uno::UNO_QUERY_THROW );
+ uno::Reference< drawing::XDrawPage > xPage(xDoc->getDrawPages()->getByIndex(0), uno::UNO_QUERY_THROW );
+ CPPUNIT_ASSERT_EQUAL_MESSAGE( "no exactly two shapes", static_cast<sal_Int32>(2), xPage->getCount() );
+
+ uno::Reference< beans::XPropertySet > xShape( getShape( 0, xPage ) );
+ uno::Reference<text::XText> xText = uno::Reference<text::XTextRange>(xShape, uno::UNO_QUERY_THROW)->getText();
+ CPPUNIT_ASSERT_MESSAGE( "not a text shape", xText.is() );
+
+ xDocShRef->DoClose();
+}
+
+void SdImportTest::testPDFImportSkipImages()
+{
+ auto pParams = std::make_shared<SfxAllItemSet>( SfxGetpApp()->GetPool() );
+ pParams->Put( SfxStringItem ( SID_FILE_FILTEROPTIONS, "SkipImages" ) );
+
+ sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc("/sd/qa/unit/data/pdf/txtpic.pdf"), PDF, pParams);
+ SdDrawDocument *pDoc = xDocShRef->GetDoc();
+ CPPUNIT_ASSERT_MESSAGE( "no document", pDoc != nullptr );
+ uno::Reference< drawing::XDrawPagesSupplier > xDoc(xDocShRef->GetDoc()->getUnoModel(), uno::UNO_QUERY_THROW );
+ uno::Reference< drawing::XDrawPage > xPage(xDoc->getDrawPages()->getByIndex(0), uno::UNO_QUERY_THROW );
+ CPPUNIT_ASSERT_EQUAL_MESSAGE( "no exactly one shape", static_cast<sal_Int32>(1), xPage->getCount() );
+
+ uno::Reference< drawing::XShape > xShape(xPage->getByIndex(0), uno::UNO_QUERY_THROW );
+ uno::Reference<text::XText> xText = uno::Reference<text::XTextRange>(xShape, uno::UNO_QUERY_THROW)->getText();
+ CPPUNIT_ASSERT_MESSAGE( "not a text shape", xText.is() );
+
+ xDocShRef->DoClose();
+}
+
+#endif
+#endif
+
+void SdImportTest::testBulletSuffix()
+{
+ sd::DrawDocShellRef xDocShRef = loadURL( m_directories.getURLFromSrc("/sd/qa/unit/data/pptx/n83889.pptx"), PPTX );
+
+ // check suffix of the char bullet
+ const SdrPage *pPage = GetPage( 1, xDocShRef );
+ SdrTextObj *pTxtObj = dynamic_cast<SdrTextObj *>( pPage->GetObj(0) );
+ CPPUNIT_ASSERT_MESSAGE( "no text object", pTxtObj != nullptr);
+ const EditTextObject& aEdit = pTxtObj->GetOutlinerParaObject()->GetTextObject();
+ const SvxNumBulletItem *pNumFmt = aEdit.GetParaAttribs(1).GetItem(EE_PARA_NUMBULLET);
+ CPPUNIT_ASSERT(pNumFmt);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE( "Bullet's suffix is wrong!", pNumFmt->GetNumRule()->GetLevel(0).GetSuffix(), OUString() );
+ xDocShRef->DoClose();
+}
+
+void SdImportTest::testBnc910045()
+{
+ // Problem with table style which defines cell color with fill style
+ sd::DrawDocShellRef xDocShRef = loadURL( m_directories.getURLFromSrc("/sd/qa/unit/data/pptx/bnc910045.pptx"), PPTX );
+ const SdrPage *pPage = GetPage( 1, xDocShRef );
+
+ sdr::table::SdrTableObj *pTableObj = dynamic_cast<sdr::table::SdrTableObj*>(pPage->GetObj(0));
+ CPPUNIT_ASSERT( pTableObj );
+ uno::Reference< table::XCellRange > xTable(pTableObj->getTable(), uno::UNO_QUERY_THROW);
+ uno::Reference< beans::XPropertySet > xCell;
+ sal_Int32 nColor;
+
+ xCell.set(xTable->getCellByPosition(0, 0), uno::UNO_QUERY_THROW);
+ xCell->getPropertyValue("FillColor") >>= nColor;
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(5210557), nColor);
+
+ xDocShRef->DoClose();
+}
+
+void SdImportTest::testRowHeight()
+{
+ sd::DrawDocShellRef xDocShRef = loadURL( m_directories.getURLFromSrc("/sd/qa/unit/data/pptx/n80340.pptx"), PPTX );
+ const SdrPage *pPage = GetPage( 1, xDocShRef );
+
+ sdr::table::SdrTableObj *pTableObj = dynamic_cast<sdr::table::SdrTableObj*>(pPage->GetObj(0));
+ CPPUNIT_ASSERT( pTableObj );
+
+ sal_Int32 nHeight;
+ const OUString sHeight("Height");
+ uno::Reference< css::table::XTable > xTable(pTableObj->getTable(), uno::UNO_SET_THROW);
+ uno::Reference< css::table::XTableRows > xRows( xTable->getRows(), uno::UNO_SET_THROW);
+ uno::Reference< beans::XPropertySet > xRefRow( xRows->getByIndex(0), uno::UNO_QUERY_THROW );
+ xRefRow->getPropertyValue( sHeight ) >>= nHeight;
+ CPPUNIT_ASSERT_EQUAL( sal_Int32(508), nHeight);
+
+ xDocShRef->DoClose();
+
+ sd::DrawDocShellRef xDocShRef2 = loadURL( m_directories.getURLFromSrc("/sd/qa/unit/data/pptx/tablescale.pptx"), PPTX );
+ const SdrPage *pPage2 = GetPage( 1, xDocShRef2 );
+
+ sdr::table::SdrTableObj *pTableObj2 = dynamic_cast<sdr::table::SdrTableObj*>(pPage2->GetObj(0));
+ CPPUNIT_ASSERT( pTableObj2 );
+
+ uno::Reference< css::table::XTable > xTable2(pTableObj2->getTable(), uno::UNO_SET_THROW);
+ uno::Reference< css::table::XTableRows > xRows2( xTable2->getRows(), uno::UNO_SET_THROW);
+
+ for(sal_Int32 nRow = 0; nRow < 7; ++nRow)
+ {
+ uno::Reference< beans::XPropertySet > xRefRow2( xRows2->getByIndex(nRow), uno::UNO_QUERY_THROW );
+ xRefRow2->getPropertyValue( "Height" ) >>= nHeight;
+ CPPUNIT_ASSERT_EQUAL( sal_Int32(800), nHeight);
+ }
+
+ xDocShRef2->DoClose();
+}
+
+void SdImportTest::testTdf93830()
+{
+ // Text shape offset was ignored
+ sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc("/sd/qa/unit/data/pptx/tdf93830.pptx"), PPTX);
+ uno::Reference< drawing::XDrawPage > xPage( getPage( 0, xDocShRef ) );
+
+ // Get the first text box from group shape
+ uno::Reference< container::XIndexAccess > xShape( xPage->getByIndex(0), uno::UNO_QUERY );
+ uno::Reference< beans::XPropertySet > xPropSet( xShape->getByIndex(3), uno::UNO_QUERY );
+ CPPUNIT_ASSERT_MESSAGE( "no textbox shape", xPropSet.is() );
+
+ sal_Int32 nTextLeftDistance = 0;
+ xPropSet->getPropertyValue( "TextLeftDistance" ) >>= nTextLeftDistance;
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(4152), nTextLeftDistance);
+
+ xDocShRef->DoClose();
+}
+
+void SdImportTest::testTdf127129()
+{
+ sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc("/sd/qa/unit/data/pptx/tdf127129.pptx"), PPTX);
+ uno::Reference< beans::XPropertySet > xShape( getShapeFromPage( 0, 0, xDocShRef ) );
+ uno::Reference< text::XTextRange > xParagraph( getParagraphFromShape( 0, xShape ) );
+ uno::Reference< text::XTextRange > xRun( getRunFromParagraph( 0, xParagraph ) );
+ uno::Reference< beans::XPropertySet > xPropSet( xRun, uno::UNO_QUERY_THROW );
+
+ sal_Int32 nCharColor;
+ xPropSet->getPropertyValue( "CharColor" ) >>= nCharColor;
+ CPPUNIT_ASSERT_EQUAL( sal_Int32(0x000000), nCharColor );
+
+ // Without the accompanying fix in place, the highlight would be -1
+ sal_Int32 nCharBackColor;
+ xPropSet->getPropertyValue( "CharBackColor" ) >>= nCharBackColor;
+ CPPUNIT_ASSERT_EQUAL( sal_Int32(0xFF00), nCharBackColor );
+
+ xDocShRef->DoClose();
+}
+void SdImportTest::testTdf93097()
+{
+ // Throwing metadata import aborted the filter, check that metadata is now imported.
+ sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc("/sd/qa/unit/data/pptx/tdf93097.pptx"), PPTX);
+ uno::Reference<document::XDocumentPropertiesSupplier> xDocumentPropertiesSupplier(xDocShRef->GetModel(), uno::UNO_QUERY);
+ uno::Reference<document::XDocumentProperties> xDocumentProperties = xDocumentPropertiesSupplier->getDocumentProperties();
+ CPPUNIT_ASSERT_EQUAL(OUString("ss"), xDocumentProperties->getTitle());
+ xDocShRef->DoClose();
+}
+
+void SdImportTest::testTdf62255()
+{
+ sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc("/sd/qa/unit/data/pptx/tdf62255.pptx"), PPTX);
+ const SdrPage *pPage = GetPage( 1, xDocShRef );
+
+ sdr::table::SdrTableObj *pTableObj;
+ pTableObj = dynamic_cast<sdr::table::SdrTableObj*>(pPage->GetObj(0));
+ CPPUNIT_ASSERT( pTableObj );
+
+ css::uno::Any aAny;
+ uno::Reference< table::XCellRange > xTable;
+ uno::Reference< beans::XPropertySet > xCell;
+ xTable.set(pTableObj->getTable(), uno::UNO_QUERY_THROW);
+ xCell.set(xTable->getCellByPosition(0, 0), uno::UNO_QUERY_THROW);
+ aAny = xCell->getPropertyValue("FillStyle");
+
+ if (aAny.hasValue())
+ {
+ drawing::FillStyle aFillStyle;
+ aAny >>= aFillStyle;
+ CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_NONE, aFillStyle);
+ }
+
+ xDocShRef->DoClose();
+}
+
+void SdImportTest::testTdf93124()
+{
+ sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc("/sd/qa/unit/data/ppt/tdf93124.ppt"), PPT);
+ uno::Reference < uno::XComponentContext > xContext = ::comphelper::getProcessComponentContext();
+ uno::Reference< drawing::XGraphicExportFilter > xGraphicExporter = drawing::GraphicExportFilter::create(xContext);
+
+ uno::Sequence< beans::PropertyValue > aFilterData(2);
+ aFilterData[0].Name = "PixelWidth";
+ aFilterData[0].Value <<= sal_Int32(320);
+ aFilterData[1].Name = "PixelHeight";
+ aFilterData[1].Value <<= sal_Int32(180);
+
+ utl::TempFile aTempFile;
+ aTempFile.EnableKillingFile();
+
+ uno::Sequence< beans::PropertyValue > aDescriptor(3);
+ aDescriptor[0].Name = "URL";
+ aDescriptor[0].Value <<= aTempFile.GetURL();
+ aDescriptor[1].Name = "FilterName";
+ aDescriptor[1].Value <<= OUString("PNG");
+ aDescriptor[2].Name = "FilterData";
+ aDescriptor[2].Value <<= aFilterData;
+
+ uno::Reference< lang::XComponent > xPage(getPage(0, xDocShRef), uno::UNO_QUERY);
+ xGraphicExporter->setSourceDocument(xPage);
+ xGraphicExporter->filter(aDescriptor);
+
+ SvFileStream aFileStream(aTempFile.GetURL(), StreamMode::READ);
+ vcl::PNGReader aPNGReader(aFileStream);
+ BitmapEx aBMPEx = aPNGReader.Read();
+
+ // make sure the bitmap is not empty and correct size (PNG export->import was successful)
+ CPPUNIT_ASSERT_EQUAL(Size(320, 180), aBMPEx.GetSizePixel());
+ Bitmap aBMP = aBMPEx.GetBitmap();
+ {
+ Bitmap::ScopedReadAccess pReadAccess(aBMP);
+ int nNonWhiteCount = 0;
+ // The word "Top" should be in rectangle 34,4 - 76,30. If text alignment is wrong, the rectangle will be white.
+ for (long nY = 4; nY < (4 + 26); ++nY)
+ {
+ for (long nX = 34; nX < (34 + 43); ++nX)
+ {
+ const Color aColor = pReadAccess->GetColor(nY, nX);
+ if ((aColor.GetRed() != 0xff) || (aColor.GetGreen() != 0xff) || (aColor.GetBlue() != 0xff))
+ ++nNonWhiteCount;
+ }
+ }
+ CPPUNIT_ASSERT_MESSAGE("Tdf93124: vertical alignment of text is incorrect!", nNonWhiteCount>50);
+ }
+ xDocShRef->DoClose();
+}
+
+void SdImportTest::testTdf99729()
+{
+ const OUString filenames[] = { "/sd/qa/unit/data/odp/tdf99729-new.odp", "/sd/qa/unit/data/odp/tdf99729-legacy.odp" };
+ int nonwhitecounts[] = { 0, 0 };
+ for (size_t i = 0; i < SAL_N_ELEMENTS(filenames); ++i)
+ {
+ // 1st check for new behaviour - having AnchoredTextOverflowLegacy compatibility flag set to false in settings.xml
+ uno::Reference<lang::XComponent> xComponent
+ = loadFromDesktop(m_directories.getURLFromSrc(filenames[i]),
+ "com.sun.star.presentation.PresentationDocument");
+
+ uno::Reference<uno::XComponentContext> xContext = getComponentContext();
+ CPPUNIT_ASSERT(xContext.is());
+ uno::Reference< drawing::XGraphicExportFilter > xGraphicExporter = drawing::GraphicExportFilter::create(xContext);
+ CPPUNIT_ASSERT(xGraphicExporter.is());
+
+ uno::Sequence< beans::PropertyValue > aFilterData(2);
+ aFilterData[0].Name = "PixelWidth";
+ aFilterData[0].Value <<= sal_Int32(320);
+ aFilterData[1].Name = "PixelHeight";
+ aFilterData[1].Value <<= sal_Int32(240);
+
+ utl::TempFile aTempFile;
+ aTempFile.EnableKillingFile();
+
+ uno::Sequence< beans::PropertyValue > aDescriptor(3);
+ aDescriptor[0].Name = "URL";
+ aDescriptor[0].Value <<= aTempFile.GetURL();
+ aDescriptor[1].Name = "FilterName";
+ aDescriptor[1].Value <<= OUString("PNG");
+ aDescriptor[2].Name = "FilterData";
+ aDescriptor[2].Value <<= aFilterData;
+
+ uno::Reference<drawing::XDrawPagesSupplier> xDrawPagesSupplier(xComponent, uno::UNO_QUERY);
+ uno::Reference<lang::XComponent> xPage(xDrawPagesSupplier->getDrawPages()->getByIndex(0),
+ uno::UNO_QUERY);
+ CPPUNIT_ASSERT(xPage.is());
+ xGraphicExporter->setSourceDocument(xPage);
+ xGraphicExporter->filter(aDescriptor);
+
+ SvFileStream aFileStream(aTempFile.GetURL(), StreamMode::READ);
+ vcl::PNGReader aPNGReader(aFileStream);
+ BitmapEx aBMPEx = aPNGReader.Read();
+ Bitmap aBMP = aBMPEx.GetBitmap();
+ Bitmap::ScopedReadAccess pRead(aBMP);
+ for (long nX = 154; nX < (154 + 12); ++nX)
+ {
+ for (long nY = 16; nY < (16 + 96); ++nY)
+ {
+ const Color aColor = pRead->GetColor(nY, nX);
+ if ((aColor.GetRed() != 0xff) || (aColor.GetGreen() != 0xff) || (aColor.GetBlue() != 0xff))
+ ++nonwhitecounts[i];
+ }
+ }
+ xComponent->dispose();
+ }
+ // The numbers 1-9 should be above the Text Box in rectangle 154,16 - 170,112.
+ // If text alignment is wrong, the rectangle will be white.
+ CPPUNIT_ASSERT_MESSAGE("Tdf99729: vertical alignment of text is incorrect!", nonwhitecounts[0]>100); // it is 134 with cleartype disabled
+ // The numbers 1-9 should be below the Text Box -> rectangle 154,16 - 170,112 should be white.
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Tdf99729: legacy vertical alignment of text is incorrect!", 0, nonwhitecounts[1]);
+}
+
+void SdImportTest::testTdf89927()
+{
+ sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc("/sd/qa/unit/data/pptx/tdf89927.pptx"), PPTX);
+ uno::Reference< beans::XPropertySet > xShape( getShapeFromPage( 0, 0, xDocShRef ) );
+ uno::Reference< text::XTextRange > xParagraph( getParagraphFromShape( 0, xShape ) );
+ uno::Reference< text::XTextRange > xRun( getRunFromParagraph( 0, xParagraph ) );
+ uno::Reference< beans::XPropertySet > xPropSet( xRun, uno::UNO_QUERY_THROW );
+
+ sal_Int32 nCharColor;
+ xPropSet->getPropertyValue( "CharColor" ) >>= nCharColor;
+ CPPUNIT_ASSERT_EQUAL( sal_Int32(0xFFFFFF), nCharColor );
+
+ xDocShRef->DoClose();
+}
+
+void SdImportTest::testTdf93868()
+{
+ sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc("/sd/qa/unit/data/pptx/tdf93868.pptx"), PPTX);
+
+ const SdrPage *pPage = &(GetPage( 1, xDocShRef )->TRG_GetMasterPage());
+ CPPUNIT_ASSERT_EQUAL(size_t(5), pPage->GetObjCount());
+ CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_SOLID, dynamic_cast<const XFillStyleItem&>(pPage->GetObj(0)->GetMergedItem(XATTR_FILLSTYLE)).GetValue());
+ CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_GRADIENT, dynamic_cast<const XFillStyleItem&>(pPage->GetObj(1)->GetMergedItem(XATTR_FILLSTYLE)).GetValue());
+
+ xDocShRef->DoClose();
+}
+
+void SdImportTest::testTdf95932()
+{
+ sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc("/sd/qa/unit/data/pptx/tdf95932.pptx"), PPTX);
+
+ const SdrPage *pPage = GetPage( 1, xDocShRef );
+ SdrObject *const pObj = pPage->GetObj(2);
+ CPPUNIT_ASSERT(pObj);
+
+ const XFillStyleItem& rStyleItem = dynamic_cast<const XFillStyleItem&>(
+ pObj->GetMergedItem(XATTR_FILLSTYLE));
+ CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_SOLID, rStyleItem.GetValue());
+ const XFillColorItem& rColorItem = dynamic_cast<const XFillColorItem&>(
+ pObj->GetMergedItem(XATTR_FILLCOLOR));
+ CPPUNIT_ASSERT_EQUAL(sal_uInt32(0x76bf3d), sal_uInt32(rColorItem.GetColorValue()));
+
+ xDocShRef->DoClose();
+}
+
+void SdImportTest::testTdf99030()
+{
+ sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc("/sd/qa/unit/data/pptx/tdf99030.pptx"), PPTX);
+
+ uno::Reference< drawing::XMasterPagesSupplier > xDoc(
+ xDocShRef->GetDoc()->getUnoModel(), uno::UNO_QUERY_THROW );
+ uno::Reference< drawing::XDrawPage > xPage(
+ xDoc->getMasterPages()->getByIndex( 0 ), uno::UNO_QUERY_THROW );
+ uno::Reference< beans::XPropertySet > xPropSet( xPage, uno::UNO_QUERY );
+
+ sal_Int32 nFillColor(0);
+ uno::Any aAny = xPropSet->getPropertyValue( "Background" );
+ if (aAny.hasValue())
+ {
+ uno::Reference< beans::XPropertySet > xBackgroundPropSet;
+ aAny >>= xBackgroundPropSet;
+ xBackgroundPropSet->getPropertyValue( "FillColor" ) >>= nFillColor;
+ }
+ CPPUNIT_ASSERT_EQUAL( sal_Int32(0x676A55), nFillColor );
+
+ xDocShRef->DoClose();
+}
+
+void SdImportTest::testTdf49561()
+{
+ sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc("/sd/qa/unit/data/ppt/tdf49561.ppt"), PPT);
+
+ uno::Reference< drawing::XMasterPagesSupplier > xDoc(
+ xDocShRef->GetDoc()->getUnoModel(), uno::UNO_QUERY_THROW );
+ uno::Reference< drawing::XDrawPage > xPage(
+ xDoc->getMasterPages()->getByIndex( 0 ), uno::UNO_QUERY_THROW );
+ CPPUNIT_ASSERT_EQUAL( sal_Int32(5), xPage->getCount() );
+
+ uno::Reference< beans::XPropertySet > xShape( getShape( 3, xPage ) );
+ uno::Reference<text::XTextRange> xParagraph( getParagraphFromShape( 0, xShape ) );
+ uno::Reference<text::XTextRange> xRun( getRunFromParagraph (0, xParagraph ) );
+ uno::Reference< beans::XPropertySet > xPropSet(xRun , uno::UNO_QUERY_THROW );
+
+ float fCharHeight = 0;
+ CPPUNIT_ASSERT(xPropSet->getPropertyValue("CharHeight") >>= fCharHeight);
+ CPPUNIT_ASSERT_EQUAL(12.f, fCharHeight);
+
+ OUString aCharFontName;
+ CPPUNIT_ASSERT(xPropSet->getPropertyValue("CharFontName") >>= aCharFontName);
+ CPPUNIT_ASSERT_EQUAL(OUString("Stencil"), aCharFontName);
+
+ xDocShRef->DoClose();
+}
+
+void SdImportTest::testTdf103473()
+{
+ sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc("/sd/qa/unit/data/pptx/tdf103473.pptx"), PPTX);
+
+ const SdrPage *pPage = GetPage(1, xDocShRef);
+ SdrTextObj *const pObj = dynamic_cast<SdrTextObj *const>(pPage->GetObj(0));
+ CPPUNIT_ASSERT(pObj);
+ ::tools::Rectangle aRect = pObj->GetGeoRect();
+ CPPUNIT_ASSERT_EQUAL(3629L, aRect.Left());
+ CPPUNIT_ASSERT_EQUAL(4431L, aRect.Top());
+ CPPUNIT_ASSERT_EQUAL(8353L, aRect.Right());
+ CPPUNIT_ASSERT_EQUAL(9155L, aRect.Bottom());
+
+ xDocShRef->DoClose();
+}
+
+void SdImportTest::testAoo124143()
+{
+ sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc("/sd/qa/unit/data/odg/ooo124143-1.odg"), ODG);
+
+ uno::Reference<beans::XPropertySet> const xImage(getShapeFromPage(0, 0, xDocShRef));
+ uno::Reference<drawing::XGluePointsSupplier> const xGPS(xImage, uno::UNO_QUERY);
+ uno::Reference<container::XIdentifierAccess> const xGluePoints(xGPS->getGluePoints(), uno::UNO_QUERY);
+
+ uno::Sequence<sal_Int32> const ids(xGluePoints->getIdentifiers());
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(6), ids.getLength());
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(0), ids[0]);
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(1), ids[1]);
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(2), ids[2]);
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(3), ids[3]);
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(4), ids[4]);
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(5), ids[5]);
+
+ // interesting ones are custom 4, 5
+ drawing::GluePoint2 glue4;
+ xGluePoints->getByIdentifier(4) >>= glue4;
+ CPPUNIT_ASSERT_EQUAL(sal_Int32( 2470), glue4.Position.X);
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(-1810), glue4.Position.Y);
+
+ drawing::GluePoint2 glue5;
+ xGluePoints->getByIdentifier(5) >>= glue5;
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(-2975), glue5.Position.X);
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(-2165), glue5.Position.Y);
+
+ // now check connectors
+ uno::Reference<beans::XPropertySet> const xEllipse(getShapeFromPage(1, 0, xDocShRef));
+ uno::Reference<beans::XPropertySet> const xConn1(getShapeFromPage(2, 0, xDocShRef));
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xConn1->getPropertyValue("StartGluePointIndex").get<sal_Int32>());
+ CPPUNIT_ASSERT_EQUAL(xEllipse, xConn1->getPropertyValue("StartShape").get<uno::Reference<beans::XPropertySet>>());
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(4), xConn1->getPropertyValue("EndGluePointIndex").get<sal_Int32>());
+ CPPUNIT_ASSERT_EQUAL(xImage, xConn1->getPropertyValue("EndShape").get<uno::Reference<beans::XPropertySet>>());
+ uno::Reference<beans::XPropertySet> const xConn2(getShapeFromPage(3, 0, xDocShRef));
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(3), xConn2->getPropertyValue("StartGluePointIndex").get<sal_Int32>());
+ CPPUNIT_ASSERT_EQUAL(xEllipse, xConn2->getPropertyValue("StartShape").get<uno::Reference<beans::XPropertySet>>());
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(5), xConn2->getPropertyValue("EndGluePointIndex").get<sal_Int32>());
+ CPPUNIT_ASSERT_EQUAL(xImage, xConn2->getPropertyValue("EndShape").get<uno::Reference<beans::XPropertySet>>());
+
+ xDocShRef->DoClose();
+}
+
+void SdImportTest::testTdf103567()
+{
+ sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc("/sd/qa/unit/data/odp/tdf103567.odp"), ODP);
+ for (int i = 0; i < 4; ++i)
+ {
+ uno::Reference<beans::XPropertySet> const xShape(getShapeFromPage(i, 0, xDocShRef));
+ uno::Reference<document::XEventsSupplier> const xEventsSupplier(xShape, uno::UNO_QUERY);
+ uno::Reference<container::XNameAccess> const xEvents(xEventsSupplier->getEvents());
+ OString const msg("shape " + OString::number(i) + ": ");
+
+ CPPUNIT_ASSERT(xEvents->hasByName("OnClick"));
+ uno::Sequence<beans::PropertyValue> props;
+ xEvents->getByName("OnClick") >>= props;
+ comphelper::SequenceAsHashMap const map(props);
+ {
+ auto iter(map.find("EventType"));
+ CPPUNIT_ASSERT_MESSAGE(OString(msg + "no EventType").getStr(), iter != map.end());
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(msg.getStr(), OUString("Presentation"), iter->second.get<OUString>());
+ }
+ {
+ auto iter(map.find("ClickAction"));
+ CPPUNIT_ASSERT_MESSAGE(OString(msg + "no ClickAction").getStr(), iter != map.end());
+ if (i % 2 == 0)
+ {
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(msg.getStr(), css::presentation::ClickAction_DOCUMENT, iter->second.get<css::presentation::ClickAction>());
+ }
+ else
+ {
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(msg.getStr(), css::presentation::ClickAction_NEXTPAGE, iter->second.get<css::presentation::ClickAction>());
+ }
+ }
+ if (i % 2 == 0)
+ {
+ auto iter(map.find("Bookmark"));
+ CPPUNIT_ASSERT_MESSAGE(OString(msg + "no Bookmark").getStr(), iter != map.end());
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(msg.getStr(), OUString("http://example.com/"), iter->second.get<OUString>());
+ }
+ }
+
+ xDocShRef->DoClose();
+}
+
+void SdImportTest::testTdf103792()
+{
+ // Title text shape on the actual slide contained no text neither a placeholder text.
+ sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc("/sd/qa/unit/data/pptx/tdf103792.pptx"), PPTX);
+
+ const SdrPage *pPage = GetPage(1, xDocShRef);
+ CPPUNIT_ASSERT_MESSAGE("No page found", pPage != nullptr);
+ SdrObject *pObj = pPage->GetObj(0);
+ CPPUNIT_ASSERT_MESSAGE("Wrong object", pObj != nullptr);
+ SdrTextObj *pTxtObj = dynamic_cast<SdrTextObj *>(pObj);
+ CPPUNIT_ASSERT_MESSAGE("Not a text object", pTxtObj != nullptr);
+
+ const EditTextObject& aEdit = pTxtObj->GetOutlinerParaObject()->GetTextObject();
+ CPPUNIT_ASSERT_EQUAL(OUString("Click to add Title"), aEdit.GetText(0));
+
+ xDocShRef->DoClose();
+}
+
+void SdImportTest::testTdf103876()
+{
+ // Title text shape's placeholder text did not inherit the corresponding text properties
+ sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc("/sd/qa/unit/data/pptx/tdf103876.pptx"), PPTX);
+ uno::Reference< beans::XPropertySet > xShape( getShapeFromPage( 0, 0, xDocShRef ) );
+
+ // Check paragraph alignment
+ sal_Int16 nParaAdjust = 0;
+ xShape->getPropertyValue( "ParaAdjust" ) >>= nParaAdjust;
+ CPPUNIT_ASSERT_EQUAL(style::ParagraphAdjust_CENTER, static_cast<style::ParagraphAdjust>(nParaAdjust));
+
+ // Check character color
+ sal_Int32 nCharColor;
+ xShape->getPropertyValue( "CharColor" ) >>= nCharColor;
+ CPPUNIT_ASSERT_EQUAL( sal_Int32(0xFF0000), nCharColor );
+
+ xDocShRef->DoClose();
+}
+
+void SdImportTest::testTdf79007()
+{
+ sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc("sd/qa/unit/data/pptx/tdf79007.pptx"), PPTX);
+
+ uno::Reference<beans::XPropertySet> xShape1(getShapeFromPage(0, 0, xDocShRef));
+ CPPUNIT_ASSERT_MESSAGE("Not a shape", xShape1.is());
+
+ // Check we map mso washout to our watermark
+ drawing::ColorMode aColorMode1;
+ xShape1->getPropertyValue("GraphicColorMode") >>= aColorMode1;
+ CPPUNIT_ASSERT_EQUAL(drawing::ColorMode_WATERMARK, aColorMode1);
+
+ sal_Int16 nContrast1;
+ xShape1->getPropertyValue("AdjustContrast") >>= nContrast1;
+ CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int16>(0), nContrast1);
+
+ sal_Int16 nLuminance1;
+ xShape1->getPropertyValue("AdjustLuminance") >>= nLuminance1;
+ CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int16>(0), nLuminance1);
+
+ uno::Reference<beans::XPropertySet> xShape2(getShapeFromPage(1, 0, xDocShRef));
+ CPPUNIT_ASSERT_MESSAGE("Not a shape", xShape2.is());
+
+ // Check we map mso grayscale to our grayscale
+ drawing::ColorMode aColorMode2;
+ xShape2->getPropertyValue("GraphicColorMode") >>= aColorMode2;
+ CPPUNIT_ASSERT_EQUAL(drawing::ColorMode_GREYS, aColorMode2);
+
+ sal_Int16 nContrast2;
+ xShape2->getPropertyValue("AdjustContrast") >>= nContrast2;
+ CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int16>(0), nContrast2);
+
+ sal_Int16 nLuminance2;
+ xShape2->getPropertyValue("AdjustLuminance") >>= nLuminance2;
+ CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int16>(0), nLuminance2);
+
+ uno::Reference<beans::XPropertySet> xShape3(getShapeFromPage(2, 0, xDocShRef));
+ CPPUNIT_ASSERT_MESSAGE("Not a shape", xShape3.is());
+
+ // Check we map mso black/white to our black/white
+ drawing::ColorMode aColorMode3;
+ xShape3->getPropertyValue("GraphicColorMode") >>= aColorMode3;
+ CPPUNIT_ASSERT_EQUAL(drawing::ColorMode_MONO, aColorMode3);
+
+ sal_Int16 nContrast3;
+ xShape3->getPropertyValue("AdjustContrast") >>= nContrast3;
+ CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int16>(0), nContrast3);
+
+ sal_Int16 nLuminance3;
+ xShape3->getPropertyValue("AdjustLuminance") >>= nLuminance3;
+ CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int16>(0), nLuminance3);
+
+ xDocShRef->DoClose();
+}
+
+void SdImportTest::testTdf129686()
+{
+ sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc("sd/qa/unit/data/pptx/tdf129686.pptx"), PPTX);
+ uno::Reference< beans::XPropertySet > xShape( getShapeFromPage( 0, 0, xDocShRef ) );
+
+ // Get first paragraph of the text
+ uno::Reference<text::XTextRange> const xParagraph( getParagraphFromShape( 0, xShape ) );
+
+ // Get first run of the paragraph
+ uno::Reference<text::XTextRange> xRun( getRunFromParagraph (0, xParagraph ) );
+ uno::Reference< beans::XPropertySet > xPropSet( xRun, uno::UNO_QUERY_THROW );
+ sal_Int16 nTransparency = 0;
+ xPropSet->getPropertyValue("CharTransparence") >>= nTransparency;
+
+ // 100 = no transparency
+ CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int16>(100), nTransparency);
+
+ xDocShRef->DoClose();
+}
+
+void SdImportTest::testTdf104015()
+{
+ // Shape fill, line and effect properties were not inherited from master slide shape
+ sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc("sd/qa/unit/data/pptx/tdf104015.pptx"), PPTX);
+
+ const SdrPage *pPage = GetPage( 1, xDocShRef );
+ CPPUNIT_ASSERT_MESSAGE("No page found", pPage != nullptr);
+ SdrObject *const pObj = pPage->GetObj(0);
+ CPPUNIT_ASSERT_MESSAGE("Wrong object", pObj != nullptr);
+ // Should have a red fill color
+ {
+ const XFillStyleItem& rStyleItem = dynamic_cast<const XFillStyleItem&>(
+ pObj->GetMergedItem(XATTR_FILLSTYLE));
+ CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_SOLID, rStyleItem.GetValue());
+ const XFillColorItem& rColorItem = dynamic_cast<const XFillColorItem&>(
+ pObj->GetMergedItem(XATTR_FILLCOLOR));
+ CPPUNIT_ASSERT_EQUAL(sal_uInt32(0xFF0000), sal_uInt32(rColorItem.GetColorValue()));
+ }
+ // Should have a blue line
+ {
+ const XLineStyleItem& rStyleItem = dynamic_cast<const XLineStyleItem&>(
+ pObj->GetMergedItem(XATTR_LINESTYLE));
+ CPPUNIT_ASSERT_EQUAL(drawing::LineStyle_SOLID, rStyleItem.GetValue());
+
+ const XLineColorItem& rColorItem = dynamic_cast<const XLineColorItem&>(
+ pObj->GetMergedItem(XATTR_LINECOLOR));
+ CPPUNIT_ASSERT_EQUAL(sal_uInt32(0x0000FF), sal_uInt32(rColorItem.GetColorValue()));
+ }
+ // Should have some shadow
+ {
+ const SdrOnOffItem& rShadowItem = dynamic_cast<const SdrOnOffItem&>(
+ pObj->GetMergedItem(SDRATTR_SHADOW));
+ CPPUNIT_ASSERT(rShadowItem.GetValue());
+ }
+
+ xDocShRef->DoClose();
+}
+
+void SdImportTest::testTdf104201()
+{
+ // Group shape properties did not overwrite the child shapes' fill
+ sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc("sd/qa/unit/data/pptx/tdf104201.pptx"), PPTX);
+
+ const SdrPage *pPage = GetPage(1, xDocShRef);
+ CPPUNIT_ASSERT_MESSAGE("No page found", pPage != nullptr);
+
+ // First shape has red fill, but this should be overwritten by green group fill
+ {
+ SdrObject *const pObj = pPage->GetObj(0);
+ CPPUNIT_ASSERT_MESSAGE("Wrong object", pObj != nullptr);
+ const XFillStyleItem& rStyleItem = dynamic_cast<const XFillStyleItem&>(
+ pObj->GetMergedItem(XATTR_FILLSTYLE));
+ CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_SOLID, rStyleItem.GetValue());
+ const XFillColorItem& rColorItem = dynamic_cast<const XFillColorItem&>(
+ pObj->GetMergedItem(XATTR_FILLCOLOR));
+ CPPUNIT_ASSERT_EQUAL(sal_uInt32(0x00FF00), sal_uInt32(rColorItem.GetColorValue()));
+ }
+ // Second shape has blue fill, but this should be overwritten by green group fill
+ {
+ SdrObject *const pObj = pPage->GetObj(0);
+ CPPUNIT_ASSERT_MESSAGE("Wrong object", pObj != nullptr);
+ const XFillStyleItem& rStyleItem = dynamic_cast<const XFillStyleItem&>(
+ pObj->GetMergedItem(XATTR_FILLSTYLE));
+ CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_SOLID, rStyleItem.GetValue());
+ const XFillColorItem& rColorItem = dynamic_cast<const XFillColorItem&>(
+ pObj->GetMergedItem(XATTR_FILLCOLOR));
+ CPPUNIT_ASSERT_EQUAL(sal_uInt32(0x00FF00), sal_uInt32(rColorItem.GetColorValue()));
+ }
+
+ xDocShRef->DoClose();
+}
+
+void SdImportTest::testTdf103477()
+{
+ sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc("/sd/qa/unit/data/pptx/tdf103477.pptx"), PPTX);
+
+ const SdrPage *pPage = GetPage( 1, xDocShRef );
+
+ SdrTextObj *pTxtObj = dynamic_cast<SdrTextObj *>( pPage->GetObj(6) );
+ CPPUNIT_ASSERT_MESSAGE( "no text object", pTxtObj != nullptr );
+
+ const EditTextObject& aEdit = pTxtObj->GetOutlinerParaObject()->GetTextObject();
+ const SvxNumBulletItem *pNumFmt = aEdit.GetParaAttribs(0).GetItem(EE_PARA_NUMBULLET);
+ CPPUNIT_ASSERT(pNumFmt);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE( "Bullet's color is wrong!", Color(0x000000), pNumFmt->GetNumRule()->GetLevel(1).GetBulletColor());
+
+ xDocShRef->DoClose();
+}
+
+void SdImportTest::testTdf105150()
+{
+ sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc("sd/qa/unit/data/pptx/tdf105150.pptx"), PPTX);
+ const SdrPage* pPage = GetPage(1, xDocShRef);
+ const SdrObject* pObj = pPage->GetObj(1);
+ auto& rFillStyleItem = dynamic_cast<const XFillStyleItem&>(pObj->GetMergedItem(XATTR_FILLSTYLE));
+ // This was drawing::FillStyle_NONE, <p:sp useBgFill="1"> was ignored when
+ // the slide didn't have an explicit background fill.
+ CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_SOLID, rFillStyleItem.GetValue());
+ xDocShRef->DoClose();
+}
+
+void SdImportTest::testTdf123684()
+{
+ sd::DrawDocShellRef xDocShRef
+ = loadURL(m_directories.getURLFromSrc("sd/qa/unit/data/pptx/tdf123684.pptx"), PPTX);
+ const SdrPage* pPage = GetPage(1, xDocShRef);
+ const SdrObject* pObj = pPage->GetObj(0);
+ auto& rFillStyleItem
+ = dynamic_cast<const XFillStyleItem&>(pObj->GetMergedItem(XATTR_FILLSTYLE));
+ // Without the accompanying fix in place, this test would have failed with 'Expected: 0; Actual:
+ // 1', i.e. the shape's fill was FillStyle_SOLID, making the text of the shape unreadable.
+ CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_NONE, rFillStyleItem.GetValue());
+ xDocShRef->DoClose();
+}
+
+void SdImportTest::testTdf105150PPT()
+{
+ sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc("sd/qa/unit/data/ppt/tdf105150.ppt"), PPT);
+ const SdrPage* pPage = GetPage(1, xDocShRef);
+ const SdrObject* pObj = pPage->GetObj(1);
+ // This was drawing::FillStyle_NONE, the shape's mso_fillBackground was
+ // ignored when the slide didn't have an explicit background fill.
+ auto& rFillStyleItem = dynamic_cast<const XFillStyleItem&>(pObj->GetMergedItem(XATTR_FILLSTYLE));
+ CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_SOLID, rFillStyleItem.GetValue());
+ xDocShRef->DoClose();
+}
+
+void SdImportTest::testTdf104445()
+{
+ // Extra bullets were added to the first shape
+ sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc("sd/qa/unit/data/pptx/tdf104445.pptx"), PPTX);
+
+ // First shape should not have bullet
+ {
+ uno::Reference< beans::XPropertySet > xShape(getShapeFromPage(0, 0, xDocShRef));
+ uno::Reference< text::XText > xText = uno::Reference< text::XTextRange>(xShape, uno::UNO_QUERY_THROW)->getText();
+ CPPUNIT_ASSERT_MESSAGE("Not a text shape", xText.is());
+ uno::Reference< beans::XPropertySet > xPropSet(xText, uno::UNO_QUERY_THROW);
+
+ uno::Reference< container::XIndexAccess > xNumRule;
+ xPropSet->getPropertyValue("NumberingRules") >>= xNumRule;
+ uno::Sequence<beans::PropertyValue> aBulletProps;
+ xNumRule->getByIndex(0) >>= aBulletProps;
+
+ for (beans::PropertyValue const & rProp : std::as_const(aBulletProps))
+ {
+ if(rProp.Name == "NumberingType")
+ CPPUNIT_ASSERT_EQUAL(sal_Int16(style::NumberingType::NUMBER_NONE), rProp.Value.get<sal_Int16>());
+ if(rProp.Name == "LeftMargin")
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(0), rProp.Value.get<sal_Int32>());
+ }
+ }
+ // Second shape should have bullet set
+ {
+ uno::Reference< beans::XPropertySet > xShape(getShapeFromPage(1, 0, xDocShRef));
+ uno::Reference< text::XText > xText = uno::Reference< text::XTextRange>(xShape, uno::UNO_QUERY_THROW)->getText();
+ CPPUNIT_ASSERT_MESSAGE("Not a text shape", xText.is());
+ uno::Reference< beans::XPropertySet > xPropSet(xText, uno::UNO_QUERY_THROW);
+
+ uno::Reference< container::XIndexAccess > xNumRule;
+ xPropSet->getPropertyValue("NumberingRules") >>= xNumRule;
+ uno::Sequence<beans::PropertyValue> aBulletProps;
+ xNumRule->getByIndex(0) >>= aBulletProps;
+
+ for(beans::PropertyValue const & rProp : std::as_const(aBulletProps))
+ {
+ if(rProp.Name == "NumberingType")
+ CPPUNIT_ASSERT_EQUAL(sal_Int16(style::NumberingType::CHAR_SPECIAL), rProp.Value.get<sal_Int16>());
+ if(rProp.Name == "LeftMargin")
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(635), rProp.Value.get<sal_Int32>());
+ }
+ }
+ xDocShRef->DoClose();
+}
+
+namespace
+{
+
+bool checkPatternValues(std::vector<sal_uInt8>& rExpected, Bitmap& rBitmap)
+{
+ bool bResult = true;
+
+ const Color aFGColor(0xFF0000);
+ const Color aBGColor(0xFFFFFF);
+
+ Bitmap::ScopedReadAccess pAccess(rBitmap);
+ for (long y = 0; y < pAccess->Height(); ++y)
+ {
+ Scanline pScanline = pAccess->GetScanline( y );
+ for (long x = 0; x < pAccess->Width(); ++x)
+ {
+ Color aColor = pAccess->GetPixelFromData(pScanline, x);
+ sal_uInt8 aValue = rExpected[y*8+x];
+
+ if (aValue == 1 && aColor != aFGColor)
+ bResult = false;
+ else if (aValue == 0 && aColor != aBGColor)
+ bResult = false;
+ }
+ }
+
+ return bResult;
+}
+
+} // end anonymous namespace
+
+bool SdImportTest::checkPattern(sd::DrawDocShellRef const & rDocRef, int nShapeNumber, std::vector<sal_uInt8>& rExpected)
+{
+ uno::Reference<beans::XPropertySet> xShape(getShapeFromPage(nShapeNumber, 0, rDocRef));
+ CPPUNIT_ASSERT_MESSAGE("Not a shape", xShape.is());
+
+ Bitmap aBitmap;
+ if (xShape.is())
+ {
+ uno::Any aBitmapAny = xShape->getPropertyValue("FillBitmap");
+ uno::Reference<awt::XBitmap> xBitmap;
+ if (aBitmapAny >>= xBitmap)
+ {
+ uno::Sequence<sal_Int8> aBitmapSequence(xBitmap->getDIB());
+ SvMemoryStream aBitmapStream(aBitmapSequence.getArray(),
+ aBitmapSequence.getLength(),
+ StreamMode::READ);
+ ReadDIB(aBitmap, aBitmapStream, true);
+ }
+ }
+ CPPUNIT_ASSERT_EQUAL(8L, aBitmap.GetSizePixel().Width());
+ CPPUNIT_ASSERT_EQUAL(8L, aBitmap.GetSizePixel().Height());
+ return checkPatternValues(rExpected, aBitmap);
+}
+
+/* Test checks that importing a PPT file with all supported fill patterns is
+ * correctly imported as a tiled fill bitmap with the expected pattern.
+ */
+void SdImportTest::testPatternImport()
+{
+ sd::DrawDocShellRef xDocRef = loadURL(m_directories.getURLFromSrc("sd/qa/unit/data/ppt/FillPatterns.ppt"), PPT);
+
+ std::vector<sal_uInt8> aExpectedPattern1 = {
+ 1,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,1,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ };
+ std::vector<sal_uInt8> aExpectedPattern2 = {
+ 1,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,1,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 1,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,1,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ };
+ std::vector<sal_uInt8> aExpectedPattern3 = {
+ 1,0,0,0,1,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,1,0,0,0,1,0,
+ 0,0,0,0,0,0,0,0,
+ 1,0,0,0,1,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,1,0,0,0,1,0,
+ 0,0,0,0,0,0,0,0,
+ };
+ std::vector<sal_uInt8> aExpectedPattern4 = {
+ 1,0,0,0,1,0,0,0,
+ 0,0,1,0,0,0,1,0,
+ 1,0,0,0,1,0,0,0,
+ 0,0,1,0,0,0,1,0,
+ 1,0,0,0,1,0,0,0,
+ 0,0,1,0,0,0,1,0,
+ 1,0,0,0,1,0,0,0,
+ 0,0,1,0,0,0,1,0,
+ };
+ std::vector<sal_uInt8> aExpectedPattern5 = {
+ 1,0,1,0,1,0,1,0,
+ 0,1,0,0,0,1,0,0,
+ 1,0,1,0,1,0,1,0,
+ 0,0,0,1,0,0,0,1,
+ 1,0,1,0,1,0,1,0,
+ 0,1,0,0,0,1,0,0,
+ 1,0,1,0,1,0,1,0,
+ 0,0,0,1,0,0,0,1,
+ };
+ std::vector<sal_uInt8> aExpectedPattern6 = {
+ 1,0,1,0,1,0,1,0,
+ 0,1,0,1,0,1,0,1,
+ 1,0,1,0,1,0,1,0,
+ 0,1,0,1,0,0,0,1,
+ 1,0,1,0,1,0,1,0,
+ 0,1,0,1,0,1,0,1,
+ 1,0,1,0,1,0,1,0,
+ 0,0,0,1,0,1,0,1,
+ };
+ std::vector<sal_uInt8> aExpectedPattern7 = {
+ 1,0,1,0,1,0,1,0,
+ 0,1,0,1,0,1,0,1,
+ 1,0,1,0,1,0,1,0,
+ 0,1,0,1,0,1,0,1,
+ 1,0,1,0,1,0,1,0,
+ 0,1,0,1,0,1,0,1,
+ 1,0,1,0,1,0,1,0,
+ 0,1,0,1,0,1,0,1,
+ };
+ std::vector<sal_uInt8> aExpectedPattern8 = {
+ 1,1,1,0,1,1,1,0,
+ 0,1,0,1,0,1,0,1,
+ 1,0,1,1,1,0,1,1,
+ 0,1,0,1,0,1,0,1,
+ 1,1,1,0,1,1,1,0,
+ 0,1,0,1,0,1,0,1,
+ 1,0,1,1,1,0,1,1,
+ 0,1,0,1,0,1,0,1,
+ };
+ std::vector<sal_uInt8> aExpectedPattern9 = {
+ 0,1,1,1,0,1,1,1,
+ 1,1,0,1,1,1,0,1,
+ 0,1,1,1,0,1,1,1,
+ 1,1,0,1,1,1,0,1,
+ 0,1,1,1,0,1,1,1,
+ 1,1,0,1,1,1,0,1,
+ 0,1,1,1,0,1,1,1,
+ 1,1,0,1,1,1,0,1,
+ };
+ std::vector<sal_uInt8> aExpectedPattern10 = {
+ 0,1,1,1,0,1,1,1,
+ 1,1,1,1,1,1,1,1,
+ 1,1,0,1,1,1,0,1,
+ 1,1,1,1,1,1,1,1,
+ 0,1,1,1,0,1,1,1,
+ 1,1,1,1,1,1,1,1,
+ 1,1,0,1,1,1,0,1,
+ 1,1,1,1,1,1,1,1,
+ };
+ std::vector<sal_uInt8> aExpectedPattern11 = {
+ 1,1,1,0,1,1,1,1,
+ 1,1,1,1,1,1,1,1,
+ 1,1,1,1,1,1,1,0,
+ 1,1,1,1,1,1,1,1,
+ 1,1,1,0,1,1,1,1,
+ 1,1,1,1,1,1,1,1,
+ 1,1,1,1,1,1,1,0,
+ 1,1,1,1,1,1,1,1,
+ };
+ std::vector<sal_uInt8> aExpectedPattern12 = {
+ 1,1,1,1,1,1,1,1,
+ 1,1,1,1,1,1,1,1,
+ 1,1,1,1,1,1,1,1,
+ 1,1,1,1,0,1,1,1,
+ 1,1,1,1,1,1,1,1,
+ 1,1,1,1,1,1,1,1,
+ 1,1,1,1,1,1,1,1,
+ 0,1,1,1,1,1,1,1,
+ };
+ std::vector<sal_uInt8> aExpectedPatternLine1 = {
+ 1,0,0,0,1,0,0,0,
+ 0,1,0,0,0,1,0,0,
+ 0,0,1,0,0,0,1,0,
+ 0,0,0,1,0,0,0,1,
+ 1,0,0,0,1,0,0,0,
+ 0,1,0,0,0,1,0,0,
+ 0,0,1,0,0,0,1,0,
+ 0,0,0,1,0,0,0,1,
+ };
+ std::vector<sal_uInt8> aExpectedPatternLine2 = {
+ 0,0,0,1,0,0,0,1,
+ 0,0,1,0,0,0,1,0,
+ 0,1,0,0,0,1,0,0,
+ 1,0,0,0,1,0,0,0,
+ 0,0,0,1,0,0,0,1,
+ 0,0,1,0,0,0,1,0,
+ 0,1,0,0,0,1,0,0,
+ 1,0,0,0,1,0,0,0,
+ };
+ std::vector<sal_uInt8> aExpectedPatternLine3 = {
+ 1,1,0,0,1,1,0,0,
+ 0,1,1,0,0,1,1,0,
+ 0,0,1,1,0,0,1,1,
+ 1,0,0,1,1,0,0,1,
+ 1,1,0,0,1,1,0,0,
+ 0,1,1,0,0,1,1,0,
+ 0,0,1,1,0,0,1,1,
+ 1,0,0,1,1,0,0,1,
+ };
+ std::vector<sal_uInt8> aExpectedPatternLine4 = {
+ 0,0,1,1,0,0,1,1,
+ 0,1,1,0,0,1,1,0,
+ 1,1,0,0,1,1,0,0,
+ 1,0,0,1,1,0,0,1,
+ 0,0,1,1,0,0,1,1,
+ 0,1,1,0,0,1,1,0,
+ 1,1,0,0,1,1,0,0,
+ 1,0,0,1,1,0,0,1,
+ };
+ std::vector<sal_uInt8> aExpectedPatternLine5 = {
+ 1,1,0,0,0,0,0,1,
+ 1,1,1,0,0,0,0,0,
+ 0,1,1,1,0,0,0,0,
+ 0,0,1,1,1,0,0,0,
+ 0,0,0,1,1,1,0,0,
+ 0,0,0,0,1,1,1,0,
+ 0,0,0,0,0,1,1,1,
+ 1,0,0,0,0,0,1,1,
+ };
+ std::vector<sal_uInt8> aExpectedPatternLine6 = {
+ 1,0,0,0,0,0,1,1,
+ 0,0,0,0,0,1,1,1,
+ 0,0,0,0,1,1,1,0,
+ 0,0,0,1,1,1,0,0,
+ 0,0,1,1,1,0,0,0,
+ 0,1,1,1,0,0,0,0,
+ 1,1,1,0,0,0,0,0,
+ 1,1,0,0,0,0,0,1,
+ };
+ std::vector<sal_uInt8> aExpectedPatternLine7 = {
+ 1,0,0,0,1,0,0,0,
+ 1,0,0,0,1,0,0,0,
+ 1,0,0,0,1,0,0,0,
+ 1,0,0,0,1,0,0,0,
+ 1,0,0,0,1,0,0,0,
+ 1,0,0,0,1,0,0,0,
+ 1,0,0,0,1,0,0,0,
+ 1,0,0,0,1,0,0,0,
+ };
+ std::vector<sal_uInt8> aExpectedPatternLine8 = {
+ 1,1,1,1,1,1,1,1,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 1,1,1,1,1,1,1,1,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ };
+ std::vector<sal_uInt8> aExpectedPatternLine9 = {
+ 0,1,0,1,0,1,0,1,
+ 0,1,0,1,0,1,0,1,
+ 0,1,0,1,0,1,0,1,
+ 0,1,0,1,0,1,0,1,
+ 0,1,0,1,0,1,0,1,
+ 0,1,0,1,0,1,0,1,
+ 0,1,0,1,0,1,0,1,
+ 0,1,0,1,0,1,0,1,
+ };
+ std::vector<sal_uInt8> aExpectedPatternLine10 = {
+ 1,1,1,1,1,1,1,1,
+ 0,0,0,0,0,0,0,0,
+ 1,1,1,1,1,1,1,1,
+ 0,0,0,0,0,0,0,0,
+ 1,1,1,1,1,1,1,1,
+ 0,0,0,0,0,0,0,0,
+ 1,1,1,1,1,1,1,1,
+ 0,0,0,0,0,0,0,0,
+ };
+ std::vector<sal_uInt8> aExpectedPatternLine11 = {
+ 1,1,0,0,1,1,0,0,
+ 1,1,0,0,1,1,0,0,
+ 1,1,0,0,1,1,0,0,
+ 1,1,0,0,1,1,0,0,
+ 1,1,0,0,1,1,0,0,
+ 1,1,0,0,1,1,0,0,
+ 1,1,0,0,1,1,0,0,
+ 1,1,0,0,1,1,0,0,
+ };
+ std::vector<sal_uInt8> aExpectedPatternLine12 = {
+ 1,1,1,1,1,1,1,1,
+ 1,1,1,1,1,1,1,1,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 1,1,1,1,1,1,1,1,
+ 1,1,1,1,1,1,1,1,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ };
+
+ CPPUNIT_ASSERT_MESSAGE("Pattern1 - 5%" , checkPattern(xDocRef, 0, aExpectedPattern1));
+ CPPUNIT_ASSERT_MESSAGE("Pattern2 - 10%", checkPattern(xDocRef, 1, aExpectedPattern2));
+ CPPUNIT_ASSERT_MESSAGE("Pattern3 - 20%", checkPattern(xDocRef, 2, aExpectedPattern3));
+ CPPUNIT_ASSERT_MESSAGE("Pattern4 - 25%", checkPattern(xDocRef, 3, aExpectedPattern4));
+ CPPUNIT_ASSERT_MESSAGE("Pattern5 - 30%", checkPattern(xDocRef, 4, aExpectedPattern5));
+ CPPUNIT_ASSERT_MESSAGE("Pattern6 - 40%", checkPattern(xDocRef, 5, aExpectedPattern6));
+ CPPUNIT_ASSERT_MESSAGE("Pattern7 - 50%", checkPattern(xDocRef, 6, aExpectedPattern7));
+ CPPUNIT_ASSERT_MESSAGE("Pattern8 - 60%", checkPattern(xDocRef, 7, aExpectedPattern8));
+ CPPUNIT_ASSERT_MESSAGE("Pattern9 - 70%", checkPattern(xDocRef, 8, aExpectedPattern9));
+ CPPUNIT_ASSERT_MESSAGE("Pattern10 - 75%", checkPattern(xDocRef, 9, aExpectedPattern10));
+ CPPUNIT_ASSERT_MESSAGE("Pattern11 - 80%", checkPattern(xDocRef, 10, aExpectedPattern11));
+ CPPUNIT_ASSERT_MESSAGE("Pattern12 - 90%", checkPattern(xDocRef, 11, aExpectedPattern12));
+
+ CPPUNIT_ASSERT_MESSAGE("Pattern13 - Light downward diagonal", checkPattern(xDocRef, 12, aExpectedPatternLine1));
+ CPPUNIT_ASSERT_MESSAGE("Pattern14 - Light upward diagonal", checkPattern(xDocRef, 13, aExpectedPatternLine2));
+ CPPUNIT_ASSERT_MESSAGE("Pattern15 - Dark downward diagonal", checkPattern(xDocRef, 14, aExpectedPatternLine3));
+ CPPUNIT_ASSERT_MESSAGE("Pattern16 - Dark upward diagonal", checkPattern(xDocRef, 15, aExpectedPatternLine4));
+ CPPUNIT_ASSERT_MESSAGE("Pattern17 - Wide downward diagonal", checkPattern(xDocRef, 16, aExpectedPatternLine5));
+ CPPUNIT_ASSERT_MESSAGE("Pattern18 - Wide upward diagonal", checkPattern(xDocRef, 17, aExpectedPatternLine6));
+
+ CPPUNIT_ASSERT_MESSAGE("Pattern19 - Light vertical", checkPattern(xDocRef, 18, aExpectedPatternLine7));
+ CPPUNIT_ASSERT_MESSAGE("Pattern20 - Light horizontal", checkPattern(xDocRef, 19, aExpectedPatternLine8));
+ CPPUNIT_ASSERT_MESSAGE("Pattern21 - Narrow vertical", checkPattern(xDocRef, 20, aExpectedPatternLine9));
+ CPPUNIT_ASSERT_MESSAGE("Pattern22 - Narrow horizontal", checkPattern(xDocRef, 21, aExpectedPatternLine10));
+ CPPUNIT_ASSERT_MESSAGE("Pattern23 - Dark vertical", checkPattern(xDocRef, 22, aExpectedPatternLine11));
+ CPPUNIT_ASSERT_MESSAGE("Pattern24 - Dark horizontal", checkPattern(xDocRef, 23, aExpectedPatternLine12));
+
+ // TODO: other patterns in the test document
+
+ xDocRef->DoClose();
+}
+
+void SdImportTest::testTdf100926()
+{
+ sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc("sd/qa/unit/data/pptx/tdf100926.pptx"), PPTX);
+ const SdrPage* pPage = GetPage(1, xDocShRef);
+ CPPUNIT_ASSERT(pPage != nullptr);
+
+ sdr::table::SdrTableObj *pTableObj = dynamic_cast<sdr::table::SdrTableObj*>(pPage->GetObj(0));
+ CPPUNIT_ASSERT(pTableObj != nullptr);
+ uno::Reference< table::XCellRange > xTable(pTableObj->getTable(), uno::UNO_QUERY_THROW);
+
+ sal_Int32 nRotation = 0;
+ uno::Reference< beans::XPropertySet > xCell(xTable->getCellByPosition(0, 0), uno::UNO_QUERY_THROW);
+ xCell->getPropertyValue("RotateAngle") >>= nRotation;
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(27000), nRotation);
+
+ xCell.set(xTable->getCellByPosition(1, 0), uno::UNO_QUERY_THROW);
+ xCell->getPropertyValue("RotateAngle") >>= nRotation;
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(9000), nRotation);
+
+ xCell.set(xTable->getCellByPosition(2, 0), uno::UNO_QUERY_THROW);
+ xCell->getPropertyValue("RotateAngle") >>= nRotation;
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(0), nRotation);
+
+ xDocShRef->DoClose();
+}
+
+void SdImportTest::testTdf89064()
+{
+ sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc("sd/qa/unit/data/pptx/tdf89064.pptx"), PPTX);
+ uno::Reference< presentation::XPresentationPage > xPage (getPage(0, xDocShRef), uno::UNO_QUERY_THROW);
+ uno::Reference< drawing::XDrawPage > xNotesPage (xPage->getNotesPage(), uno::UNO_SET_THROW);
+ CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(1), xNotesPage->getCount());
+
+ xDocShRef->DoClose();
+}
+
+void SdImportTest::testTdf108925()
+{
+ // Test document contains bulleting with too small bullet size (1%) which breaks the lower constraint
+ // So it should be converted to the lowest allowed value (25%).
+ sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc("sd/qa/unit/data/odp/tdf108925.odp"), ODP);
+ const SdrPage *pPage = GetPage(1, xDocShRef);
+ SdrTextObj *pTxtObj = dynamic_cast<SdrTextObj *>(pPage->GetObj(0));
+ CPPUNIT_ASSERT_MESSAGE("No text object", pTxtObj != nullptr);
+ const EditTextObject& aEdit = pTxtObj->GetOutlinerParaObject()->GetTextObject();
+
+ const SvxNumBulletItem *pNumFmt = aEdit.GetParaAttribs(0).GetItem(EE_PARA_NUMBULLET);
+ CPPUNIT_ASSERT(pNumFmt);
+ CPPUNIT_ASSERT_EQUAL(sal_uInt16(25), pNumFmt->GetNumRule()->GetLevel(0).GetBulletRelSize());
+
+ xDocShRef->DoClose();
+}
+
+void SdImportTest::testTdf109067()
+{
+ sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc("sd/qa/unit/data/pptx/tdf109067.pptx"), PPTX);
+ uno::Reference< beans::XPropertySet > xShape(getShapeFromPage(0, 0, xDocShRef), uno::UNO_SET_THROW);
+ awt::Gradient gradient;
+ CPPUNIT_ASSERT(xShape->getPropertyValue("FillGradient") >>= gradient);
+ CPPUNIT_ASSERT_EQUAL(sal_Int16(450), gradient.Angle);
+
+ xDocShRef->DoClose();
+}
+
+void SdImportTest::testTdf109187()
+{
+ sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc("sd/qa/unit/data/pptx/tdf109187.pptx"), PPTX);
+ uno::Reference< beans::XPropertySet > xArrow1(getShapeFromPage(0, 0, xDocShRef), uno::UNO_SET_THROW);
+ awt::Gradient aGradient1;
+ CPPUNIT_ASSERT(xArrow1->getPropertyValue("FillGradient") >>= aGradient1);
+ CPPUNIT_ASSERT_EQUAL(sal_Int16(2250), aGradient1.Angle);
+ uno::Reference< beans::XPropertySet > xArrow2(getShapeFromPage(1, 0, xDocShRef), uno::UNO_SET_THROW);
+ awt::Gradient aGradient2;
+ CPPUNIT_ASSERT(xArrow2->getPropertyValue("FillGradient") >>= aGradient2);
+ CPPUNIT_ASSERT_EQUAL(sal_Int16(1350), aGradient2.Angle);
+
+ xDocShRef->DoClose();
+}
+
+void SdImportTest::testTdf108926()
+{
+ sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc("sd/qa/unit/data/pptx/tdf108926.ppt"), PPT);
+ uno::Reference< presentation::XPresentationPage > xPage (getPage(0, xDocShRef), uno::UNO_QUERY_THROW);
+ uno::Reference< drawing::XDrawPage > xNotesPage (xPage->getNotesPage(), uno::UNO_SET_THROW);
+ CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(2), xNotesPage->getCount());
+
+ // Second object should be imported as an empty presentation shape
+ uno::Reference< beans::XPropertySet > xPresentationShape(xNotesPage->getByIndex(1), uno::UNO_QUERY);
+ CPPUNIT_ASSERT(xPresentationShape.is());
+ bool bIsEmptyPresObject = false;
+ xPresentationShape->getPropertyValue( "IsEmptyPresentationObject" ) >>= bIsEmptyPresObject;
+ CPPUNIT_ASSERT(bIsEmptyPresObject);
+
+ xDocShRef->DoClose();
+}
+
+void SdImportTest::testTdf100065()
+{
+ sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc("sd/qa/unit/data/pptx/tdf100065.pptx"), PPTX);
+
+ uno::Reference< container::XIndexAccess > xGroupShape1(getShapeFromPage(0, 0, xDocShRef), uno::UNO_QUERY_THROW);
+ uno::Reference< beans::XPropertySet > xShape1(xGroupShape1->getByIndex(1), uno::UNO_QUERY_THROW);
+ sal_Int32 nAngle1;
+ CPPUNIT_ASSERT(xShape1->getPropertyValue("RotateAngle") >>= nAngle1);
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(2000), nAngle1);
+
+ uno::Reference< container::XIndexAccess > xGroupShape2(getShapeFromPage(1, 0, xDocShRef), uno::UNO_QUERY_THROW);
+ uno::Reference< beans::XPropertySet > xShape2(xGroupShape2->getByIndex(0), uno::UNO_QUERY_THROW);
+ sal_Int32 nAngle2;
+ CPPUNIT_ASSERT(xShape2->getPropertyValue("RotateAngle") >>= nAngle2);
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(18000), nAngle2);
+
+ xDocShRef->DoClose();
+}
+
+void SdImportTest::testTdf90626()
+{
+ sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc("sd/qa/unit/data/pptx/tdf90626.pptx"), PPTX);
+ const SdrPage *pPage = GetPage(1, xDocShRef);
+ SdrTextObj *pTxtObj = dynamic_cast<SdrTextObj *>(pPage->GetObj(1));
+ CPPUNIT_ASSERT_MESSAGE("No text object", pTxtObj != nullptr);
+ const EditTextObject& aEdit = pTxtObj->GetOutlinerParaObject()->GetTextObject();
+ for(int i = 0; i < 4; i++)
+ {
+ const SvxNumBulletItem *pNumFmt = aEdit.GetParaAttribs(i).GetItem(EE_PARA_NUMBULLET);
+ CPPUNIT_ASSERT(pNumFmt);
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(long(371), pNumFmt->GetNumRule()->GetLevel(0).GetGraphicSize().getHeight(), long(1));
+ }
+
+ xDocShRef->DoClose();
+}
+
+void SdImportTest::testTdf114488()
+{
+ // This doc has two images - one WMF and the other PNG (fallback image).
+ // When loading this doc, the WMF image should be preferred over the PNG image.
+ sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc("sd/qa/unit/data/odg/tdf114488.fodg"), FODG);
+ uno::Reference<beans::XPropertySet> xShape(getShapeFromPage(0, 0, xDocShRef), uno::UNO_SET_THROW);
+ uno::Reference<graphic::XGraphic> xGraphic;
+ xShape->getPropertyValue("Graphic") >>= xGraphic;
+ CPPUNIT_ASSERT(xGraphic.is());
+ OUString sMimeType(comphelper::GraphicMimeTypeHelper::GetMimeTypeForXGraphic(xGraphic));
+ CPPUNIT_ASSERT_EQUAL(OUString("image/x-wmf"), sMimeType);
+
+ xDocShRef->DoClose();
+}
+
+void SdImportTest::testTdf134174()
+{
+ sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc("sd/qa/unit/data/pptx/tdf134174.pptx"), PPTX);
+ uno::Reference<beans::XPropertySet> xShape(getShapeFromPage(0, 0, xDocShRef), uno::UNO_SET_THROW);
+ CPPUNIT_ASSERT(xShape.is());
+
+ uno::Reference<graphic::XGraphic> xGraphic;
+ xShape->getPropertyValue("FillBitmap") >>= xGraphic;
+ CPPUNIT_ASSERT(xGraphic.is());
+
+ Graphic aGraphic(xGraphic);
+ BitmapEx aBitmap(aGraphic.GetBitmapEx());
+ CPPUNIT_ASSERT_EQUAL( Color(9118171), aBitmap.GetPixelColor( 0, 0 ));
+
+ xDocShRef->DoClose();
+}
+
+void SdImportTest::testTdf114913()
+{
+ sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc("sd/qa/unit/data/pptx/tdf114913.pptx"), PPTX);
+ SdrTextObj *pTxtObj = dynamic_cast<SdrTextObj *>(GetPage(1, xDocShRef)->GetObj(1));
+ CPPUNIT_ASSERT_MESSAGE("No text object", pTxtObj != nullptr);
+ const SvxNumBulletItem *pItem = pTxtObj->GetOutlinerParaObject()->GetTextObject().GetParaAttribs(0).GetItem(EE_PARA_NUMBULLET);
+ CPPUNIT_ASSERT(pItem);
+ CPPUNIT_ASSERT_EQUAL(long(691), pItem->GetNumRule()->GetLevel(0).GetGraphicSize().getHeight());
+
+ xDocShRef->DoClose();
+}
+
+void SdImportTest::testTdf114821()
+{
+ css::uno::Any aAny;
+ sd::DrawDocShellRef xDocShRef = loadURL( m_directories.getURLFromSrc( "/sd/qa/unit/data/pptx/tdf114821.pptx" ), PPTX );
+
+ uno::Reference< beans::XPropertySet > xPropSet( getShapeFromPage( 0, 0, xDocShRef ) );
+ aAny = xPropSet->getPropertyValue( "Model" );
+ CPPUNIT_ASSERT_MESSAGE( "The shape doesn't have the property", aAny.hasValue() );
+
+ uno::Reference< chart::XChartDocument > xChartDoc;
+ aAny >>= xChartDoc;
+ CPPUNIT_ASSERT_MESSAGE( "failed to load chart", xChartDoc.is() );
+ uno::Reference< chart2::XChartDocument > xChart2Doc( xChartDoc, uno::UNO_QUERY );
+ CPPUNIT_ASSERT_MESSAGE( "failed to load chart", xChart2Doc.is() );
+
+ uno::Reference< chart2::XCoordinateSystemContainer > xBCooSysCnt( xChart2Doc->getFirstDiagram(), uno::UNO_QUERY );
+ uno::Sequence< uno::Reference< chart2::XCoordinateSystem > > aCooSysSeq( xBCooSysCnt->getCoordinateSystems() );
+ uno::Reference< chart2::XChartTypeContainer > xCTCnt( aCooSysSeq[0], uno::UNO_QUERY );
+
+ uno::Reference< chart2::XDataSeriesContainer > xDSCnt( xCTCnt->getChartTypes()[0], uno::UNO_QUERY );
+ CPPUNIT_ASSERT_MESSAGE( "failed to load data series", xDSCnt.is() );
+ uno::Sequence< uno::Reference< chart2::XDataSeries > > aSeriesSeq( xDSCnt->getDataSeries() );
+ CPPUNIT_ASSERT_EQUAL_MESSAGE( "Invalid Series count", static_cast<sal_Int32>( 1 ), aSeriesSeq.getLength() );
+
+ // These Labels have custom position, so the exported LabelPlacement (reference point) by MSO is OUTSIDE/OUTEND
+ // Check the first label
+ const css::uno::Reference< css::beans::XPropertySet >& rPropSet0( aSeriesSeq[0]->getDataPointByIndex( 0 ) );
+ CPPUNIT_ASSERT( rPropSet0.is() );
+ sal_Int32 aPlacement;
+ rPropSet0->getPropertyValue( "LabelPlacement" ) >>= aPlacement;
+ CPPUNIT_ASSERT_EQUAL( css::chart::DataLabelPlacement::OUTSIDE, aPlacement );
+
+ // Check the second label
+ const css::uno::Reference< css::beans::XPropertySet >& rPropSet1( aSeriesSeq[0]->getDataPointByIndex( 1 ) );
+ CPPUNIT_ASSERT( rPropSet1.is() );
+ rPropSet1->getPropertyValue( "LabelPlacement" ) >>= aPlacement;
+ CPPUNIT_ASSERT_EQUAL( css::chart::DataLabelPlacement::OUTSIDE, aPlacement );
+
+ // Check the third label
+ const css::uno::Reference< css::beans::XPropertySet >& rPropSet2( aSeriesSeq[0]->getDataPointByIndex( 2 ) );
+ CPPUNIT_ASSERT( rPropSet2.is() );
+ rPropSet2->getPropertyValue( "LabelPlacement") >>= aPlacement;
+ CPPUNIT_ASSERT_EQUAL( css::chart::DataLabelPlacement::OUTSIDE, aPlacement );
+
+ xDocShRef->DoClose();
+}
+
+void SdImportTest::testTdf115394()
+{
+ sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc("/sd/qa/unit/data/pptx/tdf115394.pptx"), PPTX);
+ double fTransitionDuration;
+
+ // Slow in MS formats
+ SdPage* pPage1 = xDocShRef->GetDoc()->GetSdPage(0, PageKind::Standard);
+ fTransitionDuration = pPage1->getTransitionDuration();
+ CPPUNIT_ASSERT_EQUAL(1.0, fTransitionDuration);
+
+ // Medium in MS formats
+ SdPage* pPage2 = xDocShRef->GetDoc()->GetSdPage(1, PageKind::Standard);
+ fTransitionDuration = pPage2->getTransitionDuration();
+ CPPUNIT_ASSERT_EQUAL(0.75, fTransitionDuration);
+
+ // Fast in MS formats
+ SdPage* pPage3 = xDocShRef->GetDoc()->GetSdPage(2, PageKind::Standard);
+ fTransitionDuration = pPage3->getTransitionDuration();
+ CPPUNIT_ASSERT_EQUAL(0.5, fTransitionDuration);
+
+ // Custom values
+ SdPage* pPage4 = xDocShRef->GetDoc()->GetSdPage(3, PageKind::Standard);
+ fTransitionDuration = pPage4->getTransitionDuration();
+ CPPUNIT_ASSERT_EQUAL(0.25, fTransitionDuration);
+
+ SdPage* pPage5 = xDocShRef->GetDoc()->GetSdPage(4, PageKind::Standard);
+ fTransitionDuration = pPage5->getTransitionDuration();
+ CPPUNIT_ASSERT_EQUAL(4.25, fTransitionDuration);
+
+ xDocShRef->DoClose();
+}
+
+void SdImportTest::testTdf115394PPT()
+{
+ sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc("/sd/qa/unit/data/ppt/tdf115394.ppt"), PPT);
+ double fTransitionDuration;
+
+ // Fast
+ SdPage* pPage1 = xDocShRef->GetDoc()->GetSdPage(0, PageKind::Standard);
+ fTransitionDuration = pPage1->getTransitionDuration();
+ CPPUNIT_ASSERT_EQUAL(0.5, fTransitionDuration);
+
+ // Medium
+ SdPage* pPage2 = xDocShRef->GetDoc()->GetSdPage(1, PageKind::Standard);
+ fTransitionDuration = pPage2->getTransitionDuration();
+ CPPUNIT_ASSERT_EQUAL(0.75, fTransitionDuration);
+
+ // Slow
+ SdPage* pPage3 = xDocShRef->GetDoc()->GetSdPage(2, PageKind::Standard);
+ fTransitionDuration = pPage3->getTransitionDuration();
+ CPPUNIT_ASSERT_EQUAL(1.0, fTransitionDuration);
+
+ xDocShRef->DoClose();
+}
+
+void SdImportTest::testTdf51340()
+{
+ // Line spacing was not inherited from upper levels (slide layout, master slide)
+ sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc("/sd/qa/unit/data/pptx/tdf51340.pptx"), PPTX);
+ uno::Reference< beans::XPropertySet > xShape( getShapeFromPage( 1, 0, xDocShRef ) );
+
+ // First paragraph has a 90% line spacing set on master slide
+ uno::Reference<text::XTextRange> xParagraph( getParagraphFromShape( 0, xShape ) );
+ uno::Reference< beans::XPropertySet > xPropSet( xParagraph, uno::UNO_QUERY_THROW );
+ css::style::LineSpacing aSpacing;
+ xPropSet->getPropertyValue( "ParaLineSpacing" ) >>= aSpacing;
+ CPPUNIT_ASSERT_EQUAL( css::style::LineSpacingMode::PROP, aSpacing.Mode );
+ CPPUNIT_ASSERT_EQUAL( static_cast<sal_Int16>(90), aSpacing.Height );
+
+ // Second paragraph has a 125% line spacing set on slide layout
+ xParagraph.set( getParagraphFromShape( 1, xShape ) );
+ xPropSet.set( xParagraph, uno::UNO_QUERY_THROW );
+ xPropSet->getPropertyValue( "ParaLineSpacing" ) >>= aSpacing;
+ CPPUNIT_ASSERT_EQUAL( css::style::LineSpacingMode::PROP, aSpacing.Mode );
+ CPPUNIT_ASSERT_EQUAL( static_cast<sal_Int16>(125), aSpacing.Height );
+
+ // Third paragraph has a 70% line spacing set directly on normal slide (master slide property is overridden)
+ xParagraph.set( getParagraphFromShape( 2, xShape ) );
+ xPropSet.set( xParagraph, uno::UNO_QUERY_THROW );
+ xPropSet->getPropertyValue( "ParaLineSpacing" ) >>= aSpacing;
+ CPPUNIT_ASSERT_EQUAL( css::style::LineSpacingMode::PROP, aSpacing.Mode );
+ CPPUNIT_ASSERT_EQUAL( static_cast<sal_Int16>(70), aSpacing.Height );
+
+ // Fourth paragraph has a 190% line spacing set directly on normal slide (slide layout property is overridden)
+ xParagraph.set( getParagraphFromShape( 3, xShape ) );
+ xPropSet.set( xParagraph, uno::UNO_QUERY_THROW );
+ xPropSet->getPropertyValue( "ParaLineSpacing" ) >>= aSpacing;
+ CPPUNIT_ASSERT_EQUAL( css::style::LineSpacingMode::PROP, aSpacing.Mode );
+ CPPUNIT_ASSERT_EQUAL( static_cast<sal_Int16>(190), aSpacing.Height );
+
+ xDocShRef->DoClose();
+}
+
+void SdImportTest::testTdf116899()
+{
+ // This is a PPT created in Impress and roundtripped in PP, the key times become [1, -1] in PP,
+ // a time of -1 (-1000) in PPT means key times have to be distributed evenly between 0 and 1
+ sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc("/sd/qa/unit/data/ppt/tdf116899.ppt"), PPT);
+
+ uno::Reference< drawing::XDrawPagesSupplier > xDoc(
+ xDocShRef->GetDoc()->getUnoModel(), uno::UNO_QUERY_THROW );
+ uno::Reference< drawing::XDrawPage > xPage(
+ xDoc->getDrawPages()->getByIndex(0), uno::UNO_QUERY_THROW );
+ uno::Reference< animations::XAnimationNodeSupplier > xAnimNodeSupplier(
+ xPage, uno::UNO_QUERY_THROW );
+ uno::Reference< animations::XAnimationNode > xRootNode(
+ xAnimNodeSupplier->getAnimationNode() );
+ std::vector< uno::Reference< animations::XAnimationNode > > aAnimVector;
+ anim::create_deep_vector(xRootNode, aAnimVector);
+ uno::Reference< animations::XAnimate > xNode(
+ aAnimVector[8], uno::UNO_QUERY_THROW );
+ CPPUNIT_ASSERT_EQUAL_MESSAGE( "Number of key times in the animation node isn't 2.", static_cast<sal_Int32>(2), xNode->getKeyTimes().getLength() );
+ CPPUNIT_ASSERT_EQUAL_MESSAGE( "First key time in the animation node isn't 0, key times aren't normalized.", 0., xNode->getKeyTimes()[0] );
+ CPPUNIT_ASSERT_EQUAL_MESSAGE( "Second key time in the animation node isn't 1, key times aren't normalized.", 1., xNode->getKeyTimes()[1] );
+
+ xDocShRef->DoClose();
+}
+
+void SdImportTest::testTdf77747()
+{
+ sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc("/sd/qa/unit/data/ppt/tdf77747.ppt"), PPT);
+ CPPUNIT_ASSERT(xDocShRef.is());
+ SdrTextObj *pTxtObj = dynamic_cast<SdrTextObj *>(GetPage(1, xDocShRef)->GetObj(0));
+ CPPUNIT_ASSERT_MESSAGE("No text object", pTxtObj != nullptr);
+ const SvxNumBulletItem *pNumFmt = pTxtObj->GetOutlinerParaObject()->GetTextObject().GetParaAttribs(0).GetItem(EE_PARA_NUMBULLET);
+ CPPUNIT_ASSERT(pNumFmt);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE( "Bullet's suffix is wrong!", OUString("-"), pNumFmt->GetNumRule()->GetLevel(0).GetSuffix() );
+ CPPUNIT_ASSERT_EQUAL_MESSAGE( "Bullet's numbering type is wrong!", SVX_NUM_NUMBER_HEBREW,
+ pNumFmt->GetNumRule()->GetLevel(0).GetNumberingType());
+
+ xDocShRef->DoClose();
+}
+
+void SdImportTest::testTdf116266()
+{
+ sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc("/sd/qa/unit/data/odp/tdf116266.odp"), ODP);
+ SdDrawDocument *pDoc = xDocShRef->GetDoc();
+ sfx2::LinkManager* rLinkManager = pDoc->GetLinkManager();
+ // The document contains one SVG stored as a link.
+ CPPUNIT_ASSERT_EQUAL(size_t(1), rLinkManager->GetLinks().size());
+
+ xDocShRef->DoClose();
+}
+
+void SdImportTest::testTdf120028()
+{
+ // Check that the table shape has 4 columns.
+ ::sd::DrawDocShellRef xDocShRef
+ = loadURL(m_directories.getURLFromSrc("/sd/qa/unit/data/pptx/tdf120028.pptx"), PPTX);
+ uno::Reference<drawing::XDrawPagesSupplier> xDoc(xDocShRef->GetDoc()->getUnoModel(),
+ uno::UNO_QUERY);
+ CPPUNIT_ASSERT(xDoc.is());
+
+ uno::Reference<drawing::XDrawPage> xPage(xDoc->getDrawPages()->getByIndex(0), uno::UNO_QUERY);
+ CPPUNIT_ASSERT(xPage.is());
+
+ // This failed, shape was not a table, all text was rendered in a single
+ // column.
+ uno::Reference<beans::XPropertySet> xShape(getShape(0, xPage));
+ uno::Reference<table::XColumnRowRange> xModel(xShape->getPropertyValue("Model"),
+ uno::UNO_QUERY);
+ CPPUNIT_ASSERT(xModel.is());
+
+ uno::Reference<table::XTableColumns> xColumns = xModel->getColumns();
+ CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(4), xColumns->getCount());
+
+ // Check font size in the A1 cell.
+ uno::Reference<table::XCellRange> xCells(xModel, uno::UNO_QUERY);
+ uno::Reference<beans::XPropertySet> xCell(xCells->getCellByPosition(0, 0), uno::UNO_QUERY);
+ uno::Reference<text::XTextRange> xParagraph(getParagraphFromShape(0, xCell));
+ uno::Reference<text::XTextRange> xRun(getRunFromParagraph(0, xParagraph));
+ uno::Reference<beans::XPropertySet> xPropSet(xRun, uno::UNO_QUERY);
+ double fCharHeight = 0;
+ xPropSet->getPropertyValue("CharHeight") >>= fCharHeight;
+ // This failed, non-scaled height was 13.5.
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(11.5, fCharHeight, 1E-12);
+
+ xDocShRef->DoClose();
+}
+
+void SdImportTest::testTdf120028b()
+{
+ // Check that the table shape has 4 columns.
+ ::sd::DrawDocShellRef xDocShRef
+ = loadURL(m_directories.getURLFromSrc("/sd/qa/unit/data/pptx/tdf120028b.pptx"), PPTX);
+ uno::Reference<drawing::XDrawPagesSupplier> xDoc(xDocShRef->GetDoc()->getUnoModel(),
+ uno::UNO_QUERY);
+ CPPUNIT_ASSERT(xDoc.is());
+
+ uno::Reference<drawing::XDrawPage> xPage(xDoc->getDrawPages()->getByIndex(0), uno::UNO_QUERY);
+ CPPUNIT_ASSERT(xPage.is());
+
+ uno::Reference<beans::XPropertySet> xShape(getShape(0, xPage));
+ CPPUNIT_ASSERT(xShape.is());
+
+ uno::Reference<table::XColumnRowRange> xModel(xShape->getPropertyValue("Model"),
+ uno::UNO_QUERY);
+ CPPUNIT_ASSERT(xModel.is());
+
+ uno::Reference<table::XTableColumns> xColumns = xModel->getColumns();
+ CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(4), xColumns->getCount());
+
+ // Check font color in the A1 cell.
+ uno::Reference<table::XCellRange> xCells(xModel, uno::UNO_QUERY);
+ uno::Reference<beans::XPropertySet> xCell(xCells->getCellByPosition(0, 0), uno::UNO_QUERY);
+ uno::Reference<text::XTextRange> xParagraph(getParagraphFromShape(0, xCell));
+ uno::Reference<text::XTextRange> xRun(getRunFromParagraph(0, xParagraph));
+ uno::Reference<beans::XPropertySet> xPropSet(xRun, uno::UNO_QUERY);
+ sal_Int32 nCharColor = 0;
+ xPropSet->getPropertyValue("CharColor") >>= nCharColor;
+ // This was 0x1f497d, not white: text list style from placeholder shape
+ // from slide layout was ignored.
+ CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(0xffffff), nCharColor);
+
+ xDocShRef->DoClose();
+}
+
+void SdImportTest::testDescriptionImport()
+{
+ sd::DrawDocShellRef xDocShRef
+ = loadURL(m_directories.getURLFromSrc("/sd/qa/unit/data/pptx/altdescription.pptx"), PPTX);
+
+ uno::Reference<beans::XPropertySet> xPropertySet(
+ getShapeFromPage(/*nShape=*/2, /*nPage=*/0, xDocShRef));
+ OUString sDesc;
+
+ xPropertySet->getPropertyValue("Description") >>= sDesc;
+
+ CPPUNIT_ASSERT_EQUAL(OUString("We Can Do It!"), sDesc);
+
+ xDocShRef->DoClose();
+}
+
+void SdImportTest::testTdf83247()
+{
+ auto GetPause = [this](const OUString& sSrc, sal_Int32 nFormat) {
+ sd::DrawDocShellRef xDocShRef
+ = loadURL(m_directories.getURLFromSrc(sSrc), nFormat);
+ uno::Reference<presentation::XPresentationSupplier> xPresentationSupplier(
+ xDocShRef->GetDoc()->getUnoModel(), uno::UNO_QUERY);
+ uno::Reference<beans::XPropertySet> xPresentationProps(
+ xPresentationSupplier->getPresentation(), uno::UNO_QUERY_THROW);
+
+ auto retVal = xPresentationProps->getPropertyValue("Pause");
+ xDocShRef->DoClose();
+ return retVal.get<sal_Int32>();
+ };
+
+ // 1. Check that presentation:pause attribute is imported correctly
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(10), GetPause("/sd/qa/unit/data/odp/loopPause10.odp", ODP));
+
+ // 2. ODF compliance: if presentation:pause attribute is absent, it must be treated as 0
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(0), GetPause("/sd/qa/unit/data/odp/loopNoPause.odp", ODP));
+
+ // 3. Import PPT: pause should be 0
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(0), GetPause("/sd/qa/unit/data/ppt/loopNoPause.ppt", PPT));
+}
+
+void SdImportTest::testTdf47365()
+{
+ sd::DrawDocShellRef xDocShRef
+ = loadURL(m_directories.getURLFromSrc("/sd/qa/unit/data/pptx/loopNoPause.pptx"), PPTX);
+ uno::Reference<presentation::XPresentationSupplier> xPresentationSupplier(
+ xDocShRef->GetDoc()->getUnoModel(), uno::UNO_QUERY_THROW);
+ uno::Reference<beans::XPropertySet> xPresentationProps(xPresentationSupplier->getPresentation(),
+ uno::UNO_QUERY_THROW);
+
+ const bool bEndlessVal = xPresentationProps->getPropertyValue("IsEndless").get<bool>();
+ const sal_Int32 nPauseVal = xPresentationProps->getPropertyValue("Pause").get<sal_Int32>();
+
+ // Check that we import "loop" attribute of the presentation, and don't introduce any pauses
+ CPPUNIT_ASSERT(bEndlessVal);
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(0), nPauseVal);
+
+ xDocShRef->DoClose();
+}
+
+void SdImportTest::testTdf122899()
+{
+ // tdf122899 FILEOPEN: ppt: old kind arc from MS Office 97 is broken
+ // Error was, that the path coordinates of a mso_sptArc shape were read as sal_Int16
+ // although they are unsigned 16 bit. This leads to wrong positions of start and end
+ // point and results to a huge shape width in the test document.
+ OUString aSrc="sd/qa/unit/data/ppt/tdf122899_Arc_90_to_91_clockwise.ppt";
+ sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc(aSrc), PPT);
+ uno::Reference<drawing::XDrawPagesSupplier> xDrawPagesSupplier(
+ xDocShRef->GetDoc()->getUnoModel(), uno::UNO_QUERY_THROW);
+ CPPUNIT_ASSERT_MESSAGE("Could not get XDrawPagesSupplier", xDrawPagesSupplier.is());
+ uno::Reference<drawing::XDrawPages> xDrawPages(xDrawPagesSupplier->getDrawPages());
+ uno::Reference<drawing::XDrawPage> xDrawPage(xDrawPages->getByIndex(0), uno::UNO_QUERY_THROW);
+ CPPUNIT_ASSERT_MESSAGE("Could not get xDrawPage", xDrawPage.is());
+ uno::Reference<drawing::XShape> xShape(xDrawPage->getByIndex(0), uno::UNO_QUERY);
+ CPPUNIT_ASSERT_MESSAGE("Could not get xShape", xShape.is());
+ awt::Rectangle aFrameRect;
+ uno::Reference<beans::XPropertySet> xShapeProps(xShape, uno::UNO_QUERY);
+ CPPUNIT_ASSERT_MESSAGE("Could not get the shape properties", xShapeProps.is());
+ xShapeProps->getPropertyValue(UNO_NAME_MISC_OBJ_FRAMERECT) >>= aFrameRect;
+ // original width is 9cm, add some tolerance
+ CPPUNIT_ASSERT_LESS(static_cast<sal_Int32>(9020), aFrameRect.Width);
+
+ xDocShRef->DoClose();
+}
+
+void SdImportTest::testOOXTheme()
+{
+ sd::DrawDocShellRef xDocShRef
+ = loadURL(m_directories.getURLFromSrc("/sd/qa/unit/data/pptx/ooxtheme.pptx"), PPTX);
+
+ uno::Reference<beans::XPropertySet> xPropSet(xDocShRef->GetDoc()->getUnoModel(), uno::UNO_QUERY_THROW);
+ uno::Sequence<beans::PropertyValue> aGrabBag;
+ xPropSet->getPropertyValue("InteropGrabBag") >>= aGrabBag;
+
+ bool bTheme = false;
+ for (beans::PropertyValue const & prop : std::as_const(aGrabBag))
+ {
+ if (prop.Name == "OOXTheme")
+ {
+ bTheme = true;
+ uno::Reference<xml::dom::XDocument> aThemeDom;
+ CPPUNIT_ASSERT(prop.Value >>= aThemeDom); // PropertyValue of proper type
+ CPPUNIT_ASSERT(aThemeDom.get()); // Reference not empty
+ }
+ }
+ CPPUNIT_ASSERT(bTheme); // Grab Bag has all the expected elements
+
+ xDocShRef->DoClose();
+}
+
+void SdImportTest::testCropToShape()
+{
+ sd::DrawDocShellRef xDocShRef
+ = loadURL(m_directories.getURLFromSrc("/sd/qa/unit/data/pptx/crop-to-shape.pptx"), PPTX);
+ uno::Reference<drawing::XDrawPagesSupplier> xDrawPagesSupplier(
+ xDocShRef->GetDoc()->getUnoModel(), uno::UNO_QUERY_THROW);
+ CPPUNIT_ASSERT_MESSAGE("Could not get XDrawPagesSupplier", xDrawPagesSupplier.is());
+ uno::Reference<drawing::XDrawPages> xDrawPages(xDrawPagesSupplier->getDrawPages());
+ uno::Reference<drawing::XDrawPage> xDrawPage(xDrawPages->getByIndex(0), uno::UNO_QUERY_THROW);
+ CPPUNIT_ASSERT_MESSAGE("Could not get xDrawPage", xDrawPage.is());
+ uno::Reference<drawing::XShape> xShape(xDrawPage->getByIndex(0), uno::UNO_QUERY);
+ CPPUNIT_ASSERT_EQUAL(OUString{"com.sun.star.drawing.CustomShape"}, xShape->getShapeType());
+ CPPUNIT_ASSERT_MESSAGE("Could not get xShape", xShape.is());
+ uno::Reference<beans::XPropertySet> xShapeProps(xShape, uno::UNO_QUERY);
+ css::drawing::FillStyle fillStyle;
+ xShapeProps->getPropertyValue("FillStyle") >>= fillStyle;
+ CPPUNIT_ASSERT_EQUAL(css::drawing::FillStyle_BITMAP, fillStyle);
+ css::drawing::BitmapMode bitmapmode;
+ xShapeProps->getPropertyValue("FillBitmapMode") >>= bitmapmode;
+ CPPUNIT_ASSERT_EQUAL(css::drawing::BitmapMode_STRETCH, bitmapmode);
+}
+
+void SdImportTest::testTdf127964()
+{
+ sd::DrawDocShellRef xDocShRef
+ = loadURL(m_directories.getURLFromSrc("sd/qa/unit/data/pptx/tdf127964.pptx"), PPTX);
+ const SdrPage* pPage = GetPage(1, xDocShRef);
+ const SdrObject* pObj = pPage->GetObj(0);
+ auto& rFillStyleItem
+ = dynamic_cast<const XFillStyleItem&>(pObj->GetMergedItem(XATTR_FILLSTYLE));
+ CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_SOLID, rFillStyleItem.GetValue());
+
+ auto& rFillColorItem
+ = dynamic_cast<const XFillColorItem&>(pObj->GetMergedItem(XATTR_FILLCOLOR));
+ // Without the accompanying fix in place, this test would have failed with:
+ // - Expected: 4294967295
+ // - Actual : 5210557
+ // i.e. instead of transparent (which then got rendered as white), the shape fill color was
+ // blue.
+ CPPUNIT_ASSERT_EQUAL(COL_TRANSPARENT, rFillColorItem.GetColorValue());
+ xDocShRef->DoClose();
+}
+
+void SdImportTest::testTdf106638()
+{
+ sd::DrawDocShellRef xDocShRef
+ = loadURL(m_directories.getURLFromSrc("sd/qa/unit/data/pptx/tdf106638.pptx"), PPTX);
+ uno::Reference<beans::XPropertySet> xShape(getShapeFromPage(0, 0, xDocShRef));
+ uno::Reference<text::XTextRange> const xPara(getParagraphFromShape(1, xShape));
+ uno::Reference<text::XText> xText= xPara->getText();
+ uno::Reference<text::XTextCursor> xTextCursor = xText->createTextCursorByRange(xPara->getStart());
+ uno::Reference<beans::XPropertySet> xPropSet(xTextCursor, uno::UNO_QUERY_THROW );
+ OUString aCharFontName;
+ CPPUNIT_ASSERT(xTextCursor->goRight(1, true));
+ // First character U+f0fe that uses Wingding
+ xPropSet->getPropertyValue("CharFontName") >>= aCharFontName;
+ CPPUNIT_ASSERT_EQUAL(OUString("Wingdings"), aCharFontName);
+
+ // The rest characters that do not use Wingding.
+ CPPUNIT_ASSERT(xTextCursor->goRight(45, true));
+ xPropSet->getPropertyValue("CharFontName") >>= aCharFontName;
+ CPPUNIT_ASSERT(aCharFontName != "Wingdings");
+}
+
+void SdImportTest::testTdf128684()
+{
+ sd::DrawDocShellRef xDocShRef
+ = loadURL(m_directories.getURLFromSrc("/sd/qa/unit/data/pptx/tdf128684.pptx"), PPTX);
+ uno::Reference<drawing::XDrawPagesSupplier> xDoc(xDocShRef->GetDoc()->getUnoModel(),
+ uno::UNO_QUERY);
+ CPPUNIT_ASSERT(xDoc.is());
+ uno::Reference<drawing::XDrawPage> xPage(xDoc->getDrawPages()->getByIndex(0), uno::UNO_QUERY);
+ CPPUNIT_ASSERT(xPage.is());
+ uno::Reference<beans::XPropertySet> xShape(getShape(0, xPage));
+ CPPUNIT_ASSERT(xShape.is());
+ uno::Any aAny = xShape->getPropertyValue("CustomShapeGeometry");
+ CPPUNIT_ASSERT(aAny.hasValue());
+ uno::Sequence<beans::PropertyValue> aProps;
+ CPPUNIT_ASSERT(aAny >>= aProps);
+ sal_Int32 nRotateAngle = 0;
+ for( const auto& rProp : std::as_const(aProps) )
+ {
+ if( rProp.Name == "TextPreRotateAngle")
+ {
+ rProp.Value >>= nRotateAngle;
+ }
+ }
+ CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(-90), nRotateAngle);
+}
+
+void SdImportTest::testTdf113198()
+{
+ sd::DrawDocShellRef xDocShRef
+ = loadURL(m_directories.getURLFromSrc("sd/qa/unit/data/pptx/tdf113198.pptx"), PPTX);
+
+ uno::Reference<beans::XPropertySet> xShape(getShapeFromPage(0, 0, xDocShRef));
+ sal_Int16 nParaAdjust = -1;
+ xShape->getPropertyValue("ParaAdjust") >>= nParaAdjust;
+ CPPUNIT_ASSERT_EQUAL(style::ParagraphAdjust_CENTER, static_cast<style::ParagraphAdjust>(nParaAdjust));
+}
+
+void SdImportTest::testTdf119187()
+{
+ std::vector< sd::DrawDocShellRef > xDocShRef;
+ // load document
+ xDocShRef.push_back(loadURL(m_directories.getURLFromSrc("sd/qa/unit/data/pptx/tdf119187.pptx"), PPTX));
+ // load resaved document
+ xDocShRef.push_back(saveAndReload( xDocShRef.at(0).get(), PPTX ));
+
+ // check documents
+ for (const sd::DrawDocShellRef& xDoc : xDocShRef)
+ {
+ // get shape properties
+ const SdrPage* pPage = GetPage(1, xDoc);
+ CPPUNIT_ASSERT(pPage);
+ SdrObject* pObj = pPage->GetObj(0);
+ CPPUNIT_ASSERT(pObj);
+ const sdr::properties::BaseProperties & rProperties = pObj->GetProperties();
+
+ // check text vertical alignment
+ const SdrTextVertAdjustItem& rSdrTextVertAdjustItem = rProperties.GetItem(SDRATTR_TEXT_VERTADJUST);
+ const SdrTextVertAdjust eTVA = rSdrTextVertAdjustItem.GetValue();
+ CPPUNIT_ASSERT_EQUAL(SDRTEXTVERTADJUST_TOP, eTVA);
+ }
+}
+
+void SdImportTest::testShapeGlowEffectPPTXImpoer()
+{
+ sd::DrawDocShellRef xDocShRef
+ = loadURL(m_directories.getURLFromSrc("sd/qa/unit/data/pptx/shape-glow-effect.pptx"), PPTX);
+
+ uno::Reference<beans::XPropertySet> xShape(getShapeFromPage(0, 0, xDocShRef));
+ sal_Int32 nRadius = -1;
+ xShape->getPropertyValue("GlowEffectRadius") >>= nRadius;
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(388), nRadius); // 139700 EMU = 388.0556 mm/100
+ Color nColor;
+ xShape->getPropertyValue("GlowEffectColor") >>= nColor;
+ CPPUNIT_ASSERT_EQUAL(Color(0xFFC000), nColor);
+ sal_Int16 nTransparency;
+ xShape->getPropertyValue("GlowEffectTransparency") >>= nTransparency;
+ CPPUNIT_ASSERT_EQUAL(sal_Int16(60), nTransparency);
+}
+
+CPPUNIT_TEST_SUITE_REGISTRATION(SdImportTest);
+
+CPPUNIT_PLUGIN_IMPLEMENT();
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */