sd/qa/unit/data/pptx/pres-with-notes.pptx |binary
 sd/qa/unit/export-tests-ooxml4.cxx        |   35 ++++++++++++++++++++++++++++++
 sd/source/filter/eppt/eppt.cxx            |   21 +++++++++++++-----
 sd/source/filter/eppt/eppt.hxx            |    4 +++
 sd/source/filter/eppt/epptooxml.hxx       |    4 +++
 sd/source/filter/eppt/pptx-epptooxml.cxx  |   32 +++++++++++++++++++++++----
 6 files changed, 86 insertions(+), 10 deletions(-)

New commits:
commit a298ba36047e17cf6a0f6b3d17ae40aed282f47b
Author:     Samuel Mehrbrodt <samuel.mehrbr...@allotropia.de>
AuthorDate: Thu Jun 13 19:26:04 2024 +0200
Commit:     Samuel Mehrbrodt <samuel.mehrbr...@allotropia.de>
CommitDate: Mon Jun 17 10:30:19 2024 +0200

    ppt: Don't export notes author/date when in privacy mode
    
    Change-Id: Id748b79e7685f5e99df142aa2aa9449a18a32d5c
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/168821
    Tested-by: Jenkins
    Reviewed-by: Samuel Mehrbrodt <samuel.mehrbr...@allotropia.de>

diff --git a/sd/source/filter/eppt/eppt.cxx b/sd/source/filter/eppt/eppt.cxx
index 32af30aecd97..bb0544c5d068 100644
--- a/sd/source/filter/eppt/eppt.cxx
+++ b/sd/source/filter/eppt/eppt.cxx
@@ -42,6 +42,7 @@
 #include <com/sun/star/task/XStatusIndicator.hpp>
 #include <comphelper/sequence.hxx>
 #include <tools/zcodec.hxx>
+#include <unotools/securityoptions.hxx>
 #include <filter/msfilter/classids.hxx>
 #include <filter/msfilter/msoleexp.hxx>
 #include <filter/msfilter/msdffimp.hxx>
@@ -82,6 +83,7 @@ PPTWriter::PPTWriter( rtl::Reference<SotStorage> xSvStorage,
     mpVBA                   ( pVBA ),
     mnExEmbed               ( 0 ),
     mpExEmbed               ( new SvMemoryStream ),
+    mpAuthorIDs             ( new SvtSecurityMapPersonalInfo ),
     mnPagesWritten          ( 0 ),
     mnTxId                  ( 0x7a2f64 ),
     mnDiaMode               ( 0 ),
@@ -149,8 +151,6 @@ void PPTWriter::exportPPTPost( )
     mbStatus = true;
 };
 
-static void ImplExportComments( const uno::Reference< drawing::XDrawPage >& 
xPage, SvMemoryStream& rBinaryTagData10Atom );
-
 void PPTWriter::ImplWriteSlide( sal_uInt32 nPageNum, sal_uInt32 nMasterNum, 
sal_uInt16 nMode,
                                 bool bHasBackground, Reference< XPropertySet > 
const & aXBackgroundPropSet )
 {
@@ -1056,13 +1056,20 @@ static OUString getInitials( const OUString& rName )
     return sInitials.makeStringAndClear();
 }
 
