[Libreoffice-commits] core.git: Branch 'feature/cib_contract3753' - 36 commits - basctl/source cui/source download.lst external/nss filter/source icon-themes/breeze icon-themes/breeze_dark icon-themes/breeze_dark_svg icon-themes/breeze_svg icon-themes/karasa_jaga icon-themes/karasa_jaga_svg icon-themes/sifr icon-themes/sifr_dark icon-themes/sifr_dark_svg icon-themes/sifr_svg include/oox oox/source sw/inc sw/qa sw/source writerfilter/source
Michael Stahl (via logerrit)
logerrit at kemper.freedesktop.org
Wed Aug 26 18:24:02 UTC 2020
Rebased ref, commits from common ancestor:
commit 3a2df7388cc8a53382da0b5b23792bbca70e1d5e
Author: Michael Stahl <Michael.Stahl at cib.de>
AuthorDate: Wed Aug 26 17:08:00 2020 +0200
Commit: Michael Stahl <Michael.Stahl at cib.de>
CommitDate: Wed Aug 26 20:06:05 2020 +0200
sw: DOCX export: don't export text frames as transparent
Writer paints text frames without fill still as opaque but nothing is
written in the DOCX file and Word by default treats DrawingML text frame
as transparent (the VML fallback is opaque though).
Change-Id: I0ce539ac8084c5047b4732abc5c199589ee369ee
diff --git a/sw/qa/extras/ooxmlexport/data/frame.fodt b/sw/qa/extras/ooxmlexport/data/frame.fodt
new file mode 100644
index 000000000000..c474b8de5e9e
--- /dev/null
+++ b/sw/qa/extras/ooxmlexport/data/frame.fodt
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<office:document xmlns:css3t="http://www.w3.org/TR/css3-text/" xmlns:chart="urn:oasis:names:tc:opendocument:xmlns:chart:1.0" xmlns:svg="urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0" xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" xmlns:oooc="http://openoffice.org/2004/calc" xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0" xmlns:ooow="http://openoffice.org/2004/writer" xmlns:meta="urn:oasis:names:tc:opendocument:xmlns:meta:1.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rpt="http://openoffice.org/2005/report" xmlns:draw="urn:oasis:names:tc:opendocument:xmlns:drawing:1.0" xmlns:config="urn:oasis:names:tc:opendocument:xmlns:config:1.0" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0" xmlns:ooo="http://openoffice.org/2004/office" xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" xmlns:formx="urn:openoffice:names:experimental:ooxml-odf-interop:xmlns:form:1.0" xmlns:d
r3d="urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0" xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0" xmlns:number="urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0" xmlns:of="urn:oasis:names:tc:opendocument:xmlns:of:1.2" xmlns:math="http://www.w3.org/1998/Math/MathML" xmlns:form="urn:oasis:names:tc:opendocument:xmlns:form:1.0" xmlns:script="urn:oasis:names:tc:opendocument:xmlns:script:1.0" xmlns:dom="http://www.w3.org/2001/xml-events" xmlns:xforms="http://www.w3.org/2002/xforms" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:grddl="http://www.w3.org/2003/g/data-view#" office:version="1.3" office:mimetype="application/vnd.oasis.opendocument.text">
+ <office:font-face-decls>
+ <style:font-face style:name="Liberation Serif" svg:font-family="'Liberation Serif'" style:font-family-generic="roman" style:font-pitch="variable"/>
+ <style:font-face style:name="Lohit Devanagari" svg:font-family="'Lohit Devanagari'" style:font-family-generic="system" style:font-pitch="variable"/>
+ <style:font-face style:name="Source Han Serif CN" svg:font-family="'Source Han Serif CN'" style:font-family-generic="system" style:font-pitch="variable"/>
+ </office:font-face-decls>
+ <office:styles>
+ <style:default-style style:family="graphic">
+ <style:graphic-properties svg:stroke-color="#3465a4" draw:fill-color="#729fcf" fo:wrap-option="no-wrap" draw:shadow-offset-x="0.3cm" draw:shadow-offset-y="0.3cm" draw:start-line-spacing-horizontal="0.283cm" draw:start-line-spacing-vertical="0.283cm" draw:end-line-spacing-horizontal="0.283cm" draw:end-line-spacing-vertical="0.283cm" style:flow-with-text="false"/>
+ <style:paragraph-properties style:text-autospace="ideograph-alpha" style:line-break="strict" style:writing-mode="lr-tb" style:font-independent-line-spacing="false">
+ <style:tab-stops/>
+ </style:paragraph-properties>
+ <style:text-properties style:use-window-font-color="true" style:font-name="Liberation Serif" fo:font-size="12pt" fo:language="de" fo:country="DE" style:letter-kerning="true" style:font-name-asian="Source Han Serif CN" style:font-size-asian="10.5pt" style:language-asian="zh" style:country-asian="CN" style:font-name-complex="Lohit Devanagari" style:font-size-complex="12pt" style:language-complex="hi" style:country-complex="IN"/>
+ </style:default-style>
+ <style:default-style style:family="paragraph">
+ <style:paragraph-properties fo:orphans="2" fo:widows="2" fo:hyphenation-ladder-count="no-limit" style:text-autospace="ideograph-alpha" style:punctuation-wrap="hanging" style:line-break="strict" style:tab-stop-distance="1.251cm" style:writing-mode="page"/>
+ <style:text-properties style:use-window-font-color="true" style:font-name="Liberation Serif" fo:font-size="12pt" fo:language="de" fo:country="DE" style:letter-kerning="true" style:font-name-asian="Source Han Serif CN" style:font-size-asian="10.5pt" style:language-asian="zh" style:country-asian="CN" style:font-name-complex="Lohit Devanagari" style:font-size-complex="12pt" style:language-complex="hi" style:country-complex="IN" fo:hyphenate="false" fo:hyphenation-remain-char-count="2" fo:hyphenation-push-char-count="2"/>
+ </style:default-style>
+ <style:default-style style:family="table">
+ <style:table-properties table:border-model="collapsing"/>
+ </style:default-style>
+ <style:default-style style:family="table-row">
+ <style:table-row-properties fo:keep-together="auto"/>
+ </style:default-style>
+ <style:style style:name="Standard" style:family="paragraph" style:class="text"/>
+ <style:style style:name="Frame_20_contents" style:display-name="Frame contents" style:family="paragraph" style:parent-style-name="Standard" style:class="extra"/>
+ <style:style style:name="Frame" style:family="graphic">
+ <style:graphic-properties text:anchor-type="paragraph" svg:x="0cm" svg:y="0cm" fo:margin-left="0.201cm" fo:margin-right="0.201cm" fo:margin-top="0.201cm" fo:margin-bottom="0.201cm" style:wrap="parallel" style:number-wrapped-paragraphs="no-limit" style:wrap-contour="false" style:vertical-pos="top" style:vertical-rel="paragraph-content" style:horizontal-pos="center" style:horizontal-rel="paragraph-content" fo:padding="0.15cm" fo:border="0.06pt solid #000000"/>
+ </style:style>
+
+ <text:notes-configuration text:note-class="footnote" style:num-format="1" text:start-value="0" text:footnotes-position="page" text:start-numbering-at="document"/>
+ <text:notes-configuration text:note-class="endnote" style:num-format="i" text:start-value="0"/>
+ <text:linenumbering-configuration text:number-lines="false" text:offset="0.499cm" style:num-format="1" text:number-position="left" text:increment="5"/>
+ </office:styles>
+ <office:automatic-styles>
+ <style:style style:name="fr1" style:family="graphic" style:parent-style-name="Frame">
+ <style:graphic-properties style:wrap="run-through" style:number-wrapped-paragraphs="no-limit" style:vertical-pos="from-top" style:vertical-rel="paragraph" style:horizontal-pos="from-left" style:horizontal-rel="paragraph" draw:opacity="0%" draw:wrap-influence-on-position="once-concurrent"/>
+ </style:style>
+ <style:style style:name="fr2" style:family="graphic" style:parent-style-name="Frame">
+ <style:graphic-properties style:wrap="run-through" style:number-wrapped-paragraphs="no-limit" style:vertical-pos="from-top" style:vertical-rel="paragraph" style:horizontal-pos="from-left" style:horizontal-rel="paragraph" fo:background-color="#e8f2a1" draw:fill="solid" draw:fill-color="#e8f2a1" draw:wrap-influence-on-position="once-concurrent"/>
+ </style:style>
+ <style:style style:name="fr3" style:family="graphic" style:parent-style-name="Frame">
+ <style:graphic-properties style:run-through="foreground" style:wrap="run-through" style:number-wrapped-paragraphs="no-limit" style:vertical-pos="from-top" style:vertical-rel="paragraph" style:horizontal-pos="from-left" style:horizontal-rel="paragraph"/>
+ </style:style>
+ <style:page-layout style:name="pm1">
+ <style:page-layout-properties fo:page-width="21.001cm" fo:page-height="29.7cm" style:num-format="1" style:print-orientation="portrait" fo:margin-top="2cm" fo:margin-bottom="2cm" fo:margin-left="2cm" fo:margin-right="2cm" style:writing-mode="lr-tb" style:layout-grid-color="#c0c0c0" style:layout-grid-lines="20" style:layout-grid-base-height="0.706cm" style:layout-grid-ruby-height="0.353cm" style:layout-grid-mode="none" style:layout-grid-ruby-below="false" style:layout-grid-print="false" style:layout-grid-display="false" style:footnote-max-height="0cm">
+ <style:footnote-sep style:width="0.018cm" style:distance-before-sep="0.101cm" style:distance-after-sep="0.101cm" style:line-style="solid" style:adjustment="left" style:rel-width="25%" style:color="#000000"/>
+ </style:page-layout-properties>
+ <style:header-style/>
+ <style:footer-style/>
+ </style:page-layout>
+ </office:automatic-styles>
+ <office:master-styles>
+ <style:master-page style:name="Standard" style:page-layout-name="pm1"/>
+ </office:master-styles>
+ <office:body>
+ <office:text>
+ <text:p text:style-name="Standard"><draw:frame draw:style-name="fr3" draw:name="Frame1" text:anchor-type="paragraph" svg:x="0.87cm" svg:y="0cm" svg:width="2cm" draw:z-index="0">
+ <draw:text-box fo:min-height="0.499cm">
+ <text:p text:style-name="Frame_20_contents">opaque</text:p>
+ </draw:text-box>
+ </draw:frame><draw:frame draw:style-name="fr2" draw:name="Frame2" text:anchor-type="paragraph" svg:x="3.069cm" svg:y="0cm" svg:width="2cm" draw:z-index="1">
+ <draw:text-box fo:min-height="0.499cm">
+ <text:p text:style-name="Frame_20_contents">solid</text:p>
+ </draw:text-box>
+ </draw:frame><draw:frame draw:style-name="fr1" draw:name="Frame3" text:anchor-type="paragraph" svg:x="5.33cm" svg:y="0cm" svg:width="2.281cm" draw:z-index="2">
+ <draw:text-box fo:min-height="0.499cm">
+ <text:p text:style-name="Frame_20_contents">transparent</text:p>
+ </draw:text-box>
+ </draw:frame></text:p>
+ </office:text>
+ </office:body>
+</office:document>
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport6.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport6.cxx
index a8fe7ac73ea0..4318856bdae2 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport6.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport6.cxx
@@ -142,6 +142,29 @@ DECLARE_OOXMLEXPORT_TEST(testDMLSolidfillAlpha, "dml-solidfill-alpha.docx")
CPPUNIT_ASSERT_EQUAL(sal_Int16(20), getProperty<sal_Int16>(xShape, "FillTransparence"));
}
+DECLARE_OOXMLEXPORT_TEST(testDMLTextFrameNoFill, "frame.fodt")
+{
+ // Problem is that default text frame background is white in Writer and transparent in Word
+ uno::Reference<beans::XPropertySet> xShape1(getShape(1), uno::UNO_QUERY);
+// it is re-imported as solid
+// CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_NONE, getProperty<drawing::FillStyle>(xShape1, "FillStyle"));
+ CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_SOLID, getProperty<drawing::FillStyle>(xShape1, "FillStyle"));
+ CPPUNIT_ASSERT_EQUAL(sal_Int16(0), getProperty<sal_Int16>(xShape1, "FillTransparence"));
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(0xffffff), getProperty<sal_Int32>(xShape1, "FillColor"));
+
+ uno::Reference<beans::XPropertySet> xShape2(getShape(2), uno::UNO_QUERY);
+ CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_SOLID, getProperty<drawing::FillStyle>(xShape2, "FillStyle"));
+ CPPUNIT_ASSERT_EQUAL(sal_Int16(0), getProperty<sal_Int16>(xShape2, "FillTransparence"));
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(0xE8F2A1), getProperty<sal_Int32>(xShape2, "FillColor"));
+
+ uno::Reference<beans::XPropertySet> xShape3(getShape(3), uno::UNO_QUERY);
+// it is re-imported as solid
+// CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_NONE, getProperty<drawing::FillStyle>(xShape3, "FillStyle"));
+ CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_SOLID, getProperty<drawing::FillStyle>(xShape3, "FillStyle"));
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(0xffffff), getProperty<sal_Int32>(xShape3, "FillColor"));
+ CPPUNIT_ASSERT_EQUAL(sal_Int16(100), getProperty<sal_Int16>(xShape3, "FillTransparence"));
+}
+
DECLARE_OOXMLEXPORT_TEST(testDMLCustomGeometry, "dml-customgeometry-cubicbezier.docx")
{
diff --git a/sw/source/filter/ww8/attributeoutputbase.hxx b/sw/source/filter/ww8/attributeoutputbase.hxx
index 3d8daa633daa..38cd3f8893b3 100644
--- a/sw/source/filter/ww8/attributeoutputbase.hxx
+++ b/sw/source/filter/ww8/attributeoutputbase.hxx
@@ -668,6 +668,8 @@ public:
( ww8::WW8TableNodeInfoInner const * pTableTextNodeInfoInner,
long& rPageSize, bool& rRelBoxSize );
+ virtual void MaybeOutputBrushItem(SfxItemSet const&) { }
+
/// Exports the definition (image, size) of a single numbering picture bullet.
virtual void BulletDefinition(int /*nId*/, const Graphic& /*rGraphic*/, Size /*aSize*/) {}
diff --git a/sw/source/filter/ww8/docxattributeoutput.cxx b/sw/source/filter/ww8/docxattributeoutput.cxx
index c03d971e8fdc..867b7a446436 100644
--- a/sw/source/filter/ww8/docxattributeoutput.cxx
+++ b/sw/source/filter/ww8/docxattributeoutput.cxx
@@ -90,9 +90,11 @@
#include <editeng/editobj.hxx>
#include <editeng/keepitem.hxx>
#include <svx/xfillit0.hxx>
+#include <svx/xflclit.hxx>
#include <svx/xflgrit.hxx>
#include <svx/fmglob.hxx>
#include <svx/svdouno.hxx>
+#include <svx/unobrushitemhelper.hxx>
#include <svl/grabbagitem.hxx>
#include <sfx2/sfxbasemodel.hxx>
#include <tools/datetimeutils.hxx>
@@ -5822,6 +5824,27 @@ oox::drawingml::DrawingML& DocxAttributeOutput::GetDrawingML()
return m_rDrawingML;
}
+void DocxAttributeOutput::MaybeOutputBrushItem(SfxItemSet const& rSet)
+{
+ const XFillStyleItem* pXFillStyleItem(rSet.GetItem<XFillStyleItem>(XATTR_FILLSTYLE));
+
+ if ((pXFillStyleItem && pXFillStyleItem->GetValue() != drawing::FillStyle_NONE)
+ || !m_rExport.SdrExporter().getDMLTextFrameSyntax())
+ {
+ return;
+ }
+
+ // sw text frames are opaque by default, even with fill none!
+ std::unique_ptr<SfxItemSet> const pClone(rSet.Clone());
+ XFillColorItem const aColor(OUString(), COL_WHITE);
+ pClone->Put(aColor);
+ // call getSvxBrushItemForSolid - this also takes XFillTransparenceItem into account
+ XFillStyleItem const aSolid(drawing::FillStyle_SOLID);
+ pClone->Put(aSolid);
+ std::unique_ptr<SvxBrushItem> const pBrush(getSvxBrushItemFromSourceSet(*pClone, RES_BACKGROUND));
+ FormatBackground(*pBrush);
+}
+
/// Functor to do case-insensitive ordering of OUString instances.
struct OUStringIgnoreCase
{
@@ -8615,6 +8638,7 @@ void DocxAttributeOutput::FormatBox( const SvxBoxItem& rBox )
{
if (m_rExport.SdrExporter().getDMLTextFrameSyntax())
{
+ // ugh, exporting fill here is quite some hack... this OutputItemSet abstraction is quite leaky
// <a:gradFill> should be before <a:ln>.
const SfxPoolItem* pItem = GetExport().HasItem(XATTR_FILLSTYLE);
if (pItem)
diff --git a/sw/source/filter/ww8/docxattributeoutput.hxx b/sw/source/filter/ww8/docxattributeoutput.hxx
index a7733d62209b..2b6e83dde2d6 100644
--- a/sw/source/filter/ww8/docxattributeoutput.hxx
+++ b/sw/source/filter/ww8/docxattributeoutput.hxx
@@ -1013,6 +1013,7 @@ public:
virtual OUString FindRelId(BitmapChecksum nChecksum) override;
virtual void CacheRelId(BitmapChecksum nChecksum, const OUString& rRelId) override;
virtual oox::drawingml::DrawingML& GetDrawingML() override;
+ virtual void MaybeOutputBrushItem(SfxItemSet const&) override;
void BulletDefinition(int nId, const Graphic& rGraphic, Size aSize) override;
diff --git a/sw/source/filter/ww8/ww8atr.cxx b/sw/source/filter/ww8/ww8atr.cxx
index 952f6ab140db..429abb63dbf9 100644
--- a/sw/source/filter/ww8/ww8atr.cxx
+++ b/sw/source/filter/ww8/ww8atr.cxx
@@ -332,6 +332,8 @@ void MSWordExportBase::OutputItemSet( const SfxItemSet& rSet, bool bPapFormat, b
ExportPoolItemsToCHP(aItems, nScript, nullptr);
if ( bPapFormat )
{
+ AttrOutput().MaybeOutputBrushItem(rSet);
+
for ( const auto& rItem : aItems )
{
pItem = rItem.second;
@@ -350,6 +352,13 @@ void MSWordExportBase::OutputItemSet( const SfxItemSet& rSet, bool bPapFormat, b
std::shared_ptr<SvxBrushItem> aBrush(getSvxBrushItemFromSourceSet(rSet, RES_BACKGROUND));
AttrOutput().OutputItem(*aBrush);
}
+#if 0
+ else
+ {
+ // note: *does not work* due to undocumented Word behavior: must be before a:ln element at least
+ AttrOutput().MaybeOutputBrushItem(rSet);
+ }
+#endif
}
m_pISet = nullptr; // for double attributes
}
commit 8b77adebd25638946749ce2ff6d09eece78a78bf
Author: Michael Stahl <Michael.Stahl at cib.de>
AuthorDate: Thu Aug 13 11:07:37 2020 +0200
Commit: Michael Stahl <Michael.Stahl at cib.de>
CommitDate: Wed Aug 26 19:59:50 2020 +0200
sw: DOCX export: for soft-page-breaks, export continuous section breaks
When a section break is produced based on layout information such as
soft-page-break and follow page style, it's a bad idea to generate a
page break because the break may be in a different position in Word,
particularly if it was inside a fieldmark instruction.
It wouldn't work that well to ignore such page breaks in
MSWordExportBase::NeedTextNodeSplit() because then they would be created
when reaching the next node anyway, via FindPageDesc() fall-back to
layout.
Unfortunately this breaks the test tdf113849_evenAndOddHeaders.odt
which has a page style with follow-page-style on the first page; on
re-import from DOCX, the continuous section is now no longer converted
to a page break, so pages 2-3 have the wrong header/footers... this
seems impossible to fix in general in the import because it doesn't know
whether the continuous section break coincides with a layout page break.
Arguably this worked before mostly by accident? tdf#113849 isn't about
this afaics... Change the test file to have an explicit page break
there, which round-trips as intended. The real fix would be adding
continuous page style change to Writer i guess...
Change-Id: I00ffe3971607c148a7d5c13b89afb936718611c0
diff --git a/sw/qa/extras/ooxmlexport/data/tdf113849_evenAndOddHeaders.odt b/sw/qa/extras/ooxmlexport/data/tdf113849_evenAndOddHeaders.odt
index d9aa0ae23541..ae9b2af14ee7 100644
Binary files a/sw/qa/extras/ooxmlexport/data/tdf113849_evenAndOddHeaders.odt and b/sw/qa/extras/ooxmlexport/data/tdf113849_evenAndOddHeaders.odt differ
diff --git a/sw/source/filter/ww8/docxexport.cxx b/sw/source/filter/ww8/docxexport.cxx
index a212f4e5c9b8..74f06116484a 100644
--- a/sw/source/filter/ww8/docxexport.cxx
+++ b/sw/source/filter/ww8/docxexport.cxx
@@ -619,7 +619,8 @@ sal_uLong DocxExport::ReplaceCr( sal_uInt8 )
void DocxExport::PrepareNewPageDesc( const SfxItemSet* pSet,
const SwNode& rNd, const SwFormatPageDesc* pNewPgDescFormat,
- const SwPageDesc* pNewPgDesc )
+ const SwPageDesc* pNewPgDesc,
+ bool const bViaLayout)
{
// tell the attribute output that we are ready to write the section
// break [has to be output inside paragraph properties]
@@ -632,13 +633,12 @@ void DocxExport::PrepareNewPageDesc( const SfxItemSet* pSet,
if ( pNewPgDescFormat )
{
- m_pSections->AppendSection( *pNewPgDescFormat, rNd, pFormat, nLnNm );
+ m_pSections->AppendSection(*pNewPgDescFormat, rNd, pFormat, nLnNm, bViaLayout);
}
else if ( pNewPgDesc )
{
- m_pSections->AppendSection( pNewPgDesc, rNd, pFormat, nLnNm );
+ m_pSections->AppendSection(pNewPgDesc, rNd, pFormat, nLnNm, bViaLayout);
}
-
}
void DocxExport::InitStyles()
diff --git a/sw/source/filter/ww8/docxexport.hxx b/sw/source/filter/ww8/docxexport.hxx
index 00b908dc7efa..35e37a98ae39 100644
--- a/sw/source/filter/ww8/docxexport.hxx
+++ b/sw/source/filter/ww8/docxexport.hxx
@@ -218,7 +218,8 @@ protected:
virtual void PrepareNewPageDesc( const SfxItemSet* pSet,
const SwNode& rNd,
const SwFormatPageDesc* pNewPgDescFormat,
- const SwPageDesc* pNewPgDesc ) override;
+ const SwPageDesc* pNewPgDesc,
+ bool bViaLayout ) override;
private:
/// Setup pStyles and write styles.xml
diff --git a/sw/source/filter/ww8/rtfexport.cxx b/sw/source/filter/ww8/rtfexport.cxx
index 366cc18b3b0c..0e8733b48d63 100644
--- a/sw/source/filter/ww8/rtfexport.cxx
+++ b/sw/source/filter/ww8/rtfexport.cxx
@@ -948,7 +948,7 @@ ErrCode RtfExport::ExportDocument_Impl()
void RtfExport::PrepareNewPageDesc(const SfxItemSet* pSet, const SwNode& rNd,
const SwFormatPageDesc* pNewPgDescFormat,
- const SwPageDesc* pNewPgDesc)
+ const SwPageDesc* pNewPgDesc, bool const)
{
const SwSectionFormat* pFormat = GetSectionFormat(rNd);
const sal_uLong nLnNm = GetSectionLineNo(pSet, rNd);
diff --git a/sw/source/filter/ww8/rtfexport.hxx b/sw/source/filter/ww8/rtfexport.hxx
index 055aa50ff04e..527574ad701e 100644
--- a/sw/source/filter/ww8/rtfexport.hxx
+++ b/sw/source/filter/ww8/rtfexport.hxx
@@ -125,8 +125,8 @@ protected:
/// Get ready for a new section.
void PrepareNewPageDesc(const SfxItemSet* pSet, const SwNode& rNd,
- const SwFormatPageDesc* pNewPgDescFormat,
- const SwPageDesc* pNewPgDesc) override;
+ const SwFormatPageDesc* pNewPgDescFormat, const SwPageDesc* pNewPgDesc,
+ bool bViaLayout) override;
/// Return value indicates if an inherited outline numbering is suppressed.
bool DisallowInheritingOutlineNumbering(const SwFormat& rFormat) override;
diff --git a/sw/source/filter/ww8/wrtw8nds.cxx b/sw/source/filter/ww8/wrtw8nds.cxx
index 36026312a332..b97c6f7950d0 100644
--- a/sw/source/filter/ww8/wrtw8nds.cxx
+++ b/sw/source/filter/ww8/wrtw8nds.cxx
@@ -2742,7 +2742,7 @@ void MSWordExportBase::OutputTextNode( SwTextNode& rNode )
// too.
const SwPageDesc* pNextPageDesc = m_pCurrentPageDesc->GetFollow();
assert(pNextPageDesc);
- PrepareNewPageDesc( rNode.GetpSwAttrSet(), rNode, nullptr , pNextPageDesc);
+ PrepareNewPageDesc( rNode.GetpSwAttrSet(), rNode, nullptr , pNextPageDesc, true);
}
}
else if (!bNeedParaSplit)
diff --git a/sw/source/filter/ww8/wrtw8sty.cxx b/sw/source/filter/ww8/wrtw8sty.cxx
index eb06b97195bb..e264d51a1ff2 100644
--- a/sw/source/filter/ww8/wrtw8sty.cxx
+++ b/sw/source/filter/ww8/wrtw8sty.cxx
@@ -1092,12 +1092,13 @@ const WW8_SepInfo* MSWordSections::CurrentSectionInfo()
}
void MSWordSections::AppendSection( const SwPageDesc* pPd,
- const SwSectionFormat* pSectionFormat, sal_uLong nLnNumRestartNo, bool bIsFirstParagraph )
+ const SwSectionFormat*const pSectionFormat, sal_uLong const nLnNumRestartNo,
+ bool const bIsFirstParagraph, bool const bIsContinuous)
{
if (HeaderFooterWritten()) {
return; // #i117955# prevent new sections in endnotes
}
- aSects.emplace_back( pPd, pSectionFormat, nLnNumRestartNo, boost::none, nullptr, bIsFirstParagraph );
+ aSects.emplace_back(pPd, pSectionFormat, nLnNumRestartNo, boost::none, nullptr, bIsFirstParagraph, bIsContinuous);
NeedsDocumentProtected( aSects.back() );
}
@@ -1112,13 +1113,14 @@ void WW8_WrPlcSepx::AppendSep( WW8_CP nStartCp, const SwPageDesc* pPd,
}
void MSWordSections::AppendSection( const SwFormatPageDesc& rPD,
- const SwNode& rNd, const SwSectionFormat* pSectionFormat, sal_uLong nLnNumRestartNo )
+ const SwNode& rNd, const SwSectionFormat*const pSectionFormat,
+ sal_uLong const nLnNumRestartNo, bool const bIsContinuous)
{
if (HeaderFooterWritten()) {
return; // #i117955# prevent new sections in endnotes
}
- WW8_SepInfo aI( rPD.GetPageDesc(), pSectionFormat, nLnNumRestartNo, rPD.GetNumOffset(), &rNd );
+ WW8_SepInfo aI(rPD.GetPageDesc(), pSectionFormat, nLnNumRestartNo, rPD.GetNumOffset(), &rNd, false, bIsContinuous);
aSects.push_back( aI );
NeedsDocumentProtected( aI );
@@ -1548,9 +1550,9 @@ void MSWordExportBase::SectionProperties( const WW8_SepInfo& rSepInfo, WW8_PdAtt
/* sprmSBkc, break code: 0 No break, 1 New column
2 New page, 3 Even page, 4 Odd page
*/
- sal_uInt8 nBreakCode = 2; // default start new page
+ sal_uInt8 nBreakCode = rSepInfo.isContinuous ? 0 : 2; // default start new page
bool bOutPgDscSet = true, bLeftRightPgChain = false, bOutputStyleItemSet = false;
- bool bEnsureHeaderFooterWritten = rSepInfo.pSectionFormat && rSepInfo.bIsFirstParagraph;
+ bool bEnsureHeaderFooterWritten = (rSepInfo.pSectionFormat && rSepInfo.bIsFirstParagraph) || rSepInfo.isContinuous;
const SwFrameFormat* pPdFormat = &pPd->GetMaster();
if ( rSepInfo.pSectionFormat )
{
diff --git a/sw/source/filter/ww8/wrtww8.hxx b/sw/source/filter/ww8/wrtww8.hxx
index 3f64071e2120..0e36006b9794 100644
--- a/sw/source/filter/ww8/wrtww8.hxx
+++ b/sw/source/filter/ww8/wrtww8.hxx
@@ -181,13 +181,16 @@ struct WW8_SepInfo
sal_uLong const nLnNumRestartNo;
::boost::optional<sal_uInt16> const oPgRestartNo;
bool const bIsFirstParagraph;
+ bool isContinuous;
WW8_SepInfo( const SwPageDesc* pPD, const SwSectionFormat* pFormat,
sal_uLong nLnRestart, ::boost::optional<sal_uInt16> oPgRestart = boost::none,
- const SwNode* pNd = nullptr, bool bIsFirstPara = false )
+ const SwNode* pNd = nullptr, bool bIsFirstPara = false,
+ bool bIsContinuous = false)
: pPageDesc( pPD ), pSectionFormat( pFormat ), pPDNd( pNd ),
nLnNumRestartNo( nLnRestart ), oPgRestartNo( oPgRestart ),
bIsFirstParagraph( bIsFirstPara )
+ , isContinuous(bIsContinuous)
{}
bool IsProtected() const;
@@ -216,11 +219,13 @@ public:
void AppendSection( const SwPageDesc* pPd,
const SwSectionFormat* pSectionFormat,
sal_uLong nLnNumRestartNo,
- bool bIsFirstParagraph = false );
+ bool bIsFirstParagraph = false,
+ bool bIsContinuous = false);
void AppendSection( const SwFormatPageDesc& rPd,
const SwNode& rNd,
const SwSectionFormat* pSectionFormat,
- sal_uLong nLnNumRestartNo );
+ sal_uLong nLnNumRestartNo,
+ bool bIsContinuous = false);
/// Number of columns based on the most recent WW8_SepInfo.
sal_uInt16 CurrentNumberOfColumns( const SwDoc &rDoc ) const;
@@ -857,7 +862,8 @@ protected:
virtual void PrepareNewPageDesc( const SfxItemSet* pSet,
const SwNode& rNd,
const SwFormatPageDesc* pNewPgDescFormat,
- const SwPageDesc* pNewPgDesc ) = 0;
+ const SwPageDesc* pNewPgDesc,
+ bool bViaLayout ) = 0;
/// Return value indicates if an inherited outline numbering is suppressed.
virtual bool DisallowInheritingOutlineNumbering(const SwFormat &rFormat) = 0;
@@ -1124,7 +1130,8 @@ public:
virtual void PrepareNewPageDesc( const SfxItemSet* pSet,
const SwNode& rNd,
const SwFormatPageDesc* pNewPgDescFormat,
- const SwPageDesc* pNewPgDesc ) override;
+ const SwPageDesc* pNewPgDesc,
+ bool bViaLayout ) override;
static void Out_BorderLine(ww::bytes& rO, const ::editeng::SvxBorderLine* pLine,
sal_uInt16 nDist, sal_uInt16 nSprmNo, sal_uInt16 nSprmNoVer9,
diff --git a/sw/source/filter/ww8/ww8atr.cxx b/sw/source/filter/ww8/ww8atr.cxx
index 80efe524b472..952f6ab140db 100644
--- a/sw/source/filter/ww8/ww8atr.cxx
+++ b/sw/source/filter/ww8/ww8atr.cxx
@@ -457,7 +457,9 @@ void MSWordExportBase::OutputSectionBreaks( const SfxItemSet *pSet, const SwNode
//section.
bool bBreakSet = false;
- const SwPageDesc * pPageDesc = rNd.FindPageDesc();
+ size_t idx(0);
+ const SwPageDesc * pPageDesc = rNd.FindPageDesc(&idx);
+ bool isViaLayout(idx == rNd.GetIndex());
// Even if pAktPageDesc != pPageDesc ,it might be because of the different header & footer types.
if (m_pCurrentPageDesc != pPageDesc)
@@ -524,6 +526,7 @@ void MSWordExportBase::OutputSectionBreaks( const SfxItemSet *pSet, const SwNode
static_cast<const SwFormatPageDesc*>(pItem)->GetRegisteredIn() != nullptr)
{
bBreakSet = true;
+ assert(!isViaLayout);
bNewPageDesc = true;
pPgDesc = static_cast<const SwFormatPageDesc*>(pItem);
m_pCurrentPageDesc = pPgDesc->GetPageDesc();
@@ -551,6 +554,7 @@ void MSWordExportBase::OutputSectionBreaks( const SfxItemSet *pSet, const SwNode
}
}
bBreakSet = true;
+ isViaLayout = false;
if ( !bRemoveHardBreakInsideTable )
{
@@ -617,7 +621,7 @@ void MSWordExportBase::OutputSectionBreaks( const SfxItemSet *pSet, const SwNode
if ( bNewPageDesc && m_pCurrentPageDesc )
{
- PrepareNewPageDesc( pSet, rNd, pPgDesc, m_pCurrentPageDesc );
+ PrepareNewPageDesc(pSet, rNd, pPgDesc, m_pCurrentPageDesc, isViaLayout);
}
m_bBreakBefore = false;
m_bPrevTextNodeIsEmpty = isTextNodeEmpty ;
@@ -632,7 +636,7 @@ bool MSWordExportBase::OutputFollowPageDesc( const SfxItemSet* pSet, const SwTex
m_pCurrentPageDesc &&
m_pCurrentPageDesc != m_pCurrentPageDesc->GetFollow() )
{
- PrepareNewPageDesc( pSet, *pNd, nullptr, m_pCurrentPageDesc->GetFollow() );
+ PrepareNewPageDesc(pSet, *pNd, nullptr, m_pCurrentPageDesc->GetFollow(), true);
bRet = true;
}
@@ -670,7 +674,8 @@ sal_uLong MSWordExportBase::GetSectionLineNo( const SfxItemSet* pSet, const SwNo
void WW8Export::PrepareNewPageDesc( const SfxItemSet*pSet,
const SwNode& rNd,
const SwFormatPageDesc* pNewPgDescFormat,
- const SwPageDesc* pNewPgDesc )
+ const SwPageDesc* pNewPgDesc,
+ bool const )
{
// The PageDescs will only be inserted in WW8Writer::pSepx with the corresponding
// position by the occurrences of PageDesc attributes. The construction and
commit 77c18475158efc7f3c48d36080c2f4c8e10b3403
Author: Michael Stahl <Michael.Stahl at cib.de>
AuthorDate: Thu Aug 6 14:12:04 2020 +0200
Commit: Michael Stahl <Michael.Stahl at cib.de>
CommitDate: Wed Aug 26 19:59:49 2020 +0200
sw: HACK to disble DrawingML export for rotated text shapes
Change-Id: I7542d0dd000b974ce490b9b81f3d85412e2409f2
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport.cxx
index 9a771a5f81b7..70b63e251495 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport.cxx
@@ -444,9 +444,11 @@ DECLARE_OOXMLEXPORT_TEST(testRot90Fliph, "rot90-fliph.docx")
// The problem was that a shape rotation of 90° got turned into 270° after roundtrip.
if (xmlDocPtr pXmlDoc = parseExport("word/document.xml"))
{
+#if 0
assertXPath(pXmlDoc, "//a:xfrm", "flipH", "1");
// This was 16200000 (270 * 60000).
assertXPath(pXmlDoc, "//a:xfrm", "rot", "5400000");
+#endif
}
}
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport15.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport15.cxx
index 3218ca060469..09ff67d0fb58 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport15.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport15.cxx
@@ -42,6 +42,7 @@ DECLARE_OOXMLEXPORT_TEST(testAtPageShapeRelOrientation, "rotated_shape.fodt")
if (!pXmlDocument)
return;
+#if 0
assertXPathContent(pXmlDocument, "/w:document/w:body/w:p/w:r/mc:AlternateContent[1]/mc:Choice/w:drawing/wp:anchor"
"/wp:positionH/wp:posOffset", "-480060");
assertXPath(pXmlDocument, "/w:document/w:body/w:p/w:r/mc:AlternateContent[1]/mc:Choice/w:drawing/wp:anchor"
@@ -60,13 +61,14 @@ DECLARE_OOXMLEXPORT_TEST(testAtPageShapeRelOrientation, "rotated_shape.fodt")
"/wp:positionV/wp:posOffset", "1080135");
assertXPath(pXmlDocument, "/w:document/w:body/w:p/w:r/w:drawing/wp:anchor"
"/wp:positionV", "relativeFrom", "page");
+#endif
// now test text rotation -> VML writing direction
- assertXPath(pXmlDocument, "/w:document/w:body/w:p/w:r/mc:AlternateContent[1]/mc:Fallback/w:pict/v:shape/v:textbox", "style", "mso-layout-flow-alt:bottom-to-top");
+ assertXPath(pXmlDocument, "/w:document/w:body/w:p/w:r/w:pict/v:shape/v:textbox", "style", "mso-layout-flow-alt:bottom-to-top");
// text wrap -> VML
- assertXPath(pXmlDocument, "/w:document/w:body/w:p/w:r/mc:AlternateContent[1]/mc:Fallback/w:pict/v:shape/w10:wrap", "type", "none");
+ assertXPath(pXmlDocument, "/w:document/w:body/w:p/w:r/w:pict/v:shape/w10:wrap", "type", "none");
// vertical alignment -> VML
- OUString const style = getXPath(pXmlDocument, "/w:document/w:body/w:p/w:r/mc:AlternateContent[1]/mc:Fallback/w:pict/v:shape", "style");
+ OUString const style = getXPath(pXmlDocument, "/w:document/w:body/w:p/w:r/w:pict/v:shape", "style");
CPPUNIT_ASSERT(style.indexOf("v-text-anchor:middle") != -1);
}
diff --git a/sw/source/filter/ww8/docxsdrexport.cxx b/sw/source/filter/ww8/docxsdrexport.cxx
index 7cacc4eb3173..b86c64daeb24 100644
--- a/sw/source/filter/ww8/docxsdrexport.cxx
+++ b/sw/source/filter/ww8/docxsdrexport.cxx
@@ -16,6 +16,7 @@
#include <editeng/opaqitem.hxx>
#include <editeng/boxitem.hxx>
#include <svx/svdogrp.hxx>
+#include <svx/svdotext.hxx>
#include <oox/token/namespaces.hxx>
#include <textboxhelper.hxx>
#include <fmtanchr.hxx>
@@ -983,6 +984,24 @@ bool DocxSdrExport::Impl::isSupportedDMLShape(const uno::Reference<drawing::XSha
return true;
}
+bool lcl_isRotatedText(SdrObject const& rShape, uno::Reference<drawing::XShape> const& xShape)
+{
+ uno::Reference<beans::XPropertySet> const xProps(xShape, uno::UNO_QUERY);
+ sal_Int32 nRotateAngle = sal_Int32();
+ if (!dynamic_cast<SdrTextObj const*>(&rShape)
+ || !xProps->getPropertySetInfo()->hasPropertyByName("RotateAngle")
+ || !(xProps->getPropertyValue("RotateAngle") >>= nRotateAngle))
+ {
+ return false;
+ }
+ if (nRotateAngle == 9000) // is it enough, or should it be any angle != 0?
+ {
+ SAL_INFO("sw.ww8", "HACK: forcing rotated shape to VML only");
+ return true;
+ }
+ return false;
+}
+
void DocxSdrExport::writeDMLAndVMLDrawing(const SdrObject* sdrObj,
const SwFrameFormat& rFrameFormat, int nAnchorId)
{
@@ -1001,6 +1020,7 @@ void DocxSdrExport::writeDMLAndVMLDrawing(const SdrObject* sdrObj,
// In case we are already inside a DML block, then write the shape only as VML, turn out that's allowed to do.
// A common service created in util to check for VML shapes which are allowed to have textbox in content
if ((msfilter::util::HasTextBoxContent(eShapeType)) && Impl::isSupportedDMLShape(xShape)
+ && !lcl_isRotatedText(*sdrObj, xShape)
&& (!bDMLAndVMLDrawingOpen || lcl_isLockedCanvas(xShape))) // Locked canvas is OK inside DML
{
m_pImpl->getSerializer()->startElementNS(XML_mc, XML_AlternateContent);
commit e18cb30ca250474561ceb85806846ce28301bf8c
Author: Michael Stahl <Michael.Stahl at cib.de>
AuthorDate: Fri Aug 7 15:50:12 2020 +0200
Commit: Michael Stahl <Michael.Stahl at cib.de>
CommitDate: Wed Aug 26 19:59:49 2020 +0200
oox: VML export: convert ESCHER_Prop_AnchorText to v-text-anchor
Change-Id: I903cac8d7b02138680613b5a1b6dab4b1c448158
diff --git a/oox/source/export/vmlexport.cxx b/oox/source/export/vmlexport.cxx
index 555796c47a9c..ee93cf32bd27 100644
--- a/oox/source/export/vmlexport.cxx
+++ b/oox/source/export/vmlexport.cxx
@@ -430,6 +430,47 @@ void VMLExport::Commit( EscherPropertyContainer& rProps, const tools::Rectangle&
bAlreadyWritten[ ESCHER_Prop_WrapText ] = true;
break;
+ case ESCHER_Prop_AnchorText: // 135
+ {
+ char const* pValue(nullptr);
+ switch (opt.nPropValue)
+ {
+ case ESCHER_AnchorTop:
+ pValue = "top";
+ break;
+ case ESCHER_AnchorMiddle:
+ pValue = "middle";
+ break;
+ case ESCHER_AnchorBottom:
+ pValue = "bottom";
+ break;
+ case ESCHER_AnchorTopCentered:
+ pValue = "top-center";
+ break;
+ case ESCHER_AnchorMiddleCentered:
+ pValue = "middle-center";
+ break;
+ case ESCHER_AnchorBottomCentered:
+ pValue = "bottom-center";
+ break;
+ case ESCHER_AnchorTopBaseline:
+ pValue = "top-baseline";
+ break;
+ case ESCHER_AnchorBottomBaseline:
+ pValue = "bottom-baseline";
+ break;
+ case ESCHER_AnchorTopCenteredBaseline:
+ pValue = "top-center-baseline";
+ break;
+ case ESCHER_AnchorBottomCenteredBaseline:
+ pValue = "bottom-center-baseline";
+ break;
+ }
+ m_ShapeStyle.append(";v-text-anchor:");
+ m_ShapeStyle.append(pValue);
+ }
+ break;
+
case ESCHER_Prop_txflTextFlow: // 136
{
// at least "bottom-to-top" only has an effect when it's on the v:textbox element, not on v:shape
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport15.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport15.cxx
index 6bc298fa559a..3218ca060469 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport15.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport15.cxx
@@ -65,7 +65,9 @@ DECLARE_OOXMLEXPORT_TEST(testAtPageShapeRelOrientation, "rotated_shape.fodt")
assertXPath(pXmlDocument, "/w:document/w:body/w:p/w:r/mc:AlternateContent[1]/mc:Fallback/w:pict/v:shape/v:textbox", "style", "mso-layout-flow-alt:bottom-to-top");
// text wrap -> VML
assertXPath(pXmlDocument, "/w:document/w:body/w:p/w:r/mc:AlternateContent[1]/mc:Fallback/w:pict/v:shape/w10:wrap", "type", "none");
-
+ // vertical alignment -> VML
+ OUString const style = getXPath(pXmlDocument, "/w:document/w:body/w:p/w:r/mc:AlternateContent[1]/mc:Fallback/w:pict/v:shape", "style");
+ CPPUNIT_ASSERT(style.indexOf("v-text-anchor:middle") != -1);
}
CPPUNIT_PLUGIN_IMPLEMENT();
commit 9dc09334cc6e8c46d0c6806a843756bc766d0af7
Author: Michael Stahl <Michael.Stahl at cib.de>
AuthorDate: Fri Aug 7 15:45:25 2020 +0200
Commit: Michael Stahl <Michael.Stahl at cib.de>
CommitDate: Wed Aug 26 19:59:49 2020 +0200
oox: VML export: produce bottom-to-top in a better way
Replace code added in 090c61eb93db4302d4565d5f11f7673190835fdb
with something that uses the already generated ESCHER property; this
lets a warning about the unhandled property disappear too.
Change-Id: Ieed83dd8e17e92eea9901124fce5e6da2a17196a
diff --git a/include/oox/export/vmlexport.hxx b/include/oox/export/vmlexport.hxx
index 83b5b91c0d41..7c2d3a62da6f 100644
--- a/include/oox/export/vmlexport.hxx
+++ b/include/oox/export/vmlexport.hxx
@@ -99,6 +99,9 @@ class OOX_DLLPUBLIC VMLExport : public EscherEx
/// Remember style, the most important shape attribute ;-)
OStringBuffer m_ShapeStyle;
+ /// style for textbox
+ OStringBuffer m_TextboxStyle;
+
/// Remember the generated shape id.
OString m_sShapeId;
diff --git a/oox/source/export/vmlexport.cxx b/oox/source/export/vmlexport.cxx
index 6fcc83a66da6..555796c47a9c 100644
--- a/oox/source/export/vmlexport.cxx
+++ b/oox/source/export/vmlexport.cxx
@@ -430,6 +430,28 @@ void VMLExport::Commit( EscherPropertyContainer& rProps, const tools::Rectangle&
bAlreadyWritten[ ESCHER_Prop_WrapText ] = true;
break;
+ case ESCHER_Prop_txflTextFlow: // 136
+ {
+ // at least "bottom-to-top" only has an effect when it's on the v:textbox element, not on v:shape
+ assert(m_TextboxStyle.isEmpty());
+ switch (opt.nPropValue)
+ {
+ case ESCHER_txflHorzN:
+ m_TextboxStyle.append("layout-flow:horizontal");
+ break;
+ case ESCHER_txflTtoBA:
+ m_TextboxStyle.append("layout-flow:vertical");
+ break;
+ case ESCHER_txflBtoT:
+ m_TextboxStyle.append("mso-layout-flow-alt:bottom-to-top");
+ break;
+ default:
+ assert(false); // unimplemented in escher export
+ break;
+ }
+ }
+ break;
+
// coordorigin
case ESCHER_Prop_geoLeft: // 320
case ESCHER_Prop_geoTop: // 321
@@ -1345,6 +1367,8 @@ sal_Int32 VMLExport::StartShape()
// start of the shape
m_pSerializer->startElementNS( XML_v, nShapeElement, XFastAttributeListRef( m_pShapeAttrList ) );
+ OString const textboxStyle(m_TextboxStyle.makeStringAndClear());
+
// now check if we have some editeng text (not associated textbox) and we have a text exporter registered
const SdrTextObj* pTxtObj = dynamic_cast<const SdrTextObj*>( m_pSdrObject );
if (pTxtObj && m_pTextExport && msfilter::util::HasTextBoxContent(m_nShapeType) && !IsWaterMarkShape(m_pSdrObject->GetName()) && !lcl_isTextBox(m_pSdrObject))
@@ -1369,19 +1393,11 @@ sal_Int32 VMLExport::StartShape()
if( pParaObj )
{
- uno::Reference<beans::XPropertySet> xPropertySet(const_cast<SdrObject*>(m_pSdrObject)->getUnoShape(), uno::UNO_QUERY);
sax_fastparser::FastAttributeList* pTextboxAttrList = FastSerializerHelper::createAttrList();
sax_fastparser::XFastAttributeListRef xTextboxAttrList(pTextboxAttrList);
- if (xPropertySet->getPropertySetInfo()->hasPropertyByName("RotateAngle"))
+ if (!textboxStyle.isEmpty())
{
- sal_Int32 nTextRotateAngle = sal_Int32();
- if (xPropertySet->getPropertyValue("RotateAngle") >>= nTextRotateAngle)
- {
- if (nTextRotateAngle == 9000)
- {
- pTextboxAttrList->add(XML_style, "mso-layout-flow-alt:bottom-to-top");
- }
- }
+ pTextboxAttrList->add(XML_style, textboxStyle);
}
// this is reached only in case some text is attached to the shape
commit f59510917add2ce59a440e80104cf1a65dc32135
Author: Michael Stahl <Michael.Stahl at cib.de>
AuthorDate: Fri Aug 7 15:26:48 2020 +0200
Commit: Michael Stahl <Michael.Stahl at cib.de>
CommitDate: Wed Aug 26 19:59:49 2020 +0200
filter: MSO export: convert TextWrap property to Escher_Wrap*
There's a paucity of working wrapping modes in Escher unfortunately.
Change-Id: Ibaf99c3249a6492dc129f9c9b5707778038f9a4c
diff --git a/filter/source/msfilter/escherex.cxx b/filter/source/msfilter/escherex.cxx
index f04043e9156a..a2071237deb7 100644
--- a/filter/source/msfilter/escherex.cxx
+++ b/filter/source/msfilter/escherex.cxx
@@ -66,6 +66,7 @@
#include <com/sun/star/drawing/FlagSequence.hpp>
#include <com/sun/star/drawing/PolygonFlags.hpp>
#include <com/sun/star/text/WritingMode.hpp>
+#include <com/sun/star/text/WrapTextMode.hpp>
#include <com/sun/star/drawing/TextVerticalAdjust.hpp>
#include <com/sun/star/drawing/TextHorizontalAdjust.hpp>
#include <com/sun/star/drawing/EnhancedCustomShapeSegment.hpp>
@@ -699,6 +700,10 @@ void EscherPropertyContainer::CreateTextProperties(
bool bWordWrap ( false );
bool bAutoGrowSize ( false );
+ uno::Any aTextWrap;
+
+ EscherPropertyValueHelper::GetPropertyValue(aTextWrap, rXPropSet, "TextWrap", true);
+
if ( EscherPropertyValueHelper::GetPropertyValue( aAny, rXPropSet, "TextWritingMode", true ) )
aAny >>= eWM;
if ( EscherPropertyValueHelper::GetPropertyValue( aAny, rXPropSet, "TextVerticalAdjust", true ) )
@@ -837,6 +842,21 @@ void EscherPropertyContainer::CreateTextProperties(
nTextAttr |= 0x20002;
}
}
+
+ if (aTextWrap.hasValue())
+ { // explicit text wrap overrides whatever was inferred previously
+ switch (aTextWrap.get<text::WrapTextMode>())
+ {
+ case text::WrapTextMode_THROUGH:
+ eWrapMode = ESCHER_WrapNone;
+ break;
+ // in theory there are 3 more Escher_Wrap, but [MS-ODRAW] says they are useless
+ default:
+ eWrapMode = ESCHER_WrapSquare;
+ break;
+ }
+ }
+
AddOpt( ESCHER_Prop_dxTextLeft, nLeft * 360 );
AddOpt( ESCHER_Prop_dxTextRight, nRight * 360 );
AddOpt( ESCHER_Prop_dyTextTop, nTop * 360 );
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport15.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport15.cxx
index 51e4c6b63b96..6bc298fa559a 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport15.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport15.cxx
@@ -63,6 +63,8 @@ DECLARE_OOXMLEXPORT_TEST(testAtPageShapeRelOrientation, "rotated_shape.fodt")
// now test text rotation -> VML writing direction
assertXPath(pXmlDocument, "/w:document/w:body/w:p/w:r/mc:AlternateContent[1]/mc:Fallback/w:pict/v:shape/v:textbox", "style", "mso-layout-flow-alt:bottom-to-top");
+ // text wrap -> VML
+ assertXPath(pXmlDocument, "/w:document/w:body/w:p/w:r/mc:AlternateContent[1]/mc:Fallback/w:pict/v:shape/w10:wrap", "type", "none");
}
commit 7e02dfef33079412558263f1302b12211271666a
Author: Michael Stahl <Michael.Stahl at cib.de>
AuthorDate: Fri Aug 7 16:41:18 2020 +0200
Commit: Michael Stahl <Michael.Stahl at cib.de>
CommitDate: Wed Aug 26 19:59:49 2020 +0200
sw: register w10 prefix
Change-Id: I1ca9c3c7c4f36b666ee7d17967b80fdaa7004874
diff --git a/sw/qa/inc/swmodeltestbase.hxx b/sw/qa/inc/swmodeltestbase.hxx
index 38f8e95a4a40..d62b92b58fc0 100644
--- a/sw/qa/inc/swmodeltestbase.hxx
+++ b/sw/qa/inc/swmodeltestbase.hxx
@@ -962,6 +962,7 @@ protected:
xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("a14"), BAD_CAST("http://schemas.microsoft.com/office/drawing/2010/main"));
xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("c"), BAD_CAST("http://schemas.openxmlformats.org/drawingml/2006/chart"));
xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("o"), BAD_CAST("urn:schemas-microsoft-com:office:office"));
+ xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("w10"), BAD_CAST("urn:schemas-microsoft-com:office:word"));
// odt
xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("office"), BAD_CAST("urn:oasis:names:tc:opendocument:xmlns:office:1.0"));
xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("style"), BAD_CAST("urn:oasis:names:tc:opendocument:xmlns:style:1.0"));
commit a817d45dca64472240ebc8dc006f1969eaf90cb4
Author: Michael Stahl <Michael.Stahl at cib.de>
AuthorDate: Thu Aug 6 14:11:38 2020 +0200
Commit: Michael Stahl <Michael.Stahl at cib.de>
CommitDate: Wed Aug 26 19:59:49 2020 +0200
oox: VML export: for rotated text shape, produce bottom-to-top
This is for shapes that fail the lcl_isTextBox() check in
VMLExport::StartShape(), they can be rotated too but with a different
property than the "TextPreRotateAngle" that is used in
VMLExport::EndShape().
Change-Id: I530aae8b7138f47bae8434e205632f5f4adbb231
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/100249
Tested-by: Jenkins
Reviewed-by: Michael Stahl <michael.stahl at cib.de>
(cherry picked from commit 090c61eb93db4302d4565d5f11f7673190835fdb)
diff --git a/oox/source/export/vmlexport.cxx b/oox/source/export/vmlexport.cxx
index 98f3243e5461..6fcc83a66da6 100644
--- a/oox/source/export/vmlexport.cxx
+++ b/oox/source/export/vmlexport.cxx
@@ -1369,8 +1369,23 @@ sal_Int32 VMLExport::StartShape()
if( pParaObj )
{
+ uno::Reference<beans::XPropertySet> xPropertySet(const_cast<SdrObject*>(m_pSdrObject)->getUnoShape(), uno::UNO_QUERY);
+ sax_fastparser::FastAttributeList* pTextboxAttrList = FastSerializerHelper::createAttrList();
+ sax_fastparser::XFastAttributeListRef xTextboxAttrList(pTextboxAttrList);
+ if (xPropertySet->getPropertySetInfo()->hasPropertyByName("RotateAngle"))
+ {
+ sal_Int32 nTextRotateAngle = sal_Int32();
+ if (xPropertySet->getPropertyValue("RotateAngle") >>= nTextRotateAngle)
+ {
+ if (nTextRotateAngle == 9000)
+ {
+ pTextboxAttrList->add(XML_style, "mso-layout-flow-alt:bottom-to-top");
+ }
+ }
+ }
+
// this is reached only in case some text is attached to the shape
- m_pSerializer->startElementNS(XML_v, XML_textbox);
+ m_pSerializer->startElementNS(XML_v, XML_textbox, xTextboxAttrList);
m_pTextExport->WriteOutliner(*pParaObj);
m_pSerializer->endElementNS(XML_v, XML_textbox);
if( bOwnParaObj )
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport15.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport15.cxx
index 634215adab08..51e4c6b63b96 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport15.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport15.cxx
@@ -60,6 +60,10 @@ DECLARE_OOXMLEXPORT_TEST(testAtPageShapeRelOrientation, "rotated_shape.fodt")
"/wp:positionV/wp:posOffset", "1080135");
assertXPath(pXmlDocument, "/w:document/w:body/w:p/w:r/w:drawing/wp:anchor"
"/wp:positionV", "relativeFrom", "page");
+
+ // now test text rotation -> VML writing direction
+ assertXPath(pXmlDocument, "/w:document/w:body/w:p/w:r/mc:AlternateContent[1]/mc:Fallback/w:pict/v:shape/v:textbox", "style", "mso-layout-flow-alt:bottom-to-top");
+
}
CPPUNIT_PLUGIN_IMPLEMENT();
commit f6b1a80ea89c2e68f5f048728002528e7e5e927a
Author: Michael Stahl <Michael.Stahl at cib.de>
AuthorDate: Tue Aug 4 19:09:38 2020 +0200
Commit: Michael Stahl <Michael.Stahl at cib.de>
CommitDate: Wed Aug 26 19:59:48 2020 +0200
tdf#135464 sw: avoid invalid combinations of HoriOrientRelation and FLY_AT_PAGE
... when using Anchor->To Page context menu.
For shapes, in SwDoc::ChgAnchor() and for sw flys in
SwDoc::SetFlyFrameAnchor().
Change-Id: I7d747b2558ef69df99636ea0fb0409deb461a79a
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/100131
Tested-by: Jenkins
Reviewed-by: Michael Stahl <michael.stahl at cib.de>
(cherry picked from commit 1de2b0d3234462b488db54d36ebc17e2b579b0f0)
diff --git a/sw/source/core/doc/docfly.cxx b/sw/source/core/doc/docfly.cxx
index 4451115905a8..cc3b858028c2 100644
--- a/sw/source/core/doc/docfly.cxx
+++ b/sw/source/core/doc/docfly.cxx
@@ -372,6 +372,7 @@ sal_Int8 SwDoc::SetFlyFrameAnchor( SwFrameFormat& rFormat, SfxItemSet& rSet, boo
pItem = nullptr;
SwFormatHoriOrient aOldH( rFormat.GetHoriOrient() );
+ bool bPutOldH(false);
if( text::HoriOrientation::NONE == aOldH.GetHoriOrient() && ( !pItem ||
aOldH.GetPos() == static_cast<const SwFormatHoriOrient*>(pItem)->GetPos() ))
@@ -386,6 +387,22 @@ sal_Int8 SwDoc::SetFlyFrameAnchor( SwFrameFormat& rFormat, SfxItemSet& rSet, boo
aOldH.SetRelationOrient( pH->GetRelationOrient() );
}
aOldH.SetPos( nPos );
+ bPutOldH = true;
+ }
+ if (nNew == RndStdIds::FLY_AT_PAGE)
+ {
+ sal_Int16 nRelOrient(pItem
+ ? static_cast<const SwFormatHoriOrient*>(pItem)->GetRelationOrient()
+ : aOldH.GetRelationOrient());
+ if (sw::GetAtPageRelOrientation(nRelOrient, false))
+ {
+ SAL_INFO("sw.ui", "fixing horizontal RelOrientation for at-page anchor");
+ aOldH.SetRelationOrient(nRelOrient);
+ bPutOldH = true;
+ }
+ }
+ if (bPutOldH)
+ {
rSet.Put( aOldH );
}
@@ -915,6 +932,17 @@ bool SwDoc::ChgAnchor( const SdrMarkList& _rMrkList,
// of attributes (method call <SetAttr(..)>) takes care of the
// invalidation of the object position.
SetAttr( aNewAnch, *pContact->GetFormat() );
+ if (aNewAnch.GetAnchorId() == RndStdIds::FLY_AT_PAGE)
+ {
+ SwFormatHoriOrient item(pContact->GetFormat()->GetHoriOrient());
+ sal_Int16 nRelOrient(item.GetRelationOrient());
+ if (sw::GetAtPageRelOrientation(nRelOrient, false))
+ {
+ SAL_INFO("sw.ui", "fixing horizontal RelOrientation for at-page anchor");
+ item.SetRelationOrient(text::RelOrientation::PAGE_FRAME);
+ SetAttr(item, *pContact->GetFormat());
+ }
+ }
if ( _bPosCorr )
{
// #i33313# - consider not connected 'virtual' drawing
diff --git a/sw/source/core/layout/anchoreddrawobject.cxx b/sw/source/core/layout/anchoreddrawobject.cxx
index 079468fdf062..f3813192c928 100644
--- a/sw/source/core/layout/anchoreddrawobject.cxx
+++ b/sw/source/core/layout/anchoreddrawobject.cxx
@@ -719,7 +719,10 @@ void SwAnchoredDrawObject::AdjustPositioningAttr( const SwFrame* _pNewAnchorFram
nVertRelPos = aObjRect.Top() - aAnchorPos.Y();
}
- GetFrameFormat().SetFormatAttr( SwFormatHoriOrient( nHoriRelPos, text::HoriOrientation::NONE, text::RelOrientation::FRAME ) );
+ GetFrameFormat().SetFormatAttr( SwFormatHoriOrient( nHoriRelPos, text::HoriOrientation::NONE,
+ GetFrameFormat().GetAnchor().GetAnchorId() == RndStdIds::FLY_AT_PAGE
+ ? text::RelOrientation::PAGE_FRAME
+ : text::RelOrientation::FRAME ) );
GetFrameFormat().SetFormatAttr( SwFormatVertOrient( nVertRelPos, text::VertOrientation::NONE, text::RelOrientation::FRAME ) );
}
commit 9da304f54bc945acaa4d5ecee2e1ad350ba8679f
Author: Michael Stahl <Michael.Stahl at cib.de>
AuthorDate: Tue Aug 4 18:56:08 2020 +0200
Commit: Michael Stahl <Michael.Stahl at cib.de>
CommitDate: Wed Aug 26 19:59:48 2020 +0200
tdf#135464 sw: ODT->DOCX: fix positioning of at-page shapes and frames
Exporting at-page anchored flys to DOCX can result in wrong positions,
because DocxSdrExport::startDMLAnchorInline() converts
text::RelOrientation::FRAME to relativeFrom="column", i.e. the margin,
but sw displays it as relative to the page.
In fact at-page and FRAME is an invalid combination according to the
table in ODF 1.3, 20.298 style:horizontal-pos, the paragraph and
character relations are not valid for page-anchored flys.
Since there are lots of ODT files with this invalid combination, try to
fix it on import, in SwXFrame and SwXShape.
Funnily, SwXShape is attached before the properties are set, while
SwXFrame is attached after the properties are set.
The anchor frame for at-page is always a SwPageFrame.
Unfortunately there is a case where PRINT_AREA and PAGE_PRINT_AREA
differ, namely the CalcClipRect() only handles PRINT_AREA so it will
crop to the right margin with that but not with PAGE_PRINT_AREA,
so don't map this value.
Change-Id: I4d5f7f87d045ac4539b9170e55c34d4afe801f4d
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/100130
Tested-by: Jenkins
Reviewed-by: Michael Stahl <michael.stahl at cib.de>
(cherry picked from commit 12645900dece0a9aa0661fee796c27f672217977)
diff --git a/sw/inc/fmtornt.hxx b/sw/inc/fmtornt.hxx
index 24ffdc907e26..d0bea643f980 100644
--- a/sw/inc/fmtornt.hxx
+++ b/sw/inc/fmtornt.hxx
@@ -108,6 +108,12 @@ inline const SwFormatVertOrient &SwFormat::GetVertOrient(bool bInP) const
inline const SwFormatHoriOrient &SwFormat::GetHoriOrient(bool bInP) const
{ return m_aSet.GetHoriOrient(bInP); }
+namespace sw {
+
+ bool GetAtPageRelOrientation(sal_Int16 & rOrientation, bool const isIgnorePrintArea);
+
+}
+
#endif
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/qa/extras/ooxmlexport/data/rotated_shape.fodt b/sw/qa/extras/ooxmlexport/data/rotated_shape.fodt
new file mode 100644
index 000000000000..fce84f93e945
--- /dev/null
+++ b/sw/qa/extras/ooxmlexport/data/rotated_shape.fodt
@@ -0,0 +1,81 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<office:document xmlns:officeooo="http://openoffice.org/2009/office" xmlns:css3t="http://www.w3.org/TR/css3-text/" xmlns:grddl="http://www.w3.org/2003/g/data-view#" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:formx="urn:openoffice:names:experimental:ooxml-odf-interop:xmlns:form:1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:chart="urn:oasis:names:tc:opendocument:xmlns:chart:1.0" xmlns:svg="urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0" xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" xmlns:oooc="http://openoffice.org/2004/calc" xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0" xmlns:ooow="http://openoffice.org/2004/writer" xmlns:meta="urn:oasis:names:tc:opendocument:xmlns:meta:1.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rpt="http://openoffice.org/2005/report" xmlns:draw="urn:oasis:names:tc:opendocument:xmlns:drawing:1.0" xmlns:config="urn:oasis:names:tc:opendocument:xmlns
:config:1.0" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0" xmlns:ooo="http://openoffice.org/2004/office" xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" xmlns:dr3d="urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0" xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0" xmlns:number="urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0" xmlns:of="urn:oasis:names:tc:opendocument:xmlns:of:1.2" xmlns:calcext="urn:org:documentfoundation:names:experimental:calc:xmlns:calcext:1.0" xmlns:tableooo="http://openoffice.org/2009/table" xmlns:drawooo="http://openoffice.org/2010/draw" xmlns:loext="urn:org:documentfoundation:names:experimental:office:xmlns:loext:1.0" xmlns:dom="http://www.w3.org/2001/xml-events" xmlns:field="urn:openoffice:names:experimental:ooo-ms-interop:xmlns:field:1.0" xmlns:math="http://www.w3.org/1998/Math/MathML" xmlns:form="urn:oasis:names:tc:opendocument:xmlns:form:1.0" xmlns:script="ur
n:oasis:names:tc:opendocument:xmlns:script:1.0" xmlns:xforms="http://www.w3.org/2002/xforms" office:version="1.3" office:mimetype="application/vnd.oasis.opendocument.text">
+ <office:font-face-decls>
+ <style:font-face style:name="Times New Roman" svg:font-family="'Times New Roman'" style:font-family-generic="roman" style:font-pitch="variable"/>
+ <style:font-face style:name="Arial" svg:font-family="Arial" style:font-family-generic="swiss" style:font-pitch="variable"/>
+ <style:font-face style:name="Lucida Sans" svg:font-family="'Lucida Sans'" style:font-family-generic="system" style:font-pitch="variable"/>
+ <style:font-face style:name="NSimSun" svg:font-family="NSimSun" style:font-family-generic="system" style:font-pitch="variable"/>
+ </office:font-face-decls>
+ <office:styles>
+ <style:default-style style:family="graphic">
+ <style:graphic-properties svg:stroke-color="#3465a4" draw:fill-color="#729fcf" fo:wrap-option="no-wrap" draw:shadow-offset-x="0.3cm" draw:shadow-offset-y="0.3cm" draw:start-line-spacing-horizontal="0.283cm" draw:start-line-spacing-vertical="0.283cm" draw:end-line-spacing-horizontal="0.283cm" draw:end-line-spacing-vertical="0.283cm" style:flow-with-text="false"/>
+ <style:paragraph-properties style:text-autospace="ideograph-alpha" style:line-break="strict" style:font-independent-line-spacing="false">
+ <style:tab-stops/>
+ </style:paragraph-properties>
+ <style:text-properties style:use-window-font-color="true" loext:opacity="0%" style:font-name="Times New Roman" fo:font-size="12pt" fo:language="de" fo:country="DE" style:letter-kerning="true" style:font-name-asian="NSimSun" style:font-size-asian="10.5pt" style:language-asian="zh" style:country-asian="CN" style:font-name-complex="Lucida Sans" style:font-size-complex="12pt" style:language-complex="hi" style:country-complex="IN"/>
+ </style:default-style>
+ <style:default-style style:family="paragraph">
+ <style:paragraph-properties fo:orphans="2" fo:widows="2" fo:hyphenation-ladder-count="no-limit" style:text-autospace="ideograph-alpha" style:punctuation-wrap="hanging" style:line-break="strict" style:tab-stop-distance="1.251cm" style:writing-mode="page"/>
+ <style:text-properties style:use-window-font-color="true" loext:opacity="0%" style:font-name="Times New Roman" fo:font-size="12pt" fo:language="de" fo:country="DE" style:letter-kerning="true" style:font-name-asian="NSimSun" style:font-size-asian="10.5pt" style:language-asian="zh" style:country-asian="CN" style:font-name-complex="Lucida Sans" style:font-size-complex="12pt" style:language-complex="hi" style:country-complex="IN" fo:hyphenate="false" fo:hyphenation-remain-char-count="2" fo:hyphenation-push-char-count="2" loext:hyphenation-no-caps="false"/>
+ </style:default-style>
+ <style:default-style style:family="table">
+ <style:table-properties table:border-model="collapsing"/>
+ </style:default-style>
+ <style:default-style style:family="table-row">
+ <style:table-row-properties fo:keep-together="auto"/>
+ </style:default-style>
+ <style:style style:name="Standard" style:family="paragraph" style:class="text"/>
+ <text:notes-configuration text:note-class="footnote" style:num-format="1" text:start-value="0" text:footnotes-position="page" text:start-numbering-at="document"/>
+ <text:notes-configuration text:note-class="endnote" style:num-format="i" text:start-value="0"/>
+ <text:linenumbering-configuration text:number-lines="false" text:offset="0.499cm" style:num-format="1" text:number-position="left" text:increment="5"/>
+ </office:styles>
+ <office:automatic-styles>
+ <style:style style:name="P1" style:family="paragraph">
+ <style:paragraph-properties style:writing-mode="lr-tb"/>
+ </style:style>
+ <style:style style:name="P2" style:family="paragraph">
+ <loext:graphic-properties draw:fill="none" draw:fill-color="#ffffff"/>
+ <style:paragraph-properties style:writing-mode="lr-tb"/>
+ <style:text-properties fo:font-size="11pt"/>
+ </style:style>
+ <style:style style:name="T1" style:family="text">
+ <style:text-properties style:use-window-font-color="true" loext:opacity="0%" style:font-name="Arial" fo:font-size="7pt" fo:language="de" fo:country="DE" style:font-name-asian="Times New Roman" style:font-size-asian="7pt" style:font-name-complex="Arial" style:font-size-complex="12pt" style:language-complex="ar" style:country-complex="SA"/>
+ </style:style>
+ <style:style style:name="gr1" style:family="graphic">
+ <style:graphic-properties draw:stroke="none" draw:fill="none" draw:fill-color="#ffffff" draw:textarea-horizontal-align="justify" draw:textarea-vertical-align="middle" draw:auto-grow-height="false" draw:auto-grow-width="false" fo:padding-top="0.254cm" fo:padding-bottom="0.254cm" fo:padding-left="0.127cm" fo:padding-right="0.127cm" fo:wrap-option="wrap" draw:shadow="hidden" style:run-through="foreground" style:wrap="run-through" style:number-wrapped-paragraphs="no-limit" style:vertical-pos="from-top" style:vertical-rel="page" style:horizontal-pos="from-left" style:horizontal-rel="paragraph" draw:wrap-influence-on-position="once-concurrent" loext:allow-overlap="true" style:flow-with-text="false"/>
+ <style:paragraph-properties style:writing-mode="lr-tb"/>
+ </style:style>
+ <style:style style:name="fr1" style:family="graphic" style:parent-style-name="Graphics">
+ <style:graphic-properties style:horizontal-pos="from-left" style:horizontal-rel="paragraph" style:vertical-pos="from-top" style:vertical-rel="page" style:mirror="none" fo:clip="rect(0cm, 0cm, 0cm, 0cm)" draw:luminance="0%" draw:contrast="0%" draw:red="0%" draw:green="0%" draw:blue="0%" draw:gamma="100%" draw:color-inversion="false" draw:image-opacity="100%" draw:color-mode="standard"/>
+ </style:style>
+ <style:page-layout style:name="pm1">
+ <style:page-layout-properties fo:page-width="21.001cm" fo:page-height="29.7cm" style:num-format="1" style:print-orientation="portrait" fo:margin-top="2cm" fo:margin-bottom="2cm" fo:margin-left="2cm" fo:margin-right="2cm" style:writing-mode="lr-tb" style:layout-grid-color="#c0c0c0" style:layout-grid-lines="20" style:layout-grid-base-height="0.706cm" style:layout-grid-ruby-height="0.353cm" style:layout-grid-mode="none" style:layout-grid-ruby-below="false" style:layout-grid-print="false" style:layout-grid-display="false" style:footnote-max-height="0cm">
+ <style:footnote-sep style:width="0.018cm" style:distance-before-sep="0.101cm" style:distance-after-sep="0.101cm" style:line-style="solid" style:adjustment="left" style:rel-width="25%" style:color="#000000"/>
+ </style:page-layout-properties>
+ <style:header-style/>
+ <style:footer-style/>
+ </style:page-layout>
+ </office:automatic-styles>
+ <office:master-styles>
+ <style:master-page style:name="Standard" style:page-layout-name="pm1"/>
+ </office:master-styles>
+ <office:body>
+ <office:text>
+ <draw:frame text:anchor-type="page" text:anchor-page-number="1" draw:z-index="0" draw:name="Shape1" draw:style-name="gr1" draw:text-style-name="P2" svg:width="5.896cm" svg:height="0.957cm" draw:transform="rotate (1.5707963267949) translate (1.13418055555556cm 26.0579305555556cm)">
+ <draw:text-box>
+ <text:p text:style-name="P1"><text:span text:style-name="T1"><text:s/></text:span><text:span text:style-name="T1">Foo</text:span></text:p>
+ </draw:text-box>
+ </draw:frame><draw:frame draw:style-name="fr1" draw:name="Image1" text:anchor-type="page" text:anchor-page-number="1" svg:width="0.67cm" svg:height="0.67cm" draw:z-index="0"><draw:image draw:mime-type="image/png" svg:x="2cm" svg:y="3cm">
+ <office:binary-data>iVBORw0KGgoAAAANSUhEUgAAABMAAAATCAYAAAByUDbMAAAAAXNSR0IArs4c6QAAAAZiS0dE
+ AP8A/wD/oL2nkwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9sJBhI0A6HXrrIAAABl
+ SURBVDjLY/z//z8DtQATMYokl7D8p4phMIOIMZCJFBcRMpCJVK/hM5CJnDDCJc9EbmBjU8dE
+ jkG41DPhM+h5zB9GfHx0fTgjAJtGfOIMDAwMLMQoItZAJgYqglHDhpNhjNQsaQHF4y3hS/bS
+ HgAAAABJRU5ErkJggg==
+ </office:binary-data>
+ </draw:image>
+ </draw:frame>
+ <text:p text:style-name="Standard"/>
+ </office:text>
+ </office:body>
+</office:document>
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport15.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport15.cxx
index dedad4d00eab..634215adab08 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport15.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport15.cxx
@@ -33,6 +33,35 @@ DECLARE_OOXMLEXPORT_TEST(testTdf133334_followPgStyle, "tdf133334_followPgStyle.o
CPPUNIT_ASSERT_EQUAL(2, getPages());
}
+DECLARE_OOXMLEXPORT_TEST(testAtPageShapeRelOrientation, "rotated_shape.fodt")
+{
+ // invalid combination of at-page anchor and horizontal-rel="paragraph"
+ // caused relativeFrom="column" instead of relativeFrom="page"
+
+ xmlDocPtr pXmlDocument = parseExport("word/document.xml");
+ if (!pXmlDocument)
+ return;
+
+ assertXPathContent(pXmlDocument, "/w:document/w:body/w:p/w:r/mc:AlternateContent[1]/mc:Choice/w:drawing/wp:anchor"
+ "/wp:positionH/wp:posOffset", "-480060");
+ assertXPath(pXmlDocument, "/w:document/w:body/w:p/w:r/mc:AlternateContent[1]/mc:Choice/w:drawing/wp:anchor"
+ "/wp:positionH", "relativeFrom", "page");
+ assertXPathContent(pXmlDocument, "/w:document/w:body/w:p/w:r/mc:AlternateContent[1]/mc:Choice/w:drawing/wp:anchor"
+ "/wp:positionV/wp:posOffset", "8147685");
+ assertXPath(pXmlDocument, "/w:document/w:body/w:p/w:r/mc:AlternateContent[1]/mc:Choice/w:drawing/wp:anchor"
+ "/wp:positionV", "relativeFrom", "page");
+
+ // same for sw
+ assertXPathContent(pXmlDocument, "/w:document/w:body/w:p/w:r/w:drawing/wp:anchor"
+ "/wp:positionH/wp:posOffset", "720090");
+ assertXPath(pXmlDocument, "/w:document/w:body/w:p/w:r/w:drawing/wp:anchor"
+ "/wp:positionH", "relativeFrom", "page");
+ assertXPathContent(pXmlDocument, "/w:document/w:body/w:p/w:r/w:drawing/wp:anchor"
+ "/wp:positionV/wp:posOffset", "1080135");
+ assertXPath(pXmlDocument, "/w:document/w:body/w:p/w:r/w:drawing/wp:anchor"
+ "/wp:positionV", "relativeFrom", "page");
+}
+
CPPUNIT_PLUGIN_IMPLEMENT();
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/layout/atrfrm.cxx b/sw/source/core/layout/atrfrm.cxx
index 79235781896d..18700e9b2eb4 100644
--- a/sw/source/core/layout/atrfrm.cxx
+++ b/sw/source/core/layout/atrfrm.cxx
@@ -98,6 +98,39 @@
using namespace ::com::sun::star;
+namespace sw {
+
+bool GetAtPageRelOrientation(sal_Int16 & rOrientation, bool const isIgnorePrintArea)
+{
+ switch (rOrientation)
+ {
+ case text::RelOrientation::CHAR:
+ case text::RelOrientation::FRAME:
+ rOrientation = text::RelOrientation::PAGE_FRAME;
+ return true;
+ case text::RelOrientation::PRINT_AREA:
+ if (isIgnorePrintArea)
+ {
+ return false;
+ }
+ else
+ {
+ rOrientation = text::RelOrientation::PAGE_PRINT_AREA;
+ return true;
+ }
+ case text::RelOrientation::FRAME_LEFT:
+ rOrientation = text::RelOrientation::PAGE_LEFT;
+ return true;
+ case text::RelOrientation::FRAME_RIGHT:
+ rOrientation = text::RelOrientation::PAGE_RIGHT;
+ return true;
+ default:
+ return false;
+ }
+}
+
+} // namespace sw
+
SfxPoolItem* SwFormatLineNumber::CreateDefault() { return new SwFormatLineNumber; }
static sal_Int16 lcl_IntToRelation(const uno::Any& rVal)
diff --git a/sw/source/core/unocore/unodraw.cxx b/sw/source/core/unocore/unodraw.cxx
index c3d6057c0b39..0bb1b1b0fa36 100644
--- a/sw/source/core/unocore/unodraw.cxx
+++ b/sw/source/core/unocore/unodraw.cxx
@@ -1226,6 +1226,21 @@ void SwXShape::setPropertyValue(const OUString& rPropertyName, const uno::Any& a
}
}
}
+ else if (pEntry->nWID == RES_HORI_ORIENT
+ && pEntry->nMemberId == MID_HORIORIENT_RELATION
+ && aSet.Get(RES_ANCHOR).GetAnchorId() == RndStdIds::FLY_AT_PAGE)
+ {
+ uno::Any value(aValue);
+ sal_Int16 nRelOrient(text::RelOrientation::PAGE_FRAME);
+ aValue >>= nRelOrient;
+ if (sw::GetAtPageRelOrientation(nRelOrient, true))
+ {
+ SAL_WARN("sw.core", "SwXShape: fixing invalid horizontal RelOrientation for at-page anchor");
+ value <<= nRelOrient;
+ }
+ m_pPropSet->setPropertyValue( *pEntry, value, aSet );
+ pFormat->SetFormatAttr(aSet);
+ }
else
{
m_pPropSet->setPropertyValue( *pEntry, aValue, aSet );
diff --git a/sw/source/core/unocore/unoframe.cxx b/sw/source/core/unocore/unoframe.cxx
index e2e5c9411715..0636d530662c 100644
--- a/sw/source/core/unocore/unoframe.cxx
+++ b/sw/source/core/unocore/unoframe.cxx
@@ -2749,6 +2749,19 @@ void SwXFrame::attachToRange(uno::Reference<text::XTextRange> const& xTextRange,
aAnchor.SetAnchor( aPam.GetPoint() );
aFrameSet.Put(aAnchor);
}
+
+ if (eAnchorId == RndStdIds::FLY_AT_PAGE)
+ {
+ sal_Int16 nRelOrient(aFrameSet.Get(RES_HORI_ORIENT).GetRelationOrient());
+ if (sw::GetAtPageRelOrientation(nRelOrient, true))
+ {
+ SAL_WARN("sw.core", "SwXFrame: fixing invalid horizontal RelOrientation for at-page anchor");
+
+ SwFormatHoriOrient item(aFrameSet.Get(RES_HORI_ORIENT));
+ item.SetRelationOrient(nRelOrient);
+ aFrameSet.Put(item);
+ }
+ }
}
const ::uno::Any* pStyle;
commit a6e90bbfd64c641aac0e3fe6bb887bd9987d1ede
Author: Michael Stahl <Michael.Stahl at cib.de>
AuthorDate: Tue Apr 14 17:42:06 2020 +0200
Commit: Michael Stahl <Michael.Stahl at cib.de>
CommitDate: Wed Aug 26 19:59:48 2020 +0200
sw: DOCX export: export AddExternalLeading as w:noLeading
For 11pt Arial, can fit 59 paragraphs on a page vs. 57...
This is annoyingly complicated by the fact that Word 2013 ignores
w:noLeading element if compatibilityMode is 15.
Change-Id: Ie3093eabba45cdf6e7903ed860f5bad24dcc0323
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/92208
Tested-by: Jenkins
Reviewed-by: Michael Stahl <michael.stahl at cib.de>
(cherry picked from commit 968a7e3247169489d29cc7de0079eea12a663870)
For the backport, don't care about compatibilityMode, it won't be in
grab-bag on ODF import so rely on the default of 12.
Change-Id: Ia41d6a4c99ebcc364997d0bb565addf7dc546ced
diff --git a/sw/source/filter/ww8/docxattributeoutput.cxx b/sw/source/filter/ww8/docxattributeoutput.cxx
index c368e6682833..c03d971e8fdc 100644
--- a/sw/source/filter/ww8/docxattributeoutput.cxx
+++ b/sw/source/filter/ww8/docxattributeoutput.cxx
@@ -3695,6 +3695,7 @@ sal_Int32 lcl_getWordCompatibilityMode( const SwDoc& rDoc )
uno::Reference< beans::XPropertySet > xPropSet( rDoc.GetDocShell()->GetBaseModel(), uno::UNO_QUERY_THROW );
uno::Reference< beans::XPropertySetInfo > xPropSetInfo = xPropSet->getPropertySetInfo();
+ sal_Int32 nWordCompatibilityMode = -1;
if ( xPropSetInfo->hasPropertyByName( UNO_NAME_MISC_OBJ_INTEROPGRABBAG ) )
{
uno::Sequence< beans::PropertyValue > propList;
@@ -3725,14 +3726,14 @@ sal_Int32 lcl_getWordCompatibilityMode( const SwDoc& rDoc )
if ( sName == "compatibilityMode" && sUri == "http://schemas.microsoft.com/office/word" )
{
- return sVal.toInt32();
+ nWordCompatibilityMode = sVal.toInt32();
}
}
}
}
}
- return -1; // Word compatibility mode not found
+ return nWordCompatibilityMode;
}
}
diff --git a/sw/source/filter/ww8/docxexport.cxx b/sw/source/filter/ww8/docxexport.cxx
index 7fed578100d1..a212f4e5c9b8 100644
--- a/sw/source/filter/ww8/docxexport.cxx
+++ b/sw/source/filter/ww8/docxexport.cxx
@@ -895,6 +895,21 @@ void DocxExport::WriteProperties( )
m_pFilter->exportDocumentProperties( xDocProps, bSecurityOptOpenReadOnly );
}
+static auto
+WriteCompat(SwDoc const& rDoc, ::sax_fastparser::FSHelperPtr const& rpFS
+ ) -> void
+{
+ if (!rDoc.getIDocumentSettingAccess().get(DocumentSettingId::ADD_EXT_LEADING))
+ {
+ rpFS->singleElementNS(XML_w, XML_noLeading);
+ }
+ // Do not justify lines with manual break
+ if (rDoc.getIDocumentSettingAccess().get(DocumentSettingId::DO_NOT_JUSTIFY_LINES_WITH_MANUAL_BREAK))
+ {
+ rpFS->singleElementNS(XML_w, XML_doNotExpandShiftReturn);
+ }
+}
+
void DocxExport::WriteSettings()
{
SwViewShell *pViewShell(m_pDoc->getIDocumentLayoutAccess().GetCurrentViewShell());
@@ -978,14 +993,6 @@ void DocxExport::WriteSettings()
pFS->singleElementNS( XML_w, XML_defaultTabStop, FSNS( XML_w, XML_val ),
OString::number(m_aSettings.defaultTabStop) );
- // Do not justify lines with manual break
- if( m_pDoc->getIDocumentSettingAccess().get( DocumentSettingId::DO_NOT_JUSTIFY_LINES_WITH_MANUAL_BREAK ))
- {
- pFS->startElementNS(XML_w, XML_compat);
- pFS->singleElementNS(XML_w, XML_doNotExpandShiftReturn);
- pFS->endElementNS( XML_w, XML_compat );
- }
-
// export current mail merge database and table names
SwDBData aData = m_pDoc->GetDBData();
if ( !aData.sDataSource.isEmpty() && aData.nCommandType == css::sdb::CommandType::TABLE && !aData.sCommand.isEmpty() )
@@ -1046,6 +1053,7 @@ void DocxExport::WriteSettings()
bHasDummyRedlineProtectionKey = aKey.getLength() == 1 && aKey[0] == 1;
}
const OUString aGrabBagName = UNO_NAME_MISC_OBJ_INTEROPGRABBAG;
+ bool bHasCompat = false;
if ( xPropSetInfo->hasPropertyByName( aGrabBagName ) )
{
uno::Sequence< beans::PropertyValue > propList;
@@ -1076,6 +1084,10 @@ void DocxExport::WriteSettings()
{
pFS->startElementNS(XML_w, XML_compat);
+ WriteCompat(*m_pDoc, pFS);
+
+ bHasCompat = true;
+
uno::Sequence< beans::PropertyValue > aCompatSettingsSequence;
rProp.Value >>= aCompatSettingsSequence;
@@ -1161,6 +1173,14 @@ void DocxExport::WriteSettings()
}
}
}
+ if (!bHasCompat)
+ {
+ pFS->startElementNS(XML_w, XML_compat);
+
+ WriteCompat(*m_pDoc, pFS);
+
+ pFS->endElementNS( XML_w, XML_compat );
+ }
if (! hasProtectionProperties)
{
commit c426fcff44a4d2592db621e10ada78678f7d37d2
Author: Michael Stahl <Michael.Stahl at cib.de>
AuthorDate: Tue Apr 14 18:10:53 2020 +0200
Commit: Michael Stahl <Michael.Stahl at cib.de>
CommitDate: Wed Aug 26 19:59:48 2020 +0200
writerfilter: DOCX import: import w:noLeading as AddExternalLeading
Change-Id: I3d7fa2984975205d284575c60c6c47284b00c4a0
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/92209
Tested-by: Jenkins
Reviewed-by: Michael Stahl <michael.stahl at cib.de>
(cherry picked from commit 3cd3ae30217a80449799d7d9426c3756c572712e)
diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.cxx b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
index 3b95e006ffad..288c18b83fd4 100644
--- a/writerfilter/source/dmapper/DomainMapper_Impl.cxx
+++ b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
@@ -6610,6 +6610,10 @@ void DomainMapper_Impl::ApplySettingsTable()
if( m_pSettingsTable->GetEmbedSystemFonts())
xSettings->setPropertyValue( getPropertyName( PROP_EMBED_SYSTEM_FONTS ), uno::makeAny(true) );
xSettings->setPropertyValue("AddParaTableSpacing", uno::makeAny(m_pSettingsTable->GetDoNotUseHTMLParagraphAutoSpacing()));
+ if (m_pSettingsTable->GetNoLeading())
+ {
+ xSettings->setPropertyValue("AddExternalLeading", uno::makeAny(!m_pSettingsTable->GetNoLeading()));
+ }
if( m_pSettingsTable->GetProtectForm() )
xSettings->setPropertyValue("ProtectForm", uno::makeAny( true ));
}
diff --git a/writerfilter/source/dmapper/SettingsTable.cxx b/writerfilter/source/dmapper/SettingsTable.cxx
index 90fb9c98752d..87b4871ca9b6 100644
--- a/writerfilter/source/dmapper/SettingsTable.cxx
+++ b/writerfilter/source/dmapper/SettingsTable.cxx
@@ -256,6 +256,7 @@ struct SettingsTable_Impl
bool m_bRedlineProtection;
OUString m_sRedlineProtectionKey;
bool m_bDisplayBackgroundShape;
+ bool m_bNoLeading = false;
uno::Sequence<beans::PropertyValue> m_pThemeFontLangProps;
@@ -571,6 +572,9 @@ void SettingsTable::lcl_sprm(Sprm& rSprm)
case NS_ooxml::LN_CT_Settings_displayBackgroundShape:
m_pImpl->m_bDisplayBackgroundShape = nIntValue;
break;
+ case NS_ooxml::LN_CT_Compat_noLeading:
+ m_pImpl->m_bNoLeading = nIntValue != 0;
+ break;
default:
{
#ifdef DBG_UTIL
@@ -795,6 +799,11 @@ bool SettingsTable::GetLongerSpaceSequence() const
return m_pImpl->m_bLongerSpaceSequence;
}
+bool SettingsTable::GetNoLeading() const
+{
+ return m_pImpl->m_bNoLeading;
+}
+
}//namespace dmapper
} //namespace writerfilter
diff --git a/writerfilter/source/dmapper/SettingsTable.hxx b/writerfilter/source/dmapper/SettingsTable.hxx
index 26c69d907b35..7f8cc8ba9bc4 100644
--- a/writerfilter/source/dmapper/SettingsTable.hxx
+++ b/writerfilter/source/dmapper/SettingsTable.hxx
@@ -78,6 +78,7 @@ class SettingsTable : public LoggedProperties, public LoggedTable
bool GetNoColumnBalance() const;
bool GetProtectForm() const;
bool GetLongerSpaceSequence() const;
+ bool GetNoLeading() const;
bool GetNoHyphenateCaps() const;
sal_Int16 GetHypenationZone() const;
commit 4d2f2c7ca37e618e0ac64fd22e5315ecccc8df5b
Author: Michael Stahl <Michael.Stahl at cib.de>
AuthorDate: Tue Aug 25 17:30:16 2020 +0200
Commit: Thorsten Behrens <Thorsten.Behrens at CIB.de>
CommitDate: Wed Aug 26 14:26:13 2020 +0200
tdf#135018 sw_redlinehide: fix accept delete redline at start of body
There is no predecessor text node.
(regression from 34b32f56e7f76639ee3a31cfc230a3340acf635a)
Change-Id: I5f6a1a7a1a35a2a6e600166dc1afcf6c4bf9d389
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/101337
Tested-by: Jenkins
Reviewed-by: Michael Stahl <michael.stahl at cib.de>
(cherry picked from commit a64511dc929a91926ade0c132b310214fdb1bdea)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/101354
Reviewed-by: Thorsten Behrens <Thorsten.Behrens at CIB.de>
diff --git a/sw/source/core/txtnode/ndtxt.cxx b/sw/source/core/txtnode/ndtxt.cxx
index da7a8d372d7c..3d721ebee00b 100644
--- a/sw/source/core/txtnode/ndtxt.cxx
+++ b/sw/source/core/txtnode/ndtxt.cxx
@@ -880,7 +880,10 @@ void CheckResetRedlineMergeFlag(SwTextNode & rNode, Recreate const eRecreateMerg
if (eRecreateMerged != sw::Recreate::No)
{
SwTextNode * pMergeNode(&rNode);
- if (eRecreateMerged == sw::Recreate::Predecessor)
+ if (eRecreateMerged == sw::Recreate::Predecessor
+ // tdf#135018 check that there is a predecessor node, i.e. rNode
+ // isn't the first node after the body start node
+ && rNode.GetNodes()[rNode.GetIndex() - 1]->StartOfSectionIndex() != 0)
{
for (sal_uLong i = rNode.GetIndex() - 1; ; --i)
{
commit d0ebd31df55d6bec2a0a7f84978712e49b90b993
Author: Michael Stahl <Michael.Stahl at cib.de>
AuthorDate: Tue Aug 25 14:44:39 2020 +0200
Commit: Thorsten Behrens <Thorsten.Behrens at CIB.de>
CommitDate: Wed Aug 26 14:25:57 2020 +0200
(related: tdf#132160) sw: fix lcl_RejectRedline if end is on table node
This happens on Undo:
sw/source/core/undo/undobj.cxx:1394: void SwRedlineSaveData::RedlineToDoc(const SwPaM&): Assertion `result != IDocumentRedlineAccess::AppendResult::IGNORED' failed.
Because the SwRedlineSaveData was created in SwUndoDelete ctor from
this:
(rr) p *pRedl
$18 = (SwRangeRedline) {
<SwPaM> = SwPaM = {
point = SwPosition (node 13457, offset 0),
mark = SwPosition (node 13455, offset 0)
},
(rr) p pRedl->GetPoint()->nNode.GetNode().GetNodes()[13457]
$19 = (SwTableNode *) 0x80bdbe0
DelFullPara() will delete the end node, see "m_rDoc.GetNodes().Delete(
aRg.aStart, nNodeDiff+1 );" or equivalent in SwUndoDelete.
So if the end is on a start node, set it back to the previous node,
because deleting just a start node is a bad idea.
Change-Id: Ib7c35c103ce05ede39e66505fa47fa70bfece018
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/101334
Tested-by: Jenkins
Reviewed-by: Michael Stahl <michael.stahl at cib.de>
(cherry picked from commit e2fe4fde592564d35099ad1e2659ad682dfb77f5)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/101352
Reviewed-by: Thorsten Behrens <Thorsten.Behrens at CIB.de>
diff --git a/sw/qa/extras/uiwriter/data/tdf132160.odt b/sw/qa/extras/uiwriter/data/tdf132160.odt
new file mode 100644
index 000000000000..8a8ae7b8b1cb
Binary files /dev/null and b/sw/qa/extras/uiwriter/data/tdf132160.odt differ
diff --git a/sw/qa/extras/uiwriter/uiwriter.cxx b/sw/qa/extras/uiwriter/uiwriter.cxx
index c14306e233c9..be8a972a181a 100644
--- a/sw/qa/extras/uiwriter/uiwriter.cxx
+++ b/sw/qa/extras/uiwriter/uiwriter.cxx
@@ -4231,6 +4231,24 @@ void SwUiWriterTest::testDde()
#endif
}
+CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testTdf132160)
+{
+ load(DATA_DIRECTORY, "tdf132160.odt");
+
+ SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument*>(mxComponent.get());
+ CPPUNIT_ASSERT(pTextDoc);
+
+ // this would crash due to delete redline starting with ToX
+ lcl_dispatchCommand(mxComponent, ".uno:RejectAllTrackedChanges", {});
+
+ // this would crash due to insert redline ending on table node
+ lcl_dispatchCommand(mxComponent, ".uno:Undo", {});
+
+ lcl_dispatchCommand(mxComponent, ".uno:Redo", {});
+
+ lcl_dispatchCommand(mxComponent, ".uno:Undo", {});
+}
+
//IdleTask class to add a low priority Idle task
class IdleTask
{
diff --git a/sw/source/core/doc/DocumentRedlineManager.cxx b/sw/source/core/doc/DocumentRedlineManager.cxx
index 8e026a876dc9..ff9b05743d10 100644
--- a/sw/source/core/doc/DocumentRedlineManager.cxx
+++ b/sw/source/core/doc/DocumentRedlineManager.cxx
@@ -658,6 +658,11 @@ namespace
{
aPam.GetBound().nContent.Assign( nullptr, 0 );
aPam.GetBound( false ).nContent.Assign( nullptr, 0 );
+ if (aPam.End()->nNode.GetNode().IsStartNode())
+ { // end node will be deleted too! see nNodeDiff+1
+ --aPam.End()->nNode;
+ }
+ assert(!aPam.End()->nNode.GetNode().IsStartNode());
rDoc.getIDocumentContentOperations().DelFullPara( aPam );
}
else
commit 9adb750c0066cda6f534e8e9430de5b236f4b2bd
Author: Caolán McNamara <caolanm at redhat.com>
AuthorDate: Tue Aug 25 13:53:46 2020 +0100
Commit: Caolán McNamara <caolanm at redhat.com>
CommitDate: Wed Aug 26 13:16:19 2020 +0200
tdf#127802 support tristate for hidden/unhidden text
Change-Id: I9a8ad72ae3ee45ac2521e662b17d3d22d98aa055
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/101331
Tested-by: Jenkins
Reviewed-by: Caolán McNamara <caolanm at redhat.com>
diff --git a/cui/source/inc/chardlg.hxx b/cui/source/inc/chardlg.hxx
index 9e4419d4406e..bbd1dff4dab9 100644
--- a/cui/source/inc/chardlg.hxx
+++ b/cui/source/inc/chardlg.hxx
@@ -169,6 +169,12 @@ private:
sal_uInt16 m_nHtmlMode;
bool m_bUnderlineColorDisabled;
+ weld::TriStateEnabled m_aOutlineState;
+ weld::TriStateEnabled m_aShadowState;
+ weld::TriStateEnabled m_aBlinkingState;
+ weld::TriStateEnabled m_aHiddenState;
+ weld::TriStateEnabled m_aIndividualWordsState;
+
std::unique_ptr<weld::Label> m_xFontColorFT;
std::unique_ptr<ColorListBox> m_xFontColorLB;
std::unique_ptr<weld::Label> m_xEffectsFT;
@@ -203,8 +209,11 @@ private:
void SelectHdl_Impl(const weld::ComboBox*);
DECL_LINK(SelectListBoxHdl_Impl, weld::ComboBox&, void);
+ DECL_LINK(OutlineBtnClickHdl, weld::ToggleButton&, void);
+ DECL_LINK(ShadowBtnClickHdl, weld::ToggleButton&, void);
+ DECL_LINK(BlinkingBtnClickHdl, weld::ToggleButton&, void);
+ DECL_LINK(HiddenBtnClickHdl, weld::ToggleButton&, void);
DECL_LINK(CbClickHdl_Impl, weld::ToggleButton&, void);
- DECL_LINK(TristClickHdl_Impl, weld::ToggleButton&, void);
DECL_LINK(UpdatePreview_Impl, weld::ComboBox&, void);
DECL_LINK(ColorBoxSelectHdl_Impl, ColorListBox&, void);
diff --git a/cui/source/tabpages/chardlg.cxx b/cui/source/tabpages/chardlg.cxx
index d7dca728de87..c541df780999 100644
--- a/cui/source/tabpages/chardlg.cxx
+++ b/cui/source/tabpages/chardlg.cxx
@@ -1416,10 +1416,11 @@ void SvxCharEffectsPage::Initialize()
m_xEffectsLB->set_active( 0 );
+ m_xHiddenBtn->connect_toggled(LINK(this, SvxCharEffectsPage, HiddenBtnClickHdl));
m_xIndividualWordsBtn->connect_toggled(LINK(this, SvxCharEffectsPage, CbClickHdl_Impl));
- Link<weld::ToggleButton&,void> aLink2 = LINK(this, SvxCharEffectsPage, TristClickHdl_Impl);
- m_xOutlineBtn->connect_toggled(aLink2);
- m_xShadowBtn->connect_toggled(aLink2);
+ m_xOutlineBtn->connect_toggled(LINK(this, SvxCharEffectsPage, OutlineBtnClickHdl));
+ m_xShadowBtn->connect_toggled(LINK(this, SvxCharEffectsPage, ShadowBtnClickHdl));
+ m_xBlinkingBtn->connect_toggled(LINK(this, SvxCharEffectsPage, BlinkingBtnClickHdl));
if ( !SvtLanguageOptions().IsAsianTypographyEnabled() )
{
@@ -1495,7 +1496,7 @@ void SvxCharEffectsPage::UpdatePreview_Impl()
rCTLFont.SetCaseMap( eCaps == SvxCaseMap::SmallCaps ? SvxCaseMap::NotMapped : eCaps );
}
- bool bWordLine = m_xIndividualWordsBtn->get_active();
+ bool bWordLine = StateToAttr( m_xIndividualWordsBtn->get_state() );
rFont.SetWordLineMode( bWordLine );
rCJKFont.SetWordLineMode( bWordLine );
rCTLFont.SetWordLineMode( bWordLine );
@@ -1645,13 +1646,10 @@ IMPL_LINK_NOARG(SvxCharEffectsPage, UpdatePreview_Impl, weld::ComboBox&, void)
UpdatePreview_Impl();
}
-IMPL_LINK_NOARG(SvxCharEffectsPage, CbClickHdl_Impl, weld::ToggleButton&, void)
+IMPL_LINK(SvxCharEffectsPage, CbClickHdl_Impl, weld::ToggleButton&, rToggle, void)
{
+ m_aIndividualWordsState.ButtonToggled(rToggle);
UpdatePreview_Impl();
-}
-
-IMPL_LINK_NOARG(SvxCharEffectsPage, TristClickHdl_Impl, weld::ToggleButton&, void)
-{
UpdatePreview_Impl();
}
@@ -1802,15 +1800,18 @@ void SvxCharEffectsPage::Reset( const SfxItemSet* rSet )
switch ( eState )
{
case SfxItemState::UNKNOWN:
+ m_aIndividualWordsState.bTriStateEnabled = false;
m_xIndividualWordsBtn->hide();
break;
case SfxItemState::DISABLED:
case SfxItemState::READONLY:
+ m_aIndividualWordsState.bTriStateEnabled = false;
m_xIndividualWordsBtn->set_sensitive(false);
break;
case SfxItemState::DONTCARE:
+ m_aIndividualWordsState.bTriStateEnabled = true;
m_xIndividualWordsBtn->set_state( TRISTATE_INDET );
break;
@@ -1822,6 +1823,7 @@ void SvxCharEffectsPage::Reset( const SfxItemSet* rSet )
rCJKFont.SetWordLineMode( rItem.GetValue() );
rCTLFont.SetWordLineMode( rItem.GetValue() );
+ m_aIndividualWordsState.bTriStateEnabled = false;
m_xIndividualWordsBtn->set_active(rItem.GetValue());
m_xIndividualWordsBtn->set_sensitive(bEnable);
break;
@@ -1936,15 +1938,18 @@ void SvxCharEffectsPage::Reset( const SfxItemSet* rSet )
switch ( eState )
{
case SfxItemState::UNKNOWN:
+ m_aOutlineState.bTriStateEnabled = false;
m_xOutlineBtn->hide();
break;
case SfxItemState::DISABLED:
case SfxItemState::READONLY:
+ m_aOutlineState.bTriStateEnabled = false;
m_xOutlineBtn->set_sensitive(false);
break;
case SfxItemState::DONTCARE:
+ m_aOutlineState.bTriStateEnabled = true;
m_xOutlineBtn->set_state(TRISTATE_INDET);
break;
@@ -1952,6 +1957,7 @@ void SvxCharEffectsPage::Reset( const SfxItemSet* rSet )
case SfxItemState::SET:
{
const SvxContourItem& rItem = static_cast<const SvxContourItem&>(rSet->Get( nWhich ));
+ m_aOutlineState.bTriStateEnabled = false;
m_xOutlineBtn->set_state(static_cast<TriState>(rItem.GetValue()));
break;
}
@@ -1964,15 +1970,18 @@ void SvxCharEffectsPage::Reset( const SfxItemSet* rSet )
switch ( eState )
{
case SfxItemState::UNKNOWN:
+ m_aShadowState.bTriStateEnabled = false;
m_xShadowBtn->hide();
break;
case SfxItemState::DISABLED:
case SfxItemState::READONLY:
+ m_aShadowState.bTriStateEnabled = false;
m_xShadowBtn->set_sensitive(false);
break;
case SfxItemState::DONTCARE:
+ m_aShadowState.bTriStateEnabled = true;
m_xShadowBtn->set_state( TRISTATE_INDET );
break;
@@ -1980,6 +1989,7 @@ void SvxCharEffectsPage::Reset( const SfxItemSet* rSet )
case SfxItemState::SET:
{
const SvxShadowedItem& rItem = static_cast<const SvxShadowedItem&>(rSet->Get( nWhich ));
+ m_aShadowState.bTriStateEnabled = false;
m_xShadowBtn->set_state( static_cast<TriState>(rItem.GetValue()) );
break;
}
@@ -1992,15 +2002,18 @@ void SvxCharEffectsPage::Reset( const SfxItemSet* rSet )
switch ( eState )
{
case SfxItemState::UNKNOWN:
+ m_aBlinkingState.bTriStateEnabled = false;
m_xBlinkingBtn->hide();
break;
case SfxItemState::DISABLED:
case SfxItemState::READONLY:
+ m_aBlinkingState.bTriStateEnabled = false;
m_xBlinkingBtn->set_sensitive(false);
break;
case SfxItemState::DONTCARE:
+ m_aBlinkingState.bTriStateEnabled = true;
m_xBlinkingBtn->set_state( TRISTATE_INDET );
break;
@@ -2008,6 +2021,7 @@ void SvxCharEffectsPage::Reset( const SfxItemSet* rSet )
case SfxItemState::SET:
{
const SvxBlinkItem& rItem = static_cast<const SvxBlinkItem&>(rSet->Get( nWhich ));
+ m_aBlinkingState.bTriStateEnabled = false;
m_xBlinkingBtn->set_state( static_cast<TriState>(rItem.GetValue()) );
break;
}
@@ -2019,15 +2033,18 @@ void SvxCharEffectsPage::Reset( const SfxItemSet* rSet )
switch ( eState )
{
case SfxItemState::UNKNOWN:
+ m_aHiddenState.bTriStateEnabled = false;
m_xHiddenBtn->hide();
break;
case SfxItemState::DISABLED:
case SfxItemState::READONLY:
+ m_aHiddenState.bTriStateEnabled = false;
m_xHiddenBtn->set_sensitive(false);
break;
case SfxItemState::DONTCARE:
+ m_aHiddenState.bTriStateEnabled = true;
m_xHiddenBtn->set_state(TRISTATE_INDET);
break;
@@ -2035,6 +2052,7 @@ void SvxCharEffectsPage::Reset( const SfxItemSet* rSet )
case SfxItemState::SET:
{
const SvxCharHiddenItem& rItem = static_cast<const SvxCharHiddenItem&>(rSet->Get( nWhich ));
+ m_aHiddenState.bTriStateEnabled = false;
m_xHiddenBtn->set_state(static_cast<TriState>(rItem.GetValue()));
break;
}
@@ -2050,6 +2068,28 @@ void SvxCharEffectsPage::Reset( const SfxItemSet* rSet )
ChangesApplied();
}
+IMPL_LINK(SvxCharEffectsPage, HiddenBtnClickHdl, weld::ToggleButton&, rToggle, void)
+{
+ m_aHiddenState.ButtonToggled(rToggle);
+}
+
+IMPL_LINK(SvxCharEffectsPage, OutlineBtnClickHdl, weld::ToggleButton&, rToggle, void)
+{
+ m_aOutlineState.ButtonToggled(rToggle);
+ UpdatePreview_Impl();
+}
+
+IMPL_LINK(SvxCharEffectsPage, ShadowBtnClickHdl, weld::ToggleButton&, rToggle, void)
+{
+ m_aShadowState.ButtonToggled(rToggle);
+ UpdatePreview_Impl();
+}
+
+IMPL_LINK(SvxCharEffectsPage, BlinkingBtnClickHdl, weld::ToggleButton&, rToggle, void)
+{
+ m_aBlinkingState.ButtonToggled(rToggle);
+}
+
void SvxCharEffectsPage::ChangesApplied()
{
m_xUnderlineLB->save_value();
@@ -2173,23 +2213,26 @@ bool SvxCharEffectsPage::FillItemSet( SfxItemSet* rSet )
bChanged = true;
// Individual words
+ const SfxItemSet* pExampleSet = GetDialogExampleSet();
nWhich = GetWhich( SID_ATTR_CHAR_WORDLINEMODE );
pOld = GetOldItem( *rSet, SID_ATTR_CHAR_WORDLINEMODE );
+ TriState eState = m_xIndividualWordsBtn->get_state();
+ const SfxPoolItem* pItem;
if ( pOld )
{
const SvxWordLineModeItem& rItem = *static_cast<const SvxWordLineModeItem*>(pOld);
- if ( rItem.GetValue() == m_xIndividualWordsBtn->get_active() )
+ if ( rItem.GetValue() == StateToAttr( eState ) && m_xIndividualWordsBtn->get_saved_state() == eState )
bChanged = false;
}
- if ( rOldSet.GetItemState( nWhich ) == SfxItemState::DONTCARE &&
- ! m_xIndividualWordsBtn->get_state_changed_from_saved() )
- bChanged = false;
+ if ( !bChanged && pExampleSet && pExampleSet->GetItemState( nWhich, false, &pItem ) == SfxItemState::SET &&
+ !StateToAttr( eState ) && static_cast<const SvxWordLineModeItem*>(pItem)->GetValue() )
+ bChanged = true;
- if ( bChanged )
+ if ( bChanged && eState != TRISTATE_INDET )
{
- rSet->Put( SvxWordLineModeItem( m_xIndividualWordsBtn->get_active(), nWhich ) );
+ rSet->Put( SvxWordLineModeItem( StateToAttr( eState ), nWhich ) );
bModified = true;
}
else if ( SfxItemState::DEFAULT == rOldSet.GetItemState( nWhich, false ) )
@@ -2282,11 +2325,9 @@ bool SvxCharEffectsPage::FillItemSet( SfxItemSet* rSet )
}
// Outline
- const SfxItemSet* pExampleSet = GetDialogExampleSet();
nWhich = GetWhich( SID_ATTR_CHAR_CONTOUR );
pOld = GetOldItem( *rSet, SID_ATTR_CHAR_CONTOUR );
- TriState eState = m_xOutlineBtn->get_state();
- const SfxPoolItem* pItem;
+ eState = m_xOutlineBtn->get_state();
if ( pOld )
{
commit 1a3c4545db30e222ef8456ccdbf51d07a18adbca
Author: Michael Stahl <Michael.Stahl at cib.de>
AuthorDate: Mon Aug 24 19:29:14 2020 +0200
Commit: Caolán McNamara <caolanm at redhat.com>
CommitDate: Wed Aug 26 11:01:15 2020 +0200
tdf#132160 sw_redlinehide: more pathological redline problems
This is similar to 63dba5203e8bc7fc390943cb8208ae904f18e3bb except here
the redline starts with a section (in particular an entire alphabetical
index); this one is at node 13489 to node 14206.
There's another fun one, starts with a table but has a text node
following it, at node 8222 to 8231; this case also wasn't handled
correctly at least in one direction. Fix that by continuing iteration
... etc. - the rest is truncated
More information about the Libreoffice-commits
mailing list