23#include <rtl/ustring.hxx>
24#include <rtl/ustrbuf.hxx>
26#include <osl/diagnose.h>
27#include <com/sun/star/frame/XModel.hpp>
28#include <com/sun/star/beans/XPropertySet.hpp>
29#include <com/sun/star/beans/UnknownPropertyException.hpp>
30#include <com/sun/star/container/XEnumerationAccess.hpp>
32#include <com/sun/star/container/XEnumeration.hpp>
33#include <com/sun/star/document/XRedlinesSupplier.hpp>
34#include <com/sun/star/text/XText.hpp>
35#include <com/sun/star/text/XTextContent.hpp>
36#include <com/sun/star/text/XTextSection.hpp>
37#include <com/sun/star/util/DateTime.hpp>
47#include <tools/datetime.hxx>
53using ::com::sun::star::beans::PropertyValue;
54using ::com::sun::star::beans::XPropertySet;
55using ::com::sun::star::beans::UnknownPropertyException;
56using ::com::sun::star::document::XRedlinesSupplier;
57using ::com::sun::star::container::XEnumerationAccess;
58using ::com::sun::star::container::XEnumeration;
59using ::com::sun::star::text::XText;
60using ::com::sun::star::text::XTextContent;
61using ::com::sun::star::text::XTextSection;
62using ::com::sun::star::uno::Any;
63using ::com::sun::star::uno::Reference;
64using ::com::sun::star::uno::Sequence;
72, pCurrentChangesList(nullptr)
83 const Reference<XPropertySet> & rPropSet,
119 const Reference<XText> & rText,
128 ChangesMapType::iterator aFind =
aChangeMap.find(rText);
135 if (rChangesList.empty())
144 for (
auto const& change : rChangesList)
153 const Reference<XText> & rText)
158 ChangesMapType::iterator aIter =
aChangeMap.find(rText);
161 auto rv =
aChangeMap.emplace(std::piecewise_construct, std::forward_as_tuple(rText), std::forward_as_tuple());
183 Reference<XRedlinesSupplier> xSupplier(
rExport.
GetModel(), uno::UNO_QUERY);
187 Reference<XEnumerationAccess> aEnumAccess = xSupplier->getRedlines();
193 bool bEnabled = *o3tl::doAccess<bool>(aDocPropertySet->getPropertyValue(
197 if ( !(aEnumAccess->hasElements() || bEnabled) )
202 if ( !bEnabled != !aEnumAccess->hasElements() )
215 Reference<XEnumeration> aEnum = aEnumAccess->createEnumeration();
216 while (aEnum->hasMoreElements())
218 Any aAny = aEnum->nextElement();
219 Reference<XPropertySet> xPropSet;
223 "can't get XPropertySet; skipping Redline");
228 aAny = xPropSet->getPropertyValue(
"IsInHeaderFooter");
229 if (! *o3tl::doAccess<bool>(aAny))
242 const Reference<XPropertySet> & rPropSet)
248 Any aIsStart = rPropSet->getPropertyValue(
"IsStart");
249 Any aIsCollapsed = rPropSet->getPropertyValue(
"IsCollapsed");
251 if ( *o3tl::doAccess<bool>(aIsStart) ||
252 *o3tl::doAccess<bool>(aIsCollapsed) )
257 Any aAny = rPropSet->getPropertyValue(
"RedlineText");
258 Reference<XText> xText;
270 Reference<XRedlinesSupplier> xSupplier(
rExport.
GetModel(), uno::UNO_QUERY);
274 Reference<XEnumerationAccess> aEnumAccess = xSupplier->getRedlines();
277 if (!aEnumAccess->hasElements())
281 Reference<XEnumeration> aEnum = aEnumAccess->createEnumeration();
282 while (aEnum->hasMoreElements())
284 Any aAny = aEnum->nextElement();
285 Reference<XPropertySet> xPropSet;
289 "can't get XPropertySet; skipping Redline");
295 aAny = xPropSet->getPropertyValue(
"IsInHeaderFooter");
296 if (! *o3tl::doAccess<bool>(aAny))
305 const Reference<XPropertySet> & rPropSet)
309 Any aAny = rPropSet->getPropertyValue(
"IsCollapsed");
310 bool bCollapsed = *o3tl::doAccess<bool>(aAny);
317 aAny = rPropSet->getPropertyValue(
"IsStart");
318 const bool bStart = *o3tl::doAccess<bool>(aAny);
330 eElement,
false,
false);
336 const Reference<XPropertySet> & rPropSet)
342 Any aAny = rPropSet->getPropertyValue(
"MergeLastPara");
343 if( ! *o3tl::doAccess<bool>(aAny) )
354 aAny = rPropSet->getPropertyValue(
"RedlineType");
363 aAny = rPropSet->getPropertyValue(
"RedlineText");
364 Reference<XText> xText;
377 aAny = rPropSet->getPropertyValue(
"RedlineSuccessorData");
378 Sequence<PropertyValue> aSuccessorData;
379 aAny >>= aSuccessorData;
383 if (aSuccessorData.hasElements())
400 std::u16string_view sApiName)
402 if (sApiName ==
u"Delete")
406 else if (sApiName ==
u"Insert")
410 else if (sApiName ==
u"Format")
416 OSL_FAIL(
"unknown redline type");
417 static const OUString sUnknownChange(
"UnknownChange");
418 return sUnknownChange;
425 const Reference<XPropertySet> & rPropSet)
427 Any aAny = rPropSet->getPropertyValue(
"RedlineIdentifier");
436 const Reference<XPropertySet> & rPropSet)
444 Any aAny = rPropSet->getPropertyValue(
"RedlineAuthor");
457 aAny = rPropSet->getPropertyValue(
"RedlineDateTime");
458 util::DateTime aDateTime;
463 ? util::DateTime(0, 0, 0, 0, 1, 1, 1970,
true)
464 : aDateTime,
nullptr);
472 aAny = rPropSet->getPropertyValue(
"RedlineComment");
479 const Sequence<PropertyValue> & rPropertyValues)
488 for(
const PropertyValue& rVal : rPropertyValues)
490 if( rVal.Name ==
"RedlineAuthor" )
504 else if( rVal.Name ==
"RedlineComment" )
506 rVal.Value >>= sComment;
508 else if( rVal.Name ==
"RedlineDateTime" )
510 util::DateTime aDateTime;
511 rVal.Value >>= aDateTime;
514 ? util::DateTime(0, 0, 0, 0, 1, 1, 1970,
true)
515 : aDateTime,
nullptr);
521 else if( rVal.Name ==
"RedlineType" )
527 "hierarchical change must be insertion");
537 const Reference<XPropertySet> & rPropSet,
540 if( ! rPropSet.is() )
547 aAny = rPropSet->getPropertyValue(bStart ? OUString(
"StartRedline") : OUString(
"EndRedline"));
549 catch(
const UnknownPropertyException&)
555 Sequence<PropertyValue> aValues;
559 bool bIsCollapsed =
false;
560 bool bIsStart =
true;
563 for(
const auto& rValue : std::as_const(aValues))
565 if (rValue.Name ==
"RedlineIdentifier")
567 rValue.Value >>=
sId;
570 else if (rValue.Name ==
"IsCollapsed")
572 bIsCollapsed = *o3tl::doAccess<bool>(rValue.Value);
574 else if (rValue.Name ==
"IsStart")
576 bIsStart = *o3tl::doAccess<bool>(rValue.Value);
599 const Reference<XTextContent> & rContent,
602 Reference<XPropertySet> xPropSet(rContent, uno::UNO_QUERY);
609 OSL_FAIL(
"XPropertySet expected");
614 const Reference<XTextSection> & rSection,
617 Reference<XPropertySet> xPropSet(rSection, uno::UNO_QUERY);
624 OSL_FAIL(
"XPropertySet expected");
630 if (rComment.empty())
636 std::u16string_view aSubString;
::std::vector< css::uno::Reference< css::beans::XPropertySet > > ChangesVectorType
rtl::Reference< XMLTextParagraphExport > const & GetTextParagraphExport()
void AddAttribute(sal_uInt16 nPrefix, const OUString &rName, const OUString &rValue)
void Characters(const OUString &rChars)
const css::uno::Reference< css::frame::XModel > & GetModel() const
void SAL_DLLPRIVATE AddAttributeIdLegacy(sal_uInt16 const nLegacyPrefix, OUString const &rValue)
add xml:id and legacy namespace id
size_t GetInfoID(const OUString sPersonalInfo) const
bool getNextToken(std::u16string_view &rToken)
void ExportChangeInline(const css::uno::Reference< css::beans::XPropertySet > &rPropSet)
export the change mark contained in the text body
void ExportChangeAutoStyle(const css::uno::Reference< css::beans::XPropertySet > &rPropSet)
export the auto styles used in this change
ChangesVectorType * pCurrentChangesList
map of recorded changes
void ExportChangesListElements()
export the changes list (<text:tracked-changes>)
void ExportChangesListAutoStyles()
export the auto styles needed by the changes list
OUString const & ConvertTypeName(std::u16string_view sApiName)
convert the change type from API to XML names
void WriteComment(std::u16string_view rComment)
write a comment string as sequence of <text:p> elements
void ExportStartOrEndRedline(const css::uno::Reference< css::beans::XPropertySet > &rPropSet, bool bStart)
export redline marks which start or end at start nodes, i.e.
static OUString GetRedlineID(const css::uno::Reference< css::beans::XPropertySet > &rPropSet)
Get ID string!
void ExportChangedRegion(const css::uno::Reference< css::beans::XPropertySet > &rPropSet)
export the changed-region element
void ExportChange(const css::uno::Reference< css::beans::XPropertySet > &rPropSet, bool bAutoStyle)
export a change
const OUString sFormatChange
void ExportChangeInfo(const css::uno::Reference< css::beans::XPropertySet > &rPropSet)
export a change-info element (from a PropertySet)
void SetCurrentXText()
Do not record changes.
void ExportChangesList(bool bAutoStyles)
export the list of changes (complete list minus recorded changed)
ChangesMapType aChangeMap
XMLRedlineExport(SvXMLExport &rExp)
const OUString sInsertion
static void convertDateTime(OUStringBuffer &rBuffer, const css::util::DateTime &rDateTime, sal_Int16 const *pTimeZoneOffset, bool bAddTimeIf0AM=false)
#define DBG_ASSERT(sCon, aError)
#define SAL_WARN_IF(condition, area, stream)
@ DocWarnRemovePersonalInfo
bool IsOptionSet(EOption eOption)
Handling of tokens in XML:
XMLTokenEnum
The enumeration of all XML tokens.
@ XML_MERGE_LAST_PARAGRAPH
const OUString & GetXMLToken(enum XMLTokenEnum eToken)
return the OUString representation for eToken
constexpr sal_uInt16 XML_NAMESPACE_DC
constexpr sal_uInt16 XML_NAMESPACE_TEXT
constexpr sal_uInt16 XML_NAMESPACE_OFFICE