diff options
Diffstat (limited to '')
-rw-r--r-- | sw/qa/extras/unowriter/data/bookmarkintable.fodt | 82 | ||||
-rw-r--r-- | sw/qa/extras/unowriter/data/image-comment-at-char.odt | bin | 0 -> 10244 bytes | |||
-rw-r--r-- | sw/qa/extras/unowriter/data/renderable-page-position.odt | bin | 0 -> 8465 bytes | |||
-rw-r--r-- | sw/qa/extras/unowriter/data/selection-in-table-enum.odt | bin | 0 -> 8941 bytes | |||
-rw-r--r-- | sw/qa/extras/unowriter/data/table-line-spacing.docx | bin | 0 -> 11383 bytes | |||
-rw-r--r-- | sw/qa/extras/unowriter/data/tdf134250.fodt | 86 | ||||
-rw-r--r-- | sw/qa/extras/unowriter/data/tdf134252.fodt | 95 | ||||
-rw-r--r-- | sw/qa/extras/unowriter/data/tdf134252_onlytable_protected.fodt | 87 | ||||
-rw-r--r-- | sw/qa/extras/unowriter/data/test.jpg | bin | 0 -> 1136 bytes | |||
-rw-r--r-- | sw/qa/extras/unowriter/data/view-cursor-page-style.fodt | 23 | ||||
-rw-r--r-- | sw/qa/extras/unowriter/data/xautotextgroup.odt | bin | 0 -> 11151 bytes | |||
-rw-r--r-- | sw/qa/extras/unowriter/unowriter.cxx | 1210 |
12 files changed, 1583 insertions, 0 deletions
diff --git a/sw/qa/extras/unowriter/data/bookmarkintable.fodt b/sw/qa/extras/unowriter/data/bookmarkintable.fodt new file mode 100644 index 000000000..641200fef --- /dev/null +++ b/sw/qa/extras/unowriter/data/bookmarkintable.fodt @@ -0,0 +1,82 @@ +<?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="urn: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:meta><meta:creation-date>2020-11-24T13:16:34.248376640</meta:creation-date><dc:date>2020-11-24T14:47:04.359492742</dc:date><meta:editing-duration>PT2M22S</meta:editing-duration><meta:editing-cycles>2</meta:editing-cycles><meta:generator>LibreOfficeDev/7.1.0.0.alpha1$Linux_X86_64 LibreOffice_project/a871df849fad8f923db945cf0606f30603380ef7</meta:generator><meta:document-statistic meta:table-count="1" meta:image-count="0" meta:object-count="0" meta:page-count="1" meta:paragraph-count="1" meta:word-count="1" meta:character-count="5" meta:non-whitespace-character-count="5"/></office:meta> + <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="Arial Unicode MS" svg:font-family="'Arial Unicode MS'" 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: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="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="Arial Unicode MS" 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="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="Arial Unicode MS" 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"/> + <style:style style:name="Table_20_Contents" style:display-name="Table Contents" style:family="paragraph" style:parent-style-name="Standard" style:class="extra"> + <style:paragraph-properties fo:orphans="0" fo:widows="0" text:number-lines="false" text:line-number="0"/> + </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="Table1" style:family="table"> + <style:table-properties style:width="17cm" table:align="margins"/> + </style:style> + <style:style style:name="Table1.A" style:family="table-column"> + <style:table-column-properties style:column-width="17cm" style:rel-column-width="65535*"/> + </style:style> + <style:style style:name="Table1.A1" style:family="table-cell"> + <style:table-cell-properties fo:padding="0.097cm" fo:border="0.05pt solid #000000"/> + </style:style> + <style:style style:name="P1" style:family="paragraph" style:parent-style-name="Table_20_Contents"> + <style:text-properties officeooo:rsid="001c6504" officeooo:paragraph-rsid="001c6504"/> + </style:style> + <style:style style:name="T1" style:family="text"> + <style:text-properties officeooo:rsid="001cbfb2"/> + </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:sequence-decls> + <text:sequence-decl text:display-outline-level="0" text:name="Illustration"/> + <text:sequence-decl text:display-outline-level="0" text:name="Table"/> + <text:sequence-decl text:display-outline-level="0" text:name="Text"/> + <text:sequence-decl text:display-outline-level="0" text:name="Drawing"/> + <text:sequence-decl text:display-outline-level="0" text:name="Figure"/> + </text:sequence-decls> + <table:table table:name="Table1" table:style-name="Table1"> + <table:table-column table:style-name="Table1.A"/> + <table:table-row table:style-name="TableLine91390352"> + <table:table-cell table:style-name="Table1.A1" office:value-type="string"> + <text:p text:style-name="P1"><text:span text:style-name="T1">a</text:span><text:bookmark-start text:name="Bookmark 1"/>foo<text:bookmark-end text:name="Bookmark 1"/><text:span text:style-name="T1">b</text:span></text:p> + </table:table-cell> + </table:table-row> + </table:table> + <text:p text:style-name="Standard"/> + </office:text> + </office:body> +</office:document> diff --git a/sw/qa/extras/unowriter/data/image-comment-at-char.odt b/sw/qa/extras/unowriter/data/image-comment-at-char.odt Binary files differnew file mode 100644 index 000000000..ba959d68a --- /dev/null +++ b/sw/qa/extras/unowriter/data/image-comment-at-char.odt diff --git a/sw/qa/extras/unowriter/data/renderable-page-position.odt b/sw/qa/extras/unowriter/data/renderable-page-position.odt Binary files differnew file mode 100644 index 000000000..3baddaf21 --- /dev/null +++ b/sw/qa/extras/unowriter/data/renderable-page-position.odt diff --git a/sw/qa/extras/unowriter/data/selection-in-table-enum.odt b/sw/qa/extras/unowriter/data/selection-in-table-enum.odt Binary files differnew file mode 100644 index 000000000..bef9b0ea7 --- /dev/null +++ b/sw/qa/extras/unowriter/data/selection-in-table-enum.odt diff --git a/sw/qa/extras/unowriter/data/table-line-spacing.docx b/sw/qa/extras/unowriter/data/table-line-spacing.docx Binary files differnew file mode 100644 index 000000000..60621f03c --- /dev/null +++ b/sw/qa/extras/unowriter/data/table-line-spacing.docx diff --git a/sw/qa/extras/unowriter/data/tdf134250.fodt b/sw/qa/extras/unowriter/data/tdf134250.fodt new file mode 100644 index 000000000..86aaa140c --- /dev/null +++ b/sw/qa/extras/unowriter/data/tdf134250.fodt @@ -0,0 +1,86 @@ +<?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="urn:oasis:names:tc:opendocument:xmlns:script:1.0" xmlns:xforms="http://www.w3.org/2002/xforms" office:version="1.2" 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" loext:opacity="0%" 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" loext:opacity="0%" 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" 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"/> + <style:style style:name="Table_20_Contents" style:display-name="Table Contents" style:family="paragraph" style:parent-style-name="Standard" style:class="extra"> + <style:paragraph-properties fo:orphans="0" fo:widows="0" text:number-lines="false" text:line-number="0"/> + </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="Table1" style:family="table"> + <style:table-properties style:width="17cm" table:align="margins"/> + </style:style> + <style:style style:name="Table1.A" style:family="table-column"> + <style:table-column-properties style:column-width="17cm" style:rel-column-width="65535*"/> + </style:style> + <style:style style:name="Table1.A1" style:family="table-cell"> + <style:table-cell-properties fo:padding="0.097cm" fo:border="0.05pt solid #000000"/> + </style:style> + <style:style style:name="P1" style:family="paragraph" style:parent-style-name="Standard"> + <style:text-properties officeooo:rsid="001fe5a9" officeooo:paragraph-rsid="001fe5a9"/> + </style:style> + <style:style style:name="P2" style:family="paragraph" style:parent-style-name="Table_20_Contents"> + <style:text-properties officeooo:rsid="001fe5a9" officeooo:paragraph-rsid="001fe5a9"/> + </style:style> + <style:style style:name="T1" style:family="text"> + <style:text-properties fo:font-weight="bold" style:font-weight-asian="bold" style:font-weight-complex="bold"/> + </style:style> + <style:style style:name="Sect1" style:family="section"> + <style:section-properties style:editable="false"> + <style:columns fo:column-count="1" fo:column-gap="0cm"/> + </style:section-properties> + </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: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:section text:style-name="Sect1" text:name="Section1"> + <table:table table:name="Table1" table:style-name="Table1"> + <table:table-column table:style-name="Table1.A"/> + <table:table-row> + <table:table-cell table:style-name="Table1.A1" office:value-type="string"> + <text:p text:style-name="P2">foo</text:p> + </table:table-cell> + </table:table-row> + </table:table> + <text:p text:style-name="P1">b<text:span text:style-name="T1">a</text:span><text:bookmark text:name="Bookmark 1"/>r</text:p> + </text:section> + </office:text> + </office:body> +</office:document> diff --git a/sw/qa/extras/unowriter/data/tdf134252.fodt b/sw/qa/extras/unowriter/data/tdf134252.fodt new file mode 100644 index 000000000..6e19ac847 --- /dev/null +++ b/sw/qa/extras/unowriter/data/tdf134252.fodt @@ -0,0 +1,95 @@ +<?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="urn: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="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" loext:opacity="0%" 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" loext:opacity="0%" 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" 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="Table1" style:family="table"> + <style:table-properties style:width="17cm" table:align="margins"/> + </style:style> + <style:style style:name="Table1.A" style:family="table-column"> + <style:table-column-properties style:column-width="17cm" style:rel-column-width="65535*"/> + </style:style> + <style:style style:name="Table1.A1" style:family="table-cell"> + <style:table-cell-properties fo:padding="0.097cm" fo:border="0.05pt solid #000000"/> + </style:style> + <style:style style:name="P1" style:family="paragraph" style:parent-style-name="Standard"> + <style:text-properties officeooo:rsid="00078615" officeooo:paragraph-rsid="00078615"/> + </style:style> + <style:style style:name="P3" style:family="paragraph" style:parent-style-name="Table_20_Contents"> + <style:text-properties officeooo:rsid="00095b34" officeooo:paragraph-rsid="00095b34"/> + </style:style> + <style:style style:name="Sect1" style:family="section"> + <style:section-properties fo:background-color="#81d41a" style:editable="false"> + <style:columns fo:column-count="1" fo:column-gap="0cm"/> + <style:background-image/> + </style:section-properties> + </style:style> + <style:style style:name="Sect2" style:family="section"> + <style:section-properties style:editable="false"> + <style:columns fo:column-count="1" fo:column-gap="0cm"/> + </style:section-properties> + </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:sequence-decls> + <text:sequence-decl text:display-outline-level="0" text:name="Illustration"/> + <text:sequence-decl text:display-outline-level="0" text:name="Table"/> + <text:sequence-decl text:display-outline-level="0" text:name="Text"/> + <text:sequence-decl text:display-outline-level="0" text:name="Drawing"/> + <text:sequence-decl text:display-outline-level="0" text:name="Figure"/> + </text:sequence-decls> + <text:section text:style-name="Sect1" text:name="Section1"> + <text:p text:style-name="P1">bar</text:p> + <table:table table:name="Table1" table:style-name="Table1"> + <table:table-column table:style-name="Table1.A"/> + <table:table-row> + <table:table-cell table:style-name="Table1.A1" office:value-type="string"> + <text:p text:style-name="P3">baz</text:p> + </table:table-cell> + </table:table-row> + </table:table> + </text:section> + <text:section text:style-name="Sect2" text:name="Section2"> + <text:p text:style-name="P1">foo</text:p> + </text:section> + </office:text> + </office:body> +</office:document> diff --git a/sw/qa/extras/unowriter/data/tdf134252_onlytable_protected.fodt b/sw/qa/extras/unowriter/data/tdf134252_onlytable_protected.fodt new file mode 100644 index 000000000..f588fdba0 --- /dev/null +++ b/sw/qa/extras/unowriter/data/tdf134252_onlytable_protected.fodt @@ -0,0 +1,87 @@ +<?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="urn: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="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" loext:opacity="0%" 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" loext:opacity="0%" 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" 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="Table1" style:family="table"> + <style:table-properties style:width="17cm" table:align="margins"/> + </style:style> + <style:style style:name="Table1.A" style:family="table-column"> + <style:table-column-properties style:column-width="17cm" style:rel-column-width="65535*"/> + </style:style> + <style:style style:name="Table1.A1" style:family="table-cell"> + <style:table-cell-properties fo:padding="0.097cm" fo:border="0.05pt solid #000000"/> + </style:style> + <style:style style:name="P1" style:family="paragraph" style:parent-style-name="Standard"> + <style:text-properties officeooo:rsid="00078615" officeooo:paragraph-rsid="00078615"/> + </style:style> + <style:style style:name="P3" style:family="paragraph" style:parent-style-name="Table_20_Contents"> + <style:text-properties officeooo:rsid="00095b34" officeooo:paragraph-rsid="00095b34"/> + </style:style> + <style:style style:name="Sect1" style:family="section"> + <style:section-properties fo:background-color="#81d41a" style:editable="false"> + <style:columns fo:column-count="1" fo:column-gap="0cm"/> + <style:background-image/> + </style:section-properties> + </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:sequence-decls> + <text:sequence-decl text:display-outline-level="0" text:name="Illustration"/> + <text:sequence-decl text:display-outline-level="0" text:name="Table"/> + <text:sequence-decl text:display-outline-level="0" text:name="Text"/> + <text:sequence-decl text:display-outline-level="0" text:name="Drawing"/> + <text:sequence-decl text:display-outline-level="0" text:name="Figure"/> + </text:sequence-decls> + <text:section text:style-name="Sect1" text:name="Section1"> + <table:table table:name="Table1" table:style-name="Table1"> + <table:table-column table:style-name="Table1.A"/> + <table:table-row> + <table:table-cell table:style-name="Table1.A1" office:value-type="string" table:protected="true"> + <text:p text:style-name="P3">baz</text:p> + </table:table-cell> + </table:table-row> + </table:table> + </text:section> + <text:p text:style-name="P1">foo</text:p> + </office:text> + </office:body> +</office:document> diff --git a/sw/qa/extras/unowriter/data/test.jpg b/sw/qa/extras/unowriter/data/test.jpg Binary files differnew file mode 100644 index 000000000..12b393569 --- /dev/null +++ b/sw/qa/extras/unowriter/data/test.jpg diff --git a/sw/qa/extras/unowriter/data/view-cursor-page-style.fodt b/sw/qa/extras/unowriter/data/view-cursor-page-style.fodt new file mode 100644 index 000000000..c386e72c9 --- /dev/null +++ b/sw/qa/extras/unowriter/data/view-cursor-page-style.fodt @@ -0,0 +1,23 @@ +<?xml version="1.0" encoding="UTF-8"?> +<office:document xmlns:grddl="http://www.w3.org/2003/g/data-view#" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:css3t="http://www.w3.org/TR/css3-text/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:formx="urn:openoffice:names:experimental:ooxml-odf-interop:xmlns:form:1.0" xmlns:xforms="http://www.w3.org/2002/xforms" xmlns:dom="http://www.w3.org/2001/xml-events" xmlns:script="urn:oasis:names:tc:opendocument:xmlns:script:1.0" xmlns:form="urn:oasis:names:tc:opendocument:xmlns:form:1.0" xmlns:math="http://www.w3.org/1998/Math/MathML" xmlns:field="urn:openoffice:names:experimental:ooo-ms-interop:xmlns:field:1.0" xmlns:of="urn:oasis:names:tc:opendocument:xmlns:of:1.2" xmlns:oooc="http://openoffice.org/2004/calc" xmlns:ooow="http://openoffice.org/2004/writer" xmlns:config="urn:oasis:names:tc:opendocument:xmlns:config:1.0" xmlns:tableooo="http://openoffice.org/2009/table" xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" xmlns:calcext="urn:org:documentfoundation:names:experimental:calc:xmlns:calcext:1.0" xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" xmlns:loext="urn:org:documentfoundation:names:experimental:office:xmlns:loext:1.0" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ooo="http://openoffice.org/2004/office" xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0" xmlns:meta="urn:oasis:names:tc:opendocument:xmlns:meta:1.0" xmlns:officeooo="http://openoffice.org/2009/office" xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0" xmlns:drawooo="http://openoffice.org/2010/draw" xmlns:draw="urn:oasis:names:tc:opendocument:xmlns:drawing:1.0" xmlns:dr3d="urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0" xmlns:svg="urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0" xmlns:chart="urn:oasis:names:tc:opendocument:xmlns:chart:1.0" xmlns:rpt="http://openoffice.org/2005/report" xmlns:number="urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0" office:version="1.2" office:mimetype="application/vnd.oasis.opendocument.text"> + <office:styles> + <style:default-style style:family="paragraph"/> + <style:style style:name="Standard" style:family="paragraph" style:class="text"/> + </office:styles> + <office:automatic-styles> + <style:style style:name="P1" style:family="paragraph" style:parent-style-name="Standard" style:master-page-name="First_20_Page"/> + <style:page-layout style:name="pm1"> + <style:page-layout-properties fo:page-width="21.001cm" fo:page-height="9.7cm" style:print-orientation="landscape" fo:margin-top="2cm" fo:margin-bottom="2cm" fo:margin-left="2cm" fo:margin-right="2cm"> + </style:page-layout-properties> + </style:page-layout> + </office:automatic-styles> + <office:master-styles> + <style:master-page style:name="Standard" style:page-layout-name="pm1"/> + <style:master-page style:name="First_20_Page" style:display-name="First Page" style:page-layout-name="pm1" style:next-style-name="Standard"/> + </office:master-styles> + <office:body> + <office:text> + <text:p text:style-name="P1">01<text:line-break/>02<text:line-break/>03<text:line-break/>04<text:line-break/>05<text:line-break/>06<text:line-break/>07<text:line-break/>08<text:line-break/>09<text:line-break/>10<text:line-break/>11<text:line-break/>12<text:line-break/>13<text:line-break/>14<text:line-break/>15<text:line-break/>16</text:p> + </office:text> + </office:body> +</office:document> diff --git a/sw/qa/extras/unowriter/data/xautotextgroup.odt b/sw/qa/extras/unowriter/data/xautotextgroup.odt Binary files differnew file mode 100644 index 000000000..e1cb9e7ea --- /dev/null +++ b/sw/qa/extras/unowriter/data/xautotextgroup.odt diff --git a/sw/qa/extras/unowriter/unowriter.cxx b/sw/qa/extras/unowriter/unowriter.cxx new file mode 100644 index 000000000..8daa22949 --- /dev/null +++ b/sw/qa/extras/unowriter/unowriter.cxx @@ -0,0 +1,1210 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include <swmodeltestbase.hxx> + +#include <com/sun/star/awt/FontSlant.hpp> +#include <com/sun/star/datatransfer/XTransferableSupplier.hpp> +#include <com/sun/star/datatransfer/XTransferableTextSupplier.hpp> +#include <com/sun/star/table/XCellRange.hpp> +#include <com/sun/star/text/TextContentAnchorType.hpp> +#include <com/sun/star/text/AutoTextContainer.hpp> +#include <com/sun/star/text/VertOrientation.hpp> +#include <com/sun/star/text/XAutoTextGroup.hpp> +#include <com/sun/star/text/XTextPortionAppend.hpp> +#include <com/sun/star/text/XTextContentAppend.hpp> +#include <com/sun/star/text/XTextRangeCompare.hpp> +#include <com/sun/star/text/XPasteListener.hpp> +#include <com/sun/star/rdf/URI.hpp> +#include <com/sun/star/rdf/URIs.hpp> +#include <com/sun/star/awt/XDevice.hpp> +#include <com/sun/star/awt/XToolkit.hpp> +#include <com/sun/star/graphic/XGraphic.hpp> +#include <com/sun/star/style/LineSpacing.hpp> +#include <com/sun/star/view/XSelectionSupplier.hpp> +#include <com/sun/star/text/XTextDocument.hpp> +#include <com/sun/star/container/XNameContainer.hpp> +#include <com/sun/star/view/XRenderable.hpp> +#include <com/sun/star/text/XBookmarksSupplier.hpp> +#include <com/sun/star/text/XTextViewCursorSupplier.hpp> +#include <com/sun/star/text/XTextTable.hpp> +#include <com/sun/star/text/XPageCursor.hpp> + +#include <comphelper/propertyvalue.hxx> +#include <tools/UnitConversion.hxx> +#include <toolkit/helper/vclunohelper.hxx> +#include <vcl/graphicfilter.hxx> +#include <comphelper/sequenceashashmap.hxx> +#include <comphelper/processfactory.hxx> + +#include <wrtsh.hxx> +#include <ndtxt.hxx> +#include <swdtflvr.hxx> +#include <view.hxx> +#include <PostItMgr.hxx> +#include <postithelper.hxx> +#include <AnnotationWin.hxx> +#include <flyfrm.hxx> +#include <fmtanchr.hxx> +#include <unotxdoc.hxx> +#include <docsh.hxx> + +using namespace ::com::sun::star; + +namespace +{ +constexpr OUStringLiteral DATA_DIRECTORY = u"/sw/qa/extras/unowriter/data/"; + +/// Listener implementation for testPasteListener. +class PasteListener : public cppu::WeakImplHelper<text::XPasteListener> +{ + OUString m_aString; + uno::Reference<text::XTextContent> m_xTextGraphicObject; + +public: + void SAL_CALL notifyPasteEvent(const uno::Sequence<beans::PropertyValue>& rEvent) override; + + OUString& GetString(); + uno::Reference<text::XTextContent>& GetTextGraphicObject(); +}; + +void PasteListener::notifyPasteEvent(const uno::Sequence<beans::PropertyValue>& rEvent) +{ + comphelper::SequenceAsHashMap aMap(rEvent); + auto it = aMap.find("TextRange"); + if (it != aMap.end()) + { + auto xTextRange = it->second.get<uno::Reference<text::XTextRange>>(); + if (xTextRange.is()) + m_aString = xTextRange->getString(); + return; + } + + it = aMap.find("TextGraphicObject"); + if (it != aMap.end()) + { + auto xTextGraphicObject = it->second.get<uno::Reference<text::XTextContent>>(); + if (xTextGraphicObject.is()) + m_xTextGraphicObject = xTextGraphicObject; + } +} + +OUString& PasteListener::GetString() { return m_aString; } + +uno::Reference<text::XTextContent>& PasteListener::GetTextGraphicObject() +{ + return m_xTextGraphicObject; +} +} + +/// Test to assert UNO API call results of Writer. +class SwUnoWriter : public SwModelTestBase +{ +public: + SwUnoWriter() + : SwModelTestBase(DATA_DIRECTORY, "writer8") + { + } +}; + +CPPUNIT_TEST_FIXTURE(SwUnoWriter, testDefaultCharStyle) +{ + // Create a new document, type a character, set its char style to Emphasis + // and assert the style was set. + loadURL("private:factory/swriter", nullptr); + + uno::Reference<text::XTextDocument> xTextDocument(mxComponent, uno::UNO_QUERY); + uno::Reference<text::XSimpleText> xBodyText = xTextDocument->getText(); + xBodyText->insertString(xBodyText->getStart(), "x", false); + + uno::Reference<text::XTextCursor> xCursor(xBodyText->createTextCursor()); + xCursor->goLeft(1, true); + + uno::Reference<beans::XPropertySet> xCursorProps(xCursor, uno::UNO_QUERY); + xCursorProps->setPropertyValue("CharStyleName", uno::Any(OUString("Emphasis"))); + CPPUNIT_ASSERT_EQUAL(awt::FontSlant_ITALIC, + getProperty<awt::FontSlant>(xCursorProps, "CharPosture")); + + // Now reset the char style and assert that the font slant is back to none. + // This resulted in a lang.IllegalArgumentException, Standard was not + // mapped to 'Default Style'. + xCursorProps->setPropertyValue("CharStyleName", uno::Any(OUString("Standard"))); + CPPUNIT_ASSERT_EQUAL(awt::FontSlant_NONE, + getProperty<awt::FontSlant>(xCursorProps, "CharPosture")); +} + +CPPUNIT_TEST_FIXTURE(SwUnoWriter, testInsertStringExpandsHints) +{ + loadURL("private:factory/swriter", nullptr); + uno::Reference<text::XTextDocument> const xTextDocument(mxComponent, uno::UNO_QUERY); + uno::Reference<text::XText> const xText(xTextDocument->getText()); + uno::Reference<text::XTextCursor> const xCursor(xText->createTextCursor()); + uno::Reference<beans::XPropertySet> const xProps(xCursor, uno::UNO_QUERY); + + xText->insertString(xCursor, "ab", false); + xCursor->gotoStart(false); + xCursor->goRight(1, true); + CPPUNIT_ASSERT_EQUAL(awt::FontSlant_NONE, getProperty<awt::FontSlant>(xProps, "CharPosture")); + xProps->setPropertyValue("CharPosture", uno::Any(awt::FontSlant_ITALIC)); + xCursor->collapseToEnd(); + xText->insertString(xCursor, "x", false); + xCursor->goLeft(1, true); + CPPUNIT_ASSERT_EQUAL(OUString("x"), xCursor->getString()); + CPPUNIT_ASSERT_EQUAL(awt::FontSlant_ITALIC, getProperty<awt::FontSlant>(xProps, "CharPosture")); +} + +CPPUNIT_TEST_FIXTURE(SwUnoWriter, testInsertTextPortionNotExpandsHints) +{ + loadURL("private:factory/swriter", nullptr); + uno::Reference<text::XTextDocument> const xTextDocument(mxComponent, uno::UNO_QUERY); + uno::Reference<text::XText> const xText(xTextDocument->getText()); + uno::Reference<text::XTextPortionAppend> const xTextA(xText, uno::UNO_QUERY); + uno::Reference<text::XTextCursor> const xCursor(xText->createTextCursor()); + uno::Reference<beans::XPropertySet> const xProps(xCursor, uno::UNO_QUERY); + + xText->insertString(xCursor, "ab", false); + xCursor->gotoStart(false); + xCursor->goRight(1, true); + CPPUNIT_ASSERT_EQUAL(awt::FontSlant_NONE, getProperty<awt::FontSlant>(xProps, "CharPosture")); + xProps->setPropertyValue("CharPosture", uno::Any(awt::FontSlant_ITALIC)); + xCursor->collapseToEnd(); + xTextA->insertTextPortion("x", uno::Sequence<beans::PropertyValue>(), xCursor); + xCursor->goLeft(1, true); + CPPUNIT_ASSERT_EQUAL(OUString("x"), xCursor->getString()); + CPPUNIT_ASSERT_EQUAL(awt::FontSlant_NONE, getProperty<awt::FontSlant>(xProps, "CharPosture")); +} + +CPPUNIT_TEST_FIXTURE(SwUnoWriter, testInsertTextContentExpandsHints) +{ + loadURL("private:factory/swriter", nullptr); + uno::Reference<text::XTextDocument> const xTextDocument(mxComponent, uno::UNO_QUERY); + uno::Reference<lang::XMultiServiceFactory> const xFactory(mxComponent, uno::UNO_QUERY); + uno::Reference<text::XText> const xText(xTextDocument->getText()); + uno::Reference<text::XTextCursor> const xCursor(xText->createTextCursor()); + uno::Reference<beans::XPropertySet> const xProps(xCursor, uno::UNO_QUERY); + + xText->insertString(xCursor, "ab", false); + xCursor->gotoStart(false); + xCursor->goRight(1, true); + CPPUNIT_ASSERT_EQUAL(awt::FontSlant_NONE, getProperty<awt::FontSlant>(xProps, "CharPosture")); + xProps->setPropertyValue("CharPosture", uno::Any(awt::FontSlant_ITALIC)); + xCursor->collapseToEnd(); + uno::Reference<text::XTextContent> const xContent( + xFactory->createInstance("com.sun.star.text.Footnote"), uno::UNO_QUERY); + xText->insertTextContent(xCursor, xContent, false); + xCursor->goLeft(1, true); + CPPUNIT_ASSERT_EQUAL(OUString("1"), xCursor->getString()); + CPPUNIT_ASSERT_EQUAL(awt::FontSlant_ITALIC, getProperty<awt::FontSlant>(xProps, "CharPosture")); +} + +CPPUNIT_TEST_FIXTURE(SwUnoWriter, testInsertTextContentWithPropertiesNotExpandsHints) +{ + loadURL("private:factory/swriter", nullptr); + uno::Reference<text::XTextDocument> const xTextDocument(mxComponent, uno::UNO_QUERY); + uno::Reference<lang::XMultiServiceFactory> const xFactory(mxComponent, uno::UNO_QUERY); + uno::Reference<text::XText> const xText(xTextDocument->getText()); + uno::Reference<text::XTextContentAppend> const xTextA(xText, uno::UNO_QUERY); + uno::Reference<text::XTextCursor> const xCursor(xText->createTextCursor()); + uno::Reference<beans::XPropertySet> const xProps(xCursor, uno::UNO_QUERY); + + xText->insertString(xCursor, "ab", false); + xCursor->gotoStart(false); + xCursor->goRight(1, true); + CPPUNIT_ASSERT_EQUAL(awt::FontSlant_NONE, getProperty<awt::FontSlant>(xProps, "CharPosture")); + xProps->setPropertyValue("CharPosture", uno::Any(awt::FontSlant_ITALIC)); + xCursor->collapseToEnd(); + uno::Reference<text::XTextContent> const xContent( + xFactory->createInstance("com.sun.star.text.Footnote"), uno::UNO_QUERY); + xTextA->insertTextContentWithProperties(xContent, uno::Sequence<beans::PropertyValue>(), + xCursor); + xCursor->goLeft(1, true); + CPPUNIT_ASSERT_EQUAL(OUString("1"), xCursor->getString()); + CPPUNIT_ASSERT_EQUAL(awt::FontSlant_NONE, getProperty<awt::FontSlant>(xProps, "CharPosture")); +} + +CPPUNIT_TEST_FIXTURE(SwUnoWriter, testGraphicDescriptorURL) +{ + loadURL("private:factory/swriter", nullptr); + + // Create a graphic object, but don't insert it yet. + uno::Reference<lang::XMultiServiceFactory> xFactory(mxComponent, uno::UNO_QUERY); + uno::Reference<beans::XPropertySet> xTextGraphic( + xFactory->createInstance("com.sun.star.text.TextGraphicObject"), uno::UNO_QUERY); + + // Set a URL on it. + OUString aGraphicURL = m_directories.getURLFromSrc(DATA_DIRECTORY) + "test.jpg"; + xTextGraphic->setPropertyValue("GraphicURL", uno::Any(aGraphicURL)); + xTextGraphic->setPropertyValue("AnchorType", + uno::Any(text::TextContentAnchorType_AT_CHARACTER)); + + // Insert it. + uno::Reference<text::XTextDocument> xTextDocument(mxComponent, uno::UNO_QUERY); + uno::Reference<text::XText> xBodyText = xTextDocument->getText(); + uno::Reference<text::XTextCursor> xCursor(xBodyText->createTextCursor()); + uno::Reference<text::XTextContent> xTextContent(xTextGraphic, uno::UNO_QUERY); + xBodyText->insertTextContent(xCursor, xTextContent, false); + + // This failed, the graphic object had no graphic. + auto xGraphic = getProperty<uno::Reference<graphic::XGraphic>>(getShape(1), "Graphic"); + CPPUNIT_ASSERT(xGraphic.is()); +} + +CPPUNIT_TEST_FIXTURE(SwUnoWriter, testGraphicDescriptorURLBitmap) +{ + loadURL("private:factory/swriter", nullptr); + + // Load a bitmap into the bitmap table. + uno::Reference<lang::XMultiServiceFactory> xFactory(mxComponent, uno::UNO_QUERY); + uno::Reference<container::XNameContainer> xBitmaps( + xFactory->createInstance("com.sun.star.drawing.BitmapTable"), uno::UNO_QUERY); + OUString aGraphicURL = m_directories.getURLFromSrc(DATA_DIRECTORY) + "test.jpg"; + xBitmaps->insertByName("test", uno::Any(aGraphicURL)); + + // Create a graphic. + uno::Reference<beans::XPropertySet> xTextGraphic( + xFactory->createInstance("com.sun.star.text.TextGraphicObject"), uno::UNO_QUERY); + xTextGraphic->setPropertyValue("GraphicURL", xBitmaps->getByName("test")); + xTextGraphic->setPropertyValue("AnchorType", + uno::Any(text::TextContentAnchorType_AT_CHARACTER)); + + // Insert it. + uno::Reference<text::XTextDocument> xTextDocument(mxComponent, uno::UNO_QUERY); + uno::Reference<text::XText> xBodyText = xTextDocument->getText(); + uno::Reference<text::XTextCursor> xCursor(xBodyText->createTextCursor()); + uno::Reference<text::XTextContent> xTextContent(xTextGraphic, uno::UNO_QUERY); + xBodyText->insertTextContent(xCursor, xTextContent, false); + + // This failed: setting GraphicURL to the result of getByName() did not + // work anymore. + auto xGraphic = getProperty<uno::Reference<graphic::XGraphic>>(getShape(1), "Graphic"); + CPPUNIT_ASSERT(xGraphic.is()); +} + +static bool ensureAutoTextExistsByTitle(const uno::Reference<text::XAutoTextGroup>& autoTextGroup, + std::u16string_view autoTextName) +{ + const uno::Sequence<OUString> aTitles(autoTextGroup->getTitles()); + for (const auto& rTitle : aTitles) + { + if (rTitle == autoTextName) + return true; + } + return false; +} + +static bool ensureAutoTextExistsByName(const uno::Reference<text::XAutoTextGroup>& autoTextGroup, + std::u16string_view autoTextName) +{ + const uno::Sequence<OUString> aTitles(autoTextGroup->getElementNames()); + for (const auto& rTitle : aTitles) + { + if (rTitle == autoTextName) + return true; + } + return false; +} + +CPPUNIT_TEST_FIXTURE(SwUnoWriter, testXAutoTextGroup) +{ + load(mpTestDocumentPath, "xautotextgroup.odt"); + uno::Reference<text::XAutoTextContainer> xAutoTextContainer + = text::AutoTextContainer::create(comphelper::getProcessComponentContext()); + + uno::Reference<text::XTextRange> xTextRange = getRun(getParagraph(1), 1); + + static const OUStringLiteral sGroupName = u"TestGroup*1"; + static const OUStringLiteral sTextName = u"TEST"; + static const OUStringLiteral sTextNameNew = u"TESTRENAMED"; + static const OUStringLiteral sTextTitle = u"Test Auto Text"; + static const OUStringLiteral sTextTitleNew = u"Test Auto Text Renamed"; + + // Create new temporary group + uno::Reference<text::XAutoTextGroup> xAutoTextGroup + = xAutoTextContainer->insertNewByName(sGroupName); + CPPUNIT_ASSERT_MESSAGE("AutoTextGroup was not found!", xAutoTextGroup.is()); + + // Insert new element and ensure it exists + uno::Reference<text::XAutoTextEntry> xAutoTextEntry + = xAutoTextGroup->insertNewByName(sTextName, sTextTitle, xTextRange); + CPPUNIT_ASSERT_MESSAGE("AutoText was not inserted!", xAutoTextEntry.is()); + CPPUNIT_ASSERT_MESSAGE("Can't find newly created AutoText by title!", + ensureAutoTextExistsByTitle(xAutoTextGroup, sTextTitle)); + CPPUNIT_ASSERT_MESSAGE("Can't find newly created AutoText by name!", + ensureAutoTextExistsByName(xAutoTextGroup, sTextName)); + + // Insert once again the same should throw an exception + CPPUNIT_ASSERT_THROW_MESSAGE("We expect an exception on insertion of same AutoText", + xAutoTextGroup->insertNewByName(sTextName, sTextTitle, xTextRange), + container::ElementExistException); + + // Rename it & ensure everything is ok + xAutoTextGroup->renameByName(sTextName, sTextNameNew, sTextTitleNew); + CPPUNIT_ASSERT_MESSAGE("Can't find renamed AutoText by title!", + ensureAutoTextExistsByTitle(xAutoTextGroup, sTextTitleNew)); + CPPUNIT_ASSERT_MESSAGE("Can't find renamed AutoText by name!", + ensureAutoTextExistsByName(xAutoTextGroup, sTextNameNew)); + // Not found by old names + CPPUNIT_ASSERT_MESSAGE("Found AutoText by old title!", + !ensureAutoTextExistsByTitle(xAutoTextGroup, sTextTitle)); + CPPUNIT_ASSERT_MESSAGE("Found AutoText by old name!", + !ensureAutoTextExistsByName(xAutoTextGroup, sTextName)); + + // Rename not existing should throw an exception + CPPUNIT_ASSERT_THROW_MESSAGE( + "We expect an exception on renaming not-existing AutoText", + xAutoTextGroup->renameByName(sTextName, sTextNameNew, sTextTitleNew), + container::ElementExistException); + + // Remove it and ensure it does not exist + xAutoTextGroup->removeByName(sTextNameNew); + CPPUNIT_ASSERT_MESSAGE("AutoText was not removed!", + !ensureAutoTextExistsByTitle(xAutoTextGroup, sTextTitleNew)); + CPPUNIT_ASSERT_MESSAGE("AutoText was not removed!", + !ensureAutoTextExistsByName(xAutoTextGroup, sTextNameNew)); + + // Remove non-existing element should throw an exception + CPPUNIT_ASSERT_THROW_MESSAGE("We expect an exception on removing not-existing AutoText", + xAutoTextGroup->removeByName(sTextName), + container::NoSuchElementException); + + // Remove our temporary group + xAutoTextContainer->removeByName(sGroupName); +} + +CPPUNIT_TEST_FIXTURE(SwUnoWriter, testSectionAnchorCopyTableAtStart) +{ + // this contains a section that starts with a table + load(DATA_DIRECTORY, "tdf134250.fodt"); + + uno::Reference<text::XTextTablesSupplier> const xTextTablesSupplier(mxComponent, + uno::UNO_QUERY); + uno::Reference<container::XIndexAccess> const xTables(xTextTablesSupplier->getTextTables(), + uno::UNO_QUERY); + CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xTables->getCount()); + + uno::Reference<text::XTextSectionsSupplier> const xTextSectionsSupplier(mxComponent, + uno::UNO_QUERY); + uno::Reference<container::XIndexAccess> const xSections( + xTextSectionsSupplier->getTextSections(), uno::UNO_QUERY); + + CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xSections->getCount()); + + uno::Reference<text::XTextContent> const xSection(xSections->getByIndex(0), uno::UNO_QUERY); + uno::Reference<text::XTextRange> const xAnchor(xSection->getAnchor()); + CPPUNIT_ASSERT_EQUAL(OUString("foo" SAL_NEWLINE_STRING "bar"), xAnchor->getString()); + + // copy the content of the section to a clipboard document + uno::Reference<datatransfer::XTransferableSupplier> const xTS( + uno::Reference<frame::XModel>(mxComponent, uno::UNO_QUERY_THROW)->getCurrentController(), + uno::UNO_QUERY); + uno::Reference<datatransfer::XTransferableTextSupplier> const xTTS(xTS, uno::UNO_QUERY); + uno::Reference<datatransfer::XTransferable> const xTransferable( + xTTS->getTransferableForTextRange(xAnchor)); + + // check this doesn't throw + CPPUNIT_ASSERT(xAnchor->getText().is()); + CPPUNIT_ASSERT(xAnchor->getStart().is()); + CPPUNIT_ASSERT(xAnchor->getEnd().is()); + + // replace section content + xAnchor->setString("quux"); + + // table in section was deleted, but not section itself + CPPUNIT_ASSERT_EQUAL(sal_Int32(0), xTables->getCount()); + CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xSections->getCount()); + CPPUNIT_ASSERT_EQUAL(OUString("\"" + "quux" /*SAL_NEWLINE_STRING*/ "\""), + OUString("\"" + xAnchor->getString() + "\"")); + + // now paste it + uno::Reference<text::XTextViewCursorSupplier> const xTVCS(xTS, uno::UNO_QUERY); + uno::Reference<text::XTextViewCursor> const xCursor(xTVCS->getViewCursor()); + xCursor->gotoEnd(false); + xTS->insertTransferable(xTransferable); + + // table in section was pasted, but not section itself + CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xTables->getCount()); + CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xSections->getCount()); + xCursor->gotoStart(true); + CPPUNIT_ASSERT_EQUAL(OUString("quux" SAL_NEWLINE_STRING "foo" SAL_NEWLINE_STRING "bar"), + xCursor->getString()); +} + +CPPUNIT_TEST_FIXTURE(SwUnoWriter, testSectionAnchorCopyTableAtEnd) +{ + // this contains a section that ends with a table (plus another section) + load(DATA_DIRECTORY, "tdf134252.fodt"); + + uno::Reference<text::XTextTablesSupplier> const xTextTablesSupplier(mxComponent, + uno::UNO_QUERY); + uno::Reference<container::XIndexAccess> const xTables(xTextTablesSupplier->getTextTables(), + uno::UNO_QUERY); + CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xTables->getCount()); + + uno::Reference<text::XTextSectionsSupplier> const xTextSectionsSupplier(mxComponent, + uno::UNO_QUERY); + uno::Reference<container::XIndexAccess> const xSections( + xTextSectionsSupplier->getTextSections(), uno::UNO_QUERY); + + CPPUNIT_ASSERT_EQUAL(sal_Int32(2), xSections->getCount()); + + uno::Reference<text::XTextContent> const xSection(xSections->getByIndex(0), uno::UNO_QUERY); + uno::Reference<text::XTextRange> const xAnchor(xSection->getAnchor()); + CPPUNIT_ASSERT_EQUAL(OUString("bar" SAL_NEWLINE_STRING "baz" SAL_NEWLINE_STRING), + xAnchor->getString()); + + // copy the content of the section to a clipboard document + uno::Reference<datatransfer::XTransferableSupplier> const xTS( + uno::Reference<frame::XModel>(mxComponent, uno::UNO_QUERY_THROW)->getCurrentController(), + uno::UNO_QUERY); + uno::Reference<datatransfer::XTransferableTextSupplier> const xTTS(xTS, uno::UNO_QUERY); + uno::Reference<datatransfer::XTransferable> const xTransferable( + xTTS->getTransferableForTextRange(xAnchor)); + + // check this doesn't throw + CPPUNIT_ASSERT(xAnchor->getText().is()); + CPPUNIT_ASSERT(xAnchor->getStart().is()); + CPPUNIT_ASSERT(xAnchor->getEnd().is()); + + // replace section content + xAnchor->setString("quux"); + + // table in section was deleted, but not section itself + CPPUNIT_ASSERT_EQUAL(sal_Int32(0), xTables->getCount()); + CPPUNIT_ASSERT_EQUAL(sal_Int32(2), xSections->getCount()); + CPPUNIT_ASSERT_EQUAL(OUString("\"" + "quux" /*SAL_NEWLINE_STRING*/ "\""), + OUString("\"" + xAnchor->getString() + "\"")); + + // now paste it + uno::Reference<text::XTextViewCursorSupplier> const xTVCS(xTS, uno::UNO_QUERY); + uno::Reference<text::XTextViewCursor> const xCursor(xTVCS->getViewCursor()); + xCursor->gotoEnd(false); + xTS->insertTransferable(xTransferable); + + // table in section was pasted, but not section itself + CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xTables->getCount()); + CPPUNIT_ASSERT_EQUAL(sal_Int32(2), xSections->getCount()); + // note: this selects the 2nd section because it calls StartOfSection() + // not SttEndDoc() like it should? + xCursor->gotoStart(true); + CPPUNIT_ASSERT_EQUAL(OUString(/*"quux" SAL_NEWLINE_STRING */ + "foobar" SAL_NEWLINE_STRING "baz" SAL_NEWLINE_STRING), + xCursor->getString()); +} + +CPPUNIT_TEST_FIXTURE(SwUnoWriter, testSectionAnchorCopyTable) +{ + // this contains a section that ends with a table (plus another section) + load(DATA_DIRECTORY, "tdf134252_onlytable_protected.fodt"); + + uno::Reference<text::XTextTablesSupplier> const xTextTablesSupplier(mxComponent, + uno::UNO_QUERY); + uno::Reference<container::XIndexAccess> const xTables(xTextTablesSupplier->getTextTables(), + uno::UNO_QUERY); + CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xTables->getCount()); + + uno::Reference<text::XTextSectionsSupplier> const xTextSectionsSupplier(mxComponent, + uno::UNO_QUERY); + uno::Reference<container::XIndexAccess> const xSections( + xTextSectionsSupplier->getTextSections(), uno::UNO_QUERY); + + CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xSections->getCount()); + + uno::Reference<text::XTextContent> const xSection(xSections->getByIndex(0), uno::UNO_QUERY); + uno::Reference<text::XTextRange> const xAnchor(xSection->getAnchor()); + CPPUNIT_ASSERT_EQUAL(OUString("baz" SAL_NEWLINE_STRING), xAnchor->getString()); + + // copy the content of the section to a clipboard document + uno::Reference<datatransfer::XTransferableSupplier> const xTS( + uno::Reference<frame::XModel>(mxComponent, uno::UNO_QUERY_THROW)->getCurrentController(), + uno::UNO_QUERY); + uno::Reference<datatransfer::XTransferableTextSupplier> const xTTS(xTS, uno::UNO_QUERY); + uno::Reference<datatransfer::XTransferable> const xTransferable( + xTTS->getTransferableForTextRange(xAnchor)); + + // check this doesn't throw + CPPUNIT_ASSERT(xAnchor->getText().is()); + CPPUNIT_ASSERT(xAnchor->getStart().is()); + CPPUNIT_ASSERT(xAnchor->getEnd().is()); + + // replace section content + xAnchor->setString("quux"); + + // table in section was deleted, but not section itself + CPPUNIT_ASSERT_EQUAL(sal_Int32(0), xTables->getCount()); + CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xSections->getCount()); + CPPUNIT_ASSERT_EQUAL(OUString("\"" + "quux" /*SAL_NEWLINE_STRING*/ "\""), + OUString("\"" + xAnchor->getString() + "\"")); + + // now paste it + uno::Reference<text::XTextViewCursorSupplier> const xTVCS(xTS, uno::UNO_QUERY); + uno::Reference<text::XTextViewCursor> const xCursor(xTVCS->getViewCursor()); + xCursor->gotoEnd(false); + xTS->insertTransferable(xTransferable); + + // table in section was pasted, but not section itself + CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xTables->getCount()); + CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xSections->getCount()); + xCursor->gotoStart(true); + CPPUNIT_ASSERT_EQUAL( + OUString("quux" SAL_NEWLINE_STRING "foo" SAL_NEWLINE_STRING "baz" SAL_NEWLINE_STRING), + xCursor->getString()); +} + +CPPUNIT_TEST_FIXTURE(SwUnoWriter, testTextRangeInTable) +{ + load(DATA_DIRECTORY, "bookmarkintable.fodt"); + + uno::Reference<text::XBookmarksSupplier> const xBS(mxComponent, uno::UNO_QUERY); + uno::Reference<container::XNameAccess> const xMarks(xBS->getBookmarks()); + uno::Reference<text::XTextContent> const xMark(xMarks->getByName("Bookmark 1"), uno::UNO_QUERY); + uno::Reference<container::XEnumerationAccess> const xAnchor(xMark->getAnchor(), uno::UNO_QUERY); + uno::Reference<container::XEnumeration> const xEnum(xAnchor->createEnumeration()); + uno::Reference<lang::XServiceInfo> const xPara(xEnum->nextElement(), uno::UNO_QUERY); + // not the top-level table! + CPPUNIT_ASSERT(!xPara->supportsService("com.sun.star.text.TextTable")); + CPPUNIT_ASSERT(!xEnum->hasMoreElements()); + uno::Reference<container::XEnumerationAccess> const xParaEA(xPara, uno::UNO_QUERY); + uno::Reference<container::XEnumeration> const xPortions(xParaEA->createEnumeration()); + uno::Reference<beans::XPropertySet> const xP1(xPortions->nextElement(), uno::UNO_QUERY); + CPPUNIT_ASSERT_EQUAL(OUString("Bookmark"), getProperty<OUString>(xP1, "TextPortionType")); + uno::Reference<beans::XPropertySet> const xP2(xPortions->nextElement(), uno::UNO_QUERY); + CPPUNIT_ASSERT_EQUAL(OUString("Text"), getProperty<OUString>(xP2, "TextPortionType")); + uno::Reference<text::XTextRange> const xP2R(xP2, uno::UNO_QUERY); + CPPUNIT_ASSERT_EQUAL(OUString("foo"), xP2R->getString()); + uno::Reference<beans::XPropertySet> const xP3(xPortions->nextElement(), uno::UNO_QUERY); + CPPUNIT_ASSERT_EQUAL(OUString("Bookmark"), getProperty<OUString>(xP3, "TextPortionType")); + CPPUNIT_ASSERT(!xPortions->hasMoreElements()); +} + +CPPUNIT_TEST_FIXTURE(SwUnoWriter, testXURI) +{ + uno::Reference<uno::XComponentContext> xContext(::comphelper::getProcessComponentContext()); + + // createKnown() + uno::Reference<rdf::XURI> xURIcreateKnown( + rdf::URI::createKnown(xContext, rdf::URIs::ODF_PREFIX), uno::UNO_SET_THROW); + CPPUNIT_ASSERT(xURIcreateKnown.is()); + CPPUNIT_ASSERT_EQUAL(OUString("http://docs.oasis-open.org/ns/office/1.2/meta/odf#"), + xURIcreateKnown->getNamespace()); + CPPUNIT_ASSERT_EQUAL(OUString("prefix"), xURIcreateKnown->getLocalName()); + CPPUNIT_ASSERT_EQUAL(OUString("http://docs.oasis-open.org/ns/office/1.2/meta/odf#prefix"), + xURIcreateKnown->getStringValue()); + + // createKnown() with invalid constant + CPPUNIT_ASSERT_THROW_MESSAGE("We expect an exception on invalid constant", + rdf::URI::createKnown(xContext, 12345), + lang::IllegalArgumentException); + + // create() + uno::Reference<rdf::XURI> xURIcreate( + rdf::URI::create(xContext, "http://example.com/url#somedata"), uno::UNO_SET_THROW); + CPPUNIT_ASSERT_EQUAL(OUString("http://example.com/url#"), xURIcreate->getNamespace()); + CPPUNIT_ASSERT_EQUAL(OUString("somedata"), xURIcreate->getLocalName()); + CPPUNIT_ASSERT_EQUAL(OUString("http://example.com/url#somedata"), xURIcreate->getStringValue()); + + // create() without local name split with "/" + uno::Reference<rdf::XURI> xURIcreate2(rdf::URI::create(xContext, "http://example.com/url"), + uno::UNO_SET_THROW); + CPPUNIT_ASSERT_EQUAL(OUString("http://example.com/"), xURIcreate2->getNamespace()); + CPPUNIT_ASSERT_EQUAL(OUString("url"), xURIcreate2->getLocalName()); + CPPUNIT_ASSERT_EQUAL(OUString("http://example.com/url"), xURIcreate2->getStringValue()); + + // create() without prefix + uno::Reference<rdf::XURI> xURIcreate3(rdf::URI::create(xContext, "#somedata"), + uno::UNO_SET_THROW); + CPPUNIT_ASSERT_EQUAL(OUString("#"), xURIcreate3->getNamespace()); + CPPUNIT_ASSERT_EQUAL(OUString("somedata"), xURIcreate3->getLocalName()); + CPPUNIT_ASSERT_EQUAL(OUString("#somedata"), xURIcreate3->getStringValue()); + + // create() with invalid URI + CPPUNIT_ASSERT_THROW_MESSAGE("We expect an exception on invalid URI", + rdf::URI::create(xContext, "some junk and not URI"), + lang::IllegalArgumentException); + + // createNS() + uno::Reference<rdf::XURI> xURIcreateNS( + rdf::URI::createNS(xContext, "http://example.com/url#", "somedata"), uno::UNO_SET_THROW); + CPPUNIT_ASSERT_EQUAL(OUString("http://example.com/url#"), xURIcreateNS->getNamespace()); + CPPUNIT_ASSERT_EQUAL(OUString("somedata"), xURIcreateNS->getLocalName()); + CPPUNIT_ASSERT_EQUAL(OUString("http://example.com/url#somedata"), + xURIcreateNS->getStringValue()); + + // TODO: What's going on here? Is such usecase valid? + uno::Reference<rdf::XURI> xURIcreateNS2( + rdf::URI::createNS(xContext, "http://example.com/url", "somedata"), uno::UNO_SET_THROW); + CPPUNIT_ASSERT_EQUAL(OUString("http://example.com/"), xURIcreateNS2->getNamespace()); + CPPUNIT_ASSERT_EQUAL(OUString("urlsomedata"), xURIcreateNS2->getLocalName()); + CPPUNIT_ASSERT_EQUAL(OUString("http://example.com/urlsomedata"), + xURIcreateNS2->getStringValue()); + + // createNS() some invalid cases + CPPUNIT_ASSERT_THROW_MESSAGE("We expect an exception on invalid URI", + rdf::URI::createNS(xContext, "bla", "bla"), + lang::IllegalArgumentException); + + CPPUNIT_ASSERT_THROW_MESSAGE("We expect an exception on invalid URI", + rdf::URI::createNS(xContext, OUString(), OUString()), + lang::IllegalArgumentException); +} + +CPPUNIT_TEST_FIXTURE(SwUnoWriter, testSetPagePrintSettings) +{ + // Create an empty new document with a single char + loadURL("private:factory/swriter", nullptr); + + uno::Reference<text::XTextDocument> xTextDocument(mxComponent, uno::UNO_QUERY); + uno::Reference<text::XSimpleText> xBodyText = xTextDocument->getText(); + xBodyText->insertString(xBodyText->getStart(), "x", false); + + uno::Reference<text::XPagePrintable> xPagePrintable(mxComponent, uno::UNO_QUERY); + + // set some stuff, try to get it back + uno::Sequence<beans::PropertyValue> aProps{ + comphelper::makePropertyValue("PageColumns", sal_Int16(2)), + comphelper::makePropertyValue("IsLandscape", true) + }; + + xPagePrintable->setPagePrintSettings(aProps); + const comphelper::SequenceAsHashMap aMap(xPagePrintable->getPagePrintSettings()); + + CPPUNIT_ASSERT_EQUAL(sal_Int16(2), aMap.getValue("PageColumns").get<short>()); + CPPUNIT_ASSERT_EQUAL(true, aMap.getValue("IsLandscape").get<bool>()); +} + +CPPUNIT_TEST_FIXTURE(SwUnoWriter, testDeleteFlyAtCharAtStart) +{ + loadURL("private:factory/swriter", nullptr); + SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument*>(mxComponent.get()); + CPPUNIT_ASSERT(pTextDoc); + SwWrtShell* const pWrtShell(pTextDoc->GetDocShell()->GetWrtShell()); + SwDoc* const pDoc(pWrtShell->GetDoc()); + + // insert some text + IDocumentContentOperations& rIDCO(pDoc->getIDocumentContentOperations()); + rIDCO.InsertString(*pWrtShell->GetCursor(), "foo bar baz"); + + // insert fly anchored at start of body text + pWrtShell->ClearMark(); + pWrtShell->SttEndDoc(true); + SfxItemSet frameSet(pDoc->GetAttrPool(), svl::Items<RES_FRMATR_BEGIN, RES_FRMATR_END - 1>); + SfxItemSet grfSet(pDoc->GetAttrPool(), svl::Items<RES_GRFATR_BEGIN, RES_GRFATR_END - 1>); + SwFormatAnchor anchor(RndStdIds::FLY_AT_CHAR); + frameSet.Put(anchor); + GraphicObject grf; + CPPUNIT_ASSERT(rIDCO.InsertGraphicObject(*pWrtShell->GetCursor(), grf, &frameSet, &grfSet)); + + // check fly + CPPUNIT_ASSERT_EQUAL(1, getShapes()); + uno::Reference<text::XTextContent> const xShape(getShape(1), uno::UNO_QUERY); + // anchored at start of body text? + uno::Reference<text::XText> const xText(pTextDoc->getText()); + uno::Reference<text::XTextRangeCompare> const xTextRC(xText, uno::UNO_QUERY); + CPPUNIT_ASSERT_EQUAL(sal_Int16(0), + xTextRC->compareRegionStarts(xText->getStart(), xShape->getAnchor())); + + // delete 1st character + uno::Reference<text::XTextCursor> const xCursor(xText->createTextCursor()); + xCursor->goRight(1, true); + xCursor->setString(""); + + // there is exactly one fly + CPPUNIT_ASSERT_EQUAL(1, getShapes()); + + // select entire body text + xCursor->gotoStart(true); + xCursor->gotoEnd(true); + xCursor->setString(""); + + // there is no fly + CPPUNIT_ASSERT_EQUAL(0, getShapes()); +} + +CPPUNIT_TEST_FIXTURE(SwUnoWriter, testSelectionInTableEnum) +{ + load(mpTestDocumentPath, "selection-in-table-enum.odt"); + // Select the A1 cell's text. + SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument*>(mxComponent.get()); + CPPUNIT_ASSERT(pTextDoc); + SwWrtShell* pWrtShell = pTextDoc->GetDocShell()->GetWrtShell(); + CPPUNIT_ASSERT(pWrtShell); + pWrtShell->Down(/*bSelect=*/false); + pWrtShell->EndPara(/*bSelect=*/true); + CPPUNIT_ASSERT_EQUAL(OUString("A1"), + pWrtShell->GetCursor()->GetNode().GetTextNode()->GetText()); + + // Access the selection. + uno::Reference<frame::XModel> xModel(mxComponent, uno::UNO_QUERY); + CPPUNIT_ASSERT(xModel.is()); + uno::Reference<container::XIndexAccess> xSelections(xModel->getCurrentSelection(), + uno::UNO_QUERY); + CPPUNIT_ASSERT(xSelections.is()); + uno::Reference<text::XTextRange> xSelection(xSelections->getByIndex(0), uno::UNO_QUERY); + CPPUNIT_ASSERT(xSelection.is()); + + // Enumerate paragraphs in the selection. + uno::Reference<container::XEnumerationAccess> xCursor( + xSelection->getText()->createTextCursorByRange(xSelection), uno::UNO_QUERY); + CPPUNIT_ASSERT(xCursor.is()); + uno::Reference<container::XEnumeration> xEnum = xCursor->createEnumeration(); + xEnum->nextElement(); + // Without the accompanying fix in place, this test would have failed: i.e. + // the enumeration contained a second paragraph, even if the cell has only + // one paragraph. + CPPUNIT_ASSERT(!xEnum->hasMoreElements()); +} + +CPPUNIT_TEST_FIXTURE(SwUnoWriter, testSelectionInTableEnumEnd) +{ + load(mpTestDocumentPath, "selection-in-table-enum.odt"); + // Select from "Before" till the table end. + SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument*>(mxComponent.get()); + CPPUNIT_ASSERT(pTextDoc); + SwWrtShell* pWrtShell = pTextDoc->GetDocShell()->GetWrtShell(); + CPPUNIT_ASSERT(pWrtShell); + pWrtShell->Down(/*bSelect=*/true); + + // Access the selection. + uno::Reference<frame::XModel> xModel(mxComponent, uno::UNO_QUERY); + CPPUNIT_ASSERT(xModel.is()); + uno::Reference<container::XIndexAccess> xSelections(xModel->getCurrentSelection(), + uno::UNO_QUERY); + CPPUNIT_ASSERT(xSelections.is()); + uno::Reference<text::XTextRange> xSelection(xSelections->getByIndex(0), uno::UNO_QUERY); + CPPUNIT_ASSERT(xSelection.is()); + CPPUNIT_ASSERT_EQUAL(OUString("Before" SAL_NEWLINE_STRING "A1" SAL_NEWLINE_STRING + "B1" SAL_NEWLINE_STRING "C2" SAL_NEWLINE_STRING + "A2" SAL_NEWLINE_STRING "B2" SAL_NEWLINE_STRING + "C2" SAL_NEWLINE_STRING), + xSelection->getString()); + + // Enumerate paragraphs in the selection. + uno::Reference<container::XEnumerationAccess> xCursor( + xSelection->getText()->createTextCursorByRange(xSelection), uno::UNO_QUERY); + CPPUNIT_ASSERT(xCursor.is()); + uno::Reference<container::XEnumeration> xEnum = xCursor->createEnumeration(); + // Before. + xEnum->nextElement(); + // Table. + xEnum->nextElement(); + // Without the accompanying fix in place, this test would have failed: i.e. + // the enumeration contained the paragraph after the table, but no part of + // that paragraph was part of the selection. + CPPUNIT_ASSERT(!xEnum->hasMoreElements()); +} + +CPPUNIT_TEST_FIXTURE(SwUnoWriter, testRenderablePagePosition) +{ + load(mpTestDocumentPath, "renderable-page-position.odt"); + // Make sure that the document has 2 pages. + uno::Reference<view::XRenderable> xRenderable(mxComponent, uno::UNO_QUERY); + CPPUNIT_ASSERT(mxComponent.is()); + + uno::Any aSelection(mxComponent); + + uno::Reference<awt::XToolkit> xToolkit = VCLUnoHelper::CreateToolkit(); + uno::Reference<awt::XDevice> xDevice(xToolkit->createScreenCompatibleDevice(32, 32)); + + uno::Reference<frame::XModel> xModel(mxComponent, uno::UNO_QUERY); + uno::Reference<frame::XController> xController = xModel->getCurrentController(); + + beans::PropertyValues aRenderOptions = { + comphelper::makePropertyValue("IsPrinter", true), + comphelper::makePropertyValue("RenderDevice", xDevice), + comphelper::makePropertyValue("View", xController), + comphelper::makePropertyValue("RenderToGraphic", true), + }; + + sal_Int32 nPages = xRenderable->getRendererCount(aSelection, aRenderOptions); + CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(2), nPages); + + // Make sure that the first page has some offset. + comphelper::SequenceAsHashMap aRenderer1( + xRenderable->getRenderer(0, aSelection, aRenderOptions)); + // Without the accompanying fix in place, this test would have failed: i.e. + // there was no PagePos key in this map. + awt::Point aPosition1 = aRenderer1["PagePos"].get<awt::Point>(); + CPPUNIT_ASSERT_GREATER(static_cast<sal_Int32>(0), aPosition1.X); + CPPUNIT_ASSERT_GREATER(static_cast<sal_Int32>(0), aPosition1.Y); + + // Make sure that the second page is below the first one. + comphelper::SequenceAsHashMap aRenderer2( + xRenderable->getRenderer(1, aSelection, aRenderOptions)); + awt::Point aPosition2 = aRenderer2["PagePos"].get<awt::Point>(); + CPPUNIT_ASSERT_GREATER(static_cast<sal_Int32>(0), aPosition2.X); + CPPUNIT_ASSERT_GREATER(aPosition1.Y, aPosition2.Y); +} + +CPPUNIT_TEST_FIXTURE(SwUnoWriter, testPasteListener) +{ + loadURL("private:factory/swriter", nullptr); + + // Insert initial string. + uno::Reference<text::XTextDocument> xTextDocument(mxComponent, uno::UNO_QUERY); + uno::Reference<text::XSimpleText> xBodyText = xTextDocument->getText(); + xBodyText->insertString(xBodyText->getStart(), "ABCDEF", false); + + // Add paste listener. + uno::Reference<text::XPasteBroadcaster> xBroadcaster(mxComponent, uno::UNO_QUERY); + uno::Reference<text::XPasteListener> xListener(new PasteListener); + auto pListener = static_cast<PasteListener*>(xListener.get()); + xBroadcaster->addPasteEventListener(xListener); + + // Cut "DE" and then paste it. + SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument*>(mxComponent.get()); + CPPUNIT_ASSERT(pTextDoc); + SwWrtShell* pWrtShell = pTextDoc->GetDocShell()->GetWrtShell(); + CPPUNIT_ASSERT(pWrtShell); + pWrtShell->Left(CRSR_SKIP_CHARS, /*bSelect=*/false, 3, /*bBasicCall=*/false); + pWrtShell->Right(CRSR_SKIP_CHARS, /*bSelect=*/true, 2, /*bBasicCall=*/false); + rtl::Reference<SwTransferable> pTransfer = new SwTransferable(*pWrtShell); + pTransfer->Cut(); + TransferableDataHelper aHelper(pTransfer); + SwTransferable::Paste(*pWrtShell, aHelper); + // Without working listener registration in place, this test would have + // failed with 'Expected: DE; Actual:', i.e. the paste listener was not + // invoked. + CPPUNIT_ASSERT_EQUAL(OUString("DE"), pListener->GetString()); + + // Make sure that paste did not overwrite anything. + CPPUNIT_ASSERT_EQUAL(OUString("ABCDEF"), xBodyText->getString()); + + // Paste again, this time overwriting "BC". + pWrtShell->Left(CRSR_SKIP_CHARS, /*bSelect=*/false, 4, /*bBasicCall=*/false); + pWrtShell->Right(CRSR_SKIP_CHARS, /*bSelect=*/true, 2, /*bBasicCall=*/false); + pListener->GetString().clear(); + SwTransferable::Paste(*pWrtShell, aHelper); + CPPUNIT_ASSERT_EQUAL(OUString("DE"), pListener->GetString()); + + // Make sure that paste overwrote "BC". + CPPUNIT_ASSERT_EQUAL(OUString("ADEDEF"), xBodyText->getString()); + + // Test image paste. + SwView& rView = pWrtShell->GetView(); + OUString aGraphicURL = m_directories.getURLFromSrc(DATA_DIRECTORY) + "test.jpg"; + rView.InsertGraphic(aGraphicURL, OUString(), /*bAsLink=*/false, + &GraphicFilter::GetGraphicFilter()); + + // Test that the pasted image is anchored as-char. + SwFlyFrame* pFly = pWrtShell->GetSelectedFlyFrame(); + CPPUNIT_ASSERT(pFly); + SwFrameFormat* pFlyFormat = pFly->GetFormat(); + CPPUNIT_ASSERT(pFlyFormat); + RndStdIds eFlyAnchor = pFlyFormat->GetAnchor().GetAnchorId(); + // Without the working image listener in place, this test would have + // failed, eFlyAnchor was FLY_AT_PARA. + CPPUNIT_ASSERT_EQUAL(RndStdIds::FLY_AT_CHAR, eFlyAnchor); + + pTransfer->Cut(); + pListener->GetString().clear(); + SwTransferable::Paste(*pWrtShell, aHelper); + // Without the working image listener in place, this test would have + // failed, the listener was not invoked in case of a graphic paste. + CPPUNIT_ASSERT(pListener->GetTextGraphicObject().is()); + CPPUNIT_ASSERT(pListener->GetString().isEmpty()); + + // Deregister paste listener, make sure it's not invoked. + xBroadcaster->removePasteEventListener(xListener); + pListener->GetString().clear(); + SwTransferable::Paste(*pWrtShell, aHelper); + CPPUNIT_ASSERT(pListener->GetString().isEmpty()); +} + +CPPUNIT_TEST_FIXTURE(SwUnoWriter, testImageCommentAtChar) +{ + // Load a document with an at-char image in it (and a comment on the image). + load(mpTestDocumentPath, "image-comment-at-char.odt"); + SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument*>(mxComponent.get()); + CPPUNIT_ASSERT(pTextDoc); + SwDoc* pDoc = pTextDoc->GetDocShell()->GetDoc(); + + // Verify that we have an annotation mark (comment with a text range) in the document. + // Without the accompanying fix in place, this test would have failed, as comments lost their + // ranges on load when their range only covered the placeholder character of the comment (which + // is also the anchor position of the image). + IDocumentMarkAccess* pMarks = pDoc->getIDocumentMarkAccess(); + CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(1), pMarks->getAnnotationMarksCount()); + + uno::Reference<text::XTextRange> xPara = getParagraph(1); + CPPUNIT_ASSERT_EQUAL(OUString("Text"), + getProperty<OUString>(getRun(xPara, 1), "TextPortionType")); + // Without the accompanying fix in place, this test would have failed with 'Expected: + // Annotation; Actual: Frame', i.e. the comment-start portion was after the commented image. + CPPUNIT_ASSERT_EQUAL(OUString("Annotation"), + getProperty<OUString>(getRun(xPara, 2), "TextPortionType")); + CPPUNIT_ASSERT_EQUAL(OUString("Frame"), + getProperty<OUString>(getRun(xPara, 3), "TextPortionType")); + CPPUNIT_ASSERT_EQUAL(OUString("AnnotationEnd"), + getProperty<OUString>(getRun(xPara, 4), "TextPortionType")); + CPPUNIT_ASSERT_EQUAL(OUString("Text"), + getProperty<OUString>(getRun(xPara, 5), "TextPortionType")); + + // Without the accompanying fix in place, this test would have failed with 'Expected: + // 5892; Actual: 1738', i.e. the anchor pos was between the "aaa" and "bbb" portions, not at the + // center of the page (horizontally) where the image is. On macOS, though, with the fix in + // place the actual value consistently is even greater with 6283 now instead of 5892, for + // whatever reason. + SwView* pView = pDoc->GetDocShell()->GetView(); + SwPostItMgr* pPostItMgr = pView->GetPostItMgr(); + for (const auto& pItem : *pPostItMgr) + { + const SwRect& rAnchor = pItem->mpPostIt->GetAnchorRect(); + CPPUNIT_ASSERT_GREATEREQUAL(static_cast<tools::Long>(5892), rAnchor.Left()); + } +} + +CPPUNIT_TEST_FIXTURE(SwUnoWriter, testChapterNumberingCharStyle) +{ + loadURL("private:factory/swriter", nullptr); + + uno::Reference<lang::XMultiServiceFactory> xDoc(mxComponent, uno::UNO_QUERY); + uno::Reference<beans::XPropertySet> xStyle( + xDoc->createInstance("com.sun.star.style.CharacterStyle"), uno::UNO_QUERY); + uno::Reference<container::XNamed> xStyleN(xStyle, uno::UNO_QUERY); + xStyle->setPropertyValue("CharColor", uno::Any(sal_Int32(0x00FF0000))); + uno::Reference<style::XStyleFamiliesSupplier> xSFS(mxComponent, uno::UNO_QUERY); + uno::Reference<container::XNameContainer> xStyles( + xSFS->getStyleFamilies()->getByName("CharacterStyles"), uno::UNO_QUERY); + xStyles->insertByName("red", uno::Any(xStyle)); + + uno::Reference<text::XChapterNumberingSupplier> xCNS(mxComponent, uno::UNO_QUERY); + uno::Reference<container::XIndexReplace> xOutline(xCNS->getChapterNumberingRules()); + { + comphelper::SequenceAsHashMap hashMap(xOutline->getByIndex(0)); + hashMap["CharStyleName"] <<= OUString("red"); + uno::Sequence<beans::PropertyValue> props; + hashMap >> props; + xOutline->replaceByIndex(0, uno::Any(props)); + } + // now rename the style + xStyleN->setName("reddishred"); + { + comphelper::SequenceAsHashMap hashMap(xOutline->getByIndex(0)); + + // tdf#137810 this failed, was old value "red" + CPPUNIT_ASSERT_EQUAL(OUString("reddishred"), hashMap["CharStyleName"].get<OUString>()); + } +} + +CPPUNIT_TEST_FIXTURE(SwUnoWriter, testViewCursorPageStyle) +{ + // Load a document with 2 pages, but a single paragraph. + load(mpTestDocumentPath, "view-cursor-page-style.fodt"); + uno::Reference<frame::XModel> xModel(mxComponent, uno::UNO_QUERY); + CPPUNIT_ASSERT(xModel.is()); + uno::Reference<text::XTextViewCursorSupplier> xController(xModel->getCurrentController(), + uno::UNO_QUERY); + CPPUNIT_ASSERT(xController.is()); + uno::Reference<text::XPageCursor> xViewCursor(xController->getViewCursor(), uno::UNO_QUERY); + CPPUNIT_ASSERT(xViewCursor.is()); + + // Go to the first page, which has an explicit page style. + xViewCursor->jumpToPage(1); + OUString aActualPageStyleName = getProperty<OUString>(xViewCursor, "PageStyleName"); + CPPUNIT_ASSERT_EQUAL(OUString("First Page"), aActualPageStyleName); + + // Go to the second page, which is still the first paragraph, but the page style is different, + // as the explicit 'First Page' page style has a next style defined (Standard). + xViewCursor->jumpToPage(2); + aActualPageStyleName = getProperty<OUString>(xViewCursor, "PageStyleName"); + // Without the accompanying fix in place, this test would have failed with: + // - Expected: Standard + // - Actual : First Page + // i.e. the cursor position was determined only based on the node index, ignoring the content + // index. + CPPUNIT_ASSERT_EQUAL(OUString("Standard"), aActualPageStyleName); +} + +CPPUNIT_TEST_FIXTURE(SwUnoWriter, testXTextCursor_setPropertyValues) +{ + // Create a new document, type a character, pass a set of property/value pairs consisting of one + // unknown property and CharStyleName, assert that it threw UnknownPropertyException (actually + // wrapped into WrappedTargetException), and assert the style was set, not discarded. + loadURL("private:factory/swriter", nullptr); + + uno::Reference<text::XTextDocument> xTextDocument(mxComponent, uno::UNO_QUERY); + uno::Reference<text::XSimpleText> xBodyText = xTextDocument->getText(); + xBodyText->insertString(xBodyText->getStart(), "x", false); + + uno::Reference<text::XTextCursor> xCursor(xBodyText->createTextCursor()); + xCursor->goLeft(1, true); + + uno::Reference<beans::XMultiPropertySet> xCursorProps(xCursor, uno::UNO_QUERY); + uno::Sequence<OUString> aPropNames = { "OneUnknownProperty", "CharStyleName" }; + uno::Sequence<uno::Any> aPropValues = { uno::Any(), uno::Any(OUString("Emphasis")) }; + CPPUNIT_ASSERT_THROW(xCursorProps->setPropertyValues(aPropNames, aPropValues), + lang::WrappedTargetException); + CPPUNIT_ASSERT_EQUAL(OUString("Emphasis"), + getProperty<OUString>(xCursorProps, "CharStyleName")); +} + +CPPUNIT_TEST_FIXTURE(SwUnoWriter, testShapeAllowOverlap) +{ + // Test the AllowOverlap frame/shape property. + + // Create a new document and insert a rectangle. + loadURL("private:factory/swriter", nullptr); + uno::Reference<lang::XMultiServiceFactory> xDocument(mxComponent, uno::UNO_QUERY); + awt::Point aPoint(1000, 1000); + awt::Size aSize(10000, 10000); + uno::Reference<drawing::XShape> xShape( + xDocument->createInstance("com.sun.star.drawing.RectangleShape"), uno::UNO_QUERY); + xShape->setPosition(aPoint); + xShape->setSize(aSize); + uno::Reference<drawing::XDrawPageSupplier> xDrawPageSupplier(xDocument, uno::UNO_QUERY); + xDrawPageSupplier->getDrawPage()->add(xShape); + + // The property is on by default, turn it off & verify. + uno::Reference<beans::XPropertySet> xShapeProperties(xShape, uno::UNO_QUERY); + xShapeProperties->setPropertyValue("AllowOverlap", uno::Any(false)); + CPPUNIT_ASSERT(!getProperty<bool>(xShapeProperties, "AllowOverlap")); + + // Turn it back to on & verify. + xShapeProperties->setPropertyValue("AllowOverlap", uno::Any(true)); + CPPUNIT_ASSERT(getProperty<bool>(xShapeProperties, "AllowOverlap")); +} + +CPPUNIT_TEST_FIXTURE(SwUnoWriter, testTextConvertToTableLineSpacing) +{ + // Load a document which has a table with a single cell. + // The cell has both a table style and a paragraph style, with different line spacing + // heights. + load(mpTestDocumentPath, "table-line-spacing.docx"); + uno::Reference<text::XTextTablesSupplier> xTablesSupplier(mxComponent, uno::UNO_QUERY); + uno::Reference<container::XIndexAccess> xTables(xTablesSupplier->getTextTables(), + uno::UNO_QUERY); + uno::Reference<text::XTextTable> xTable(xTables->getByIndex(0), uno::UNO_QUERY); + uno::Reference<table::XCell> xCell = xTable->getCellByName("A1"); + uno::Reference<text::XText> xCellText(xCell, uno::UNO_QUERY); + uno::Reference<text::XTextRange> xParagraph = getParagraphOfText(1, xCellText); + style::LineSpacing aLineSpacing + = getProperty<style::LineSpacing>(xParagraph, "ParaLineSpacing"); + // Make sure that we take the line spacing from the paragraph style, not from the table style. + // Without the accompanying fix in place, this test would have failed with: + // - Expected: 388 + // - Actual : 635 + // I.e. the 360 twips line spacing was taken from the table style, not the 220 twips one from + // the paragraph style. + CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int16>(convertTwipToMm100(220)), aLineSpacing.Height); +} + +CPPUNIT_TEST_FIXTURE(SwUnoWriter, testMultiSelect) +{ + // Create a new document and add a text with several repeated sequences. + loadURL("private:factory/swriter", nullptr); + uno::Reference<text::XTextDocument> xTextDocument(mxComponent, css::uno::UNO_QUERY_THROW); + auto xSimpleText = xTextDocument->getText(); + xSimpleText->insertString(xSimpleText->getStart(), "Abc aBc abC", false); + + // Create a search descriptor and find all occurencies of search string + css::uno::Reference<css::util::XSearchable> xSearchable(mxComponent, css::uno::UNO_QUERY_THROW); + auto xSearchDescriptor = xSearchable->createSearchDescriptor(); + xSearchDescriptor->setPropertyValue("SearchStyles", css::uno::Any(false)); + xSearchDescriptor->setPropertyValue("SearchCaseSensitive", css::uno::Any(false)); + xSearchDescriptor->setPropertyValue("SearchBackwards", css::uno::Any(true)); + xSearchDescriptor->setPropertyValue("SearchRegularExpression", css::uno::Any(false)); + xSearchDescriptor->setSearchString("abc"); + auto xSearchResult = xSearchable->findAll(xSearchDescriptor); + + // Select them all + auto xController = xTextDocument->getCurrentController(); + css::uno::Reference<css::view::XSelectionSupplier> xSelectionSupplier( + xController, css::uno::UNO_QUERY_THROW); + xSelectionSupplier->select(css::uno::Any(xSearchResult)); + css::uno::Reference<css::container::XIndexAccess> xSelection(xSelectionSupplier->getSelection(), + css::uno::UNO_QUERY_THROW); + // Now check that they all are selected in the reverse order ("SearchBackwards"). + CPPUNIT_ASSERT_EQUAL(sal_Int32(3), xSelection->getCount()); + css::uno::Reference<css::text::XTextRange> xTextRange(xSelection->getByIndex(0), + css::uno::UNO_QUERY_THROW); + // For #0, result was empty (cursor was put before the last occurrence without selection) + CPPUNIT_ASSERT_EQUAL(OUString("abC"), xTextRange->getString()); + xTextRange.set(xSelection->getByIndex(1), css::uno::UNO_QUERY_THROW); + CPPUNIT_ASSERT_EQUAL(OUString("aBc"), xTextRange->getString()); + xTextRange.set(xSelection->getByIndex(2), css::uno::UNO_QUERY_THROW); + CPPUNIT_ASSERT_EQUAL(OUString("Abc"), xTextRange->getString()); +} + +CPPUNIT_TEST_FIXTURE(SwUnoWriter, testTransparentText) +{ + // Test the CharTransparence text portion property. + + // Create a new document. + loadURL("private:factory/swriter", nullptr); + + // Set a custom transparency. + uno::Reference<beans::XPropertySet> xParagraph(getParagraph(1), uno::UNO_QUERY); + sal_Int16 nExpected = 42; + xParagraph->setPropertyValue("CharTransparence", uno::Any(nExpected)); + + // Get the transparency & verify. + CPPUNIT_ASSERT_EQUAL(nExpected, getProperty<sal_Int16>(xParagraph, "CharTransparence")); +} + +CPPUNIT_TEST_FIXTURE(SwUnoWriter, testTdf129839) +{ + // Create a new document and add a table + loadURL("private:factory/swriter", nullptr); + css::uno::Reference<css::text::XTextDocument> xTextDocument(mxComponent, + css::uno::UNO_QUERY_THROW); + css::uno::Reference<css::lang::XMultiServiceFactory> xFac(xTextDocument, + css::uno::UNO_QUERY_THROW); + css::uno::Reference<css::text::XTextTable> xTable( + xFac->createInstance("com.sun.star.text.TextTable"), css::uno::UNO_QUERY_THROW); + xTable->initialize(4, 4); + auto xSimpleText = xTextDocument->getText(); + xSimpleText->insertTextContent(xSimpleText->createTextCursor(), xTable, true); + css::uno::Reference<css::table::XCellRange> xTableCellRange(xTable, css::uno::UNO_QUERY_THROW); + // Get instance of SwXCellRange + css::uno::Reference<css::beans::XPropertySet> xCellRange( + xTableCellRange->getCellRangeByPosition(0, 0, 1, 1), css::uno::UNO_QUERY_THROW); + // Test retrieval of VertOrient property - this crashed + css::uno::Any aOrient = xCellRange->getPropertyValue("VertOrient"); + CPPUNIT_ASSERT_EQUAL(css::uno::Any(css::text::VertOrientation::NONE), aOrient); +} + +CPPUNIT_TEST_FIXTURE(SwUnoWriter, testTdf129841) +{ + // Create a new document and add a table + loadURL("private:factory/swriter", nullptr); + css::uno::Reference<css::text::XTextDocument> xTextDocument(mxComponent, + css::uno::UNO_QUERY_THROW); + css::uno::Reference<css::lang::XMultiServiceFactory> xFac(xTextDocument, + css::uno::UNO_QUERY_THROW); + css::uno::Reference<css::text::XTextTable> xTable( + xFac->createInstance("com.sun.star.text.TextTable"), css::uno::UNO_QUERY_THROW); + xTable->initialize(4, 4); + auto xSimpleText = xTextDocument->getText(); + xSimpleText->insertTextContent(xSimpleText->createTextCursor(), xTable, true); + // Get SwXTextTableCursor + css::uno::Reference<css::beans::XPropertySet> xTableCursor(xTable->createCursorByCellName("A1"), + css::uno::UNO_QUERY_THROW); + css::uno::Reference<css::table::XCellRange> xTableCellRange(xTable, css::uno::UNO_QUERY_THROW); + // Get SwXCellRange for the same cell + css::uno::Reference<css::beans::XPropertySet> xCellRange( + xTableCellRange->getCellRangeByName("A1:A1"), css::uno::UNO_QUERY_THROW); + static const OUStringLiteral sBackColor = u"BackColor"; + // Apply background color to table cursor, and read background color from cell range + css::uno::Any aRefColor(sal_Int32(0x00FF0000)); + xTableCursor->setPropertyValue(sBackColor, aRefColor); + css::uno::Any aColor = xCellRange->getPropertyValue(sBackColor); + // This failed + CPPUNIT_ASSERT_EQUAL(aRefColor, aColor); + // Now the other way round + aRefColor <<= sal_Int32(0x0000FF00); + xCellRange->setPropertyValue(sBackColor, aRefColor); + aColor = xTableCursor->getPropertyValue(sBackColor); + CPPUNIT_ASSERT_EQUAL(aRefColor, aColor); +} + +CPPUNIT_PLUGIN_IMPLEMENT(); + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |