diff options
-rw-r--r-- | sw/qa/extras/rtfexport/data/text-change-tracking.rtf | 17 | ||||
-rw-r--r-- | sw/qa/extras/rtfexport/rtfexport8.cxx | 23 | ||||
-rw-r--r-- | sw/source/filter/ww8/rtfattributeoutput.cxx | 19 | ||||
-rw-r--r-- | sw/source/filter/ww8/rtfattributeoutput.hxx | 3 | ||||
-rw-r--r-- | sw/source/filter/ww8/rtfexport.cxx | 14 | ||||
-rw-r--r-- | sw/source/filter/ww8/rtfexport.hxx | 10 |
6 files changed, 76 insertions, 10 deletions
diff --git a/sw/qa/extras/rtfexport/data/text-change-tracking.rtf b/sw/qa/extras/rtfexport/data/text-change-tracking.rtf new file mode 100644 index 000000000000..c6f72ceeade5 --- /dev/null +++ b/sw/qa/extras/rtfexport/data/text-change-tracking.rtf @@ -0,0 +1,17 @@ +{\rtf1\ansi\deff3\adeflang1025 +{\fonttbl{\f0\froman\fprq2\fcharset0 Liberat;}{\f1\froman\fprq2\fcharset2 Symbol;}{\f2\fswiss\fprq2\fcharset0 Arial;}{\f3\froman\fprq2\fcharset0 Liberation Serif{\*\falt Times New Roman};}{\f4\fswiss\fprq2\fcharset0 Liberation Sans{\*\falt Arial};}{\f5\fnil\fprq2\fcharset0 Noto Sans CJK SC;}{\f6\fnil\fprq2\fcharset0 Noto Sans Devanagari;}{\f7\fswiss\fprq0\fcharset0 Noto Sans Devanagari;}} +{\colortbl;\red0\green0\blue0;\red0\green0\blue255;\red0\green255\blue255;\red0\green255\blue0;\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255;\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;\red128\green0\blue128;\red128\green0\blue0;\red128\green128\blue0;\red128\green128\blue128;\red192\green192\blue192;} +{\stylesheet{\s0\snext0\rtlch\af6\afs24\alang1081 \ltrch\lang1031\langfe2052\hich\af3\loch\widctlpar\hyphpar0\aspalpha\ltrpar\cf0\f3\fs24\lang1031\kerning1\dbch\af8\langfe2052 Normal;} +{\*\cs15\snext15 line number;} +{\s16\sbasedon0\snext17\rtlch\af6\afs28 \ltrch\hich\af4\loch\sb240\sa120\keepn\f4\fs28\dbch\af5 Heading;} +{\s17\sbasedon0\snext17\loch\sl276\slmult1\sb0\sa140 Body Text;} +{\s18\sbasedon17\snext18\rtlch\af7 \ltrch List;} +{\s19\sbasedon0\snext19\rtlch\af7\afs24\ai \ltrch\loch\sb120\sa120\noline\fs24\i caption;} +{\s20\sbasedon0\snext20\rtlch\af7 \ltrch\loch\noline Index;} +}{\*\revtbl {Unknown;}{Max Mustermann;}} +{\*\generator LibreOfficeDev/25.2.0.0.alpha0$Linux_X86_64 LibreOffice_project/c558004906bfaef6d1983e09473e4c236de730d3}{\info{\creatim\yr2024\mo6\dy17\hr11\min1}{\revtim\yr0\mo0\dy0\hr0\min0}{\printim\yr0\mo0\dy0\hr0\min0}}{\*\userprops}\deftab709 +\hyphauto1\viewscale130\revisions\formshade\nobrkwrptbl\paperh16838\paperw11906\margl1134\margr1134\margt1134\margb1134\sectd\sbknone\sftnnar\saftnnrlc\sectunlocked1\pgwsxn11906\pghsxn16838\marglsxn1134\margrsxn1134\margtsxn1134\margbsxn1134\ftnbj\ftnstart1\ftnrstcont\ftnnar\fet\aftnrstcont\aftnstart1\aftnnrlc +{\*\ftnsep\chftnsep}\pgndec\pard\plain \s0\rtlch\af6\afs24\alang1081 \ltrch\lang1031\langfe2052\hich\af3\loch\widctlpar\hyphpar0\aspalpha\ltrpar\cf0\f3\fs24\lang1031\kerning1\dbch\af8\langfe2052\ql\ltrpar{\deleted\revauthdel1\revdttmdel667323072 \loch +Test}{\revised\revauth1\revdttm667323072 \loch +Deleted} +\par }
\ No newline at end of file diff --git a/sw/qa/extras/rtfexport/rtfexport8.cxx b/sw/qa/extras/rtfexport/rtfexport8.cxx index 1ed6eee0ded4..3f013605d625 100644 --- a/sw/qa/extras/rtfexport/rtfexport8.cxx +++ b/sw/qa/extras/rtfexport/rtfexport8.cxx @@ -482,6 +482,29 @@ CPPUNIT_TEST_FIXTURE(Test, testNotesAuthorDate) CPPUNIT_ASSERT_EQUAL(sal_Int32(-1), aRtfContent.indexOf("\\atndate", 0)); } +CPPUNIT_TEST_FIXTURE(Test, testChangesAuthor) +{ + createSwDoc("text-change-tracking.rtf"); + + auto pBatch(comphelper::ConfigurationChanges::create()); + // Remove all personal info + officecfg::Office::Common::Security::Scripting::RemovePersonalInfoOnSaving::set(true, pBatch); + pBatch->commit(); + saveAndReload(mpFilter); + + SvStream* pStream = maTempFile.GetStream(StreamMode::READ); + CPPUNIT_ASSERT(pStream); + OString aRtfContent(read_uInt8s_ToOString(*pStream, pStream->TellEnd())); + + // Make sure user name was anonymized + CPPUNIT_ASSERT_EQUAL(sal_Int32(-1), + aRtfContent.indexOf("\\revtbl {Unknown;}{Max Mustermann;}", 0)); + CPPUNIT_ASSERT(aRtfContent.indexOf("\\revtbl {Author1;}{Author2;}", 0) >= 0); + + // Make sure no date is set + CPPUNIT_ASSERT_EQUAL(sal_Int32(-1), aRtfContent.indexOf("\\revdttmdel", 0)); +} + CPPUNIT_TEST_FIXTURE(Test, testTdf158982) { auto verify = [this]() { diff --git a/sw/source/filter/ww8/rtfattributeoutput.cxx b/sw/source/filter/ww8/rtfattributeoutput.cxx index 22a76de4a109..07063fb4d5c5 100644 --- a/sw/source/filter/ww8/rtfattributeoutput.cxx +++ b/sw/source/filter/ww8/rtfattributeoutput.cxx @@ -626,13 +626,19 @@ void RtfAttributeOutput::Redline(const SwRedlineData* pRedline) if (!pRedline) return; + bool bRemoveCommentAuthorDates + = SvtSecurityOptions::IsOptionSet(SvtSecurityOptions::EOption::DocWarnRemovePersonalInfo) + && !SvtSecurityOptions::IsOptionSet( + SvtSecurityOptions::EOption::DocWarnKeepNoteAuthorDateInfo); + if (pRedline->GetType() == RedlineType::Insert) { m_aRun->append(OOO_STRING_SVTOOLS_RTF_REVISED); m_aRun->append(OOO_STRING_SVTOOLS_RTF_REVAUTH); m_aRun->append(static_cast<sal_Int32>( m_rExport.GetRedline(SW_MOD()->GetRedlineAuthor(pRedline->GetAuthor())))); - m_aRun->append(OOO_STRING_SVTOOLS_RTF_REVDTTM); + if (!bRemoveCommentAuthorDates) + m_aRun->append(OOO_STRING_SVTOOLS_RTF_REVDTTM); } else if (pRedline->GetType() == RedlineType::Delete) { @@ -640,9 +646,11 @@ void RtfAttributeOutput::Redline(const SwRedlineData* pRedline) m_aRun->append(OOO_STRING_SVTOOLS_RTF_REVAUTHDEL); m_aRun->append(static_cast<sal_Int32>( m_rExport.GetRedline(SW_MOD()->GetRedlineAuthor(pRedline->GetAuthor())))); - m_aRun->append(OOO_STRING_SVTOOLS_RTF_REVDTTMDEL); + if (!bRemoveCommentAuthorDates) + m_aRun->append(OOO_STRING_SVTOOLS_RTF_REVDTTMDEL); } - m_aRun->append(static_cast<sal_Int32>(sw::ms::DateTime2DTTM(pRedline->GetTimeStamp()))); + if (!bRemoveCommentAuthorDates) + m_aRun->append(static_cast<sal_Int32>(sw::ms::DateTime2DTTM(pRedline->GetTimeStamp()))); m_aRun->append(' '); } @@ -4092,10 +4100,10 @@ void RtfAttributeOutput::PostitField(const SwField* pField) return; } OUString sAuthor(bRemoveCommentAuthorDates - ? "Author" + OUString::number(mpAuthorIDs->GetInfoID(rPField.GetPar1())) + ? "Author" + OUString::number(m_rExport.GetInfoID(rPField.GetPar1())) : rPField.GetPar1()); OUString sInitials(bRemoveCommentAuthorDates - ? "A" + OUString::number(mpAuthorIDs->GetInfoID(rPField.GetPar1())) + ? "A" + OUString::number(m_rExport.GetInfoID(rPField.GetPar1())) : rPField.GetInitials()); m_aRunText->append("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_ATNID " "); m_aRunText->append(OUStringToOString(sInitials, m_rExport.GetCurrentEncoding())); @@ -4169,7 +4177,6 @@ RtfAttributeOutput::RtfAttributeOutput(RtfExport& rExport) , m_nParaBeforeSpacing(0) , m_bParaAfterAutoSpacing(false) , m_nParaAfterSpacing(0) - , mpAuthorIDs(new SvtSecurityMapPersonalInfo) { } diff --git a/sw/source/filter/ww8/rtfattributeoutput.hxx b/sw/source/filter/ww8/rtfattributeoutput.hxx index 7642918332ff..8ba84bed6055 100644 --- a/sw/source/filter/ww8/rtfattributeoutput.hxx +++ b/sw/source/filter/ww8/rtfattributeoutput.hxx @@ -666,9 +666,6 @@ private: editeng::WordPageMargins m_aPageMargins; - /// map authors to remove personal info - std::unique_ptr<SvtSecurityMapPersonalInfo> mpAuthorIDs; - public: explicit RtfAttributeOutput(RtfExport& rExport); diff --git a/sw/source/filter/ww8/rtfexport.cxx b/sw/source/filter/ww8/rtfexport.cxx index 88a3086c6dfc..4eb04d4f8bbf 100644 --- a/sw/source/filter/ww8/rtfexport.cxx +++ b/sw/source/filter/ww8/rtfexport.cxx @@ -56,6 +56,7 @@ #include <svtools/rtfkeywd.hxx> #include <filter/msfilter/rtfutil.hxx> #include <unotools/docinfohelper.hxx> +#include <unotools/securityoptions.hxx> #include <xmloff/odffields.hxx> #include <o3tl/string_view.hxx> #include <osl/diagnose.h> @@ -272,6 +273,11 @@ void RtfExport::WriteRevTab() GetRedline(SW_MOD()->GetRedlineAuthor(pRedl->GetAuthor())); } + bool bRemoveCommentAuthorDates + = SvtSecurityOptions::IsOptionSet(SvtSecurityOptions::EOption::DocWarnRemovePersonalInfo) + && !SvtSecurityOptions::IsOptionSet( + SvtSecurityOptions::EOption::DocWarnKeepNoteAuthorDateInfo); + // Now write the table Strm() .WriteChar('{') @@ -283,7 +289,12 @@ void RtfExport::WriteRevTab() const OUString* pAuthor = GetRedline(i); Strm().WriteChar('{'); if (pAuthor) - Strm().WriteOString(msfilter::rtfutil::OutString(*pAuthor, m_eDefaultEncoding)); + { + OUString sAuthor(bRemoveCommentAuthorDates + ? "Author" + OUString::number(GetInfoID(*pAuthor)) + : *pAuthor); + Strm().WriteOString(msfilter::rtfutil::OutString(sAuthor, m_eDefaultEncoding)); + } Strm().WriteOString(";}"); } Strm().WriteChar('}').WriteOString(SAL_NEWLINE_STRING); @@ -1155,6 +1166,7 @@ RtfExport::RtfExport(RtfExportFilter* pFilter, SwDoc& rDocument, , m_eCurrentEncoding(m_eDefaultEncoding) , m_bRTFFlySyntax(false) , m_nCurrentNodeIndex(0) + , mpAuthorIDs(new SvtSecurityMapPersonalInfo) { m_bExportModeRTF = true; // the attribute output for the document diff --git a/sw/source/filter/ww8/rtfexport.hxx b/sw/source/filter/ww8/rtfexport.hxx index 1a24aaf3e151..9f56549b7ea0 100644 --- a/sw/source/filter/ww8/rtfexport.hxx +++ b/sw/source/filter/ww8/rtfexport.hxx @@ -23,6 +23,8 @@ #include <memory> #include "wrtww8.hxx" +#include <unotools/securityoptions.hxx> + class RtfAttributeOutput; class RtfExportFilter; class RtfSdrExport; @@ -202,6 +204,12 @@ public: const SfxItemSet* GetFirstPageItemSet() const { return m_pFirstPageItemSet; } + // Get author id to remove personal info + size_t GetInfoID(const OUString sPersonalInfo) const + { + return mpAuthorIDs->GetInfoID(sPersonalInfo); + } + private: void WriteFonts(); void WriteStyles(); @@ -229,6 +237,8 @@ private: std::unique_ptr<SvMemoryStream> m_pStream; /// Item set of the first page during export of a follow page format. const SfxItemSet* m_pFirstPageItemSet = nullptr; + /// map authors to remove personal info + std::unique_ptr<SvtSecurityMapPersonalInfo> mpAuthorIDs; }; #endif // INCLUDED_SW_SOURCE_FILTER_WW8_RTFEXPORT_HXX |