summaryrefslogtreecommitdiff
path: root/writerfilter/source/dmapper/DomainMapper_Impl.cxx
diff options
context:
space:
mode:
authorMike Kaganski <mike.kaganski@collabora.com>2024-01-02 17:12:06 +0600
committerMike Kaganski <mike.kaganski@collabora.com>2024-01-03 03:16:18 +0100
commit960e37af28807ed1b376e26c4504ab755a81dfd5 (patch)
treee587de5d3fc5eb23412d97dee29981b050a67de1 /writerfilter/source/dmapper/DomainMapper_Impl.cxx
parent9c9f5c9ed7a1d11fd34be6af5b09f836ed442211 (diff)
tdf#158971: Only copy directly-set properties
Commit f09420fa189be5165b0311083ba127073500a121 (tdf#158855: Make sure to not add extra paragraph after a table in a section, 2023-12-25) had implemented copying all attributes of a paragraph using copyAllProps. But the function didn't check the states of properties, so copied also default values of properties, making them direct properties of the paragraph. Due to tdf#158972, that caused an assertion when saving, and the main problem was a set of direct properties in the paragraph. Fix that by checking the properties states. Also make sure to work with paragraphs, rather than with ranges, which treats any properties set on paragraph level as default-state on the run level. Change-Id: I7cd9c7fbb9313d666c46be201913f0223a6b4f5e Reviewed-on: https://gerrit.libreoffice.org/c/core/+/161539 Tested-by: Jenkins Reviewed-by: Mike Kaganski <mike.kaganski@collabora.com>
Diffstat (limited to 'writerfilter/source/dmapper/DomainMapper_Impl.cxx')
-rw-r--r--writerfilter/source/dmapper/DomainMapper_Impl.cxx36
1 files changed, 22 insertions, 14 deletions
diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.cxx b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
index 7d02be6dfd49..ecad048dd529 100644
--- a/writerfilter/source/dmapper/DomainMapper_Impl.cxx
+++ b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
@@ -3517,8 +3517,6 @@ static void checkAndAddPropVal(const OUString& prop, const css::uno::Any& val,
// Avoid well-known reasons for exceptions when setting property values
if (!val.hasValue())
return;
- if (prop == "CharAutoStyleName" || prop == "ParaAutoStyleName")
- return;
if (prop == "CharStyleName" || prop == "DropCapCharStyleName")
if (OUString val_string; (val >>= val_string) && val_string.isEmpty())
return;
@@ -3527,6 +3525,13 @@ static void checkAndAddPropVal(const OUString& prop, const css::uno::Any& val,
values.push_back(val);
}
+static uno::Reference<lang::XComponent>
+getParagraphOfRange(const css::uno::Reference<css::text::XTextRange>& xRange)
+{
+ uno::Reference<container::XEnumerationAccess> xEA{ xRange, uno::UNO_QUERY_THROW };
+ return { xEA->createEnumeration()->nextElement(), uno::UNO_QUERY_THROW };
+}
+
static void copyAllProps(const css::uno::Reference<css::uno::XInterface>& from,
const css::uno::Reference<css::uno::XInterface>& to)
{
@@ -3539,6 +3544,17 @@ static void copyAllProps(const css::uno::Reference<css::uno::XInterface>& from,
for (const auto& prop : rawProps)
if ((prop.Attributes & css::beans::PropertyAttribute::READONLY) == 0)
props.push_back(prop.Name);
+
+ if (css::uno::Reference<css::beans::XPropertyState> xFromState{ from, css::uno::UNO_QUERY })
+ {
+ const auto propsSeq = comphelper::containerToSequence(props);
+ const auto statesSeq = xFromState->getPropertyStates(propsSeq);
+ assert(propsSeq.getLength() == statesSeq.getLength());
+ for (sal_Int32 i = 0; i < propsSeq.getLength(); ++i)
+ if (statesSeq[i] != css::beans::PropertyState_DIRECT_VALUE)
+ std::erase(props, propsSeq[i]);
+ }
+
std::vector<css::uno::Any> values;
values.reserve(props.size());
if (css::uno::Reference<css::beans::XMultiPropertySet> xFromMulti{ xFromProps,
@@ -3614,12 +3630,11 @@ uno::Reference< beans::XPropertySet > DomainMapper_Impl::appendTextSectionAfter(
// table; then trying to go left would skip the whole table. Split the trailing
// paragraph; let the section span over the first of the two resulting paragraphs;
// destroy the last section's paragraph afterwards.
- css::uno::Reference<css::text::XTextRange> xEndPara = xCursor->getEnd();
xTextAppend->insertControlCharacter(
- xEndPara, css::text::ControlCharacter::PARAGRAPH_BREAK, false);
- css::uno::Reference<css::text::XTextRange> xNewPara = xCursor->getEnd();
+ xCursor->getEnd(), css::text::ControlCharacter::PARAGRAPH_BREAK, false);
+ auto xNewPara = getParagraphOfRange(xCursor->getEnd());
xCursor->gotoPreviousParagraph(true);
- xEndPara = xCursor->getEnd();
+ auto xEndPara = getParagraphOfRange(xCursor->getEnd());
// xEndPara may already have properties (like page break); make sure to apply them
// to the newly appended paragraph, which will be kept in the end.
copyAllProps(xEndPara, xNewPara);
@@ -3628,14 +3643,7 @@ uno::Reference< beans::XPropertySet > DomainMapper_Impl::appendTextSectionAfter(
xSection->attach(xCursor);
// Remove the extra paragraph (last inside the section)
- if (uno::Reference<container::XEnumerationAccess> xEA{ xEndPara, uno::UNO_QUERY })
- {
- if (uno::Reference<lang::XComponent> xParagraph{
- xEA->createEnumeration()->nextElement(), uno::UNO_QUERY })
- {
- xParagraph->dispose();
- }
- }
+ xEndPara->dispose();
xRet.set(xSection, uno::UNO_QUERY );
}