Rebased ref, commits from common ancestor:
commit 6a455227f23378728abb2ff7adb37d825b8a45b1
Author:     Sarper Akdemir <sarper.akde...@collabora.com>
AuthorDate: Wed Jun 9 08:24:12 2021 +0300
Commit:     Sarper Akdemir <sarper.akde...@collabora.com>
CommitDate: Thu Jun 10 17:02:15 2021 +0300

    pptx export: slide footers roundtrip unit test
    
    Change-Id: I9c4b819092ac6699617d71538c35b066d6e6f974

diff --git a/sd/qa/unit/data/pptx/tdf59323.pptx 
b/sd/qa/unit/data/pptx/tdf59323.pptx
new file mode 100755
index 000000000000..0660c0af4f23
Binary files /dev/null and b/sd/qa/unit/data/pptx/tdf59323.pptx differ
diff --git a/sd/qa/unit/export-tests-ooxml2.cxx 
b/sd/qa/unit/export-tests-ooxml2.cxx
index 432bd79d1993..2822262cecd0 100644
--- a/sd/qa/unit/export-tests-ooxml2.cxx
+++ b/sd/qa/unit/export-tests-ooxml2.cxx
@@ -211,6 +211,7 @@ public:
     void testTdf128213ShapeRot();
     void testTdf125560_textDeflate();
     void testTdf125560_textInflateTop();
+    void testTdf59323_slideFooters();
 
     CPPUNIT_TEST_SUITE(SdOOXMLExportTest2);
 
@@ -336,6 +337,7 @@ public:
     CPPUNIT_TEST(testTdf128213ShapeRot);
     CPPUNIT_TEST(testTdf125560_textDeflate);
     CPPUNIT_TEST(testTdf125560_textInflateTop);
+    CPPUNIT_TEST(testTdf59323_slideFooters);
 
     CPPUNIT_TEST_SUITE_END();
 
@@ -3160,6 +3162,41 @@ void SdOOXMLExportTest2::testTdf125560_textInflateTop()
     assertXPath(pXmlDocRels, 
"/office:document-content/office:body/office:presentation/draw:page/draw:custom-shape/draw:enhanced-geometry",
 "type", "mso-spt164");
 }
 
+void SdOOXMLExportTest2::testTdf59323_slideFooters()
+{
+    ::sd::DrawDocShellRef xDocShRef
+        = 
loadURL(m_directories.getURLFromSrc(u"/sd/qa/unit/data/pptx/tdf59323.pptx"), 
PPTX);
+
+    utl::TempFile tempFile;
+    xDocShRef = saveAndReload(xDocShRef.get(), PPTX, &tempFile);
+
+    uno::Reference<drawing::XDrawPagesSupplier> 
xDoc(xDocShRef->GetDoc()->getUnoModel(),
+                                                     uno::UNO_QUERY_THROW);
+    CPPUNIT_ASSERT_EQUAL(sal_Int32(3), xDoc->getDrawPages()->getCount());
+
+    for (int nPageIndex = 0; nPageIndex < 3; nPageIndex++)
+    {
+        uno::Reference<drawing::XDrawPage> xPage(getPage(0, xDocShRef));
+        uno::Reference<beans::XPropertySet> xPropSet(xPage, uno::UNO_QUERY);
+        CPPUNIT_ASSERT(xPropSet->getPropertyValue("IsFooterVisible") == true);
+        CPPUNIT_ASSERT(xPropSet->getPropertyValue("IsDateTimeVisible") == 
true);
+        CPPUNIT_ASSERT(xPropSet->getPropertyValue("IsPageNumberVisible") == 
true);
+    }
+
+    // Test placeholder indexes
+    xmlDocUniquePtr pXmlDocMaster = parseExport(tempFile, 
"ppt/slideMasters/slideMaster1.xml");
+    assertXPath(pXmlDocMaster, "//p:ph [@type='dt']", "idx", "2");
+    assertXPath(pXmlDocMaster, "//p:ph [@type='ftr']", "idx", "3");
+    assertXPath(pXmlDocMaster, "//p:ph [@type='sldNum']", "idx", "4");
+
+    xmlDocUniquePtr pXmlDocSlide1 = parseExport(tempFile, 
"ppt/slides/slide1.xml");
+    assertXPath(pXmlDocSlide1, "//p:ph [@type='dt']", "idx", "2");
+    assertXPath(pXmlDocSlide1, "//p:ph [@type='ftr']", "idx", "3");
+    assertXPath(pXmlDocSlide1, "//p:ph [@type='sldNum']", "idx", "4");
+
+    xDocShRef->DoClose();
+}
+
 CPPUNIT_TEST_SUITE_REGISTRATION(SdOOXMLExportTest2);
 
 CPPUNIT_PLUGIN_IMPLEMENT();
commit 35de4bc6649fc5258a1f0f12076983464bf51f82
Author:     Sarper Akdemir <sarper.akde...@collabora.com>
AuthorDate: Wed Jun 9 08:21:27 2021 +0300
Commit:     Sarper Akdemir <sarper.akde...@collabora.com>
CommitDate: Thu Jun 10 17:02:14 2021 +0300

    pptx export: add support for slide footers
    
    Change-Id: I8bfde520b0aec66405523c719844e69c6fc15b79

diff --git a/sd/source/filter/eppt/epptooxml.hxx 
b/sd/source/filter/eppt/epptooxml.hxx
index 405c5b841ae9..d33db57a92a8 100644
--- a/sd/source/filter/eppt/epptooxml.hxx
+++ b/sd/source/filter/eppt/epptooxml.hxx
@@ -122,6 +122,9 @@ private:
         @returns Placeholder index
     */
     unsigned CreateNewPlaceholderIndex(const 
css::uno::Reference<css::drawing::XShape>& rXShape);
+    css::uno::Reference<css::drawing::XShape> 
GetReferencedPlaceholderXShape(const PlaceholderType eType, PageType ePageType) 
const;
+    void WritePlaceholderReferenceShapes(PowerPointShapeExport& rDML, PageType 
ePageType);
+
     /// Should we export as .pptm, ie. do we contain macros?
     bool mbPptm;
 
diff --git a/sd/source/filter/eppt/pptx-epptooxml.cxx 
b/sd/source/filter/eppt/pptx-epptooxml.cxx
index db673d754eac..0245a20bbc3e 100644
--- a/sd/source/filter/eppt/pptx-epptooxml.cxx
+++ b/sd/source/filter/eppt/pptx-epptooxml.cxx
@@ -28,6 +28,7 @@
 
 #include <comphelper/sequenceashashmap.hxx>
 #include <comphelper/storagehelper.hxx>
+#include <comphelper/xmltools.hxx>
 #include <sax/fshelper.hxx>
 #include <rtl/ustrbuf.hxx>
 #include <sal/log.hxx>
@@ -53,6 +54,10 @@
 #include "pptx-animations.hxx"
 #include "../ppt/pptanimations.hxx"
 
+#include <svx/svdpage.hxx>
+#include <svx/unoapi.hxx>
+#include <sdpage.hxx>
+
 #include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
 #include <com/sun/star/document/XStorageBasedDocument.hpp>
 #include <utility>
@@ -107,7 +112,11 @@ public:
     ShapeExport&        WriteTextShape(const Reference< XShape >& xShape) 
override;
     ShapeExport&        WriteUnknownShape(const Reference< XShape >& xShape) 