-void ImplExportComments( const uno::Reference< drawing::XDrawPage >& xPage, 
SvMemoryStream& rBinaryTagData10Atom )
+
+void PPTWriter::ImplExportComments( const uno::Reference< drawing::XDrawPage 
>& xPage, SvMemoryStream& rBinaryTagData10Atom )
 {
     try
     {
         uno::Reference< office::XAnnotationAccess > xAnnotationAccess( xPage, 
uno::UNO_QUERY_THROW );
         uno::Reference< office::XAnnotationEnumeration > 
xAnnotationEnumeration( xAnnotationAccess->createAnnotationEnumeration() );
 
+        bool bRemoveCommentAuthorDates
+            = SvtSecurityOptions::IsOptionSet(
+                  SvtSecurityOptions::EOption::DocWarnRemovePersonalInfo)
+              && !SvtSecurityOptions::IsOptionSet(
+                     
SvtSecurityOptions::EOption::DocWarnKeepNoteAuthorDateInfo);
+
         sal_Int32 nIndex = 1;
 
         while( xAnnotationEnumeration->hasMoreElements() )
@@ -1075,11 +1082,15 @@ void ImplExportComments( const uno::Reference< 
drawing::XDrawPage >& xPage, SvMe
                 Point aPoint(o3tl::convert(aRealPoint2D.X, o3tl::Length::mm, 
o3tl::Length::master),
                              o3tl::convert(aRealPoint2D.Y, o3tl::Length::mm, 
o3tl::Length::master));
 
-                OUString sAuthor( xAnnotation->getAuthor() );
+                OUString sAuthor( bRemoveCommentAuthorDates
+                            ? "Author" + 
OUString::number(mpAuthorIDs->GetInfoID(xAnnotation->getAuthor() ))
+                            : xAnnotation->getAuthor() );
                 uno::Reference< text::XText > xText( 
xAnnotation->getTextRange() );
                 OUString sText( xText->getString() );
                 OUString sInitials( getInitials( sAuthor ) );
-                util::DateTime aDateTime( xAnnotation->getDateTime() );
+                util::DateTime aEmptyDateTime;
+                util::DateTime aDateTime(bRemoveCommentAuthorDates ? 
aEmptyDateTime
+                                                                   : 
xAnnotation->getDateTime());
                 if ( !sAuthor.isEmpty() )
                     PPTWriter::WriteCString( rBinaryTagData10Atom, sAuthor );
                 if ( !sText.isEmpty() )
diff --git a/sd/source/filter/eppt/eppt.hxx b/sd/source/filter/eppt/eppt.hxx
index 1ef07d1dcff4..3d95b4380229 100644
--- a/sd/source/filter/eppt/eppt.hxx
+++ b/sd/source/filter/eppt/eppt.hxx
@@ -24,6 +24,7 @@
 #include "escherex.hxx"
 #include <sal/types.h>
 #include <sot/storage.hxx>
+#include <unotools/securityoptions.hxx>
 #include "pptexsoundcollection.hxx"
 
 #include "text.hxx"
@@ -138,6 +139,7 @@ class PPTWriter final : public PPTWriterBase, public 
PPTExBulletProvider
         SvMemoryStream*     mpVBA;
         sal_uInt32          mnExEmbed;
         std::unique_ptr<SvMemoryStream> mpExEmbed;
+        std::unique_ptr<SvtSecurityMapPersonalInfo> mpAuthorIDs; // map 
authors to remove personal info
 
         sal_uInt32          mnPagesWritten;
         sal_uInt32          mnTxId;             // Identifier determined by 
the HOST (PP) ????
@@ -211,6 +213,8 @@ class PPTWriter final : public PPTWriterBase, public 
PPTExBulletProvider
 
         bool                ImplCloseDocument();        // we write the font, 
hyper and sound list
 
+        void                ImplExportComments(const 
css::uno::Reference<css::drawing::XDrawPage>& xPage,
+                                               SvMemoryStream& 
rBinaryTagData10Atom);
         virtual void        ImplWriteSlide( sal_uInt32 nPageNum, sal_uInt32 
nMasterID, sal_uInt16 nMode,
                                             bool bHasBackground, 
css::uno::Reference< css::beans::XPropertySet > const & aXBackgroundPropSet ) 
override;
         virtual void        ImplWriteNotes( sal_uInt32 nPageNum ) override;
commit 5fe7062f2a5f7785a15abbfbe0c0394826412e0e
Author:     Samuel Mehrbrodt <samuel.mehrbr...@allotropia.de>
AuthorDate: Thu Jun 13 15:09:13 2024 +0200
Commit:     Samuel Mehrbrodt <samuel.mehrbr...@allotropia.de>
CommitDate: Mon Jun 17 10:30:07 2024 +0200

    pptx: Don't export notes author/date when in privacy mode
    
    Change-Id: Ia2f20b05b043d45df090f2843a4d365c692770fd
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/168813
    Reviewed-by: Samuel Mehrbrodt <samuel.mehrbr...@allotropia.de>
    Tested-by: Jenkins

diff --git a/sd/qa/unit/data/pptx/pres-with-notes.pptx 
b/sd/qa/unit/data/pptx/pres-with-notes.pptx
new file mode 100644
index 000000000000..25f9692a2a1c
Binary files /dev/null and b/sd/qa/unit/data/pptx/pres-with-notes.pptx differ
diff --git a/sd/qa/unit/export-tests-ooxml4.cxx 
b/sd/qa/unit/export-tests-ooxml4.cxx
index 63af283d664f..0e11eb581bf0 100644
--- a/sd/qa/unit/export-tests-ooxml4.cxx
+++ b/sd/qa/unit/export-tests-ooxml4.cxx
@@ -14,6 +14,7 @@
 #include <editeng/editobj.hxx>
 #include <editeng/numitem.hxx>
 #include <docmodel/uno/UnoGradientTools.hxx>
+#include <officecfg/Office/Common.hxx>
 
 #include <svx/xlineit0.hxx>
 #include <svx/xlndsit.hxx>
@@ -1095,6 +1096,40 @@ CPPUNIT_TEST_FIXTURE(SdOOXMLExportTest4, 
testTdf102261_testParaTabStopDefaultDis
     }
 }
 
+CPPUNIT_TEST_FIXTURE(SdOOXMLExportTest4, testNotesAuthorDate)
+{
+    createSdImpressDoc("pptx/pres-with-notes.pptx");
+
+    auto pBatch(comphelper::ConfigurationChanges::create());
+    // 1. Remove all personal info, but keep note info
+    
officecfg::Office::Common::Security::Scripting::RemovePersonalInfoOnSaving::set(true,
 pBatch);
+    
officecfg::Office::Common::Security::Scripting::KeepNoteAuthorDateInfoOnSaving::set(true,
+                                                                               
         pBatch);
+    pBatch->commit();
+
+    saveAndReload(u"Impress Office Open XML"_ustr);
+
+    xmlDocUniquePtr pXml = parseExport(u"ppt/commentAuthors.xml"_ustr);
+    assertXPath(pXml, "/p:cmAuthorLst/p:cmAuthor[@id=0]"_ostr, "name"_ostr, 
"Hans Wurst");
+    assertXPath(pXml, "/p:cmAuthorLst/p:cmAuthor[@id=1]"_ostr, "name"_ostr, 
"Max Muster");
+
+    pXml = parseExport(u"ppt/comments/comment1.xml"_ustr);
+    assertXPath(pXml, "/p:cmLst/p:cm"_ostr, "dt"_ostr, 
"2024-06-13T12:03:08.000000000");
+
+    // 2. Remove all personal info
+    
officecfg::Office::Common::Security::Scripting::KeepNoteAuthorDateInfoOnSaving::set(false,
+                                                                               
         pBatch);
+    pBatch->commit();
+    saveAndReload(u"Impress Office Open XML"_ustr);
+
+    pXml = parseExport(u"ppt/commentAuthors.xml"_ustr);
+    assertXPath(pXml, "/p:cmAuthorLst/p:cmAuthor[@id=0]"_ostr, "name"_ostr, 
"Author1");
+    assertXPath(pXml, "/p:cmAuthorLst/p:cmAuthor[@id=1]"_ostr, "name"_ostr, 
"Author2");
+
+    pXml = parseExport(u"ppt/comments/comment1.xml"_ustr);
+    assertXPathNoAttribute(pXml, "/p:cmLst/p:cm"_ostr, "dt"_ostr);
+}
+
 CPPUNIT_TEST_FIXTURE(SdOOXMLExportTest4, 
testTableCellVerticalPropertyRoundtrip)
 {
     createSdImpressDoc("pptx/tcPr-vert-roundtrip.pptx");
diff --git a/sd/source/filter/eppt/epptooxml.hxx 
b/sd/source/filter/eppt/epptooxml.hxx
index c187c90c721c..9646afb865d8 100644
--- a/sd/source/filter/eppt/epptooxml.hxx
+++ b/sd/source/filter/eppt/epptooxml.hxx
@@ -22,6 +22,7 @@
 #include <oox/core/xmlfilterbase.hxx>
 #include <oox/vml/vmldrawing.hxx>
 #include <oox/export/shapes.hxx>
+#include <unotools/securityoptions.hxx>
 #include "epptbase.hxx"
 
 using ::sax_fastparser::FSHelperPtr;
@@ -139,6 +140,7 @@ private:
     ::sax_fastparser::FSHelperPtr mPresentationFS;
 
     LayoutInfo mLayoutInfo[OOXML_LAYOUT_SIZE];
+    std::unique_ptr<SvtSecurityMapPersonalInfo> mpAuthorIDs; // map authors to 
remove personal info
     std::vector< ::sax_fastparser::FSHelperPtr > mpSlidesFSArray;
     sal_Int32 mnLayoutFileIdMax;
 
@@ -158,6 +160,8 @@ private:
     /// Map of placeholder indexes for Master placeholders
     std::unordered_map< css::uno::Reference<css::drawing::XShape>, sal_Int32 > 
maPlaceholderShapeToIndexMap;
 
+    // Get author id to remove personal info
+    size_t GetInfoID( const OUString sPersonalInfo ) const { return 
mpAuthorIDs->GetInfoID(sPersonalInfo); }
     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 2d9e51e40fa5..728682f955d6 100644
--- a/sd/source/filter/eppt/pptx-epptooxml.cxx
+++ b/sd/source/filter/eppt/pptx-epptooxml.cxx
@@ -34,6 +34,7 @@
 #include <sal/log.hxx>
 #include <tools/UnitConversion.hxx>
 #include <tools/datetime.hxx>
+#include <unotools/securityoptions.hxx>
 #include <com/sun/star/animations/TransitionType.hpp>
 #include <com/sun/star/animations/TransitionSubType.hpp>
 #include <com/sun/star/beans/XPropertySetInfo.hpp>
@@ -342,6 +343,7 @@ ShapeExport& PowerPointShapeExport::WriteUnknownShape(const 
Reference< XShape >&
 
 PowerPointExport::PowerPointExport(const Reference< XComponentContext >& 
rContext, const uno::Sequence<uno::Any>& rArguments)
     : XmlFilterBase(rContext)
+    , mpAuthorIDs( new SvtSecurityMapPersonalInfo )
     , mnLayoutFileIdMax(1)
     , mnSlideIdMax(1 << 8)
     , mnSlideMasterIdMax(1U << 31)
@@ -1166,6 +1168,12 @@ bool PowerPointExport::WriteComments(sal_uInt32 nPageNum)
 
         if (xAnnotationEnumeration->hasMoreElements())
         {
+            bool bRemoveCommentAuthorDates
+                = SvtSecurityOptions::IsOptionSet(
+                      SvtSecurityOptions::EOption::DocWarnRemovePersonalInfo)
+                  && !SvtSecurityOptions::IsOptionSet(
+                         
SvtSecurityOptions::EOption::DocWarnKeepNoteAuthorDateInfo);
+
             FSHelperPtr pFS = openFragmentStreamWithSerializer(
                               "ppt/comments/comment" + 
OUString::number(nPageNum + 1) + ".xml",
                               
u"application/vnd.openxmlformats-officedocument.presentationml.comments+xml"_ustr);
@@ -1180,16 +1188,30 @@ bool PowerPointExport::WriteComments(sal_uInt32 
nPageNum)
                 RealPoint2D aRealPoint2D(xAnnotation->getPosition());
                 Reference< XText > xText(xAnnotation->getTextRange());
                 sal_Int32 nLastIndex;
-                sal_Int32 nId = 
GetAuthorIdAndLastIndex(xAnnotation->getAuthor(), nLastIndex);
+                OUString sAuthor(bRemoveCommentAuthorDates
+                                     ? "Author"
+                                           + 
OUString::number(GetInfoID(xAnnotation->getAuthor()))
+                                     : xAnnotation->getAuthor());
+                sal_Int32 nId = GetAuthorIdAndLastIndex(sAuthor, nLastIndex);
                 char 
cDateTime[sizeof("-32768-65535-65535T65535:65535:65535.4294967295")];
                     // reserve enough space for hypothetical max length
 
                 snprintf(cDateTime, sizeof cDateTime, "%02" SAL_PRIdINT32 
"-%02" SAL_PRIuUINT32 "-%02" SAL_PRIuUINT32 "T%02" SAL_PRIuUINT32 ":%02" 
SAL_PRIuUINT32 ":%02" SAL_PRIuUINT32 ".%09" SAL_PRIuUINT32, 
sal_Int32(aDateTime.Year), sal_uInt32(aDateTime.Month), 
sal_uInt32(aDateTime.Day), sal_uInt32(aDateTime.Hours), 
sal_uInt32(aDateTime.Minutes), sal_uInt32(aDateTime.Seconds), 
aDateTime.NanoSeconds);
 
-                pFS->startElementNS(XML_p, XML_cm,
-                                    XML_authorId, OString::number(nId),
-                                    XML_dt, cDateTime,
-                                    XML_idx, OString::number(nLastIndex));
+                util::DateTime aEmptyDate;
+                if (bRemoveCommentAuthorDates || aDateTime == aEmptyDate)
+                {
+                    pFS->startElementNS(XML_p, XML_cm,
+                                        XML_authorId, OString::number(nId),
+                                        XML_idx, OString::number(nLastIndex));
+                }
+                else
+                {
+                    pFS->startElementNS(XML_p, XML_cm,
+                                        XML_authorId, OString::number(nId),
+                                        XML_dt, cDateTime,
+                                        XML_idx, OString::number(nLastIndex));
+                }
 
                 pFS->singleElementNS(XML_p, XML_pos,
                                      XML_x, 
OString::number(std::round(convertMm100ToMasterUnit(aRealPoint2D.X * 100))),

Reply via email to