override;
     ShapeExport&        WritePlaceholderShape(const Reference< XShape >& 
xShape, PlaceholderType ePlaceholder);
+    /** Writes a placeholder shape that references the placeholder on the 
master slide */
+    ShapeExport&        WritePlaceholderReferenceShape(PlaceholderType 
ePlaceholder, unsigned nReferencedPlaceholderIdx, PageType ePageType, 
Reference<XPropertySet>& rXPagePropSet);
     ShapeExport&        WritePageShape(const Reference< XShape >& xShape, 
PageType ePageType, bool bPresObj);
+    /** Writes textbody of a placeholder that references the placeholder on 
the master slide */
+    ShapeExport&        WritePlaceholderReferenceTextBody(PlaceholderType 
ePlaceholder, PageType ePageType, const Reference<XPropertySet> xPagePropSet);
 
     // helper parts
     bool WritePlaceholder(const Reference< XShape >& xShape, PlaceholderType 
ePlaceholder, bool bMaster);
@@ -1453,6 +1462,8 @@ void PowerPointExport::WriteShapeTree(const FSHelperPtr& 
pFS, PageType ePageType
         }
     }
 
+    if ( ePageType == NORMAL || ePageType == LAYOUT )
+        WritePlaceholderReferenceShapes(aDML, ePageType);
     pFS->endElementNS(XML_p, XML_spTree);
 }
 
@@ -1518,13 +1529,135 @@ ShapeExport& 
PowerPointShapeExport::WritePlaceholderShape(const Reference< XShap
         WriteBlipFill(xProps, "Graphic");
     mpFS->endElementNS(XML_p, XML_spPr);
 
-    WriteTextBox(xShape, XML_p);
+    WriteTextBox(xShape, XML_p, bUsePlaceholderIndex);
+
+    mpFS->endElementNS(XML_p, XML_sp);
+
+    return *this;
+}
+
+ShapeExport& PowerPointShapeExport::WritePlaceholderReferenceShape(
+    PlaceholderType ePlaceholder, unsigned nReferencedPlaceholderIdx, PageType 
ePageType,
+    Reference<XPropertySet>& rXPagePropSet)
+{
+    mpFS->startElementNS(XML_p, XML_sp);
+
+    // non visual shape properties
+    mpFS->startElementNS(XML_p, XML_nvSpPr);
+    const OString aPlaceholderID("PlaceHolder " + 
OString::number(mnShapeIdMax++));
+    GetFS()->singleElementNS(XML_p, XML_cNvPr, XML_id, 
OString::number(mnShapeIdMax), XML_name,
+                             aPlaceholderID.getStr());
+
+    mpFS->startElementNS(XML_p, XML_cNvSpPr);
+    mpFS->singleElementNS(XML_a, XML_spLocks, XML_noGrp, "1");
+    mpFS->endElementNS(XML_p, XML_cNvSpPr);
+    mpFS->startElementNS(XML_p, XML_nvPr);
+
+    const char* pType = getPlaceholderTypeName(ePlaceholder);
+    mpFS->singleElementNS(XML_p, XML_ph, XML_type, pType, XML_idx,
+                          OString::number(nReferencedPlaceholderIdx));
+    mpFS->endElementNS(XML_p, XML_nvPr);
+    mpFS->endElementNS(XML_p, XML_nvSpPr);
+
+    // visual shape properties
+    mpFS->startElementNS(XML_p, XML_spPr);
+    mpFS->endElementNS(XML_p, XML_spPr);
+
+    WritePlaceholderReferenceTextBody(ePlaceholder, ePageType, rXPagePropSet);
 
     mpFS->endElementNS(XML_p, XML_sp);
 
     return *this;
 }
 
+ShapeExport& PowerPointShapeExport::WritePlaceholderReferenceTextBody(
+    PlaceholderType ePlaceholder, PageType ePageType, const 
Reference<XPropertySet> xPagePropSet)
+{
+    mpFS->startElementNS(XML_p, XML_txBody);
+    mpFS->singleElementNS(XML_a, XML_bodyPr);
+    mpFS->startElementNS(XML_a, XML_p);
+
+    switch (ePlaceholder)
+    {
+        case Header:
+            break;
+        case Footer:
+        {
+            OUString aFooterText;
+            if (ePageType == LAYOUT)
+            {
+                aFooterText = "Footer";
+            }
+            else
+            {
+                xPagePropSet->getPropertyValue("FooterText") >>= aFooterText;
+            }
+            mpFS->startElementNS(XML_a, XML_r);
+            mpFS->startElementNS(XML_a, XML_t);
+            mpFS->writeEscaped(aFooterText);
+            mpFS->endElementNS(XML_a, XML_t);
+            mpFS->endElementNS(XML_a, XML_r);
+            break;
+        }
+        case SlideNumber:
+        {
+            OUString aSlideNum;
+            int nSlideNum = 0;
+            if (ePageType == LAYOUT)
+            {
+                aSlideNum = "<#>";
+            }
+            else
+            {
+                xPagePropSet->getPropertyValue("Number") >>= nSlideNum;
+                aSlideNum = OUString::number(nSlideNum);
+            }
+            OString aUUID(comphelper::xml::generateGUIDString());
+            mpFS->startElementNS(XML_a, XML_fld, XML_id, aUUID.getStr(), 
XML_type, "slidenum");
+            mpFS->startElementNS(XML_a, XML_t);
+            mpFS->writeEscaped(aSlideNum);
+            mpFS->endElementNS(XML_a, XML_t);
+            mpFS->endElementNS(XML_a, XML_fld);
+            break;
+        }
+        case DateAndTime:
+        {
+            OString aDateTimeType = "datetime1";
+            OUString aDateTimeText;
+            int nDateTimeFormat;
+            if (ePageType == LAYOUT)
+            {
+                aDateTimeText = "Date";
+            }
+            else
+            {
+                xPagePropSet->getPropertyValue("DateTimeText") >>= 
aDateTimeText;
+                xPagePropSet->getPropertyValue("DateTimeFormat") >>= 
nDateTimeFormat;
+
+                // 4 LSBs represent the date
+                SvxDateFormat eDate = 
static_cast<SvxDateFormat>(nDateTimeFormat & 0x0f);
+                // the 4 bits after the date bits represent the time
+                SvxTimeFormat eTime = 
static_cast<SvxTimeFormat>(nDateTimeFormat >> 4);
+                aDateTimeType = 
OUStringToOString(GetDatetimeTypeFromDateTime(eDate, eTime),
+                                                  RTL_TEXTENCODING_UTF8);
+                if (aDateTimeType.equals("datetime"))
+                    aDateTimeType = "datetime1";
+            }
+            OString aUUID(comphelper::xml::generateGUIDString());
+            mpFS->startElementNS(XML_a, XML_fld, XML_id, aUUID.getStr(), 
XML_type, aDateTimeType);
+            mpFS->endElementNS(XML_a, XML_fld);
+            break;
+        }
+        default:
+            SAL_INFO("sd.eppt", "warning: no defined textbody for referenced 
placeholder type: "
+                                    << ePlaceholder);
+    }
+    mpFS->endElementNS(XML_a, XML_p);
+    mpFS->endElementNS(XML_p, XML_txBody);
+
+    return *this;
+}
+
 #define SYS_COLOR_SCHEMES "      <a:dk1>\
         <a:sysClr val=\"windowText\" lastClr=\"000000\"/>\
       </a:dk1>\
@@ -2033,12 +2166,106 @@ void PowerPointExport::WriteDiagram(const FSHelperPtr& 
pFS, PowerPointShapeExpor
     pFS->endElementNS(XML_p, XML_graphicFrame);
 }
 
+void PowerPointExport::WritePlaceholderReferenceShapes(PowerPointShapeExport& 
rDML, PageType ePageType)
+{
+    bool bCheckProps = ePageType == NORMAL;
+    Reference<XShape> xShape;
+    Any aAny;
+    OUString aText;
+    if (ePageType == LAYOUT
+        || (bCheckProps && PropValue::GetPropertyValue(aAny, mXPagePropSet, 
"IsFooterVisible", true)
+            && aAny == true && GetPropertyValue(aAny, mXPagePropSet, 
"FooterText", true)
+            && (aAny >>= aText) && !aText.isEmpty()))
+    {
+        if ((xShape = GetReferencedPlaceholderXShape(Footer, ePageType)))
+            rDML.WritePlaceholderReferenceShape(Footer,
+                                                
maPlaceholderShapeToIndexMap.find(xShape)->second,
+                                                ePageType, mXPagePropSet);
+    }
+
+    if (ePageType == LAYOUT
+        || (bCheckProps
+            && PropValue::GetPropertyValue(aAny, mXPagePropSet, 
"IsPageNumberVisible", true)
+            && aAny == true))
+    {
+        if ((xShape = GetReferencedPlaceholderXShape(SlideNumber, ePageType)))
+            rDML.WritePlaceholderReferenceShape(SlideNumber,
+                                                
maPlaceholderShapeToIndexMap.find(xShape)->second,
+                                                ePageType, mXPagePropSet);
+    }
+
+    if (ePageType == LAYOUT
+        || (bCheckProps
+            && PropValue::GetPropertyValue(aAny, mXPagePropSet, 
"IsDateTimeVisible", true)
+            && aAny == true
+            && ((GetPropertyValue(aAny, mXPagePropSet, "DateTimeText", true) 
&& (aAny >>= aText)
+                 && !aText.isEmpty())
+                || mXPagePropSet->getPropertyValue("IsDateTimeFixed") == 
false)))
+    {
+        if ((xShape = GetReferencedPlaceholderXShape(DateAndTime, ePageType)))
+            rDML.WritePlaceholderReferenceShape(DateAndTime,
+                                                
maPlaceholderShapeToIndexMap.find(xShape)->second,
+                                                ePageType, mXPagePropSet);
+    }
+}
+
 unsigned PowerPointExport::CreateNewPlaceholderIndex(const 
css::uno::Reference<XShape> &rXShape)
 {
     maPlaceholderShapeToIndexMap.insert({rXShape, ++mnPlaceholderIndexMax});
     return mnPlaceholderIndexMax;
 }
 
+Reference<XShape> PowerPointExport::GetReferencedPlaceholderXShape(const 
PlaceholderType eType,
+                                                        PageType ePageType) 
const
+{
+    PresObjKind ePresObjKind = PresObjKind::NONE;
+    switch (eType)
+    {
+        case oox::core::None:
+            break;
+        case oox::core::SlideImage:
+            break;
+        case oox::core::Notes:
+            break;
+        case oox::core::Header:
+            ePresObjKind = PresObjKind::Header;
+            break;
+        case oox::core::Footer:
+            ePresObjKind = PresObjKind::Footer;
+            break;
+        case oox::core::SlideNumber:
+            ePresObjKind = PresObjKind::SlideNumber;
+            break;
+        case oox::core::DateAndTime:
+            ePresObjKind = PresObjKind::DateTime;
+            break;
+        case oox::core::Outliner:
+            break;
+        case oox::core::Title:
+            ePresObjKind = PresObjKind::Title;
+            break;
+        case oox::core::Subtitle:
+            break;
+    }
+    if (ePresObjKind != PresObjKind::NONE)
+    {
+        SdPage* pMasterPage;
+        if (ePageType == LAYOUT)
+        {
+            // since Layout pages do not have drawpages themselves - 
mXDrawPage is still the master they reference to..
+            pMasterPage = SdPage::getImplementation(mXDrawPage);
+        }
+        else
+        {
+            pMasterPage
+                = 
&static_cast<SdPage&>(SdPage::getImplementation(mXDrawPage)->TRG_GetMasterPage());
+        }
+        if (SdrObject* pMasterFooter = pMasterPage->GetPresObj(ePresObjKind))
+            return GetXShapeForSdrObject(pMasterFooter);
+    }
+    return nullptr;
+}
+
 // UNO component
 extern "C" SAL_DLLPUBLIC_EXPORT uno::XInterface*
 css_comp_Impress_oox_PowerPointExport(uno::XComponentContext* rxCtxt,
commit f9d37aa4dbe120099eb105f777027b3baf7d1f1c
Author:     Sarper Akdemir <sarper.akde...@collabora.com>
AuthorDate: Wed Jun 9 07:58:44 2021 +0300
Commit:     Sarper Akdemir <sarper.akde...@collabora.com>
CommitDate: Thu Jun 10 17:02:14 2021 +0300

    pptx export: add initial support for lstStyles in textboxes
    
    Change-Id: Ie0cfc9b9f221093db3a1111ca29140a6dfb5e8ad

diff --git a/include/oox/export/drawingml.hxx b/include/oox/export/drawingml.hxx
index ae4e8126a3e5..547075149d37 100644
--- a/include/oox/export/drawingml.hxx
+++ b/include/oox/export/drawingml.hxx
@@ -276,10 +276,19 @@ public:
     void WriteTransformation(const tools::Rectangle& rRectangle,
                   sal_Int32 nXmlNamespace, bool bFlipH = false, bool bFlipV = 
false, sal_Int32 nRotation = 0, bool bIsGroupShape = false);
 
-    void WriteText( const css::uno::Reference< css::uno::XInterface >& 
rXIface, bool bBodyPr, bool bText = true, sal_Int32 nXmlNamespace = 0);
+    void WriteText( const css::uno::Reference< css::uno::XInterface >& 
rXIface, bool bBodyPr, bool bText = true, sal_Int32 nXmlNamespace = 0, bool 
bWritePropertiesAsLstStyles = false);
+
+    /** Populates the lstStyle with the shape's text run and paragraph 
properties */
+    void WriteLstStyles(const css::uno::Reference<css::text::XTextContent>& 
rParagraph,
+                       bool& rbOverridingCharHeight, sal_Int32& rnCharHeight,
+                       const css::uno::Reference<css::beans::XPropertySet>& 
rXShapePropSet);
     void WriteParagraph( const css::uno::Reference< css::text::XTextContent >& 
rParagraph,
                          bool& rbOverridingCharHeight, sal_Int32& 
rnCharHeight, const css::uno::Reference< css::beans::XPropertySet >& 
rXShapePropSet);
-    void WriteParagraphProperties(const css::uno::Reference< 
css::text::XTextContent >& rParagraph, float fFirstCharHeight);
+    /** Writes paragraph properties
+
+        @returns true if there was paragraph properties written false otherwise
+    */
+    bool WriteParagraphProperties(const css::uno::Reference< 
css::text::XTextContent >& rParagraph, float fFirstCharHeight, const sal_Int32 
nElement = XML_pPr );
     void WriteParagraphNumbering(const css::uno::Reference< 
css::beans::XPropertySet >& rXPropSet, float fFirstCharHeight,
                                   sal_Int16 nLevel );
     void WriteParagraphTabStops(const 
css::uno::Reference<css::beans::XPropertySet>& rXPropSet);
diff --git a/include/oox/export/shapes.hxx b/include/oox/export/shapes.hxx
index 6ac3aa754cc5..3e9bf364d400 100644
--- a/include/oox/export/shapes.hxx
+++ b/include/oox/export/shapes.hxx
@@ -179,7 +179,7 @@ public:
      * @return   <tt>*this</tt>
      */
     ShapeExport&       WriteShape( const css::uno::Reference< 
css::drawing::XShape >& xShape );
-    ShapeExport&       WriteTextBox( const css::uno::Reference< 
css::uno::XInterface >& xIface, sal_Int32 nXmlNamespace );
+    ShapeExport&       WriteTextBox( const css::uno::Reference< 
css::uno::XInterface >& xIface, sal_Int32 nXmlNamespace, bool 
bWritePropertiesAsLstStyles = false );
     virtual ShapeExport&
                         WriteTextShape( const css::uno::Reference< 
css::drawing::XShape >& xShape );
     ShapeExport&
diff --git a/oox/source/export/drawingml.cxx b/oox/source/export/drawingml.cxx
index e85686906262..3ae2ac51596b 100644
--- a/oox/source/export/drawingml.cxx
+++ b/oox/source/export/drawingml.cxx
@@ -1852,7 +1852,7 @@ void DrawingML::WriteRunProperties( const Reference< 
XPropertySet >& rRun, bool
     else if (GetProperty(rXPropSet, "CharHeight"))
     {
         nSize = static_cast<sal_Int32>(100*(*o3tl::doAccess<float>(mAny)));
-        if ( nElement == XML_rPr )
+        if ( nElement == XML_rPr || nElement == XML_defRPr )
         {
             rbOverridingCharHeight = true;
             rnCharHeight = nSize;
@@ -2756,14 +2756,14 @@ void DrawingML::WriteLinespacing( const LineSpacing& 
rSpacing )
     }
 }
 
-void DrawingML::WriteParagraphProperties( const Reference< XTextContent >& 
rParagraph, float fFirstCharHeight)
+bool DrawingML::WriteParagraphProperties( const Reference< XTextContent >& 
rParagraph, float fFirstCharHeight, sal_Int32 nElement)
 {
     Reference< XPropertySet > rXPropSet( rParagraph, UNO_QUERY );
     Reference< XPropertyState > rXPropState( rParagraph, UNO_QUERY );
     PropertyState eState;
 
     if( !rXPropSet.is() || !rXPropState.is() )
-        return;
+        return false;
 
     sal_Int16 nLevel = -1;
     if (GetProperty(rXPropSet, "NumberingLevel"))
@@ -2812,17 +2812,17 @@ void DrawingML::WriteParagraphProperties( const 
Reference< XTextContent >& rPara
     if( !(nLevel != -1
         || nAlignment != style::ParagraphAdjust_LEFT
         || bHasLinespacing) )
-        return;
+        return false;
 
     if (nParaLeftMargin) // For Paragraph
-        mpFS->startElementNS( XML_a, XML_pPr,
+        mpFS->startElementNS( XML_a, nElement,
                            XML_lvl, 
sax_fastparser::UseIf(OString::number(nLevel), nLevel > 0),
                            XML_marL, 
sax_fastparser::UseIf(OString::number(oox::drawingml::convertHmmToEmu(nParaLeftMargin)),
 nParaLeftMargin > 0),
                            XML_indent, 
sax_fastparser::UseIf(OString::number(oox::drawingml::convertHmmToEmu(nParaFirstLineIndent)),
 nParaFirstLineIndent != 0),
                            XML_algn, GetAlignment( nAlignment ),
                            XML_rtl, sax_fastparser::UseIf(ToPsz10(bRtl), 
bRtl));
     else
-        mpFS->startElementNS( XML_a, XML_pPr,
+        mpFS->startElementNS( XML_a, nElement,
                            XML_lvl, 
sax_fastparser::UseIf(OString::number(nLevel), nLevel > 0),
                            XML_marL, 
sax_fastparser::UseIf(OString::number(oox::drawingml::convertHmmToEmu(nLeftMargin)),
 nLeftMargin > 0),
                            XML_indent, 
sax_fastparser::UseIf(OString::number(oox::drawingml::convertHmmToEmu(nLineIndentation)),
 nLineIndentation != 0),
@@ -2861,7 +2861,49 @@ void DrawingML::WriteParagraphProperties( const 
Reference< XTextContent >& rPara
 
     WriteParagraphTabStops( rXPropSet );
 
-    mpFS->endElementNS( XML_a, XML_pPr );
+    if( nElement == XML_pPr)
+        mpFS->endElementNS( XML_a, nElement );
+
+    return true;
+}
+
+void DrawingML::WriteLstStyles(const 
css::uno::Reference<css::text::XTextContent>& rParagraph,
+                               bool& rbOverridingCharHeight, sal_Int32& 
rnCharHeight,
+                               const 
css::uno::Reference<css::beans::XPropertySet>& rXShapePropSet)
+{
+    Reference<XEnumerationAccess> access(rParagraph, UNO_QUERY);
+    if (!access.is())
+        return;
+
+    Reference<XEnumeration> enumeration(access->createEnumeration());
+    if (!enumeration.is())
+        return;
+
+
+    Reference<XTextRange> rRun;
+
+    if (enumeration->hasMoreElements())
+    {
+        Any aAny(enumeration->nextElement());
+        if (aAny >>= rRun)
+        {
+            float fFirstCharHeight = rnCharHeight / 1000.;
+            Reference<XPropertySet> xFirstRunPropSet(rRun, UNO_QUERY);
+            Reference<XPropertySetInfo> xFirstRunPropSetInfo
+                = xFirstRunPropSet->getPropertySetInfo();
+
+            if (xFirstRunPropSetInfo->hasPropertyByName("CharHeight"))
+                fFirstCharHeight = 
xFirstRunPropSet->getPropertyValue("CharHeight").get<float>();
+
+            mpFS->startElementNS(XML_a, XML_lstStyle);
+            if( !WriteParagraphProperties(rParagraph, fFirstCharHeight, 
XML_lvl1pPr) )
+                mpFS->startElementNS(XML_a, XML_lvl1pPr);
+            WriteRunProperties(xFirstRunPropSet, false, XML_defRPr, true, 
rbOverridingCharHeight,
+                               rnCharHeight, GetScriptType(rRun->getString()), 
rXShapePropSet);
+            mpFS->endElementNS(XML_a, XML_lvl1pPr);
+            mpFS->endElementNS(XML_a, XML_lstStyle);
+        }
+    }
 }
 
 void DrawingML::WriteParagraph( const Reference< XTextContent >& rParagraph,
@@ -2939,7 +2981,7 @@ bool DrawingML::IsFontworkShape(const 
css::uno::Reference<css::beans::XPropertyS
 }
 
 void DrawingML::WriteText(const Reference<XInterface>& rXIface, bool bBodyPr, 
bool bText,
-                           sal_Int32 nXmlNamespace)
+                          sal_Int32 nXmlNamespace, bool 
bWritePropertiesAsLstStyles)
 {
     // ToDo: Fontwork in DOCX
     Reference< XText > xXText( rXIface, UNO_QUERY );
@@ -3352,6 +3394,7 @@ void DrawingML::WriteText(const Reference<XInterface>& 
rXIface, bool bBodyPr, bo
 
     bool bOverridingCharHeight = false;
     sal_Int32 nCharHeight = -1;
+    bool bFirstParagraph = true;
 
     while( enumeration->hasMoreElements() )
     {
@@ -3359,7 +3402,13 @@ void DrawingML::WriteText(const Reference<XInterface>& 
rXIface, bool bBodyPr, bo
         Any any ( enumeration->nextElement() );
 
         if( any >>= paragraph)
-            WriteParagraph( paragraph, bOverridingCharHeight, nCharHeight, 
rXPropSet );
+        {
+            if (bFirstParagraph && bWritePropertiesAsLstStyles)
+                WriteLstStyles(paragraph, bOverridingCharHeight, nCharHeight, 
rXPropSet);
+
+            WriteParagraph(paragraph, bOverridingCharHeight, nCharHeight, 
rXPropSet);
+            bFirstParagraph = false;
+        }
     }
 }
 
diff --git a/oox/source/export/shapes.cxx b/oox/source/export/shapes.cxx
index 0f9e13fbb6e4..26f4a94b5790 100644
--- a/oox/source/export/shapes.cxx
+++ b/oox/source/export/shapes.cxx
@@ -1550,7 +1550,7 @@ ShapeExport& ShapeExport::WriteShape( const Reference< 
XShape >& xShape )
     return *this;
 }
 
-ShapeExport& ShapeExport::WriteTextBox( const Reference< XInterface >& xIface, 
sal_Int32 nXmlNamespace )
+ShapeExport& ShapeExport::WriteTextBox( const Reference< XInterface >& xIface, 
sal_Int32 nXmlNamespace, bool bWritePropertiesAsLstStyles)
 {
     // In case this shape has an associated textbox, then export that, and 
we're done.
     if (GetDocumentType() == DOCUMENT_DOCX && GetTextExport())
@@ -1575,7 +1575,7 @@ ShapeExport& ShapeExport::WriteTextBox( const Reference< 
XInterface >& xIface, s
 
         pFS->startElementNS(nXmlNamespace,
                             (GetDocumentType() != DOCUMENT_DOCX ? XML_txBody : 
XML_txbx));
-        WriteText( xIface, /*bBodyPr=*/(GetDocumentType() != DOCUMENT_DOCX) );
+        WriteText( xIface, /*bBodyPr=*/(GetDocumentType() != DOCUMENT_DOCX), 
true, 0, bWritePropertiesAsLstStyles );
         pFS->endElementNS( nXmlNamespace, (GetDocumentType() != DOCUMENT_DOCX 
? XML_txBody : XML_txbx) );
         if (GetDocumentType() == DOCUMENT_DOCX)
             WriteText( xIface, /*bBodyPr=*/true, /*bText=*/false, 
/*nXmlNamespace=*/nXmlNamespace );
commit 9fab0f525927ff0c49e9441a2a3c2642d5fe6789
Author:     Sarper Akdemir <sarper.akde...@collabora.com>
AuthorDate: Wed Jun 9 07:54:04 2021 +0300
Commit:     Sarper Akdemir <sarper.akde...@collabora.com>
CommitDate: Thu Jun 10 17:02:14 2021 +0300

    pptx export: add placeholder index to master footer placeholders
    
    Change-Id: If788f235d00b6d1cde7194d9e4a0789e019432c3

diff --git a/sd/source/filter/eppt/epptooxml.hxx 
b/sd/source/filter/eppt/epptooxml.hxx
index 42f9f5817b5c..405c5b841ae9 100644
--- a/sd/source/filter/eppt/epptooxml.hxx
+++ b/sd/source/filter/eppt/epptooxml.hxx
@@ -116,6 +116,12 @@ private:
 
     static void WriteDiagram(const FSHelperPtr& pFS, PowerPointShapeExport& 
rDML, const css::uno::Reference<css::drawing::XShape>& rXShape, int nDiagramId);
 
+    /** Create a new placeholder index for a master placeholder shape
+
+        @param rXShape Master placeholder shape
+        @returns Placeholder index
+    */
+    unsigned CreateNewPlaceholderIndex(const 
css::uno::Reference<css::drawing::XShape>& rXShape);
     /// Should we export as .pptm, ie. do we contain macros?
     bool mbPptm;
 
@@ -138,6 +144,10 @@ private:
 
     ::oox::drawingml::ShapeExport::ShapeHashMap maShapeMap;
 
+    unsigned mnPlaceholderIndexMax; //< Last used placeholder index
+    /// Map of placeholder indexes for Master placeholders
+    std::unordered_map< css::uno::Reference<css::drawing::XShape>, int > 
maPlaceholderShapeToIndexMap;
+
     struct AuthorComments {
         sal_Int32 nId;
         sal_Int32 nLastIndex;
diff --git a/sd/source/filter/eppt/pptx-epptooxml.cxx 
b/sd/source/filter/eppt/pptx-epptooxml.cxx
index 13ec3572b701..db673d754eac 100644
--- a/sd/source/filter/eppt/pptx-epptooxml.cxx
+++ b/sd/source/filter/eppt/pptx-epptooxml.cxx
@@ -126,8 +126,35 @@ void WriteSndAc(const FSHelperPtr& pFS, const OUString& 
sSoundRelId, const OUStr
         pFS->endElement(FSNS(XML_p, XML_stSnd));
         pFS->endElement(FSNS(XML_p, XML_sndAc));
 }
-}
 
+const char* getPlaceholderTypeName(PlaceholderType ePlaceholder)
+{
+    switch (ePlaceholder)
+    {
+        case SlideImage:
+            return "sldImg";
+        case Notes:
+            return "body";
+        case Header:
+            return "hdr";
+        case Footer:
+            return "ftr";
+        case SlideNumber:
+            return "sldNum";
+        case DateAndTime:
+            return "dt";
+        case Outliner:
+            return "body";
+        case Title:
+            return "title";
+        case Subtitle:
+            return "subTitle";
+        default:
+            SAL_INFO("sd.eppt", "warning: unhandled placeholder type: " << 
ePlaceholder);
+            return nullptr;
+    }
+}
+}
 }
 
 namespace {
@@ -336,6 +363,7 @@ PowerPointExport::PowerPointExport(const Reference< 
XComponentContext >& rContex
     , mnAnimationNodeIdMax(1)
     , mnDiagramId(1)
     , mbCreateNotes(false)
+    , mnPlaceholderIndexMax(1)
 {
     comphelper::SequenceAsHashMap aArgumentsMap(rArguments);
     mbPptm = aArgumentsMap.getUnpackedValueOrDefault("IsPPTM", false);
@@ -1462,41 +1490,22 @@ ShapeExport& 
PowerPointShapeExport::WritePlaceholderShape(const Reference< XShap
     mpFS->endElementNS(XML_p, XML_cNvSpPr);
     mpFS->startElementNS(XML_p, XML_nvPr);
 
-    const char* pType = nullptr;
-    switch (ePlaceholder)
+    bool bUsePlaceholderIndex
+        = ePlaceholder == Footer || ePlaceholder == DateAndTime || 
ePlaceholder == SlideNumber;
+    const char* pType = getPlaceholderTypeName(ePlaceholder);
+
+    SAL_INFO("sd.eppt", "write placeholder " << pType);
+    if (bUsePlaceholderIndex)
     {
-    case SlideImage:
-        pType = "sldImg";
-        break;
-    case Notes:
-        pType = "body";
-        break;
-    case Header:
-        pType = "hdr";
-        break;
-    case Footer:
-        pType = "ftr";
-        break;
-    case SlideNumber:
-        pType = "sldNum";
-        break;
-    case DateAndTime:
-        pType = "dt";
-        break;
-    case Outliner:
-        pType = "body";
-        break;
-    case Title:
-        pType = "title";
-        break;
-    case Subtitle:
-        pType = "subTitle";
-        break;
-    default:
-        SAL_INFO("sd.eppt", "warning: unhandled placeholder type: " << 
ePlaceholder);
+        mpFS->singleElementNS(
+            XML_p, XML_ph, XML_type, pType, XML_idx,
+            OString::number(
+                
static_cast<PowerPointExport*>(GetFB())->CreateNewPlaceholderIndex(xShape)));
+    }
+    else
+    {
+        mpFS->singleElementNS(XML_p, XML_ph, XML_type, pType);
     }
-    SAL_INFO("sd.eppt", "write placeholder " << pType);
-    mpFS->singleElementNS(XML_p, XML_ph, XML_type, pType);
     mpFS->endElementNS(XML_p, XML_nvPr);
     mpFS->endElementNS(XML_p, XML_nvSpPr);
 
@@ -2024,6 +2033,12 @@ void PowerPointExport::WriteDiagram(const FSHelperPtr& 
pFS, PowerPointShapeExpor
     pFS->endElementNS(XML_p, XML_graphicFrame);
 }
 
+unsigned PowerPointExport::CreateNewPlaceholderIndex(const 
css::uno::Reference<XShape> &rXShape)
+{
+    maPlaceholderShapeToIndexMap.insert({rXShape, ++mnPlaceholderIndexMax});
+    return mnPlaceholderIndexMax;
+}
+
 // UNO component
 extern "C" SAL_DLLPUBLIC_EXPORT uno::XInterface*
 css_comp_Impress_oox_PowerPointExport(uno::XComponentContext* rxCtxt,
commit a962a8b18d692f6d16550c7415e3a4aa67a8af0b
Author:     Sarper Akdemir <sarper.akde...@collabora.com>
AuthorDate: Wed Jun 9 07:34:32 2021 +0300
Commit:     Sarper Akdemir <sarper.akde...@collabora.com>
CommitDate: Thu Jun 10 17:02:14 2021 +0300

    pptx export: add datetime field type helpers
    
    Change-Id: Ibbfefa18d0422eddb6c37539294ed23e77fe5f22

diff --git a/include/oox/export/drawingml.hxx b/include/oox/export/drawingml.hxx
index cfcad30fa257..ae4e8126a3e5 100644
--- a/include/oox/export/drawingml.hxx
+++ b/include/oox/export/drawingml.hxx
@@ -46,6 +46,8 @@
 
 class Graphic;
 class SdrObjCustomShape;
+enum class SvxDateFormat;
+enum class SvxTimeFormat;
 
 namespace com::sun::star {
 namespace awt {
@@ -166,6 +168,22 @@ protected:
                   const css::uno::Reference< css::beans::XPropertyState >& 
rXPropState,
                   const OUString& aName, css::beans::PropertyState& eState );
     OUString GetFieldValue( const css::uno::Reference< css::text::XTextRange 
>& rRun, bool& bIsURLField );
+    /** Gets OOXML datetime field type from LO Date format
+
+        @param eDate LO Date format
+    */
+    OUString GetDatetimeTypeFromDate(SvxDateFormat eDate);
+    /** Gets OOXML datetime field type from LO Time format
+
+        @param eTime LO Time format
+    */
+    OUString GetDatetimeTypeFromTime(SvxTimeFormat eTime);
+    /** Gets OOXML datetime field type from combination of LO Time and Date 
formats
+
+        @param eDate LO Date format
+        @param eTime LO Time format
+    */
+    OUString GetDatetimeTypeFromDateTime(SvxDateFormat eDate, SvxTimeFormat 
eTime);
 
     /// Output the media (including copying a video from vnd.sun.star.Package: 
to the output if necessary).
     void WriteMediaNonVisualProperties(const 
css::uno::Reference<css::drawing::XShape>& xShape);
diff --git a/oox/source/export/drawingml.cxx b/oox/source/export/drawingml.cxx
index 32780296ce89..e85686906262 100644
--- a/oox/source/export/drawingml.cxx
+++ b/oox/source/export/drawingml.cxx
@@ -2220,40 +2220,13 @@ OUString DrawingML::GetFieldValue( const 
css::uno::Reference< css::text::XTextRa
                 {
                     sal_Int32 nNumFmt = -1;
                     rXPropSet->getPropertyValue(UNO_TC_PROP_NUMFORMAT) >>= 
nNumFmt;
-                    switch(static_cast<SvxDateFormat>(nNumFmt))
-                    {
-                        case SvxDateFormat::StdSmall:
-                        case SvxDateFormat::A: aFieldValue = "datetime"; // 
13/02/96
-                                              break;
-                        case SvxDateFormat::B: aFieldValue = "datetime1"; // 
13/02/1996
-                                              break;
-                        case SvxDateFormat::StdBig:
-                        case SvxDateFormat::D: aFieldValue = "datetime3"; // 
13 February 1996
-                                              break;
-                        default: break;
-                    }
+                    aFieldValue = 
GetDatetimeTypeFromDate(static_cast<SvxDateFormat>(nNumFmt));
                 }
                 else if(aFieldKind == "ExtTime")
                 {
                     sal_Int32 nNumFmt = -1;
                     rXPropSet->getPropertyValue(UNO_TC_PROP_NUMFORMAT) >>= 
nNumFmt;
-                    switch(static_cast<SvxTimeFormat>(nNumFmt))
-                    {
-                        case SvxTimeFormat::Standard:
-                        case SvxTimeFormat::HH24_MM_SS:
-                            aFieldValue = "datetime11"; // 13:49:38
-                            break;
-                        case SvxTimeFormat::HH24_MM:
-                            aFieldValue = "datetime10"; // 13:49
-                            break;
-                        case SvxTimeFormat::HH12_MM:
-                            aFieldValue = "datetime12"; // 01:49 PM
-                            break;
-                        case SvxTimeFormat::HH12_MM_SS:
-                            aFieldValue = "datetime13"; // 01:49:38 PM
-                            break;
-                        default: break;
-                    }
+                    aFieldValue = 
GetDatetimeTypeFromTime(static_cast<SvxTimeFormat>(nNumFmt));
                 }
                 else if(aFieldKind == "ExtFile")
                 {
@@ -2280,6 +2253,83 @@ OUString DrawingML::GetFieldValue( const 
css::uno::Reference< css::text::XTextRa
     return aFieldValue;
 }
 
+OUString DrawingML::GetDatetimeTypeFromDate(SvxDateFormat eDate)
+{
+    return GetDatetimeTypeFromDateTime(eDate, SvxTimeFormat::AppDefault);
+}
+
+OUString DrawingML::GetDatetimeTypeFromTime(SvxTimeFormat eTime)
+{
+    return GetDatetimeTypeFromDateTime(SvxDateFormat::AppDefault, eTime);
+}
+
+OUString DrawingML::GetDatetimeTypeFromDateTime(SvxDateFormat eDate, 
SvxTimeFormat eTime)
+{
+    OUString aDateField;
+    switch (eDate)
+    {
+        case SvxDateFormat::StdSmall:
+        case SvxDateFormat::A:
+            aDateField = "datetime";
+            break;
+        case SvxDateFormat::B:
+            aDateField = "datetime1"; // 13/02/1996
+            break;
+        case SvxDateFormat::StdBig:
+        case SvxDateFormat::C:
+        case SvxDateFormat::D:
+            aDateField = "datetime3"; // 13 February 1996
+            break;
+        case SvxDateFormat::E:
+        case SvxDateFormat::F:
+            aDateField = "datetime2";
+            break;
+        default:
+            break;
+    }
+
+    OUString aTimeField;
+    switch (eTime)
+    {
+        case SvxTimeFormat::Standard:
+        case SvxTimeFormat::HH24_MM_SS:
+        case SvxTimeFormat::HH24_MM_SS_00:
+            aTimeField = "datetime11"; // 13:49:38
+            break;
+        case SvxTimeFormat::HH24_MM:
+            aTimeField = "datetime10"; // 13:49
+            break;
+        case SvxTimeFormat::HH12_MM:
+        case SvxTimeFormat::HH12_MM_AMPM:
+            aTimeField = "datetime12"; // 01:49 PM
+            break;
+        case SvxTimeFormat::HH12_MM_SS:
+        case SvxTimeFormat::HH12_MM_SS_AMPM:
+        case SvxTimeFormat::HH12_MM_SS_00:
+        case SvxTimeFormat::HH12_MM_SS_00_AMPM:
+            aTimeField = "datetime13"; // 01:49:38 PM
+            break;
+        default:
+            break;
+    }
+
+    if (!aDateField.isEmpty() && aTimeField.isEmpty())
+        return aDateField;
+    else if (!aTimeField.isEmpty() && aDateField.isEmpty())
+        return aTimeField;
+    else if (!aDateField.isEmpty() && !aTimeField.isEmpty())
+    {
+        if (aTimeField.equals("datetime11") || aTimeField.equals("datetime13"))
+            // only datetime format that has Date and HH:MM:SS
+            return "datetime9"; // dd/mm/yyyy H:MM:SS
+        else
+            // only datetime format that has Date and HH:MM
+            return "datetime8"; // dd/mm/yyyy H:MM
+    }
+    else
+        return OUString();
+}
+
 void DrawingML::WriteRun( const Reference< XTextRange >& rRun,
                           bool& rbOverridingCharHeight, sal_Int32& 
rnCharHeight,
                           const css::uno::Reference< css::beans::XPropertySet 
>& rXShapePropSet)
commit c44a431424fe74079cca3332f7a64590a38ee344
Author:     Sarper Akdemir <sarper.akde...@collabora.com>
AuthorDate: Sun Apr 25 15:59:39 2021 +0300
Commit:     Sarper Akdemir <sarper.akde...@collabora.com>
CommitDate: Thu Jun 10 17:02:14 2021 +0300

    tdf#59323: pptx import: import footer fields as properties
    
    Makes footer, slidenum and datetime placeholders that are inserted to
    the slides themselves on pptx files imported as slide properties if it
    is possible to do so without losing information (style, position etc.)
    
    Also since the default way of displaying slide footers in LO use the
    respective text fields on master slides, information in master/layout
    slide datetime and footer placeholders respectively get replaced with
    <date/time> text fields and <footer> text fields.
    
    Change-Id: Ib2f7d18103b62c0c9a8453e01cfd2fd1aa1d39af

diff --git a/chart2/qa/extras/chart2import.cxx 
b/chart2/qa/extras/chart2import.cxx
index 59bd6ab2fda2..dfedf8e6916e 100644
--- a/chart2/qa/extras/chart2import.cxx
+++ b/chart2/qa/extras/chart2import.cxx
@@ -818,7 +818,7 @@ void Chart2ImportTest::testBnc864396()
 void Chart2ImportTest::testBnc889755()
 {
     load(u"/chart2/qa/extras/data/pptx/", "bnc889755.pptx");
-    uno::Reference<chart2::XChartDocument> 
xChartDoc(getChartDocFromDrawImpress(0, 6), uno::UNO_QUERY_THROW);
+    uno::Reference<chart2::XChartDocument> 
xChartDoc(getChartDocFromDrawImpress(0, 5), uno::UNO_QUERY_THROW);
     CPPUNIT_ASSERT(xChartDoc->hasInternalDataProvider());
 
     uno::Reference< chart2::XInternalDataProvider > xDataProvider( 
xChartDoc->getDataProvider(), uno::UNO_QUERY_THROW );
@@ -846,7 +846,7 @@ void Chart2ImportTest::testBnc889755()
     uno::Reference<drawing::XDrawPagesSupplier> xDoc(mxComponent, 
uno::UNO_QUERY_THROW);
     uno::Reference<drawing::XDrawPage> 
xPage(xDoc->getDrawPages()->getByIndex(0), uno::UNO_QUERY_THROW);
     // Shape "Title 3"
-    uno::Reference<beans::XPropertySet> xShapeProps(xPage->getByIndex(5), 
uno::UNO_QUERY_THROW);
+    uno::Reference<beans::XPropertySet> xShapeProps(xPage->getByIndex(4), 
uno::UNO_QUERY_THROW);
     awt::Gradient aTransparence;
     xShapeProps->getPropertyValue("FillTransparenceGradient") >>= 
aTransparence;
     CPPUNIT_ASSERT(aTransparence.StartColor != aTransparence.EndColor);
diff --git a/oox/source/ppt/pptshape.cxx b/oox/source/ppt/pptshape.cxx
index 52b911f18380..bcaa72b6dd62 100644
--- a/oox/source/ppt/pptshape.cxx
+++ b/oox/source/ppt/pptshape.cxx
@@ -20,8 +20,12 @@
 #include <oox/ppt/pptshape.hxx>
 #include <oox/core/xmlfilterbase.hxx>
 #include <drawingml/textbody.hxx>
+#include <drawingml/textparagraph.hxx>
+#include <drawingml/textfield.hxx>
 #include <drawingml/table/tableproperties.hxx>
+#include <editeng/flditem.hxx>
 
+#include <com/sun/star/text/XTextField.hpp>
 #include <com/sun/star/container/XNamed.hpp>
 #include <com/sun/star/frame/XModel.hpp>
 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
@@ -84,6 +88,19 @@ static const char* lclDebugSubType( sal_Int32 nType )
     return "unknown - please extend lclDebugSubType";
 }
 
+namespace
+{
+bool ShapeHasNoVisualPropertiesOnImport(oox::ppt::PPTShape& rPPTShape)
+{
+    return  !rPPTShape.hasNonInheritedShapeProperties()
+            && !rPPTShape.hasShapeStyleRefs()
+            && !rPPTShape.getTextBody()->hasVisualRunProperties()
+            && !rPPTShape.getTextBody()->hasNoninheritedBodyProperties()
+            && !rPPTShape.getTextBody()->hasListStyleOnImport()
+            && !rPPTShape.getTextBody()->hasParagraphProperties();
+}
+}
+
 oox::drawingml::TextListStylePtr PPTShape::getSubTypeTextListStyle( const 
SlidePersist& rSlidePersist, sal_Int32 nSubType )
 {
     oox::drawingml::TextListStylePtr pTextListStyle;
@@ -177,6 +194,37 @@ void PPTShape::addShape(
                 }
                 break;
                 case XML_dt :
+                    if ( meShapeLocation == Slide && 
!rSlidePersist.isNotesPage()
+                         && getTextBody()->getParagraphs().size() == 1
+                         && 
getTextBody()->getParagraphs().front()->getRuns().size() == 1
+                         && ShapeHasNoVisualPropertiesOnImport(*this) )
+                    {
+                        TextRunPtr& pTextRun = 
getTextBody()->getParagraphs().front()->getRuns().front();
+                        oox::drawingml::TextField* pTextField = 
dynamic_cast<oox::drawingml::TextField*>(pTextRun.get());
+                        if (pTextField)
+                        {
+                            OUString aType = pTextField->getType();
+                            if ( aType.startsWith("datetime") )
+                            {
+                                SvxDateFormat eDateFormat = 
drawingml::TextField::getLODateFormat(aType);
+                                SvxTimeFormat eTimeFormat = 
drawingml::TextField::getLOTimeFormat(aType);
+                                Reference< XPropertySet > xPropertySet( 
rSlidePersist.getPage(), UNO_QUERY );
+
+                                if( eDateFormat != SvxDateFormat::AppDefault
+                                    || eTimeFormat != 
SvxTimeFormat::AppDefault )
+                                {
+                                    // DateTimeFormat property looks for the 
date in 4 LSBs
+                                    // and looks for time format in the 4 bits 
after that
+                                    int nDateTimeFormat = 
static_cast<int>(eDateFormat) |
+                                                          
static_cast<int>(eTimeFormat) << 4;
+                                    xPropertySet->setPropertyValue( 
"IsDateTimeVisible", Any(true) );
+                                    xPropertySet->setPropertyValue( 
"IsDateTimeFixed", Any(false) );
+                                    xPropertySet->setPropertyValue( 
"DateTimeFormat", Any(nDateTimeFormat) );
+                                    return;
+                                }
+                            }
+                        }
+                    }
                     sServiceName = "com.sun.star.presentation.DateTimeShape";
                     bClearText = true;
                 break;
@@ -185,10 +233,46 @@ void PPTShape::addShape(
                     bClearText = true;
                 break;
                 case XML_ftr :
+                    if ( meShapeLocation == Slide && 
!rSlidePersist.isNotesPage()
+                         && getTextBody()->getParagraphs().size() == 1
+                         && 
getTextBody()->getParagraphs().front()->getRuns().size() == 1
+                         && ShapeHasNoVisualPropertiesOnImport(*this) )
+                    {
+                        const OUString& rFooterText = 
getTextBody()->toString();
+
+                        if( !rFooterText.isEmpty() )
+                        {
+                            // if it is possible to get the footer as a 
property the LO way,
+                            // get it and discard the shape
+                            Reference< XPropertySet > xPropertySet( 
rSlidePersist.getPage(), UNO_QUERY );
+                            xPropertySet->setPropertyValue( "IsFooterVisible", 
Any( true ) );
+                            xPropertySet->setPropertyValue( "FooterText", 
Any(rFooterText) );
+                            return;
+                        }
+                    }
                     sServiceName = "com.sun.star.presentation.FooterShape";
                     bClearText = true;
                 break;
                 case XML_sldNum :
+                    if (meShapeLocation == Slide && 
!rSlidePersist.isNotesPage()
+                        && getTextBody()->getParagraphs().size() == 1
+                        && 
getTextBody()->getParagraphs().front()->getRuns().size() == 1
+                        && ShapeHasNoVisualPropertiesOnImport(*this))
+                    {
+                        TextRunPtr& pTextRun
+                            = 
getTextBody()->getParagraphs().front()->getRuns().front();
+                        oox::drawingml::TextField* pTextField
+                            = 
dynamic_cast<oox::drawingml::TextField*>(pTextRun.get());
+                        if (pTextField && 
pTextField->getType().equals("slidenum"))
+                        {
+                            // if it is possible to get the slidenum 
placeholder as a property
+                            // do that and discard the shape
+                            Reference<XPropertySet> 
xPropertySet(rSlidePersist.getPage(),
+                                                                 UNO_QUERY);
+                            
xPropertySet->setPropertyValue("IsPageNumberVisible", Any(true));
+                            return;
+                        }
+                    }
                     sServiceName = 
"com.sun.star.presentation.SlideNumberShape";
                     bClearText = true;
                 break;
@@ -407,6 +491,26 @@ void PPTShape::addShape(
                 }
             }
 
+            // we will be losing whatever information there is in the footer 
placeholder on master/layout slides
+            // since they should have the "<footer>" textfield in them in 
order to make LibreOffice process them as expected
+            // likewise DateTime placeholder data on master/layout slides will 
be lost and replaced
+            if( (mnSubType == XML_ftr || mnSubType == XML_dt) && 
meShapeLocation != Slide )
+            {
+                OUString aFieldType;
+                if( mnSubType == XML_ftr )
+                    aFieldType = "com.sun.star.presentation.TextField.Footer";
+                else
+                    aFieldType = 
"com.sun.star.presentation.TextField.DateTime";
+                Reference < XTextField > xField( xServiceFact->createInstance( 
aFieldType ), UNO_QUERY );
+                Reference < XText > xText(mxShape, UNO_QUERY);
+                if(xText.is())
+                {
+                    xText->setString("");
+                    Reference < XTextCursor > xTextCursor = 
xText->createTextCursor();
+                    xText->insertTextContent( xTextCursor, xField, false);
+                }
+            }
+
             // if this is a group shape, we have to add also each child shape
             Reference<XShapes> xShapes(xShape, UNO_QUERY);
             if (xShapes.is())
diff --git a/sd/qa/unit/data/pptx/numfmt.pptx b/sd/qa/unit/data/pptx/numfmt.pptx
index aca6927101d6..e5f0f5cf151a 100644
Binary files a/sd/qa/unit/data/pptx/numfmt.pptx and 
b/sd/qa/unit/data/pptx/numfmt.pptx differ
diff --git a/sd/qa/unit/data/pptx/slidenum_field.pptx 
b/sd/qa/unit/data/pptx/slidenum_field.pptx
index f3c184056905..3388568831d7 100644
Binary files a/sd/qa/unit/data/pptx/slidenum_field.pptx and 
b/sd/qa/unit/data/pptx/slidenum_field.pptx differ
diff --git a/sd/qa/unit/import-tests.cxx b/sd/qa/unit/import-tests.cxx
index 22431385ea17..74a8e28ae1ad 100644
--- a/sd/qa/unit/import-tests.cxx
+++ b/sd/qa/unit/import-tests.cxx
@@ -1844,7 +1844,7 @@ void SdImportTest::testTdf95932()
     sd::DrawDocShellRef xDocShRef = 
loadURL(m_directories.getURLFromSrc(u"/sd/qa/unit/data/pptx/tdf95932.pptx"), 
PPTX);
 
     const SdrPage *pPage = GetPage( 1, xDocShRef );
-    SdrObject *const pObj = pPage->GetObj(2);
+    SdrObject *const pObj = pPage->GetObj(1);
     CPPUNIT_ASSERT(pObj);
 
     const XFillStyleItem& rStyleItem = dynamic_cast<const XFillStyleItem&>(
_______________________________________________
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to