diff options
Diffstat (limited to 'sw/qa/extras/ww8export')
66 files changed, 1108 insertions, 313 deletions
diff --git a/sw/qa/extras/ww8export/data/cell-bg-color.odt b/sw/qa/extras/ww8export/data/cell-bg-color.odt Binary files differindex 3565f40c210e..0a6a3076e5f5 100644 --- a/sw/qa/extras/ww8export/data/cell-bg-color.odt +++ b/sw/qa/extras/ww8export/data/cell-bg-color.odt diff --git a/sw/qa/extras/ww8export/data/cjklist30.doc b/sw/qa/extras/ww8export/data/cjklist30.doc Binary files differindex 48f22cf79a35..bdabe3561404 100644 --- a/sw/qa/extras/ww8export/data/cjklist30.doc +++ b/sw/qa/extras/ww8export/data/cjklist30.doc diff --git a/sw/qa/extras/ww8export/data/cjklist31.doc b/sw/qa/extras/ww8export/data/cjklist31.doc Binary files differindex 4a7d3e7e1360..d11c90a8be67 100644 --- a/sw/qa/extras/ww8export/data/cjklist31.doc +++ b/sw/qa/extras/ww8export/data/cjklist31.doc diff --git a/sw/qa/extras/ww8export/data/cjklist34.doc b/sw/qa/extras/ww8export/data/cjklist34.doc Binary files differindex 551fc89527c9..8a4620a0194a 100644 --- a/sw/qa/extras/ww8export/data/cjklist34.doc +++ b/sw/qa/extras/ww8export/data/cjklist34.doc diff --git a/sw/qa/extras/ww8export/data/cjklist35.doc b/sw/qa/extras/ww8export/data/cjklist35.doc Binary files differindex 33d247029ad9..8810acb09423 100644 --- a/sw/qa/extras/ww8export/data/cjklist35.doc +++ b/sw/qa/extras/ww8export/data/cjklist35.doc diff --git a/sw/qa/extras/ww8export/data/clearing-break.doc b/sw/qa/extras/ww8export/data/clearing-break.doc Binary files differnew file mode 100644 index 000000000000..87b51128db3f --- /dev/null +++ b/sw/qa/extras/ww8export/data/clearing-break.doc diff --git a/sw/qa/extras/ww8export/data/continuous-sections.doc b/sw/qa/extras/ww8export/data/continuous-sections.doc Binary files differnew file mode 100644 index 000000000000..cf466c9e7286 --- /dev/null +++ b/sw/qa/extras/ww8export/data/continuous-sections.doc diff --git a/sw/qa/extras/ww8export/data/empty_group.docx b/sw/qa/extras/ww8export/data/empty_group.docx Binary files differnew file mode 100644 index 000000000000..a3454746c5e0 --- /dev/null +++ b/sw/qa/extras/ww8export/data/empty_group.docx diff --git a/sw/qa/extras/ww8export/data/fdo68967.doc b/sw/qa/extras/ww8export/data/fdo68967.doc Binary files differindex 05271c3d868a..a14ecc8732e6 100644 --- a/sw/qa/extras/ww8export/data/fdo68967.doc +++ b/sw/qa/extras/ww8export/data/fdo68967.doc diff --git a/sw/qa/extras/ww8export/data/i120158.doc b/sw/qa/extras/ww8export/data/i120158.doc Binary files differindex 6adf3ec13d52..eef3154d81f2 100644 --- a/sw/qa/extras/ww8export/data/i120158.doc +++ b/sw/qa/extras/ww8export/data/i120158.doc diff --git a/sw/qa/extras/ww8export/data/inlinePageBreakFirstLine.doc b/sw/qa/extras/ww8export/data/inlinePageBreakFirstLine.doc Binary files differnew file mode 100644 index 000000000000..4f339511d664 --- /dev/null +++ b/sw/qa/extras/ww8export/data/inlinePageBreakFirstLine.doc diff --git a/sw/qa/extras/ww8export/data/listWithLgl.doc b/sw/qa/extras/ww8export/data/listWithLgl.doc Binary files differnew file mode 100644 index 000000000000..94de2967febc --- /dev/null +++ b/sw/qa/extras/ww8export/data/listWithLgl.doc diff --git a/sw/qa/extras/ww8export/data/n760294.doc b/sw/qa/extras/ww8export/data/n760294.doc Binary files differindex 04960d060b15..bfbe682e1290 100644 --- a/sw/qa/extras/ww8export/data/n760294.doc +++ b/sw/qa/extras/ww8export/data/n760294.doc diff --git a/sw/qa/extras/ww8export/data/new-page-styles.doc b/sw/qa/extras/ww8export/data/new-page-styles.doc Binary files differindex c3886fd6bf2d..6e1cf5cbd67a 100644 --- a/sw/qa/extras/ww8export/data/new-page-styles.doc +++ b/sw/qa/extras/ww8export/data/new-page-styles.doc diff --git a/sw/qa/extras/ww8export/data/nonInlinePageBreakFirstLine.doc b/sw/qa/extras/ww8export/data/nonInlinePageBreakFirstLine.doc Binary files differnew file mode 100644 index 000000000000..5351a9edecc7 --- /dev/null +++ b/sw/qa/extras/ww8export/data/nonInlinePageBreakFirstLine.doc diff --git a/sw/qa/extras/ww8export/data/object_cross_reference.odt b/sw/qa/extras/ww8export/data/object_cross_reference.odt Binary files differindex 9eaca352b68c..ee6849dc5a8b 100644 --- a/sw/qa/extras/ww8export/data/object_cross_reference.odt +++ b/sw/qa/extras/ww8export/data/object_cross_reference.odt diff --git a/sw/qa/extras/ww8export/data/ooo92948-1.doc b/sw/qa/extras/ww8export/data/ooo92948-1.doc Binary files differindex f355eaa26794..96eee00ac5e6 100644 --- a/sw/qa/extras/ww8export/data/ooo92948-1.doc +++ b/sw/qa/extras/ww8export/data/ooo92948-1.doc diff --git a/sw/qa/extras/ww8export/data/redline-export-1.odt b/sw/qa/extras/ww8export/data/redline-export-1.odt Binary files differindex 31aacce47284..a966dcf18024 100644 --- a/sw/qa/extras/ww8export/data/redline-export-1.odt +++ b/sw/qa/extras/ww8export/data/redline-export-1.odt diff --git a/sw/qa/extras/ww8export/data/redline-export-2.odt b/sw/qa/extras/ww8export/data/redline-export-2.odt Binary files differindex 2aca5eee4cd3..2d9a6167d24e 100644 --- a/sw/qa/extras/ww8export/data/redline-export-2.odt +++ b/sw/qa/extras/ww8export/data/redline-export-2.odt diff --git a/sw/qa/extras/ww8export/data/redline-export-3.odt b/sw/qa/extras/ww8export/data/redline-export-3.odt Binary files differindex 6d0d80a08090..f1b2ecd76270 100644 --- a/sw/qa/extras/ww8export/data/redline-export-3.odt +++ b/sw/qa/extras/ww8export/data/redline-export-3.odt diff --git a/sw/qa/extras/ww8export/data/rtl-gutter.doc b/sw/qa/extras/ww8export/data/rtl-gutter.doc Binary files differnew file mode 100644 index 000000000000..37cbf8707ce6 --- /dev/null +++ b/sw/qa/extras/ww8export/data/rtl-gutter.doc diff --git a/sw/qa/extras/ww8export/data/shapes-line-ellipse.doc b/sw/qa/extras/ww8export/data/shapes-line-ellipse.doc Binary files differnew file mode 100644 index 000000000000..184881c00a6d --- /dev/null +++ b/sw/qa/extras/ww8export/data/shapes-line-ellipse.doc diff --git a/sw/qa/extras/ww8export/data/tdf100961_fixedDateTime.doc b/sw/qa/extras/ww8export/data/tdf100961_fixedDateTime.doc Binary files differnew file mode 100644 index 000000000000..86f0e478d469 --- /dev/null +++ b/sw/qa/extras/ww8export/data/tdf100961_fixedDateTime.doc diff --git a/sw/qa/extras/ww8export/data/tdf104239_chapterNumberTortureTest.doc b/sw/qa/extras/ww8export/data/tdf104239_chapterNumberTortureTest.doc Binary files differnew file mode 100644 index 000000000000..dc8f65e76d40 --- /dev/null +++ b/sw/qa/extras/ww8export/data/tdf104239_chapterNumberTortureTest.doc diff --git a/sw/qa/extras/ww8export/data/tdf104239_chapterNumbering.doc b/sw/qa/extras/ww8export/data/tdf104239_chapterNumbering.doc Binary files differnew file mode 100644 index 000000000000..2e237b2e33c6 --- /dev/null +++ b/sw/qa/extras/ww8export/data/tdf104239_chapterNumbering.doc diff --git a/sw/qa/extras/ww8export/data/tdf104239_chapterNumberingLevels.doc b/sw/qa/extras/ww8export/data/tdf104239_chapterNumberingLevels.doc Binary files differnew file mode 100644 index 000000000000..8a7583c3253c --- /dev/null +++ b/sw/qa/extras/ww8export/data/tdf104239_chapterNumberingLevels.doc diff --git a/sw/qa/extras/ww8export/data/tdf104239_numbering.doc b/sw/qa/extras/ww8export/data/tdf104239_numbering.doc Binary files differnew file mode 100644 index 000000000000..ee8ad09e4b14 --- /dev/null +++ b/sw/qa/extras/ww8export/data/tdf104239_numbering.doc diff --git a/sw/qa/extras/ww8export/data/tdf104239_sharedOutlineNumId.doc b/sw/qa/extras/ww8export/data/tdf104239_sharedOutlineNumId.doc Binary files differnew file mode 100644 index 000000000000..c5deb4857f9c --- /dev/null +++ b/sw/qa/extras/ww8export/data/tdf104239_sharedOutlineNumId.doc diff --git a/sw/qa/extras/ww8export/data/tdf104704_mangledFooter.odt b/sw/qa/extras/ww8export/data/tdf104704_mangledFooter.odt Binary files differnew file mode 100644 index 000000000000..2bd8c10f9ca4 --- /dev/null +++ b/sw/qa/extras/ww8export/data/tdf104704_mangledFooter.odt diff --git a/sw/qa/extras/ww8export/data/tdf106541_cancelOutline.doc b/sw/qa/extras/ww8export/data/tdf106541_cancelOutline.doc Binary files differnew file mode 100644 index 000000000000..6b3f016f3a4d --- /dev/null +++ b/sw/qa/extras/ww8export/data/tdf106541_cancelOutline.doc diff --git a/sw/qa/extras/ww8export/data/tdf106541_inheritChapterNumbering.doc b/sw/qa/extras/ww8export/data/tdf106541_inheritChapterNumbering.doc Binary files differnew file mode 100644 index 000000000000..f56b9d6b6e6a --- /dev/null +++ b/sw/qa/extras/ww8export/data/tdf106541_inheritChapterNumbering.doc diff --git a/sw/qa/extras/ww8export/data/tdf106541_inheritChapterNumberingB.doc b/sw/qa/extras/ww8export/data/tdf106541_inheritChapterNumberingB.doc Binary files differnew file mode 100644 index 000000000000..0ff47ca3e642 --- /dev/null +++ b/sw/qa/extras/ww8export/data/tdf106541_inheritChapterNumberingB.doc diff --git a/sw/qa/extras/ww8export/data/tdf106541_inheritOutlineNumbering.doc b/sw/qa/extras/ww8export/data/tdf106541_inheritOutlineNumbering.doc Binary files differnew file mode 100644 index 000000000000..2fe243fe800a --- /dev/null +++ b/sw/qa/extras/ww8export/data/tdf106541_inheritOutlineNumbering.doc diff --git a/sw/qa/extras/ww8export/data/tdf108518_CRnumformatting.doc b/sw/qa/extras/ww8export/data/tdf108518_CRnumformatting.doc Binary files differnew file mode 100644 index 000000000000..536e92fd4729 --- /dev/null +++ b/sw/qa/extras/ww8export/data/tdf108518_CRnumformatting.doc diff --git a/sw/qa/extras/ww8export/data/tdf117994_CRnumformatting.doc b/sw/qa/extras/ww8export/data/tdf117994_CRnumformatting.doc Binary files differnew file mode 100644 index 000000000000..99744382a82b --- /dev/null +++ b/sw/qa/extras/ww8export/data/tdf117994_CRnumformatting.doc diff --git a/sw/qa/extras/ww8export/data/tdf118564.doc b/sw/qa/extras/ww8export/data/tdf118564.doc Binary files differindex 4040e05e27bf..a8c53d24796e 100644 --- a/sw/qa/extras/ww8export/data/tdf118564.doc +++ b/sw/qa/extras/ww8export/data/tdf118564.doc diff --git a/sw/qa/extras/ww8export/data/tdf124937.doc b/sw/qa/extras/ww8export/data/tdf124937.doc Binary files differnew file mode 100644 index 000000000000..eb1ab2d9e0cd --- /dev/null +++ b/sw/qa/extras/ww8export/data/tdf124937.doc diff --git a/sw/qa/extras/ww8export/data/tdf130262.doc b/sw/qa/extras/ww8export/data/tdf130262.doc Binary files differindex fb60beacd79d..f652cca8f9fd 100644 --- a/sw/qa/extras/ww8export/data/tdf130262.doc +++ b/sw/qa/extras/ww8export/data/tdf130262.doc diff --git a/sw/qa/extras/ww8export/data/tdf133504_wrapNotBeside.doc b/sw/qa/extras/ww8export/data/tdf133504_wrapNotBeside.doc Binary files differnew file mode 100644 index 000000000000..865023e34489 --- /dev/null +++ b/sw/qa/extras/ww8export/data/tdf133504_wrapNotBeside.doc diff --git a/sw/qa/extras/ww8export/data/tdf138302_restartNumbering.odt b/sw/qa/extras/ww8export/data/tdf138302_restartNumbering.odt Binary files differnew file mode 100644 index 000000000000..8c99963616a7 --- /dev/null +++ b/sw/qa/extras/ww8export/data/tdf138302_restartNumbering.odt diff --git a/sw/qa/extras/ww8export/data/tdf139495_tinyHeader.doc b/sw/qa/extras/ww8export/data/tdf139495_tinyHeader.doc Binary files differnew file mode 100644 index 000000000000..c45a6c25fd99 --- /dev/null +++ b/sw/qa/extras/ww8export/data/tdf139495_tinyHeader.doc diff --git a/sw/qa/extras/ww8export/data/tdf141649_conditionalText.doc b/sw/qa/extras/ww8export/data/tdf141649_conditionalText.doc Binary files differnew file mode 100644 index 000000000000..9e4ec49e38a6 --- /dev/null +++ b/sw/qa/extras/ww8export/data/tdf141649_conditionalText.doc diff --git a/sw/qa/extras/ww8export/data/tdf142760.doc b/sw/qa/extras/ww8export/data/tdf142760.doc Binary files differnew file mode 100644 index 000000000000..1e90532fe899 --- /dev/null +++ b/sw/qa/extras/ww8export/data/tdf142760.doc diff --git a/sw/qa/extras/ww8export/data/tdf142840.odt b/sw/qa/extras/ww8export/data/tdf142840.odt Binary files differnew file mode 100644 index 000000000000..27af4cdb5e6a --- /dev/null +++ b/sw/qa/extras/ww8export/data/tdf142840.odt diff --git a/sw/qa/extras/ww8export/data/tdf147861_customField.doc b/sw/qa/extras/ww8export/data/tdf147861_customField.doc Binary files differnew file mode 100644 index 000000000000..f18d65f4059e --- /dev/null +++ b/sw/qa/extras/ww8export/data/tdf147861_customField.doc diff --git a/sw/qa/extras/ww8export/data/tdf148380_createField.doc b/sw/qa/extras/ww8export/data/tdf148380_createField.doc Binary files differnew file mode 100644 index 000000000000..79c5e59c5ecd --- /dev/null +++ b/sw/qa/extras/ww8export/data/tdf148380_createField.doc diff --git a/sw/qa/extras/ww8export/data/tdf148380_fldLocked.doc b/sw/qa/extras/ww8export/data/tdf148380_fldLocked.doc Binary files differnew file mode 100644 index 000000000000..cee6982ee6a0 --- /dev/null +++ b/sw/qa/extras/ww8export/data/tdf148380_fldLocked.doc diff --git a/sw/qa/extras/ww8export/data/tdf150197_anlv2ListFormat.doc b/sw/qa/extras/ww8export/data/tdf150197_anlv2ListFormat.doc Binary files differnew file mode 100644 index 000000000000..93d21046d607 --- /dev/null +++ b/sw/qa/extras/ww8export/data/tdf150197_anlv2ListFormat.doc diff --git a/sw/qa/extras/ww8export/data/tdf151548_formFieldMacros.doc b/sw/qa/extras/ww8export/data/tdf151548_formFieldMacros.doc Binary files differnew file mode 100644 index 000000000000..4ea915f0afe4 --- /dev/null +++ b/sw/qa/extras/ww8export/data/tdf151548_formFieldMacros.doc diff --git a/sw/qa/extras/ww8export/data/tdf155465_paraAdjustDistribute.doc b/sw/qa/extras/ww8export/data/tdf155465_paraAdjustDistribute.doc Binary files differnew file mode 100644 index 000000000000..5a661cd837ef --- /dev/null +++ b/sw/qa/extras/ww8export/data/tdf155465_paraAdjustDistribute.doc diff --git a/sw/qa/extras/ww8export/data/tdf160049_anchorMargin.doc b/sw/qa/extras/ww8export/data/tdf160049_anchorMargin.doc Binary files differnew file mode 100644 index 000000000000..d1082515fd9c --- /dev/null +++ b/sw/qa/extras/ww8export/data/tdf160049_anchorMargin.doc diff --git a/sw/qa/extras/ww8export/data/tdf36711_inlineFrames.doc b/sw/qa/extras/ww8export/data/tdf36711_inlineFrames.doc Binary files differnew file mode 100644 index 000000000000..80a7d64cc8cd --- /dev/null +++ b/sw/qa/extras/ww8export/data/tdf36711_inlineFrames.doc diff --git a/sw/qa/extras/ww8export/data/tdf46441-2.odt b/sw/qa/extras/ww8export/data/tdf46441-2.odt Binary files differindex ed73406c5ab7..d9e8ea03e66a 100644 --- a/sw/qa/extras/ww8export/data/tdf46441-2.odt +++ b/sw/qa/extras/ww8export/data/tdf46441-2.odt diff --git a/sw/qa/extras/ww8export/data/tdf59896.doc b/sw/qa/extras/ww8export/data/tdf59896.doc Binary files differindex a3c7242992f0..bdf45712988b 100644 --- a/sw/qa/extras/ww8export/data/tdf59896.doc +++ b/sw/qa/extras/ww8export/data/tdf59896.doc diff --git a/sw/qa/extras/ww8export/data/tdf75748_inheritChapterNumberingC.doc b/sw/qa/extras/ww8export/data/tdf75748_inheritChapterNumberingC.doc Binary files differnew file mode 100644 index 000000000000..7f393612cab7 --- /dev/null +++ b/sw/qa/extras/ww8export/data/tdf75748_inheritChapterNumberingC.doc diff --git a/sw/qa/extras/ww8export/data/tdf77964.doc b/sw/qa/extras/ww8export/data/tdf77964.doc Binary files differnew file mode 100644 index 000000000000..2b36036b97b3 --- /dev/null +++ b/sw/qa/extras/ww8export/data/tdf77964.doc diff --git a/sw/qa/extras/ww8export/data/tdf79186_noLayoutInCell.odt b/sw/qa/extras/ww8export/data/tdf79186_noLayoutInCell.odt Binary files differnew file mode 100644 index 000000000000..e512f09072ce --- /dev/null +++ b/sw/qa/extras/ww8export/data/tdf79186_noLayoutInCell.odt diff --git a/sw/qa/extras/ww8export/data/tdf81705_outlineLevel.doc b/sw/qa/extras/ww8export/data/tdf81705_outlineLevel.doc Binary files differnew file mode 100644 index 000000000000..55d188356a25 --- /dev/null +++ b/sw/qa/extras/ww8export/data/tdf81705_outlineLevel.doc diff --git a/sw/qa/extras/ww8export/data/first-header-footer.doc b/sw/qa/extras/ww8export/data/tdf90408.doc Binary files differindex 023c494862a5..2335e73ea290 100644 --- a/sw/qa/extras/ww8export/data/first-header-footer.doc +++ b/sw/qa/extras/ww8export/data/tdf90408.doc diff --git a/sw/qa/extras/ww8export/data/tdf90408B.doc b/sw/qa/extras/ww8export/data/tdf90408B.doc Binary files differnew file mode 100644 index 000000000000..17b210a0bc85 --- /dev/null +++ b/sw/qa/extras/ww8export/data/tdf90408B.doc diff --git a/sw/qa/extras/ww8export/data/tdf94326_notOutlineNumbering.doc b/sw/qa/extras/ww8export/data/tdf94326_notOutlineNumbering.doc Binary files differnew file mode 100644 index 000000000000..2df22e9317c6 --- /dev/null +++ b/sw/qa/extras/ww8export/data/tdf94326_notOutlineNumbering.doc diff --git a/sw/qa/extras/ww8export/data/tdf95576.doc b/sw/qa/extras/ww8export/data/tdf95576.doc Binary files differindex a8a601885f33..348ebd71a2f6 100644 --- a/sw/qa/extras/ww8export/data/tdf95576.doc +++ b/sw/qa/extras/ww8export/data/tdf95576.doc diff --git a/sw/qa/extras/ww8export/ww8export.cxx b/sw/qa/extras/ww8export/ww8export.cxx index be85611d18e3..89d57de6e677 100644 --- a/sw/qa/extras/ww8export/ww8export.cxx +++ b/sw/qa/extras/ww8export/ww8export.cxx @@ -7,11 +7,14 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#include <sal/config.h> + +#include <string_view> + #include <swmodeltestbase.hxx> #include <com/sun/star/awt/FontWeight.hpp> #include <com/sun/star/awt/Size.hpp> -#include <com/sun/star/awt/XBitmap.hpp> #include <com/sun/star/beans/XPropertyState.hpp> #include <com/sun/star/form/validation/XValidatableFormComponent.hpp> #include <com/sun/star/frame/XStorable.hpp> @@ -25,7 +28,10 @@ #include <com/sun/star/table/TableBorder.hpp> #include <com/sun/star/table/TableBorder2.hpp> #include <com/sun/star/text/GraphicCrop.hpp> +#include <com/sun/star/text/WrapTextMode.hpp> #include <com/sun/star/text/XFormField.hpp> +#include <com/sun/star/text/XTextField.hpp> +#include <com/sun/star/text/XTextFieldsSupplier.hpp> #include <com/sun/star/text/XTextFramesSupplier.hpp> #include <com/sun/star/text/XTextTablesSupplier.hpp> #include <com/sun/star/view/DocumentZoomType.hpp> @@ -34,7 +40,7 @@ #include <com/sun/star/text/XTextViewCursorSupplier.hpp> #include <com/sun/star/text/XPageCursor.hpp> -#include <config_features.h> +#include <config_fonts.h> #include <editeng/ulspitem.hxx> #include <sfx2/bindings.hxx> #include <sfx2/request.hxx> @@ -55,68 +61,12 @@ #include <IDocumentSettingAccess.hxx> #include <docsh.hxx> #include <unotxdoc.hxx> +#include <o3tl/string_view.hxx> class Test : public SwModelTestBase { public: Test() : SwModelTestBase("/sw/qa/extras/ww8export/data/", "MS Word 97") {} - - bool mustTestImportOf(const char* filename) const override - { - // If the testcase is stored in some other format, it's pointless to test. - return OString(filename).endsWith(".doc"); - } - - /** - * Validation handling - */ - bool mustValidate(const char* filename) const override - { - const std::vector<const char*> aDenylist = - { - // the following doc exports currently don't pass binary validation - "tdf56321_flipImage_both.doc", - "cjklist30.doc", - "cjklist31.doc", - "cjklist34.doc", - "cjklist35.doc", - "fdo77454.doc", - "new-page-styles.doc", - "tdf36117_verticalAdjustment.doc", - "bnc636128.doc", - "tdf92281.doc", - "fdo59530.doc", - "fdo56513.doc", - "tscp.doc", - "zoom.doc", - "comments-nested.doc", - "commented-table.doc", - "zoomtype.doc", - "n325936.doc", - "first-header-footer.doc" - }; - - // Don't bother with non-.doc files; weed out denylisted .doc files - return (OString(filename).endsWith(".doc") && std::find(aDenylist.begin(), aDenylist.end(), filename) == aDenylist.end()); - } -protected: - - virtual void postLoad(const char* pFilename) override - { - if (OString(pFilename) == "tdf94386.odt") - { - SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument *>(mxComponent.get()); - CPPUNIT_ASSERT(pTextDoc); - SwWrtShell* pWrtShell = pTextDoc->GetDocShell()->GetWrtShell(); - - // emulate the behavior from tdf#94386 - insert an envelope to the - // document - SfxItemSet aSet(pWrtShell->GetView().GetCurShell()->GetPool(), svl::Items<FN_ENVELOP, FN_ENVELOP>{}); - aSet.Put(SwEnvItem()); - SfxRequest aRequest(FN_ENVELOP, SfxCallMode::SYNCHRON, aSet); - SW_MOD()->ExecOther(aRequest); - } - } }; DECLARE_WW8EXPORT_TEST(testN757910, "n757910.doc") @@ -245,12 +195,12 @@ xray ThisComponent.DrawPage.getByIndex(0).BoundRect DECLARE_WW8EXPORT_TEST(testTdf75539_relativeWidth, "tdf75539_relativeWidth.doc") { //divide everything by 10 to give a margin of error for rounding etc. - sal_Int32 pageWidth = parseDump("/root/page[1]/body/infos/bounds", "width").toInt32()/10; + sal_Int32 pageWidth = parseDump("/root/page[1]/body/infos/bounds"_ostr, "width"_ostr).toInt32()/10; CPPUNIT_ASSERT_EQUAL_MESSAGE("Page width", sal_Int32(9354/10), pageWidth); - CPPUNIT_ASSERT_EQUAL_MESSAGE("100% width line", pageWidth, parseDump("/root/page[1]/body/txt[2]/Special", "nWidth").toInt32()/10); - CPPUNIT_ASSERT_EQUAL_MESSAGE("50% width line", pageWidth/2, parseDump("/root/page[1]/body/txt[4]/Special", "nWidth").toInt32()/10); - CPPUNIT_ASSERT_EQUAL_MESSAGE("25% width line", pageWidth/4, parseDump("/root/page[1]/body/txt[6]/Special", "nWidth").toInt32()/10); - CPPUNIT_ASSERT_EQUAL_MESSAGE("10% width line", pageWidth/10, parseDump("/root/page[1]/body/txt[8]/Special", "nWidth").toInt32()/10); + CPPUNIT_ASSERT_EQUAL_MESSAGE("100% width line", pageWidth, parseDump("/root/page[1]/body/txt[2]/SwParaPortion/SwLineLayout/SwLinePortion"_ostr, "width"_ostr).toInt32()/10); + CPPUNIT_ASSERT_EQUAL_MESSAGE("50% width line", pageWidth/2, parseDump("/root/page[1]/body/txt[4]/SwParaPortion/SwLineLayout/SwLinePortion"_ostr, "width"_ostr).toInt32()/10); + CPPUNIT_ASSERT_EQUAL_MESSAGE("25% width line", pageWidth/4, parseDump("/root/page[1]/body/txt[6]/SwParaPortion/SwLineLayout/SwLinePortion"_ostr, "width"_ostr).toInt32()/10); + CPPUNIT_ASSERT_EQUAL_MESSAGE("10% width line", pageWidth/10, parseDump("/root/page[1]/body/txt[8]/SwParaPortion/SwLineLayout/SwLinePortion"_ostr, "width"_ostr).toInt32()/10); } DECLARE_WW8EXPORT_TEST(testN757905, "n757905.doc") @@ -260,7 +210,7 @@ DECLARE_WW8EXPORT_TEST(testN757905, "n757905.doc") // paragraph height. When in Word-compat mode, we should take the max of // the two, not just the height of the fly. - OUString aHeight = parseDump("/root/page/body/txt/infos/bounds", "height"); + OUString aHeight = parseDump("/root/page/body/txt/infos/bounds"_ostr, "height"_ostr); CPPUNIT_ASSERT(sal_Int32(31) < aHeight.toInt32()); } @@ -309,7 +259,7 @@ DECLARE_WW8EXPORT_TEST(testN823651, "n823651.doc") DECLARE_WW8EXPORT_TEST(testFdo36868, "fdo36868.doc") { - OUString aText = parseDump("/root/page/body/txt[3]/Special[@nType='PortionType::Number']", "rText"); + OUString aText = parseDump("/root/page/body/txt[3]/SwParaPortion/SwLineLayout/child::*[@type='PortionType::Number']"_ostr, "expand"_ostr); // This was 1.1. CPPUNIT_ASSERT_EQUAL(OUString("2.1"), aText); } @@ -317,7 +267,7 @@ DECLARE_WW8EXPORT_TEST(testFdo36868, "fdo36868.doc") DECLARE_WW8EXPORT_TEST(testListNolevel, "list-nolevel.doc") { // Similar to fdo#36868, numbering portions had wrong values. - OUString aText = parseDump("/root/page/body/txt[1]/Special[@nType='PortionType::Number']", "rText"); + OUString aText = parseDump("/root/page/body/txt[1]/SwParaPortion/SwLineLayout/child::*[@type='PortionType::Number']"_ostr, "expand"_ostr); // PortionType::Number was completely missing. CPPUNIT_ASSERT_EQUAL(OUString("1."), aText); } @@ -500,16 +450,12 @@ DECLARE_WW8EXPORT_TEST(testMsoBrightnessContrast, "msobrightnesscontrast.doc") uno::Reference<beans::XPropertySet> imageProperties(image, uno::UNO_QUERY); uno::Reference<graphic::XGraphic> graphic; imageProperties->getPropertyValue( "Graphic" ) >>= graphic; - uno::Reference<awt::XBitmap> bitmap(graphic, uno::UNO_QUERY); - CPPUNIT_ASSERT_EQUAL( sal_Int32(58), bitmap->getSize().Width ); - CPPUNIT_ASSERT_EQUAL( sal_Int32(320), bitmap->getSize().Height ); - const uno::Sequence< sal_Int8 > data = bitmap->getDIB(); // as .bmp data - CPPUNIT_ASSERT_EQUAL( sal_Int32(20278), data.getLength()); - CPPUNIT_ASSERT_EQUAL( -50, int(data[0x6b0])); // -50 = 206 pixel value - CPPUNIT_ASSERT_EQUAL( -50, int(data[0x6b1])); - CPPUNIT_ASSERT_EQUAL( -50, int(data[0x6b2])); - CPPUNIT_ASSERT_EQUAL( -50, int(data[0x6b3])); - CPPUNIT_ASSERT_EQUAL( -50, int(data[0x6b4])); + Graphic vclGraphic(graphic); + BitmapEx bitmap(vclGraphic.GetBitmapEx()); + CPPUNIT_ASSERT_EQUAL( tools::Long(58), bitmap.GetSizePixel().Width()); + CPPUNIT_ASSERT_EQUAL( tools::Long(320), bitmap.GetSizePixel().Height()); + CPPUNIT_ASSERT_EQUAL( Color(206,206,206), bitmap.GetPixelColor(16,27)); + CPPUNIT_ASSERT_EQUAL( Color(206,206,206), bitmap.GetPixelColor(22,48)); } DECLARE_WW8EXPORT_TEST(testTdf95321, "tdf95321.doc") @@ -596,9 +542,21 @@ DECLARE_WW8EXPORT_TEST(testFdo81102, "fdo81102.doc") DECLARE_WW8EXPORT_TEST(testBnc787942, "bnc787942.doc") { // The frame ended up on the second page instead of first. - // this is on page 1 in Word - parseDump("/root/page[1]/body/txt[4]/anchored"); + parseDump("/root/page[1]/body/txt[4]/anchored"_ostr); + + CPPUNIT_ASSERT_EQUAL(text::WrapTextMode_PARALLEL, getProperty<text::WrapTextMode>(getShape(1), "Surround")); + CPPUNIT_ASSERT_EQUAL(text::RelOrientation::PAGE_FRAME, getProperty<sal_Int16>(getShape(1), "HoriOrientRelation")); +} + +DECLARE_WW8EXPORT_TEST(testTdf133504_wrapNotBeside, "tdf133504_wrapNotBeside.doc") +{ + CPPUNIT_ASSERT_EQUAL(text::WrapTextMode_NONE, getProperty<text::WrapTextMode>(getShape(1), "Surround")); +} + +DECLARE_WW8EXPORT_TEST(testTdf36711_inlineFrames, "tdf36711_inlineFrames.doc") +{ + CPPUNIT_ASSERT_EQUAL(text::RelOrientation::FRAME, getProperty<sal_Int16>(getShape(1), "VertOrientRelation")); } DECLARE_WW8EXPORT_TEST(testLayoutHanging, "fdo68967.doc") @@ -610,10 +568,10 @@ DECLARE_WW8EXPORT_TEST(testLayoutHanging, "fdo68967.doc") DECLARE_WW8EXPORT_TEST(testfdo68963, "fdo68963.doc") { // The problem was that the text was not displayed. - CPPUNIT_ASSERT ( !parseDump("/root/page/body/tab/row[2]/cell[1]/txt/Special", "rText").isEmpty() ); - CPPUNIT_ASSERT_EQUAL( OUString("Topic 1"), parseDump("/root/page/body/tab/row[2]/cell[1]/txt/Special", "rText") ); + CPPUNIT_ASSERT ( !parseDump("/root/page/body/tab/row[2]/cell[1]/txt/SwParaPortion/SwLineLayout/SwFieldPortion"_ostr, "expand"_ostr).isEmpty() ); + CPPUNIT_ASSERT_EQUAL( OUString("Topic 1"), parseDump("/root/page/body/tab/row[2]/cell[1]/txt/SwParaPortion/SwLineLayout/SwFieldPortion"_ostr, "expand"_ostr) ); // all crossreference bookmarks should have a target. Shouldn't be any "Reference source not found" in the xml - CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(-1), parseDump("/root/page/body/txt[24]/Special[2]","rText").indexOf("Reference source not found")); + CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(-1), parseDump("/root/page/body/txt[24]/SwParaPortion/SwLineLayout/SwFieldPortion[2]"_ostr,"expand"_ostr).indexOf("Reference source not found")); } #endif @@ -711,10 +669,10 @@ DECLARE_WW8EXPORT_TEST(testTdf112535, "tdf112535.doc") SwDoc* pDoc = pTextDoc->GetDocShell()->GetDoc(); CPPUNIT_ASSERT(pDoc->GetSpzFrameFormats()); - SwFrameFormats& rFormats = *pDoc->GetSpzFrameFormats(); + auto& rFormats = *pDoc->GetSpzFrameFormats(); CPPUNIT_ASSERT(!rFormats.empty()); - const SwFrameFormat* pFormat = rFormats[0]; + const auto pFormat = rFormats[0]; CPPUNIT_ASSERT(pFormat); // Without the accompanying fix in place, this test would have failed: auto-contour was enabled @@ -725,8 +683,8 @@ DECLARE_WW8EXPORT_TEST(testTdf112535, "tdf112535.doc") DECLARE_WW8EXPORT_TEST(testTdf106291, "tdf106291.doc") { // Table cell was merged vertically instead of horizontally -> had incorrect dimensions - OUString cellWidth = parseDump("/root/page[1]/body/tab/row/cell[1]/infos/bounds", "width"); - OUString cellHeight = parseDump("/root/page[1]/body/tab/row/cell[1]/infos/bounds", "height"); + OUString cellWidth = parseDump("/root/page[1]/body/tab/row/cell[1]/infos/bounds"_ostr, "width"_ostr); + OUString cellHeight = parseDump("/root/page[1]/body/tab/row/cell[1]/infos/bounds"_ostr, "height"_ostr); CPPUNIT_ASSERT_EQUAL(sal_Int32(8650), cellWidth.toInt32()); CPPUNIT_ASSERT(cellHeight.toInt32() > 200); // height might depend on font size } @@ -762,7 +720,7 @@ DECLARE_WW8EXPORT_TEST( testTdf105570, "tdf105570.doc" ) SwDoc* pDoc = pTextDoc->GetDocShell()->GetDoc(); SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell(); SwShellCursor* pShellCursor = pWrtShell->getShellCursor( false ); - SwNodeIndex aIdx = pShellCursor->Start()->nNode; + SwNodeIndex aIdx( pShellCursor->Start()->GetNode() ); // Find first table SwTableNode* pTableNd = aIdx.GetNode().FindTableNode(); @@ -783,10 +741,16 @@ DECLARE_WW8EXPORT_TEST( testTdf105570, "tdf105570.doc" ) CPPUNIT_ASSERT_EQUAL( sal_uInt16(0), pTableNd->GetTable().GetRowsToRepeat() ); } -DECLARE_WW8EXPORT_TEST(testTdf112346, "tdf112346.doc") +CPPUNIT_TEST_FIXTURE(Test, testTdf112346) { - // This was 1, multi-page table was imported as a floating one. - CPPUNIT_ASSERT_EQUAL(0, getShapes()); + auto verify = [this]() { + // Multi-page table was imported as a single page. + CPPUNIT_ASSERT_EQUAL(2, getPages()); + }; + createSwDoc("tdf112346.doc"); + verify(); + saveAndReload("MS Word 97"); + verify(); } DECLARE_WW8EXPORT_TEST(testTdf79639, "tdf79639.doc") @@ -807,9 +771,9 @@ DECLARE_WW8EXPORT_TEST(testTdf122425_2, "tdf122425_2.doc") SwPosFlyFrames aPosFlyFrames = pDoc->GetAllFlyFormats(nullptr, false); // There is one fly frame in the document: the text box CPPUNIT_ASSERT_EQUAL(size_t(1), aPosFlyFrames.size()); - for (const auto& rPosFlyFrame : aPosFlyFrames) + for (const SwPosFlyFrame& rPosFlyFrame : aPosFlyFrames) { - const SwFrameFormat& rFormat = rPosFlyFrame->GetFormat(); + const SwFrameFormat& rFormat = rPosFlyFrame.GetFormat(); const SfxPoolItem* pItem = nullptr; // Check for correct explicitly-set values of UL spacings. Previously this was "DEFAULT", @@ -842,8 +806,7 @@ DECLARE_WW8EXPORT_TEST(testN325936, "n325936.doc") * xray ThisComponent.DrawPage(0).BackColorTransparency */ - sal_Int32 nValue = getProperty< sal_Int32 >(getShape(1), "BackColorTransparency"); - CPPUNIT_ASSERT_EQUAL(sal_Int32(100), nValue); + CPPUNIT_ASSERT_EQUAL(Color(0x000064), getProperty< Color >(getShape(1), "BackColorTransparency")); } DECLARE_WW8EXPORT_TEST(testTscp, "tscp.doc") @@ -885,19 +848,21 @@ DECLARE_WW8EXPORT_TEST(testTscp, "tscp.doc") CPPUNIT_ASSERT_EQUAL(false, static_cast<bool>(xStatements->hasMoreElements())); } -DECLARE_WW8EXPORT_TEST(testFdo45724, "fdo45724.odt") +CPPUNIT_TEST_FIXTURE(Test, testFdo45724) { + loadAndReload("fdo45724.odt"); CPPUNIT_ASSERT_EQUAL(1, getShapes()); CPPUNIT_ASSERT_EQUAL(1, getPages()); // The text and background color of the control shape was not correct. uno::Reference<drawing::XControlShape> xControlShape(getShape(1), uno::UNO_QUERY); uno::Reference<form::validation::XValidatableFormComponent> xComponent(xControlShape->getControl(), uno::UNO_QUERY); - CPPUNIT_ASSERT_EQUAL(COL_WHITE, Color(ColorTransparency, getProperty<sal_uInt32>(xComponent, "BackgroundColor"))); + CPPUNIT_ASSERT_EQUAL(COL_WHITE, getProperty<Color>(xComponent, "BackgroundColor")); CPPUNIT_ASSERT_EQUAL(OUString("xxx"), xComponent->getCurrentValue().get<OUString>()); } -DECLARE_WW8EXPORT_TEST(testTdf136620, "tdf136620.odt") +CPPUNIT_TEST_FIXTURE(Test, testTdf136620) { + loadAndReload("tdf136620.odt"); CPPUNIT_ASSERT_EQUAL(1, getShapes()); CPPUNIT_ASSERT_EQUAL(1, getPages()); @@ -913,8 +878,9 @@ DECLARE_WW8EXPORT_TEST(testTdf136620, "tdf136620.odt") CPPUNIT_ASSERT_EQUAL(sal_Int32(5853), xShape->getSize().Width); } -DECLARE_WW8EXPORT_TEST(testFdo46020, "fdo46020.odt") +CPPUNIT_TEST_FIXTURE(Test, testFdo46020) { + loadAndReload("fdo46020.odt"); CPPUNIT_ASSERT_EQUAL(1, getPages()); // The footnote in that document wasn't exported, check that it is actually exported uno::Reference<text::XFootnotesSupplier> xFootnotesSupplier(mxComponent, uno::UNO_QUERY); @@ -922,26 +888,6 @@ DECLARE_WW8EXPORT_TEST(testFdo46020, "fdo46020.odt") CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xFootnotes->getCount()); } -DECLARE_WW8EXPORT_TEST(testFirstHeaderFooter, "first-header-footer.doc") -{ - // Test import and export of a section's headerf/footerf properties. - - // The document has 6 pages. Note that we don't test if 4 or just 2 page - // styles are created, the point is that layout should be correct. - CPPUNIT_ASSERT_EQUAL(OUString("First page header"), parseDump("/root/page[1]/header/txt/text()")); - CPPUNIT_ASSERT_EQUAL(OUString("First page footer"), parseDump("/root/page[1]/footer/txt/text()")); - CPPUNIT_ASSERT_EQUAL(OUString("Even page header"), parseDump("/root/page[2]/header/txt/text()")); - CPPUNIT_ASSERT_EQUAL(OUString("Even page footer"), parseDump("/root/page[2]/footer/txt/text()")); - CPPUNIT_ASSERT_EQUAL(OUString("Odd page header"), parseDump("/root/page[3]/header/txt/text()")); - CPPUNIT_ASSERT_EQUAL(OUString("Odd page footer"), parseDump("/root/page[3]/footer/txt/text()")); - CPPUNIT_ASSERT_EQUAL(OUString("First page header2"), parseDump("/root/page[4]/header/txt/text()")); - CPPUNIT_ASSERT_EQUAL(OUString("First page footer 2"), parseDump("/root/page[4]/footer/txt/text()")); - CPPUNIT_ASSERT_EQUAL(OUString("Odd page header 2"), parseDump("/root/page[5]/header/txt/text()")); - CPPUNIT_ASSERT_EQUAL(OUString("Odd page footer 2"), parseDump("/root/page[5]/footer/txt/text()")); - CPPUNIT_ASSERT_EQUAL(OUString("Even page header 2"), parseDump("/root/page[6]/header/txt/text()")); - CPPUNIT_ASSERT_EQUAL(OUString("Even page footer 2"), parseDump("/root/page[6]/footer/txt/text()")); -} - DECLARE_WW8EXPORT_TEST(testZoom, "zoom.doc") { uno::Reference<frame::XModel> xModel(mxComponent, uno::UNO_QUERY); @@ -964,28 +910,30 @@ DECLARE_WW8EXPORT_TEST(testZoomType, "zoomtype.doc") DECLARE_WW8EXPORT_TEST(test56513, "fdo56513.doc") { - CPPUNIT_ASSERT_EQUAL(OUString("This is the header of the first section"), parseDump("/root/page[1]/header/txt/text()")); - CPPUNIT_ASSERT_EQUAL(OUString("This is the first page header of the second section"), parseDump("/root/page[2]/header/txt/text()")); - CPPUNIT_ASSERT_EQUAL(OUString("This is the non-first-page header of the second section"), parseDump("/root/page[3]/header/txt/text()")); + CPPUNIT_ASSERT_EQUAL(OUString("This is the header of the first section"), parseDump("/root/page[1]/header/txt/text()"_ostr)); + CPPUNIT_ASSERT_EQUAL(OUString("This is the first page header of the second section"), parseDump("/root/page[2]/header/txt/text()"_ostr)); + CPPUNIT_ASSERT_EQUAL(OUString("This is the non-first-page header of the second section"), parseDump("/root/page[3]/header/txt/text()"_ostr)); } DECLARE_WW8EXPORT_TEST(testNewPageStylesTable, "new-page-styles.doc") { - CPPUNIT_ASSERT_EQUAL(OUString("Sigma Space Performance Goals and Results (Page 1)*"), parseDump("/root/page[1]/header/txt/text()")); - CPPUNIT_ASSERT_EQUAL(OUString("Sigma Space Performance Assessment (Page 2)****"), parseDump("/root/page[2]/header/txt/text()")); - CPPUNIT_ASSERT_EQUAL(OUString("Sigma Space Performance Goals: Next Year (Page 3)*******"), parseDump("/root/page[3]/header/txt/text()")); + CPPUNIT_ASSERT_EQUAL(OUString("Sigma Space Performance Goals and Results (Page 1)*"), parseDump("/root/page[1]/header/txt/text()"_ostr)); + CPPUNIT_ASSERT_EQUAL(OUString("Sigma Space Performance Assessment (Page 2)****"), parseDump("/root/page[2]/header/txt/text()"_ostr)); + CPPUNIT_ASSERT_EQUAL(OUString("Sigma Space Performance Goals: Next Year (Page 3)*******"), parseDump("/root/page[3]/header/txt/text()"_ostr)); } -DECLARE_WW8EXPORT_TEST(testFdo42144, "fdo42144.odt") +CPPUNIT_TEST_FIXTURE(Test, testFdo42144) { + loadAndReload("fdo42144.odt"); CPPUNIT_ASSERT_EQUAL(1, getPages()); // Footer wasn't disabled -- instead empty footer was exported. uno::Reference<beans::XPropertySet> xStyle(getStyles("PageStyles")->getByName("Standard"), uno::UNO_QUERY); CPPUNIT_ASSERT_EQUAL(false, getProperty<bool>(xStyle, "FooterIsOn")); } -DECLARE_WW8EXPORT_TEST(testCharacterBorder, "charborder.odt") +CPPUNIT_TEST_FIXTURE(Test, testCharacterBorder) { + loadAndReload("charborder.odt"); CPPUNIT_ASSERT_EQUAL(1, getPages()); uno::Reference<beans::XPropertySet> xRun(getRun(getParagraph(1),1), uno::UNO_QUERY); // WW8 has just one border attribute (sprmCBrc) for text border so all side has @@ -1021,8 +969,9 @@ DECLARE_WW8EXPORT_TEST(testCharacterBorder, "charborder.odt") } } -DECLARE_WW8EXPORT_TEST(testTdf41542_imagePadding, "tdf41542_imagePadding.odt") +CPPUNIT_TEST_FIXTURE(Test, testTdf41542_imagePadding) { + loadAndReload("tdf41542_imagePadding.odt"); CPPUNIT_ASSERT_EQUAL(3, getShapes()); CPPUNIT_ASSERT_EQUAL(1, getPages()); // borderlessImage - image WITHOUT BORDERS : simulate padding with -crop @@ -1112,8 +1061,9 @@ DECLARE_WW8EXPORT_TEST(testCommentsNested, "comments-nested.doc") CPPUNIT_ASSERT_EQUAL(OUString("Inner"), getProperty<OUString>(xInner, "Content")); } -DECLARE_WW8EXPORT_TEST(testBorderColoursExport, "bordercolours.odt") +CPPUNIT_TEST_FIXTURE(Test, testBorderColoursExport) { + loadAndReload("bordercolours.odt"); CPPUNIT_ASSERT_EQUAL(1, getShapes()); CPPUNIT_ASSERT_EQUAL(1, getPages()); // This is very close to testBorderColours in ww8import.cxx, but for export @@ -1239,8 +1189,9 @@ DECLARE_WW8EXPORT_TEST(testBorderColoursExport, "bordercolours.odt") #endif } -DECLARE_WW8EXPORT_TEST(testRedlineExport1, "redline-export-1.odt") +CPPUNIT_TEST_FIXTURE(Test, testRedlineExport1) { + loadAndReload("redline-export-1.odt"); CPPUNIT_ASSERT_EQUAL(1, getPages()); uno::Reference<text::XTextRange> xParagraph = getParagraph(1); uno::Reference<container::XEnumerationAccess> xRunEnumAccess(xParagraph, uno::UNO_QUERY); @@ -1253,15 +1204,17 @@ DECLARE_WW8EXPORT_TEST(testRedlineExport1, "redline-export-1.odt") } } -DECLARE_WW8EXPORT_TEST(testRedlineExport2, "redline-export-2.odt") +CPPUNIT_TEST_FIXTURE(Test, testRedlineExport2) { + loadAndReload("redline-export-2.odt"); CPPUNIT_ASSERT_EQUAL(1, getPages()); //there must be redline information on the first portion of the third paragraph before and after reloading CPPUNIT_ASSERT_EQUAL(true, hasProperty(getRun(getParagraph(3), 1), "RedlineType")); } -DECLARE_WW8EXPORT_TEST(testRedlineExport3, "redline-export-3.odt") +CPPUNIT_TEST_FIXTURE(Test, testRedlineExport3) { + loadAndReload("redline-export-3.odt"); CPPUNIT_ASSERT_EQUAL(1, getPages()); //there must be redline information just on the para-break boundary between para one and two CPPUNIT_ASSERT_EQUAL(false, hasProperty(getRun(getParagraph(1), 1), "RedlineType")); @@ -1270,13 +1223,14 @@ DECLARE_WW8EXPORT_TEST(testRedlineExport3, "redline-export-3.odt") CPPUNIT_ASSERT_EQUAL(false, hasProperty(getRun(getParagraph(2), 2), "RedlineType")); } -DECLARE_WW8EXPORT_TEST(testCellBgColor, "cell-bg-color.odt") +CPPUNIT_TEST_FIXTURE(Test, testCellBgColor) { + loadAndReload("cell-bg-color.odt"); CPPUNIT_ASSERT_EQUAL(1, getPages()); 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); - CPPUNIT_ASSERT_EQUAL(sal_Int32(0xCC0000), getProperty<sal_Int32>(xTable->getCellByName("A1"), "BackColor")); + CPPUNIT_ASSERT_EQUAL(Color(0xCC0000), getProperty<Color>(xTable->getCellByName("A1"), "BackColor")); } DECLARE_WW8EXPORT_TEST(testBnc636128, "bnc636128.doc") @@ -1381,7 +1335,7 @@ DECLARE_WW8EXPORT_TEST(testRES_MIRROR_GRAPH_BOTH, "tdf56321_flipImage_both.doc") SwDoc* pDoc = pTextDoc->GetDocShell()->GetDoc(); CPPUNIT_ASSERT(pDoc); - for (int n = 0; ; n++) + for (SwNodeOffset n(0); ; n++) { SwNode* pNode = pDoc->GetNodes()[ n ]; if (SwGrfNode *pGrfNode = pNode->GetGrfNode()) @@ -1392,8 +1346,9 @@ DECLARE_WW8EXPORT_TEST(testRES_MIRROR_GRAPH_BOTH, "tdf56321_flipImage_both.doc") } } -DECLARE_WW8EXPORT_TEST(testCommentExport, "comment-export.odt") +CPPUNIT_TEST_FIXTURE(Test, testCommentExport) { + loadAndReload("comment-export.odt"); CPPUNIT_ASSERT_EQUAL(1, getPages()); struct TextPortionInfo { OUString sKind; @@ -1456,63 +1411,92 @@ DECLARE_WW8EXPORT_TEST(testCommentExport, "comment-export.odt") CPPUNIT_ASSERT_EQUAL(sNames[aTextPortions[i].nAnnotationID], xBookmark->getName()); } } + + // tdf#139759 import character highlight and shade for comment text + uno::Reference<text::XTextFieldsSupplier> xTextFieldsSupplier(mxComponent, uno::UNO_QUERY); + auto xFieldsAccess(xTextFieldsSupplier->getTextFields()); + uno::Reference<container::XEnumeration> xFields(xFieldsAccess->createEnumeration()); + uno::Reference<text::XTextField> xField(xFields->nextElement(), uno::UNO_QUERY); + uno::Reference<text::XText> xText = getProperty<uno::Reference<text::XText>>(xField, "TextRange"); + uno::Reference<text::XTextRange> xParagraph = getParagraphOfText(1, xText); + CPPUNIT_ASSERT_EQUAL(COL_WHITE, getProperty<Color>(getRun(xParagraph, 1), "CharBackColor")); } #if HAVE_MORE_FONTS -DECLARE_WW8EXPORT_TEST(testTableKeep, "tdf91083.odt") +CPPUNIT_TEST_FIXTURE(Test, testTableKeep) { + loadAndReload("tdf91083.odt"); CPPUNIT_ASSERT_EQUAL(7, getPages()); //emulate table "keep with next" -do not split table - CPPUNIT_ASSERT_EQUAL( OUString("Row 1"), parseDump("/root/page[3]/body/tab[1]/row[2]/cell[1]/txt[1]") ); - CPPUNIT_ASSERT_EQUAL( OUString("Row 1"), parseDump("/root/page[6]/body/tab[1]/row[2]/cell[1]/txt[1]") ); + CPPUNIT_ASSERT_EQUAL( OUString("Row 1"), parseDump("/root/page[3]/body/tab[1]/row[2]/cell[1]/txt[1]"_ostr) ); + CPPUNIT_ASSERT_EQUAL( OUString("Row 1"), parseDump("/root/page[6]/body/tab[1]/row[2]/cell[1]/txt[1]"_ostr) ); } #endif -DECLARE_WW8EXPORT_TEST(tesTdf91083_tableKeep2, "tdf91083_tableKeep2.odt") +CPPUNIT_TEST_FIXTURE(Test, tesTdf91083_tableKeep2) { + loadAndReload("tdf91083_tableKeep2.odt"); //emulate table "keep with next" - split large row in order to keep with previous paragraph CPPUNIT_ASSERT_EQUAL_MESSAGE("Table doesn't split, so it starts on page 2", - OUString("0"), parseDump("count(//page[1]//tab)") ); + OUString("0"), parseDump("count(//page[1]//tab)"_ostr) ); CPPUNIT_ASSERT_EQUAL_MESSAGE("Page 2 starts with a paragraph/title, not a table", - OUString("KeepWithNext"), parseDump("//page[2]/body/txt[1]") ); + OUString("KeepWithNext"), parseDump("//page[2]/body/txt[1]"_ostr) ); CPPUNIT_ASSERT_EQUAL_MESSAGE("Table sticks with previous paragraph, so it starts on page 2", - OUString("1"), parseDump("count(//page[2]//tab)") ); + OUString("1"), parseDump("count(//page[2]//tab)"_ostr) ); CPPUNIT_ASSERT_MESSAGE("Row itself splits, not the table at a row boundary", - "Cell 2" != parseDump("//page[3]//tab//row[2]/cell[1]/txt[1]") ); + "Cell 2" != parseDump("//page[3]//tab//row[2]/cell[1]/txt[1]"_ostr) ); } -DECLARE_WW8EXPORT_TEST(tesTdf91083_tableKeep3, "tdf91083_tableKeep3.odt") +CPPUNIT_TEST_FIXTURE(Test, tesTdf91083_tableKeep3) { + loadAndReload("tdf91083_tableKeep3.odt"); CPPUNIT_ASSERT_EQUAL(3, getPages()); //emulate table "keep with next" - split single row table in order to keep with previous paragraph CPPUNIT_ASSERT_EQUAL_MESSAGE("Table doesn't split, so it starts on page 2", - OUString("0"), parseDump("count(//page[1]//tab)") ); + OUString("0"), parseDump("count(//page[1]//tab)"_ostr) ); CPPUNIT_ASSERT_EQUAL_MESSAGE("Table sticks with previous paragraph, so it starts on page 2", - OUString("1"), parseDump("count(//page[2]//tab)") ); + OUString("1"), parseDump("count(//page[2]//tab)"_ostr) ); } DECLARE_WW8EXPORT_TEST(testTdf76349_textboxMargins, "tdf76349_textboxMargins.doc") { // textboxes without borders were losing their spacing items in round-tripping - CPPUNIT_ASSERT( 0 < parseDump("/root/page/body/txt/anchored/fly/infos/prtBounds", "left").toInt32() ); + CPPUNIT_ASSERT( 0 < parseDump("/root/page/body/txt/anchored/fly/infos/prtBounds"_ostr, "left"_ostr).toInt32() ); uno::Reference<drawing::XShape> xShape = getShape(1); CPPUNIT_ASSERT_EQUAL_MESSAGE("Textbox background color", Color(0xD8, 0xD8, 0xD8), getProperty<Color>(xShape, "BackColor")); } -DECLARE_WW8EXPORT_TEST(testMoveRange, "fdo66304-1.odt") +CPPUNIT_TEST_FIXTURE(Test, testMoveRange) { + loadAndReload("fdo66304-1.odt"); //the save must survive without asserting } -DECLARE_WW8EXPORT_TEST(testClearFramePams, "tdf46441-2.odt") +CPPUNIT_TEST_FIXTURE(Test, testClearFramePams) { + loadAndReload("tdf46441-2.odt"); CPPUNIT_ASSERT_EQUAL(1, getPages()); //the save must survive without asserting } -DECLARE_WW8EXPORT_TEST(testTdf94386, "tdf94386.odt") +CPPUNIT_TEST_FIXTURE(Test, testTdf94386) { + createSwDoc("tdf94386.odt"); + SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument *>(mxComponent.get()); + CPPUNIT_ASSERT(pTextDoc); + SwWrtShell* pWrtShell = pTextDoc->GetDocShell()->GetWrtShell(); + + // emulate the behavior from tdf#94386 - insert an envelope to the + // document + { + SfxItemSet aSet(pWrtShell->GetView().GetCurShell()->GetPool(), svl::Items<FN_ENVELOP, FN_ENVELOP>); + aSet.Put(SwEnvItem()); + SfxRequest aRequest(FN_ENVELOP, SfxCallMode::SYNCHRON, aSet); + SW_MOD()->ExecOther(aRequest); + } + saveAndReload("MS Word 97"); + // check that the first and next page use different page styles uno::Reference<frame::XModel> xModel(mxComponent, uno::UNO_QUERY); uno::Reference<text::XTextViewCursorSupplier> xTextViewCursorSupplier( @@ -1538,8 +1522,9 @@ DECLARE_WW8EXPORT_TEST(testTdf94386, "tdf94386.odt") CPPUNIT_ASSERT((fSize.Height != lSize.Height)); } -DECLARE_WW8EXPORT_TEST(testTdf99474, "tdf99474.odt") +CPPUNIT_TEST_FIXTURE(Test, testTdf99474) { + loadAndReload("tdf99474.odt"); CPPUNIT_ASSERT_EQUAL(1, getPages()); // The bullet colour of paragraph #3 should be COL_AUTO auto xPara = getParagraph(3); @@ -1563,8 +1548,18 @@ DECLARE_WW8EXPORT_TEST(testTdf99474, "tdf99474.odt") uno::Reference<beans::XPropertySet> xStyle( getStyles("CharacterStyles")->getByName(charStyleName), uno::UNO_QUERY); - Color charColor(ColorTransparency, getProperty<util::Color>(xStyle, "CharColor")); - CPPUNIT_ASSERT_EQUAL(sal_uInt32(COL_AUTO), sal_uInt32(charColor)); + CPPUNIT_ASSERT_EQUAL(COL_AUTO, getProperty<Color>(xStyle, "CharColor")); +} + +DECLARE_WW8EXPORT_TEST(testContinuousSectionsNoPageBreak, "continuous-sections.doc") +{ + SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument *>(mxComponent.get()); + CPPUNIT_ASSERT(pTextDoc); + SwDoc* pDoc = pTextDoc->GetDocShell()->GetDoc(); + CPPUNIT_ASSERT(pDoc); + + // Continuous section breaks should not add new pages + CPPUNIT_ASSERT_EQUAL(size_t(1), pDoc->GetPageDescCnt()); } CPPUNIT_PLUGIN_IMPLEMENT(); diff --git a/sw/qa/extras/ww8export/ww8export2.cxx b/sw/qa/extras/ww8export/ww8export2.cxx index 5b60fb1b87be..0a8693489344 100644 --- a/sw/qa/extras/ww8export/ww8export2.cxx +++ b/sw/qa/extras/ww8export/ww8export2.cxx @@ -26,36 +26,40 @@ #include <com/sun/star/text/XEndnotesSupplier.hpp> #include <svx/svdpage.hxx> +#include <o3tl/string_view.hxx> #include <ftninfo.hxx> #include <drawdoc.hxx> #include <IDocumentDrawModelAccess.hxx> #include <docsh.hxx> #include <unotxdoc.hxx> +#include <IDocumentLayoutAccess.hxx> +#include <rootfrm.hxx> +#include <pagefrm.hxx> +#include <sortedobjs.hxx> +#include <cntfrm.hxx> +#include <anchoredobject.hxx> +#include <tabfrm.hxx> +#include <flyfrms.hxx> class Test : public SwModelTestBase { public: Test() : SwModelTestBase("/sw/qa/extras/ww8export/data/", "MS Word 97") {} - - bool mustTestImportOf(const char* filename) const override - { - // If the testcase is stored in some other format, it's pointless to test. - return OString(filename).endsWith(".doc"); - } - }; + DECLARE_WW8EXPORT_TEST(testTdf99120, "tdf99120.doc") { - CPPUNIT_ASSERT_EQUAL(OUString("Section 1, odd."), parseDump("/root/page[1]/header/txt/text()")); - CPPUNIT_ASSERT_EQUAL(OUString("Section 1, even."), parseDump("/root/page[2]/header/txt/text()")); + CPPUNIT_ASSERT_EQUAL(OUString("Section 1, odd."), parseDump("/root/page[1]/header/txt/text()"_ostr)); + CPPUNIT_ASSERT_EQUAL(OUString("Section 1, even."), parseDump("/root/page[2]/header/txt/text()"_ostr)); // This failed: the header was empty on the 3rd page, as the first page header was shown. - CPPUNIT_ASSERT_EQUAL(OUString("Section 2, odd."), parseDump("/root/page[3]/header/txt/text()")); - CPPUNIT_ASSERT_EQUAL(OUString("Section 2, even."), parseDump("/root/page[4]/header/txt/text()")); + CPPUNIT_ASSERT_EQUAL(OUString("Section 2, odd."), parseDump("/root/page[3]/header/txt/text()"_ostr)); + CPPUNIT_ASSERT_EQUAL(OUString("Section 2, even."), parseDump("/root/page[4]/header/txt/text()"_ostr)); } -DECLARE_WW8EXPORT_TEST(testTdf41542_borderlessPadding, "tdf41542_borderlessPadding.odt") +CPPUNIT_TEST_FIXTURE(Test, testTdf41542_borderlessPadding) { + loadAndReload("tdf41542_borderlessPadding.odt"); // the page style's borderless padding should force this to 3 pages, not 1 CPPUNIT_ASSERT_EQUAL( 3, getPages() ); } @@ -81,29 +85,37 @@ DECLARE_WW8EXPORT_TEST(testTdf55528_relativeTableWidth, "tdf55528_relativeTableW CPPUNIT_ASSERT_EQUAL_MESSAGE("Table relative width percent", sal_Int16(98), getProperty<sal_Int16>(xTable, "RelativeWidth")); } -DECLARE_WW8EXPORT_TEST(testTdf128700_relativeTableWidth, "tdf128700_relativeTableWidth.doc") +CPPUNIT_TEST_FIXTURE(Test, testTdf128700_relativeTableWidth) { - uno::Reference<text::XTextTablesSupplier> xTextTablesSupplier(mxComponent, uno::UNO_QUERY); - uno::Reference<container::XIndexAccess> xTables(xTextTablesSupplier->getTextTables(), uno::UNO_QUERY); - uno::Reference<text::XTextTable> xTable(xTables->getByIndex(0), uno::UNO_QUERY); - - // Since the table has been converted into a floating frame, the relative width either needed to be transferred - // onto the frame, or else just thrown out. Otherwise it becomes relative to the size of the frame. - CPPUNIT_ASSERT_EQUAL_MESSAGE("Floated table can't use relative width", sal_Int16(0), getProperty<sal_Int16>(xTable, "RelativeWidth")); + auto verify = [this]() { + uno::Reference<text::XTextTablesSupplier> xTextTablesSupplier(mxComponent, uno::UNO_QUERY); + uno::Reference<container::XIndexAccess> xTables(xTextTablesSupplier->getTextTables(), uno::UNO_QUERY); + uno::Reference<text::XTextTable> xTable(xTables->getByIndex(0), uno::UNO_QUERY); + + // Since the table has been converted into a floating frame, the relative width either needed to be transferred + // onto the frame, or else just thrown out. Otherwise it becomes relative to the size of the frame. + CPPUNIT_ASSERT_EQUAL_MESSAGE("Floated table can't use relative width", sal_Int16(0), getProperty<sal_Int16>(xTable, "RelativeWidth")); + }; + // This also resulted in a layout loop when flys were allowed to split in footers. + createSwDoc("tdf128700_relativeTableWidth.doc"); + verify(); + saveAndReload("MS Word 97"); + verify(); } -DECLARE_WW8EXPORT_TEST(testTdf116436_tableBackground, "tdf116436_tableBackground.odt") +CPPUNIT_TEST_FIXTURE(Test, testTdf116436_tableBackground) { + loadAndReload("tdf116436_tableBackground.odt"); CPPUNIT_ASSERT_EQUAL(1, getPages()); uno::Reference<text::XTextTablesSupplier> xTextTablesSupplier(mxComponent, uno::UNO_QUERY); uno::Reference<container::XIndexAccess> xTables(xTextTablesSupplier->getTextTables(), uno::UNO_QUERY); uno::Reference<text::XTextTable> xTable(xTables->getByIndex(0), uno::UNO_QUERY); uno::Reference<table::XCell> xCell = xTable->getCellByName("A1"); - CPPUNIT_ASSERT_EQUAL(sal_Int32(0xF8DF7C), getProperty<sal_Int32>(xCell, "BackColor")); + CPPUNIT_ASSERT_EQUAL(Color(0xF8DF7C), getProperty<Color>(xCell, "BackColor")); xCell.set(xTable->getCellByName("A6")); - CPPUNIT_ASSERT_EQUAL(sal_Int32(0x81D41A), getProperty<sal_Int32>(xCell, "BackColor")); + CPPUNIT_ASSERT_EQUAL(Color(0x81D41A), getProperty<Color>(xCell, "BackColor")); xCell.set(xTable->getCellByName("B6")); - CPPUNIT_ASSERT_EQUAL(sal_Int32(0xFFFBCC), getProperty<sal_Int32>(xCell, "BackColor")); + CPPUNIT_ASSERT_EQUAL(Color(0xFFFBCC), getProperty<Color>(xCell, "BackColor")); } DECLARE_WW8EXPORT_TEST(testTdf37153, "tdf37153_considerWrapOnObjPos.doc") @@ -117,23 +129,24 @@ DECLARE_WW8EXPORT_TEST(testTdf37153, "tdf37153_considerWrapOnObjPos.doc") //For MSO compatibility, the image should be at the top of the cell, not at the bottom - despite VertOrientation::BOTTOM xmlDocUniquePtr pXmlDoc = parseLayoutDump(); - sal_Int32 nFlyTop = getXPath(pXmlDoc, "/root/page/body/tab/row/cell[1]/txt/anchored/fly/infos/bounds", "top").toInt32(); + sal_Int32 nFlyTop = getXPath(pXmlDoc, "/root/page/body/tab/row/cell[1]/txt/anchored/fly/infos/bounds"_ostr, "top"_ostr).toInt32(); CPPUNIT_ASSERT_MESSAGE("FlyTop should be 3820, not 6623", nFlyTop < 4000); - sal_Int32 nTextTop = getXPath(pXmlDoc, "/root/page/body/tab/row/cell[2]/txt[1]/infos/bounds", "top").toInt32(); + sal_Int32 nTextTop = getXPath(pXmlDoc, "/root/page/body/tab/row/cell[2]/txt[1]/infos/bounds"_ostr, "top"_ostr).toInt32(); CPPUNIT_ASSERT_MESSAGE("TextTop should be 5388", nTextTop > 4000); } DECLARE_WW8EXPORT_TEST(testTdf49102_mergedCellNumbering, "tdf49102_mergedCellNumbering.doc") { - CPPUNIT_ASSERT_EQUAL( OUString("2."), parseDump("/root/page/body/tab/row[4]/cell/txt/Special[@nType='PortionType::Number']", "rText") ); + CPPUNIT_ASSERT_EQUAL( OUString("2."), parseDump("/root/page/body/tab/row[4]/cell/txt/SwParaPortion/SwLineLayout/child::*[@type='PortionType::Number']"_ostr, "expand"_ostr) ); } -DECLARE_WW8EXPORT_TEST(testTdf55427_footnote2endnote, "tdf55427_footnote2endnote.odt") +CPPUNIT_TEST_FIXTURE(Test, testTdf55427_footnote2endnote) { + loadAndReload("tdf55427_footnote2endnote.odt"); uno::Reference<beans::XPropertySet> xPageStyle(getStyles("ParagraphStyles")->getByName("Footnote"), uno::UNO_QUERY); - CPPUNIT_ASSERT_EQUAL_MESSAGE( "Footnote style is rose color", sal_Int32(0xFF007F), getProperty< sal_Int32 >(xPageStyle, "CharColor") ); + CPPUNIT_ASSERT_EQUAL_MESSAGE( "Footnote style is rose color", Color(0xFF007F), getProperty< Color >(xPageStyle, "CharColor")); xPageStyle.set(getStyles("ParagraphStyles")->getByName("Endnote"), uno::UNO_QUERY); - CPPUNIT_ASSERT_EQUAL_MESSAGE( "Endnote style is cyan3 color", sal_Int32(0x2BD0D2), getProperty< sal_Int32 >(xPageStyle, "CharColor") ); + CPPUNIT_ASSERT_EQUAL_MESSAGE( "Endnote style is cyan3 color", Color(0x2BD0D2), getProperty< Color >(xPageStyle, "CharColor")); SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument*>(mxComponent.get()); CPPUNIT_ASSERT(pTextDoc); @@ -154,7 +167,7 @@ DECLARE_WW8EXPORT_TEST(testTdf55427_footnote2endnote, "tdf55427_footnote2endnote xEndnotes->getByIndex(0) >>= xEndnoteText; // ODT footnote-at-document-end's closest DOC match is an endnote, so the two imports will not exactly match by design. - if (!mbExported) + if (!isExported()) { CPPUNIT_ASSERT_EQUAL_MESSAGE( "original footnote count", sal_Int32(5), xFootnotes->getCount() ); CPPUNIT_ASSERT_EQUAL_MESSAGE( "original endnote count", sal_Int32(1), xEndnotes->getCount() ); @@ -240,8 +253,9 @@ DECLARE_WW8EXPORT_TEST(testTdf112517_maxSprms, "tdf112517_maxSprms.doc") CPPUNIT_ASSERT_EQUAL( sal_Int32(28), xTable->getRows()->getCount() ); } -DECLARE_WW8EXPORT_TEST(testTdf108448_endNote, "tdf108448_endNote.odt") +CPPUNIT_TEST_FIXTURE(Test, testTdf108448_endNote) { + loadAndReload("tdf108448_endNote.odt"); CPPUNIT_ASSERT_EQUAL(1, getPages()); uno::Reference<text::XEndnotesSupplier> xEndnotesSupplier(mxComponent, uno::UNO_QUERY); uno::Reference<container::XIndexAccess> xEndnotes = xEndnotesSupplier->getEndnotes(); @@ -251,8 +265,9 @@ DECLARE_WW8EXPORT_TEST(testTdf108448_endNote, "tdf108448_endNote.odt") CPPUNIT_ASSERT_EQUAL_MESSAGE( "Number of paragraphs in Endnote i", 1, getParagraphs(xEndnote) ); } -DECLARE_WW8EXPORT_TEST(testTdf106062_nonHangingFootnote, "tdf106062_nonHangingFootnote.odt") +CPPUNIT_TEST_FIXTURE(Test, testTdf106062_nonHangingFootnote) { + loadAndReload("tdf106062_nonHangingFootnote.odt"); CPPUNIT_ASSERT_EQUAL(1, getPages()); uno::Reference<text::XFootnotesSupplier> xFootnotesSupplier(mxComponent, uno::UNO_QUERY); uno::Reference<container::XIndexAccess> xFootnotes = xFootnotesSupplier->getFootnotes(); @@ -261,8 +276,9 @@ DECLARE_WW8EXPORT_TEST(testTdf106062_nonHangingFootnote, "tdf106062_nonHangingFo CPPUNIT_ASSERT_MESSAGE( "Footnote starts with a tab", xTextRange->getString().startsWith("\t") ); } -DECLARE_WW8EXPORT_TEST(testTdf116570_exportFootnote, "tdf116570_exportFootnote.odt") +CPPUNIT_TEST_FIXTURE(Test, testTdf116570_exportFootnote) { + loadAndReload("tdf116570_exportFootnote.odt"); CPPUNIT_ASSERT_EQUAL(1, getPages()); uno::Reference<text::XFootnotesSupplier> xFootnotesSupplier(mxComponent, uno::UNO_QUERY); uno::Reference<container::XIndexAccess> xFootnotes = xFootnotesSupplier->getFootnotes(); @@ -272,46 +288,64 @@ DECLARE_WW8EXPORT_TEST(testTdf116570_exportFootnote, "tdf116570_exportFootnote.o CPPUNIT_ASSERT_EQUAL_MESSAGE( "Number of paragraphs in first footnote", 2, getParagraphs(xFootnoteText) ); } -DECLARE_WW8EXPORT_TEST(testTdf80635_pageRightRTL, "tdf80635_pageRightRTL.doc") +CPPUNIT_TEST_FIXTURE(Test, testTdf80635_pageRightRTL) { - // tdf#80635 - transfer the float orientation to the table. - uno::Reference<text::XTextTablesSupplier> xTextTablesSupplier(mxComponent, uno::UNO_QUERY); - uno::Reference<container::XIndexAccess> xTables(xTextTablesSupplier->getTextTables(), uno::UNO_QUERY); - uno::Reference<text::XTextTable> xTable(xTables->getByIndex(0), uno::UNO_QUERY); - CPPUNIT_ASSERT_EQUAL_MESSAGE("Horizontal Orientation", text::HoriOrientation::LEFT_AND_WIDTH, getProperty<sal_Int16>(xTable, "HoriOrient")); - CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Table Indent", tools::Long(3500), getProperty<tools::Long>(xTable, "LeftMargin"), 100); - CPPUNIT_ASSERT_EQUAL_MESSAGE("Did you fix me? Text probably should wrap here", 2, getPages() ); - // If so, replace test with the table set to a greater preferred width so that the text shouldn't wrap + auto verify = [this]() { + // tdf#80635 - assert horizontal position of the table. + uno::Reference<drawing::XShape> xFly = getShape(1); + CPPUNIT_ASSERT_EQUAL(text::RelOrientation::PAGE_FRAME, getProperty<sal_Int16>(xFly, "HoriOrientRelation")); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Horizontal Orientation", text::HoriOrientation::RIGHT, getProperty<sal_Int16>(xFly, "HoriOrient")); + CPPUNIT_ASSERT_EQUAL_MESSAGE("text probably does not wrap here", 1, getPages()); + }; + createSwDoc("tdf80635_pageRightRTL.doc"); + verify(); + saveAndReload("MS Word 97"); + verify(); } -DECLARE_WW8EXPORT_TEST(testTdf80635_marginRTL, "tdf80635_marginRightRTL.doc") +CPPUNIT_TEST_FIXTURE(Test, testTdf80635_marginRTL) { - // tdf#80635 - transfer the float orientation to the table. - uno::Reference<text::XTextTablesSupplier> xTextTablesSupplier(mxComponent, uno::UNO_QUERY); - uno::Reference<container::XIndexAccess> xTables(xTextTablesSupplier->getTextTables(), uno::UNO_QUERY); - uno::Reference<text::XTextTable> xTable(xTables->getByIndex(0), uno::UNO_QUERY); - if ( !mbExported ) - CPPUNIT_ASSERT_EQUAL_MESSAGE("Horizontal Orientation", text::HoriOrientation::RIGHT, getProperty<sal_Int16>(xTable, "HoriOrient")); + auto verify = [this]() { + // tdf#80635 - assert the horizontal orientation of the table. + uno::Reference<drawing::XShape> xFly = getShape(1); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Horizontal Orientation", text::HoriOrientation::RIGHT, getProperty<sal_Int16>(xFly, "HoriOrient")); + }; + createSwDoc("tdf80635_marginRightRTL.doc"); + verify(); + saveAndReload("MS Word 97"); + verify(); } -DECLARE_WW8EXPORT_TEST(testTdf80635_marginLeft, "tdf80635_marginLeft.doc") +CPPUNIT_TEST_FIXTURE(Test, testTdf80635_marginLeft) { - // tdf#80635 - transfer the float orientation to the table. - uno::Reference<text::XTextTablesSupplier> xTextTablesSupplier(mxComponent, uno::UNO_QUERY); - uno::Reference<container::XIndexAccess> xTables(xTextTablesSupplier->getTextTables(), uno::UNO_QUERY); - uno::Reference<text::XTextTable> xTable(xTables->getByIndex(0), uno::UNO_QUERY); - // This was just the GetMinLeft of -199 - CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Table Indent", tools::Long(-2950), getProperty<tools::Long>(xTable, "LeftMargin"), 100); + auto verify = [this]() { + // tdf#80635 - assert horizontal position of the table. + uno::Reference<text::XTextTablesSupplier> xTextTablesSupplier(mxComponent, uno::UNO_QUERY); + uno::Reference<container::XIndexAccess> xTables(xTextTablesSupplier->getTextTables(), uno::UNO_QUERY); + uno::Reference<text::XTextTable> xTable(xTables->getByIndex(0), uno::UNO_QUERY); + CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Table Indent", tools::Long(0), getProperty<tools::Long>(xTable, "LeftMargin"), 100); + uno::Reference<drawing::XShape> xFly = getShape(1); + CPPUNIT_ASSERT_EQUAL(sal_Int32(-2958), getProperty<sal_Int32>(xFly, "HoriOrientPosition")); + }; + createSwDoc("tdf80635_marginLeft.doc"); + verify(); + saveAndReload("MS Word 97"); + verify(); } -DECLARE_WW8EXPORT_TEST(testTdf80635_pageLeft, "tdf80635_pageLeft.doc") +CPPUNIT_TEST_FIXTURE(Test, testTdf80635_pageLeft) { - // tdf#80635 - transfer the float orientation to the table. - uno::Reference<text::XTextTablesSupplier> xTextTablesSupplier(mxComponent, uno::UNO_QUERY); - uno::Reference<container::XIndexAccess> xTables(xTextTablesSupplier->getTextTables(), uno::UNO_QUERY); - uno::Reference<text::XTextTable> xTable(xTables->getByIndex(0), uno::UNO_QUERY); - // This was just the GetMinLeft of -199 - CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Table Indent", tools::Long(-2750), getProperty<tools::Long>(xTable, "LeftMargin"), 100); + auto verify = [this]() { + // tdf#80635 - assert horizontal orient relation of the table. + uno::Reference<drawing::XShape> xFly = getShape(1); + CPPUNIT_ASSERT_EQUAL(text::RelOrientation::PAGE_FRAME, getProperty<sal_Int16>(xFly, "HoriOrientRelation")); + CPPUNIT_ASSERT_EQUAL(text::HoriOrientation::NONE, getProperty<sal_Int16>(xFly, "HoriOrient")); + CPPUNIT_ASSERT_EQUAL(sal_Int32(-189), getProperty<sal_Int32>(xFly, "HoriOrientPosition")); + }; + createSwDoc("tdf80635_pageLeft.doc"); + verify(); + saveAndReload("MS Word 97"); + verify(); } DECLARE_WW8EXPORT_TEST(testTdf99197_defaultLTR, "tdf99197_defaultLTR.doc") @@ -323,16 +357,34 @@ DECLARE_WW8EXPORT_TEST(testTdf99197_defaultLTR, "tdf99197_defaultLTR.doc") text::WritingMode2::LR_TB, getProperty<sal_Int16>(getParagraph(2), "WritingMode") ); } -DECLARE_WW8EXPORT_TEST(testTdf107773, "tdf107773.doc") +CPPUNIT_TEST_FIXTURE(Test, testTdf107773) { - // This was 1, multi-page table was imported as a floating one. - CPPUNIT_ASSERT_EQUAL(0, getShapes()); - - // tdf#80635 - transfer the float orientation to the table. - uno::Reference<text::XTextTablesSupplier> xTextTablesSupplier(mxComponent, uno::UNO_QUERY); - uno::Reference<container::XIndexAccess> xTables(xTextTablesSupplier->getTextTables(), uno::UNO_QUERY); - uno::Reference<text::XTextTable> xTable(xTables->getByIndex(0), uno::UNO_QUERY); - CPPUNIT_ASSERT_EQUAL_MESSAGE("Horizontal Orientation", text::HoriOrientation::CENTER, getProperty<sal_Int16>(xTable, "HoriOrient")); + auto verify = [this]() { + // This failed, multi-page table was imported as a non-split frame. + SwDoc* pDoc = getSwDoc(); + SwRootFrame* pLayout = pDoc->getIDocumentLayoutAccess().GetCurrentLayout(); + auto pPage1 = dynamic_cast<SwPageFrame*>(pLayout->Lower()); + CPPUNIT_ASSERT(pPage1); + // pPage1 has no sorted (floating) objections. + CPPUNIT_ASSERT(pPage1->GetSortedObjs()); + const SwSortedObjs& rPage1Objs = *pPage1->GetSortedObjs(); + CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), rPage1Objs.size()); + auto pPage1Fly = dynamic_cast<SwFlyAtContentFrame*>(rPage1Objs[0]); + CPPUNIT_ASSERT(pPage1Fly); + auto pTab1 = dynamic_cast<SwTabFrame*>(pPage1Fly->GetLower()); + CPPUNIT_ASSERT(pTab1); + // This failed, the split fly containing a table was exported back to DOC as shape+table, + // which can't split. + CPPUNIT_ASSERT(pTab1->HasFollow()); + + // tdf#80635 - assert the horizontal orientation. + const SwFormatHoriOrient& rFormatHoriOrient = pPage1Fly->GetFormat()->GetHoriOrient(); + CPPUNIT_ASSERT_EQUAL(css::text::HoriOrientation::CENTER, rFormatHoriOrient.GetHoriOrient()); + }; + createSwDoc("tdf107773.doc"); + verify(); + saveAndReload("MS Word 97"); + verify(); } DECLARE_WW8EXPORT_TEST(testTdf112074_RTLtableJustification, "tdf112074_RTLtableJustification.doc") @@ -360,8 +412,9 @@ DECLARE_WW8EXPORT_TEST(testTdf121110_absJustify, "tdf121110_absJustify.doc") CPPUNIT_ASSERT_EQUAL( style::ParagraphAdjust_LEFT, static_cast<style::ParagraphAdjust>(getProperty<sal_Int16>(getParagraph(3), "ParaAdjust")) ); } -DECLARE_WW8EXPORT_TEST(testTdf106174_rtlParaAlign, "tdf106174_rtlParaAlign.docx") +CPPUNIT_TEST_FIXTURE(Test, testTdf106174_rtlParaAlign) { + loadAndReload("tdf106174_rtlParaAlign.docx"); CPPUNIT_ASSERT_EQUAL(sal_Int16(style::ParagraphAdjust_CENTER), getProperty<sal_Int16>(getParagraph(1), "ParaAdjust")); CPPUNIT_ASSERT_EQUAL(sal_Int16(style::ParagraphAdjust_CENTER), getProperty<sal_Int16>(getParagraph(2), "ParaAdjust")); uno::Reference<beans::XPropertySet> xPropertySet(getStyles("ParagraphStyles")->getByName("Another paragraph aligned to right"), uno::UNO_QUERY); @@ -387,19 +440,11 @@ DECLARE_WW8EXPORT_TEST(testTdf119232_startEvenPage, "tdf119232_startEvenPage.doc DECLARE_WW8EXPORT_TEST(testTdf104805, "tdf104805.doc") { - uno::Reference<beans::XPropertySet> xPropertySet(getStyles("NumberingStyles")->getByName("WW8Num1"), uno::UNO_QUERY); - uno::Reference<container::XIndexAccess> xLevels(xPropertySet->getPropertyValue("NumberingRules"), uno::UNO_QUERY); - uno::Sequence<beans::PropertyValue> aNumberingRule; - xLevels->getByIndex(1) >>= aNumberingRule; // 2nd level - for (const auto& rPair : std::as_const(aNumberingRule)) - { - if (rPair.Name == "Prefix") - // This was "." instead of empty, so the second paragraph was - // rendered as ".1" instead of "1.". - CPPUNIT_ASSERT_EQUAL(OUString(), rPair.Value.get<OUString>()); - else if (rPair.Name == "Suffix") - CPPUNIT_ASSERT_EQUAL(OUString("."), rPair.Value.get<OUString>()); - } + // Prefix was "." instead of empty, so the second paragraph was + // rendered as ".1" instead of "1.". + // Unittest modified due to Prefix/Suffix support obsolete + uno::Reference<beans::XPropertySet> xPara(getParagraph(2), uno::UNO_QUERY); + CPPUNIT_ASSERT_EQUAL(OUString("1."), getProperty<OUString>(xPara, "ListLabelString")); } DECLARE_WW8EXPORT_TEST(testTdf104334, "tdf104334.doc") @@ -422,6 +467,36 @@ DECLARE_WW8EXPORT_TEST(testTdf108072, "tdf108072.doc") CPPUNIT_ASSERT_EQUAL(true, getProperty<bool>(xTableRows->getByIndex(0), "IsSplitAllowed")); } +DECLARE_WW8EXPORT_TEST(testTdf123321, "shapes-line-ellipse.doc") +{ + // These are the 3 lines in which 1st and 3rd one were disappearing before + uno::Reference<drawing::XShape> l1 = getShape(7); + uno::Reference<drawing::XShape> l2 = getShape(8); + uno::Reference<drawing::XShape> l3 = getShape(9); + + // first line (smallest) + // Fails without the fix: Expected: 423, Actual: 2 + CPPUNIT_ASSERT_EQUAL(sal_Int32(423), l1->getSize().Height); + // Fails without the fix: Expected: 0, Actual: 2 + CPPUNIT_ASSERT_EQUAL(sal_Int32(0), l1->getSize().Width); + CPPUNIT_ASSERT_EQUAL(sal_Int32(7908), l1->getPosition().X); + CPPUNIT_ASSERT_EQUAL(sal_Int32(37), l1->getPosition().Y); + + // second line (larger) + CPPUNIT_ASSERT_EQUAL(sal_Int32(2542), l2->getSize().Height); + CPPUNIT_ASSERT_EQUAL(sal_Int32(2), l2->getSize().Width); + CPPUNIT_ASSERT_EQUAL(sal_Int32(7916), l2->getPosition().X); + CPPUNIT_ASSERT_EQUAL(sal_Int32(289), l2->getPosition().Y); + + // third line (largest) + // Fails without the fix: Expected: 7027, Actual: 2 + CPPUNIT_ASSERT_EQUAL(sal_Int32(7027), l3->getSize().Height); + // Fails without the fix: Expected: 0, Actual: 2 + CPPUNIT_ASSERT_EQUAL(sal_Int32(0), l3->getSize().Width); + CPPUNIT_ASSERT_EQUAL(sal_Int32(7911), l3->getPosition().X); + CPPUNIT_ASSERT_EQUAL(sal_Int32(231), l3->getPosition().Y); +} + DECLARE_WW8EXPORT_TEST(testTdf91687, "tdf91687.doc") { // Exported Watermarks were resized @@ -448,8 +523,9 @@ DECLARE_WW8EXPORT_TEST(testTdf111480, "tdf111480.doc") CPPUNIT_ASSERT(xText->getSize().Width > 11000); } -DECLARE_WW8EXPORT_TEST(testTdf70838, "tdf70838.odt") +CPPUNIT_TEST_FIXTURE(Test, testTdf70838) { + loadAndReload("tdf70838.odt"); CPPUNIT_ASSERT_EQUAL(1, getShapes()); CPPUNIT_ASSERT_EQUAL(1, getPages()); SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument *>(mxComponent.get()); @@ -460,8 +536,9 @@ DECLARE_WW8EXPORT_TEST(testTdf70838, "tdf70838.odt") CPPUNIT_ASSERT(aRect.GetHeight() > aRect.GetWidth()); } -DECLARE_WW8EXPORT_TEST(testTdf70838b_verticalRotation, "tdf70838b_verticalRotation.odt") +CPPUNIT_TEST_FIXTURE(Test, testTdf70838b_verticalRotation) { + loadAndReload("tdf70838b_verticalRotation.odt"); CPPUNIT_ASSERT_EQUAL(3, getShapes()); CPPUNIT_ASSERT_EQUAL(1, getPages()); SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument *>(mxComponent.get()); @@ -475,20 +552,22 @@ DECLARE_WW8EXPORT_TEST(testTdf70838b_verticalRotation, "tdf70838b_verticalRotati CPPUNIT_ASSERT_MESSAGE("Line is taller, not wider", aLine.GetHeight() > aLine.GetWidth()); } -DECLARE_WW8EXPORT_TEST( testTdf129247, "tdf129247.docx" ) +CPPUNIT_TEST_FIXTURE(Test, testTdf129247) { + loadAndReload("tdf129247.docx"); CPPUNIT_ASSERT_EQUAL(1, getPages()); // Without the fix in place, the checkbox wouldn't be exported CPPUNIT_ASSERT_EQUAL(1, getShapes()); } -DECLARE_WW8EXPORT_TEST( testActiveXCheckbox, "checkbox_control.odt" ) +CPPUNIT_TEST_FIXTURE(Test, testActiveXCheckbox) { + loadAndReload("checkbox_control.odt"); CPPUNIT_ASSERT_EQUAL(2, getShapes()); CPPUNIT_ASSERT_EQUAL(1, getPages()); // First check box anchored as a floating object uno::Reference<drawing::XControlShape> xControlShape; - if(!mbExported) + if(!isExported()) xControlShape.set(getShape(1), uno::UNO_QUERY); else xControlShape.set(getShape(2), uno::UNO_QUERY); @@ -505,7 +584,7 @@ DECLARE_WW8EXPORT_TEST( testActiveXCheckbox, "checkbox_control.odt" ) CPPUNIT_ASSERT_EQUAL(text::TextContentAnchorType_AT_CHARACTER,getProperty<text::TextContentAnchorType>(xPropertySet2,"AnchorType")); // Second check box anchored inline / as character - if(!mbExported) + if(!isExported()) xControlShape.set(getShape(2), uno::UNO_QUERY); else xControlShape.set(getShape(1), uno::UNO_QUERY); @@ -538,7 +617,7 @@ DECLARE_WW8EXPORT_TEST(testTdf67207_MERGEFIELD, "mailmerge.doc") CPPUNIT_ASSERT(xServiceInfo->supportsService("com.sun.star.text.TextField.Database")); OUString sValue; xTextField->getPropertyValue("Content") >>= sValue; - CPPUNIT_ASSERT_EQUAL(OUString(u"«Name»"), sValue); + CPPUNIT_ASSERT_EQUAL(u"«Name»"_ustr, sValue); uno::Reference<beans::XPropertySet> xFiledMaster = xDependent->getTextFieldMaster(); uno::Reference<lang::XServiceInfo> xFiledMasterServiceInfo(xFiledMaster, uno::UNO_QUERY_THROW); @@ -559,7 +638,7 @@ DECLARE_OOXMLEXPORT_TEST( testTableCrossReference, "table_cross_reference.odt" ) CPPUNIT_ASSERT_EQUAL(1, getPages()); // tdf#42346: Cross references to tables were not saved // MSO uses simple bookmarks for referencing table caption, so we do the same by export - if (!mbExported) + if (!isExported()) return; // Check whether we have all the necessary bookmarks exported and imported back @@ -713,12 +792,13 @@ DECLARE_OOXMLEXPORT_TEST( testTableCrossReference, "table_cross_reference.odt" ) CPPUNIT_ASSERT_EQUAL(sal_uInt16(8), nIndex); } -DECLARE_OOXMLEXPORT_TEST( testTableCrossReferenceCustomFormat, "table_cross_reference_custom_format.odt" ) +CPPUNIT_TEST_FIXTURE(Test, testTableCrossReferenceCustomFormat) { + loadAndReload("table_cross_reference_custom_format.odt"); CPPUNIT_ASSERT_EQUAL(1, getPages()); // tdf#42346: Cross references to tables were not saved // Check also captions with custom formatting - if (!mbExported) + if (!isExported()) return; // Check whether we have all the necessary bookmarks exported and imported back @@ -835,7 +915,7 @@ DECLARE_OOXMLEXPORT_TEST( testObjectCrossReference, "object_cross_reference.odt" CPPUNIT_ASSERT_EQUAL(2, getPages()); // tdf#42346: Cross references to objects were not saved // MSO uses simple bookmarks for referencing table caption, so we do the same by export - if (!mbExported) + if (!isExported()) return; // Check whether we have all the necessary bookmarks exported and imported back @@ -913,7 +993,7 @@ DECLARE_OOXMLEXPORT_TEST( testObjectCrossReference, "object_cross_reference.odt" { uno::Reference<text::XTextContent> xContent(xBookmarksByName->getByName("Ref_Illustration1_caption_only"), uno::UNO_QUERY); uno::Reference<text::XTextRange> xRange = xContent->getAnchor(); - CPPUNIT_ASSERT_EQUAL(OUString("an other image"), xRange->getString()); + CPPUNIT_ASSERT_EQUAL(OUString("another image"), xRange->getString()); } // Cross references to text frames @@ -983,7 +1063,7 @@ DECLARE_WW8EXPORT_TEST(testTdf112118_DOC, "tdf112118.doc") for (const auto& side : style.sideParams) { const OUString sSide = OUString::createFromAscii(side.sideName); - const OString sStage = style.styleName + OStringLiteral(" ") + side.sideName; + const OString sStage = style.styleName + OString::Concat(" ") + side.sideName; sal_Int32 nMargin = getProperty<sal_Int32>(xStyle, sSide + "Margin"); CPPUNIT_ASSERT_EQUAL_MESSAGE(OString(sStage + " margin width").getStr(), @@ -1005,8 +1085,9 @@ DECLARE_WW8EXPORT_TEST(testTdf112118_DOC, "tdf112118.doc") } } -DECLARE_WW8EXPORT_TEST(testTdf117503, "tdf117503.docx") +CPPUNIT_TEST_FIXTURE(Test, testTdf117503) { + loadAndReload("tdf117503.docx"); // This was 3, first page + standard page styles were not merged together // on export. CPPUNIT_ASSERT_EQUAL(2, getPages()); @@ -1018,12 +1099,12 @@ DECLARE_WW8EXPORT_TEST(testTdf117885, "tdf117885.doc") /* Get the vertical position of the paragraph containing the text "Start" */ sal_Int32 nParaA_Top = getXPath(pXmlDoc, - "/root/page/body/column[1]/body/txt[text()='Start']/infos/bounds", "top" + "/root/page/body/column[1]/body/txt[text()='Start']/infos/bounds"_ostr, "top"_ostr ).toInt32(); /* Get the vertical position of the paragraph containing the text "Top B" */ sal_Int32 nParaB_Top = getXPath(pXmlDoc, - "/root/page/body/column[2]/body/txt[text()='Top B']/infos/bounds", "top" + "/root/page/body/column[2]/body/txt[text()='Top B']/infos/bounds"_ostr, "top"_ostr ).toInt32(); /* These two paragraphs are supposed to be at the top of the left @@ -1031,8 +1112,9 @@ DECLARE_WW8EXPORT_TEST(testTdf117885, "tdf117885.doc") CPPUNIT_ASSERT_EQUAL(nParaA_Top, nParaB_Top); } -DECLARE_WW8EXPORT_TEST(testTdf118133, "tdf118133.docx") +CPPUNIT_TEST_FIXTURE(Test, testTdf118133) { + loadAndReload("tdf118133.docx"); // This was 0, doc import + doc export resulted in lost image due to broken // lazy-loading of tiff images. CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(15240), getShape(1)->getSize().Width); @@ -1048,6 +1130,34 @@ DECLARE_WW8EXPORT_TEST(testTdf118412, "tdf118412.doc") CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(1251), nBottomMargin); } +CPPUNIT_TEST_FIXTURE(Test, testContentControlExport) +{ + // Given a document with a (rich text) content control: + createSwDoc(); + uno::Reference<lang::XMultiServiceFactory> xMSF(mxComponent, uno::UNO_QUERY); + uno::Reference<text::XTextDocument> xTextDocument(mxComponent, uno::UNO_QUERY); + uno::Reference<text::XText> xText = xTextDocument->getText(); + uno::Reference<text::XTextCursor> xCursor = xText->createTextCursor(); + xText->insertString(xCursor, "test", /*bAbsorb=*/false); + xCursor->gotoStart(/*bExpand=*/false); + xCursor->gotoEnd(/*bExpand=*/true); + uno::Reference<text::XTextContent> xContentControl( + xMSF->createInstance("com.sun.star.text.ContentControl"), uno::UNO_QUERY); + xText->insertTextContent(xCursor, xContentControl, /*bAbsorb=*/true); + + // When saving that document to DOC and loading it back: + saveAndReload("MS Word 97"); + + // Then make sure the dummy character at the end is filtered out: + OUString aBodyText = getBodyText(); + // Without the accompanying fix in place, this test would have failed: + // - Expected: test + // - Actual : test<space> + // i.e. the CH_TXTATR_BREAKWORD at the end was written, then the import replaced that with a + // space. + CPPUNIT_ASSERT_EQUAL(OUString("test"), aBodyText); +} + CPPUNIT_PLUGIN_IMPLEMENT(); /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/qa/extras/ww8export/ww8export3.cxx b/sw/qa/extras/ww8export/ww8export3.cxx index b2afbce478de..3668e3938e16 100644 --- a/sw/qa/extras/ww8export/ww8export3.cxx +++ b/sw/qa/extras/ww8export/ww8export3.cxx @@ -11,12 +11,14 @@ #include <com/sun/star/beans/XPropertySet.hpp> #include <com/sun/star/container/XIndexAccess.hpp> +#include <com/sun/star/drawing/BitmapMode.hpp> #include <com/sun/star/drawing/FillStyle.hpp> #include <com/sun/star/drawing/LineDash.hpp> #include <com/sun/star/document/XDocumentPropertiesSupplier.hpp> #include <com/sun/star/graphic/XGraphic.hpp> #include <com/sun/star/table/ShadowFormat.hpp> #include <com/sun/star/text/XFormField.hpp> +#include <com/sun/star/text/XTextField.hpp> #include <com/sun/star/text/XTextTable.hpp> #include <com/sun/star/text/XTextTablesSupplier.hpp> #include <com/sun/star/text/WritingMode2.hpp> @@ -33,6 +35,8 @@ #include <IDocumentSettingAccess.hxx> #include <docsh.hxx> #include <unotxdoc.hxx> +#include <formatlinebreak.hxx> +#include <o3tl/string_view.hxx> class Test : public SwModelTestBase { @@ -41,12 +45,6 @@ public: : SwModelTestBase("/sw/qa/extras/ww8export/data/", "MS Word 97") { } - - bool mustTestImportOf(const char* filename) const override - { - // If the testcase is stored in some other format, it's pointless to test. - return OString(filename).endsWith(".doc"); - } }; DECLARE_WW8EXPORT_TEST(testTdf37778_readonlySection, "tdf37778_readonlySection.doc") @@ -69,6 +67,87 @@ DECLARE_WW8EXPORT_TEST(testTdf37778_readonlySection, "tdf37778_readonlySection.d CPPUNIT_ASSERT_EQUAL_MESSAGE("Last printed date", sal_Int16(2009), xDPS->getDocumentProperties()->getPrintDate().Year); } +DECLARE_WW8EXPORT_TEST(testTdf100961_fixedDateTime, "tdf100961_fixedDateTime.doc") +{ + // This should be a fixed date/time field, not the current time. + getParagraph(1, "05.01.19 04:06:08"); + + css::uno::Reference<css::text::XTextFieldsSupplier> xSupplier(mxComponent, + css::uno::UNO_QUERY_THROW); + auto xFieldsAccess(xSupplier->getTextFields()); + auto xFields(xFieldsAccess->createEnumeration()); + + css::uno::Reference<css::uno::XInterface> xField(xFields->nextElement(), css::uno::UNO_QUERY); + // Check fixed property was imported and date value was parsed correctly + CPPUNIT_ASSERT_EQUAL(true, getProperty<bool>(xField, "IsFixed")); + CPPUNIT_ASSERT_EQUAL(true, getProperty<bool>(xField, "IsDate")); + auto datetime = getProperty<css::util::DateTime>(xField, "DateTimeValue"); + CPPUNIT_ASSERT_EQUAL(sal_uInt16(5), datetime.Day); + CPPUNIT_ASSERT_EQUAL(sal_uInt16(1), datetime.Month); + CPPUNIT_ASSERT_EQUAL(sal_Int16(2019), datetime.Year); + + xField.set(xFields->nextElement(), css::uno::UNO_QUERY); + // Check fixed property was imported and time value was parsed correctly + CPPUNIT_ASSERT_EQUAL(true, getProperty<bool>(xField, "IsFixed")); + CPPUNIT_ASSERT_EQUAL(false, getProperty<bool>(xField, "IsDate")); + datetime = getProperty<css::util::DateTime>(xField, "DateTimeValue"); + CPPUNIT_ASSERT_EQUAL(sal_uInt16(4), datetime.Hours); + CPPUNIT_ASSERT_EQUAL(sal_uInt16(6), datetime.Minutes); + CPPUNIT_ASSERT_EQUAL(sal_uInt16(8), datetime.Seconds); +} + +DECLARE_WW8EXPORT_TEST(testTdf147861_customField, "tdf147861_customField.doc") +{ + // These should each be specific values, not a shared DocProperty + getParagraph(1, "CustomEditedTitle"); // edited + // A couple of \x0\x0 at the end of the import variable thwart an equality comparison + CPPUNIT_ASSERT(getParagraph(2)->getString().startsWith(" INSERT Custom Title here")); + getParagraph(3, "My Title"); // edited + + // Verify that these are fields, and not just plain text + uno::Reference<text::XTextFieldsSupplier> xTextFieldsSupplier(mxComponent, uno::UNO_QUERY); + auto xFieldsAccess(xTextFieldsSupplier->getTextFields()); + uno::Reference<container::XEnumeration> xFields(xFieldsAccess->createEnumeration()); + uno::Reference<text::XTextField> xField(xFields->nextElement(), uno::UNO_QUERY); + CPPUNIT_ASSERT_EQUAL(OUString("CustomEditedTitle"), xField->getPresentation(false)); + // The " (fixed)" part is unnecessary, but it must be consistent across a round-trip + CPPUNIT_ASSERT_EQUAL(OUString("DocInformation:Title (fixed)"), xField->getPresentation(true)); +} + +DECLARE_WW8EXPORT_TEST(testTdf148380_createField, "tdf148380_createField.doc") +{ + // Verify that these are fields, and not just plain text + uno::Reference<text::XTextFieldsSupplier> xTextFieldsSupplier(mxComponent, uno::UNO_QUERY); + auto xFieldsAccess(xTextFieldsSupplier->getTextFields()); + uno::Reference<container::XEnumeration> xFields(xFieldsAccess->createEnumeration()); + uno::Reference<text::XTextField> xField(xFields->nextElement(), uno::UNO_QUERY); + // This should NOT be "Lorenzo Chavez", or a real date since the user hand-modified the result. + CPPUNIT_ASSERT_EQUAL(OUString("Myself - that's who"), xField->getPresentation(false)); + xField.set(xFields->nextElement(), uno::UNO_QUERY); + CPPUNIT_ASSERT_EQUAL(OUString("yesterday at noon"), xField->getPresentation(false)); +} + +DECLARE_WW8EXPORT_TEST(testTdf148380_fldLocked, "tdf148380_fldLocked.doc") +{ + getParagraph(2, "4/5/2022 4:29:00 PM"); + getParagraph(4, "1/23/4567 8:9:10 PM"); + + // Verify that these are fields, and not just plain text + // (import only, since export thankfully just dumps these fixed fields as plain text + if (isExported()) + return; + uno::Reference<text::XTextFieldsSupplier> xTextFieldsSupplier(mxComponent, uno::UNO_QUERY); + auto xFieldsAccess(xTextFieldsSupplier->getTextFields()); + uno::Reference<container::XEnumeration> xFields(xFieldsAccess->createEnumeration()); + uno::Reference<text::XTextField> xField(xFields->nextElement(), uno::UNO_QUERY); + // This should NOT be updated at FILEOPEN to match the last modified time - it is locked. + CPPUNIT_ASSERT_EQUAL(OUString("4/5/2022 4:29:00 PM"), xField->getPresentation(false)); + CPPUNIT_ASSERT_EQUAL(OUString("DocInformation:Modified (fixed)"), xField->getPresentation(true)); + xField.set(xFields->nextElement(), uno::UNO_QUERY); + CPPUNIT_ASSERT_EQUAL(OUString("1/23/4567 8:9:10 PM"), xField->getPresentation(false)); + CPPUNIT_ASSERT_EQUAL(OUString("DocInformation:Last printed (fixed)"), xField->getPresentation(true)); +} + DECLARE_WW8EXPORT_TEST(testTdf138345_paraCharHighlight, "tdf138345_paraCharHighlight.doc") { uno::Reference<beans::XPropertySet> xRun(getRun(getParagraph(9), 1, "A side benefit is that "), uno::UNO_QUERY_THROW); @@ -91,7 +170,7 @@ DECLARE_WW8EXPORT_TEST(testTdf104596_wrapInHeaderTable, "tdf104596_wrapInHeaderT { xmlDocUniquePtr pXmlDoc = parseLayoutDump(); - sal_Int32 nRowHeight = getXPath(pXmlDoc, "//header/tab/row[1]/infos/bounds", "height").toInt32(); + sal_Int32 nRowHeight = getXPath(pXmlDoc, "//header/tab/row[1]/infos/bounds"_ostr, "height"_ostr).toInt32(); // The fly is supposed to be no-wrap, so the text should come underneath it, not wrap-through, // thus making the row much higher. Before, height was 706. Now it is 1067. CPPUNIT_ASSERT_MESSAGE("Text must wrap under green box", nRowHeight > 1000); @@ -112,8 +191,8 @@ DECLARE_WW8EXPORT_TEST(testGutterLeft, "gutter-left.doc") CPPUNIT_TEST_FIXTURE(Test, testGutterTop) { - load(mpTestDocumentPath, "gutter-top.doc"); - reload(mpFilter, "gutter-top.doc"); + createSwDoc("gutter-top.doc"); + saveAndReload("MS Word 97"); uno::Reference<lang::XMultiServiceFactory> xFactory(mxComponent, uno::UNO_QUERY); uno::Reference<beans::XPropertySet> xSettings( xFactory->createInstance("com.sun.star.document.Settings"), uno::UNO_QUERY); @@ -133,13 +212,13 @@ DECLARE_WW8EXPORT_TEST(testArabicZeroNumbering, "arabic-zero-numbering.doc") // - Expected: 64 // - Actual : 4 // i.e. numbering type was ARABIC, not ARABIC_ZERO. - CPPUNIT_ASSERT_EQUAL(static_cast<sal_uInt16>(style::NumberingType::ARABIC_ZERO), + CPPUNIT_ASSERT_EQUAL(o3tl::narrowing<sal_uInt16>(style::NumberingType::ARABIC_ZERO), aMap["NumberingType"].get<sal_uInt16>()); } DECLARE_WW8EXPORT_TEST(testTdf128501, "tdf128501.doc") { - if (!mbExported) + if (!isExported()) { uno::Reference<drawing::XShapeDescriptor> xShapeDescriptor = getShape(1); CPPUNIT_ASSERT_EQUAL(OUString("com.sun.star.drawing.CustomShape"), xShapeDescriptor->getShapeType()); @@ -157,12 +236,12 @@ DECLARE_WW8EXPORT_TEST(testTdf128501, "tdf128501.doc") CPPUNIT_TEST_FIXTURE(SwModelTestBase, testArabicZeroNumberingFootnote) { // Create a document, set footnote numbering type to ARABIC_ZERO. - loadURL("private:factory/swriter", nullptr); + createSwDoc(); uno::Reference<text::XFootnotesSupplier> xFootnotesSupplier(mxComponent, uno::UNO_QUERY); uno::Reference<beans::XPropertySet> xFootnoteSettings = xFootnotesSupplier->getFootnoteSettings(); sal_uInt16 nNumberingType = style::NumberingType::ARABIC_ZERO; - xFootnoteSettings->setPropertyValue("NumberingType", uno::makeAny(nNumberingType)); + xFootnoteSettings->setPropertyValue("NumberingType", uno::Any(nNumberingType)); // Insert a footnote. uno::Reference<lang::XMultiServiceFactory> xFactory(mxComponent, uno::UNO_QUERY); @@ -173,7 +252,7 @@ CPPUNIT_TEST_FIXTURE(SwModelTestBase, testArabicZeroNumberingFootnote) uno::UNO_QUERY); xTextContentAppend->appendTextContent(xFootnote, {}); - reload("MS Word 97", ""); + saveAndReload("MS Word 97"); xFootnotesSupplier.set(mxComponent, uno::UNO_QUERY); sal_uInt16 nExpected = style::NumberingType::ARABIC_ZERO; auto nActual = getProperty<sal_uInt16>(xFootnotesSupplier->getFootnoteSettings(), "NumberingType"); @@ -187,12 +266,12 @@ CPPUNIT_TEST_FIXTURE(SwModelTestBase, testArabicZeroNumberingFootnote) CPPUNIT_TEST_FIXTURE(SwModelTestBase, testChicagoNumberingFootnote) { // Create a document, set footnote numbering type to SYMBOL_CHICAGO. - loadURL("private:factory/swriter", nullptr); + createSwDoc(); uno::Reference<text::XFootnotesSupplier> xFootnotesSupplier(mxComponent, uno::UNO_QUERY); uno::Reference<beans::XPropertySet> xFootnoteSettings = xFootnotesSupplier->getFootnoteSettings(); sal_uInt16 nNumberingType = style::NumberingType::SYMBOL_CHICAGO; - xFootnoteSettings->setPropertyValue("NumberingType", uno::makeAny(nNumberingType)); + xFootnoteSettings->setPropertyValue("NumberingType", uno::Any(nNumberingType)); // Insert a footnote. uno::Reference<lang::XMultiServiceFactory> xFactory(mxComponent, uno::UNO_QUERY); @@ -203,7 +282,7 @@ CPPUNIT_TEST_FIXTURE(SwModelTestBase, testChicagoNumberingFootnote) uno::UNO_QUERY); xTextContentAppend->appendTextContent(xFootnote, {}); - reload("MS Word 97", ""); + saveAndReload("MS Word 97"); xFootnotesSupplier.set(mxComponent, uno::UNO_QUERY); sal_uInt16 nExpected = style::NumberingType::SYMBOL_CHICAGO; auto nActual = getProperty<sal_uInt16>(xFootnotesSupplier->getFootnoteSettings(), "NumberingType"); @@ -239,6 +318,23 @@ DECLARE_WW8EXPORT_TEST(testdf79553_lineNumbers, "tdf79553_lineNumbers.doc") CPPUNIT_ASSERT_MESSAGE("automatic distance", nValue > 0); } +CPPUNIT_TEST_FIXTURE(Test, testTdf138302_restartNumbering) +{ + loadAndReload("tdf138302_restartNumbering.odt"); + CPPUNIT_ASSERT_EQUAL(1, getPages()); + uno::Reference<beans::XPropertySet> xPara(getParagraph(8), uno::UNO_QUERY); + CPPUNIT_ASSERT_EQUAL(OUString("1."), getProperty<OUString>(xPara, "ListLabelString")); + + + // tdf#143982: automatic tables should export as something better than just left-and-size + uno::Reference<text::XTextTablesSupplier> xTextTablesSupplier(mxComponent, uno::UNO_QUERY); + uno::Reference<container::XIndexAccess> xTables(xTextTablesSupplier->getTextTables(), uno::UNO_QUERY); + uno::Reference<text::XTextTable> xTable(xTables->getByIndex(0), uno::UNO_QUERY); + + CPPUNIT_ASSERT(getProperty<bool>(xTable, "IsWidthRelative")); + CPPUNIT_ASSERT_EQUAL(sal_Int16(100), getProperty<sal_Int16>(xTable, "RelativeWidth")); +} + DECLARE_WW8EXPORT_TEST(testTdf122429_header, "tdf122429_header.doc") { uno::Reference<container::XNameAccess> pageStyles = getStyles("PageStyles"); @@ -247,8 +343,9 @@ DECLARE_WW8EXPORT_TEST(testTdf122429_header, "tdf122429_header.doc") CPPUNIT_ASSERT(headerIsOn); } -DECLARE_WW8EXPORT_TEST(testTdf122460_header, "tdf122460_header.odt") +CPPUNIT_TEST_FIXTURE(Test, testTdf122460_header) { + loadAndReload("tdf122460_header.odt"); CPPUNIT_ASSERT_EQUAL(1, getPages()); uno::Reference<container::XNameAccess> pageStyles = getStyles("PageStyles"); uno::Reference<style::XStyle> pageStyle(pageStyles->getByName("Default Page Style"), uno::UNO_QUERY); @@ -256,6 +353,21 @@ DECLARE_WW8EXPORT_TEST(testTdf122460_header, "tdf122460_header.odt") CPPUNIT_ASSERT(headerIsOn); } +DECLARE_WW8EXPORT_TEST(testTdf139495_tinyHeader, "tdf139495_tinyHeader.doc") +{ + // In Word 2003, this is one page, but definitely not six pages. + CPPUNIT_ASSERT(getPages() < 3); +} + +DECLARE_WW8EXPORT_TEST(testTdf124937, "tdf124937.doc") +{ + // Check it doesn't crash at import time + uno::Reference<text::XTextTablesSupplier> xTablesSupplier(mxComponent, uno::UNO_QUERY); + uno::Reference<container::XIndexAccess> xTables(xTablesSupplier->getTextTables( ), uno::UNO_QUERY); + CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xTables->getCount()); + CPPUNIT_ASSERT_EQUAL(1, getPages()); +} + DECLARE_WW8EXPORT_TEST(testFdo53985, "fdo53985.doc") { uno::Reference<text::XTextTablesSupplier> xTablesSupplier(mxComponent, uno::UNO_QUERY); @@ -300,8 +412,9 @@ DECLARE_WW8EXPORT_TEST(testTdf135672_tableGrows, "tdf135672_tableGrows.doc") CPPUNIT_ASSERT_EQUAL(sal_Int32(10800), getProperty<sal_Int32>(xTable, "Width")); } -DECLARE_WW8EXPORT_TEST(testTdf79435_legacyInputFields, "tdf79435_legacyInputFields.docx") +CPPUNIT_TEST_FIXTURE(Test, testTdf79435_legacyInputFields) { + loadAndReload("tdf79435_legacyInputFields.docx"); //using .docx input file to verify cross-format compatibility. uno::Reference<text::XFormField> xFormField = getProperty< uno::Reference<text::XFormField> >(getRun(getParagraph(5), 3), "Bookmark"); uno::Reference<container::XNameContainer> xParameters(xFormField->getParameters()); @@ -353,8 +466,9 @@ DECLARE_WW8EXPORT_TEST(testTdf79435_legacyInputFields, "tdf79435_legacyInputFiel CPPUNIT_ASSERT_EQUAL(OUString("date"), sTmp); } -DECLARE_WW8EXPORT_TEST(testTdf134264, "tdf134264.docx") +CPPUNIT_TEST_FIXTURE(Test, testTdf134264) { + loadAndReload("tdf134264.docx"); // Without the fix in place, ADDRESSBLOCK fields would have been lost after RT CPPUNIT_ASSERT_EQUAL(OUString("MF"), getParagraph(1)->getString()); CPPUNIT_ASSERT_EQUAL(OUString("M19"), getParagraph(2)->getString()); @@ -393,22 +507,29 @@ DECLARE_WW8EXPORT_TEST(testTdf120225_textControlCrossRef, "tdf120225_textControl CPPUNIT_ASSERT_EQUAL(OUString("Text1"), sTextFieldName); } -DECLARE_WW8EXPORT_TEST(testTdf134948, "tdf134948.odt") +CPPUNIT_TEST_FIXTURE(Test, testTdf134948) { + loadAndReload("tdf134948.odt"); + CPPUNIT_ASSERT_EQUAL(1, getShapes()); + CPPUNIT_ASSERT_EQUAL(1, getPages()); CPPUNIT_ASSERT_EQUAL_MESSAGE("Only 1 paragraph", 1, getParagraphs()); } -DECLARE_WW8EXPORT_TEST(testTdf132726, "tdf132726.odt") +CPPUNIT_TEST_FIXTURE(Test, testTdf132726) { + loadAndReload("tdf132726.odt"); + CPPUNIT_ASSERT_EQUAL(1, getShapes()); + CPPUNIT_ASSERT_EQUAL(1, getPages()); uno::Reference<text::XTextRange> xRun = getRun(getParagraph(1), 1, "What sentence has a yellow background? "); - CPPUNIT_ASSERT_EQUAL( COL_AUTO, Color(ColorTransparency, getProperty<sal_uInt32>(xRun, "CharBackColor")) ); + CPPUNIT_ASSERT_EQUAL( COL_AUTO, getProperty<Color>(xRun, "CharBackColor")); xRun = getRun(getParagraph(1), 2, "Why, this sentence of course"); - CPPUNIT_ASSERT_EQUAL( COL_YELLOW, Color(ColorTransparency, getProperty<sal_uInt32>(xRun, "CharBackColor")) ); + CPPUNIT_ASSERT_EQUAL( COL_YELLOW, getProperty<Color>(xRun, "CharBackColor")); } -DECLARE_WW8EXPORT_TEST(testTdf127316_autoEscapement, "tdf127316_autoEscapement.odt") +CPPUNIT_TEST_FIXTURE(Test, testTdf127316_autoEscapement) { + loadAndReload("tdf127316_autoEscapement.odt"); CPPUNIT_ASSERT_EQUAL(1, getPages()); uno::Reference<text::XTextRange> xPara = getParagraph(2); CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.f, getProperty<float>(getRun(xPara, 1, "Normal text "), "CharEscapement"), 0); @@ -420,8 +541,9 @@ DECLARE_WW8EXPORT_TEST(testTdf127316_autoEscapement, "tdf127316_autoEscapement.o CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Subscript", -10.f, getProperty<float>(getRun(xPara, 2), "CharEscapement"), 1); } -DECLARE_WW8EXPORT_TEST(testTdf127316_autoEscapement2, "tdf127316_autoEscapement2.odt") +CPPUNIT_TEST_FIXTURE(Test, testTdf127316_autoEscapement2) { + loadAndReload("tdf127316_autoEscapement2.odt"); CPPUNIT_ASSERT_EQUAL(2, getPages()); uno::Reference<text::XTextRange> xPara = getParagraph(1); CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.f, getProperty<float>(getRun(xPara, 1, "Base1"), "CharEscapement"), 0); @@ -433,8 +555,9 @@ DECLARE_WW8EXPORT_TEST(testTdf127316_autoEscapement2, "tdf127316_autoEscapement2 CPPUNIT_ASSERT_DOUBLES_EQUAL(320.f, getProperty<float>(getRun(xPara, 2,"AutoSuperscript"), "CharEscapement"), 3); } -DECLARE_WW8EXPORT_TEST(testTdf120412_proportionalEscapement, "tdf120412_proportionalEscapement.odt") +CPPUNIT_TEST_FIXTURE(Test, testTdf120412_proportionalEscapement) { + loadAndReload("tdf120412_proportionalEscapement.odt"); uno::Reference<text::XTextRange> xPara = getParagraph(2); CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.f, getProperty<float>(getRun(xPara, 2, "Base"), "CharEscapement"), 0); // Import was limiting to 100%. And export based the position on the original height, not the proportional height. @@ -449,26 +572,28 @@ DECLARE_WW8EXPORT_TEST(testTdf133453_realFontSize, "tdf133453_realFontSize.doc") DECLARE_WW8EXPORT_TEST(testTdf116194, "tdf116194.doc") { - CPPUNIT_ASSERT_EQUAL( Color(192,0,0), Color(ColorTransparency, getProperty<sal_uInt32>(getRun(getParagraph(1), 1), "CharColor")) ); + CPPUNIT_ASSERT_EQUAL( Color(0xc00000), getProperty<Color>(getRun(getParagraph(1), 1), "CharColor")); } -DECLARE_WW8EXPORT_TEST(testTdf121111_fillStyleNone, "tdf121111_fillStyleNone.docx") +CPPUNIT_TEST_FIXTURE(Test, testTdf121111_fillStyleNone) { + loadAndReload("tdf121111_fillStyleNone.docx"); uno::Reference<beans::XPropertySet> xStyle(getStyles("ParagraphStyles")->getByName("Numbering - First level"), uno::UNO_QUERY); - CPPUNIT_ASSERT_EQUAL(Color(184,204,228), Color(ColorTransparency, getProperty<sal_uInt32>(xStyle, "ParaBackColor")));//R:184 G:204 B:228 + CPPUNIT_ASSERT_EQUAL(Color(0xb8cce4), getProperty<Color>(xStyle, "ParaBackColor"));//R:184 G:204 B:228 CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_SOLID, getProperty<drawing::FillStyle>(xStyle, "FillStyle")); uno::Reference<text::XTextRange> xText(getParagraph(12)); - CPPUNIT_ASSERT_EQUAL(COL_AUTO, Color(ColorTransparency, getProperty<sal_uInt32>(xText, "ParaBackColor"))); + CPPUNIT_ASSERT_EQUAL(COL_AUTO, getProperty<Color>(xText, "ParaBackColor")); CPPUNIT_ASSERT_EQUAL_MESSAGE("No fill", drawing::FillStyle_NONE, getProperty<drawing::FillStyle>(xText, "FillStyle")); } -DECLARE_WW8EXPORT_TEST(testTdf128608_fillStyleNoneB, "tdf128608_fillStyleNoneB.odt") +CPPUNIT_TEST_FIXTURE(Test, testTdf128608_fillStyleNoneB) { + loadAndReload("tdf128608_fillStyleNoneB.odt"); CPPUNIT_ASSERT_EQUAL(1, getPages()); uno::Reference<text::XTextRange> xText(getParagraph(1)); - CPPUNIT_ASSERT_EQUAL(COL_AUTO, Color(ColorTransparency, getProperty<sal_uInt32>(xText, "ParaBackColor"))); + CPPUNIT_ASSERT_EQUAL(COL_AUTO, getProperty<Color>(xText, "ParaBackColor")); CPPUNIT_ASSERT_EQUAL_MESSAGE("No fill", drawing::FillStyle_NONE, getProperty<drawing::FillStyle>(xText, "FillStyle")); } @@ -484,9 +609,9 @@ DECLARE_WW8EXPORT_TEST(testTdf132094_transparentPageImage, "tdf132094_transparen DECLARE_WW8EXPORT_TEST(testTdf112618_textbox_no_bg, "tdf112618_textbox_no_bg.doc") { - sal_uInt16 nTransparence = getProperty<sal_Int16>(getShape(2), "FillTransparence"); - CPPUNIT_ASSERT_EQUAL(sal_uInt16(100), nTransparence); - CPPUNIT_ASSERT_EQUAL(nTransparence, getProperty<sal_uInt16>(getShape(2), "BackColorTransparency")); + Color nTransparence = getProperty<Color>(getShape(2), "FillTransparence"); + CPPUNIT_ASSERT_EQUAL(Color(0x000064), nTransparence); + CPPUNIT_ASSERT_EQUAL(nTransparence, getProperty<Color>(getShape(2), "BackColorTransparency")); } DECLARE_WW8EXPORT_TEST(testTdf101826_xattrTextBoxFill, "tdf101826_xattrTextBoxFill.doc") @@ -497,17 +622,24 @@ DECLARE_WW8EXPORT_TEST(testTdf101826_xattrTextBoxFill, "tdf101826_xattrTextBoxFi CPPUNIT_ASSERT_MESSAGE("background color", Color(0xFF, 0xFF, 0x00) != getProperty<Color>(getShape(4), "BackColor")); //Basic Picture Fill: Tux image CPPUNIT_ASSERT_EQUAL_MESSAGE("background image", drawing::FillStyle_BITMAP, getProperty<drawing::FillStyle>(getShape(5), "FillStyle")); + // Basic Pattern fill: many thin, green, vertical stripes on yellow background + auto eMode = getProperty<drawing::BitmapMode>(getShapeByName(u"Frame2"), "FillBitmapMode"); + CPPUNIT_ASSERT_EQUAL_MESSAGE("tiled pattern", drawing::BitmapMode_REPEAT, eMode); + // Basic Texture fill: tiled blue denim texture + eMode = getProperty<drawing::BitmapMode>(getShapeByName(u"Frame6"), "FillBitmapMode"); + CPPUNIT_ASSERT_EQUAL_MESSAGE("tiled texture", drawing::BitmapMode_REPEAT, eMode); } DECLARE_WW8EXPORT_TEST(testTdf123433_fillStyleStop, "tdf123433_fillStyleStop.doc") { uno::Reference<text::XTextRange> xText(getParagraph(12)); CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_NONE, getProperty<drawing::FillStyle>(xText, "FillStyle")); - CPPUNIT_ASSERT_EQUAL(COL_AUTO, Color(ColorTransparency, getProperty<sal_uInt32>(xText, "ParaBackColor"))); + CPPUNIT_ASSERT_EQUAL(COL_AUTO, getProperty<Color>(xText, "ParaBackColor")); } -DECLARE_WW8EXPORT_TEST(testTdf127862_pageFillStyle, "tdf127862_pageFillStyle.odt") +CPPUNIT_TEST_FIXTURE(Test, testTdf127862_pageFillStyle) { + loadAndReload("tdf127862_pageFillStyle.odt"); CPPUNIT_ASSERT_EQUAL(6, getPages()); uno::Reference<beans::XPropertySet> xStyle(getStyles("PageStyles")->getByName("Standard"), uno::UNO_QUERY); CPPUNIT_ASSERT(drawing::FillStyle_NONE != getProperty<drawing::FillStyle>(xStyle, "FillStyle")); @@ -524,31 +656,41 @@ DECLARE_WW8EXPORT_TEST(testTdf128608_tableParaBackColor, "tdf128608_tableParaBac uno::Reference<container::XEnumeration> xParaEnum = xParaEnumAccess->createEnumeration(); uno::Reference<text::XTextRange> xPara(xParaEnum->nextElement(), uno::UNO_QUERY); // ParaBackColor doesn't seem to be used in this case, but keep it here to make sure it stays as AUTO. - CPPUNIT_ASSERT_EQUAL(COL_AUTO, Color(ColorTransparency, getProperty<sal_uInt32>(xPara, "ParaBackColor"))); + CPPUNIT_ASSERT_EQUAL(COL_AUTO, getProperty<Color>(xPara, "ParaBackColor")); // No paragraph background colour/fill. (The cell background colour should be used.) CPPUNIT_ASSERT_EQUAL_MESSAGE("No fillstyle", drawing::FillStyle_NONE, getProperty<drawing::FillStyle>(xPara, "FillStyle")); } -DECLARE_WW8EXPORT_TEST(testTdf117217_largeTableBackgrounds, "tdf117217_largeTableBackgrounds.odt") +CPPUNIT_TEST_FIXTURE(Test, testTdf117217_largeTableBackgrounds) { + loadAndReload("tdf117217_largeTableBackgrounds.odt"); + CPPUNIT_ASSERT_EQUAL(1, getPages()); uno::Reference<text::XTextTablesSupplier> xTextTablesSupplier(mxComponent, uno::UNO_QUERY); uno::Reference<container::XIndexAccess> xTables(xTextTablesSupplier->getTextTables(), uno::UNO_QUERY); uno::Reference<text::XTextTable> xTable(xTables->getByIndex(0), uno::UNO_QUERY); // Cell 22: light-red == 16711680 uno::Reference<text::XTextRange> xCell(xTable->getCellByName("V1"), uno::UNO_QUERY_THROW); - CPPUNIT_ASSERT_EQUAL_MESSAGE("light red", sal_Int32(0xE0C2CD), getProperty<sal_Int32>(xCell, "BackColor")); + CPPUNIT_ASSERT_EQUAL_MESSAGE("light red", Color(0xE0C2CD), getProperty<Color>(xCell, "BackColor")); xCell.set(xTable->getCellByName("Z1"), uno::UNO_QUERY_THROW); - CPPUNIT_ASSERT_EQUAL_MESSAGE("light red", sal_Int32(0xE0C2CD), getProperty<sal_Int32>(xCell, "BackColor")); + CPPUNIT_ASSERT_EQUAL_MESSAGE("light red", Color(0xE0C2CD), getProperty<Color>(xCell, "BackColor")); } -DECLARE_WW8EXPORT_TEST(testTdf94009_zeroPgMargin, "tdf94009_zeroPgMargin.odt") +CPPUNIT_TEST_FIXTURE(Test, testTdf94009_zeroPgMargin) { + loadAndReload("tdf94009_zeroPgMargin.odt"); CPPUNIT_ASSERT_EQUAL(1, getPages()); uno::Reference<beans::XPropertySet> defaultStyle(getStyles("PageStyles")->getByName("Standard"), uno::UNO_QUERY); CPPUNIT_ASSERT_EQUAL(sal_Int32(0), getProperty<sal_Int32>(defaultStyle, "TopMargin")); } +DECLARE_WW8EXPORT_TEST(testTdf108518_CRnumformatting, "tdf108518_CRnumformatting.doc") +{ + CPPUNIT_ASSERT_EQUAL(OUString("6.2.3."), parseDump("//body/txt[4]/SwParaPortion/SwLineLayout/child::*[@type='PortionType::Number']"_ostr, "expand"_ostr)); + //Without this fix in place, it would become 200 (and non-bold). + CPPUNIT_ASSERT_EQUAL(OUString("220"), parseDump("//body/txt[4]/SwParaPortion/SwLineLayout/child::*[@type='PortionType::Number']/SwFont"_ostr, "height"_ostr)); +} + DECLARE_WW8EXPORT_TEST(testTdf120711_joinedParagraphWithChangeTracking, "tdf120711.doc") { sal_Int16 numFormat = getNumberingTypeOfParagraph(5); @@ -556,8 +698,9 @@ DECLARE_WW8EXPORT_TEST(testTdf120711_joinedParagraphWithChangeTracking, "tdf1207 CPPUNIT_ASSERT(style::NumberingType::CHAR_SPECIAL != numFormat); } -DECLARE_WW8EXPORT_TEST(testTdf129522_removeShadowStyle, "tdf129522_removeShadowStyle.odt") +CPPUNIT_TEST_FIXTURE(Test, testTdf129522_removeShadowStyle) { + loadAndReload("tdf129522_removeShadowStyle.odt"); CPPUNIT_ASSERT_EQUAL(1, getPages()); uno::Reference< container::XNameAccess > paragraphStyles = getStyles("ParagraphStyles"); uno::Reference< beans::XPropertySet > xStyleProps(paragraphStyles->getByName("Shadow"), uno::UNO_QUERY_THROW); @@ -579,6 +722,14 @@ DECLARE_WW8EXPORT_TEST(testTdf129522_removeShadowStyle, "tdf129522_removeShadowS CPPUNIT_ASSERT_EQUAL(table::ShadowLocation_NONE, aShadow.Location); } +DECLARE_WW8EXPORT_TEST(testTdf81705_outlineLevel, "tdf81705_outlineLevel.doc") +{ + // direct formatting resets outline level to body text (0) + CPPUNIT_ASSERT_EQUAL_MESSAGE("Paragraph C", sal_uInt16(0), getProperty<sal_uInt16>(getParagraph(3), "OutlineLevel")); + // myStyle sets outline level to 1. + CPPUNIT_ASSERT_EQUAL_MESSAGE("Paragraph D", sal_uInt16(1), getProperty<sal_uInt16>(getParagraph(4), "OutlineLevel")); +} + DECLARE_WW8EXPORT_TEST(testBtlrCell, "btlr-cell.doc") { // Without the accompanying fix in place, this test would have failed, as @@ -638,8 +789,9 @@ DECLARE_WW8EXPORT_TEST(testImageCommentAtChar, "image-comment-at-char.doc") getProperty<OUString>(getRun(xPara, 5), "TextPortionType")); } -DECLARE_WW8EXPORT_TEST(testTdf126708emf, "tdf126708_containsemf.odt") +CPPUNIT_TEST_FIXTURE(Test, testTdf126708emf) { + loadAndReload("tdf126708_containsemf.odt"); CPPUNIT_ASSERT_EQUAL(1, getShapes()); CPPUNIT_ASSERT_EQUAL(1, getPages()); auto xShape = getShape(1); @@ -657,11 +809,12 @@ DECLARE_WW8EXPORT_TEST(testTdf126708emf, "tdf126708_containsemf.odt") CPPUNIT_ASSERT(abs(xSize.Width - 17000) <= 6); } -DECLARE_WW8EXPORT_TEST(testBtlrFrame, "btlr-frame.odt") +CPPUNIT_TEST_FIXTURE(Test, testBtlrFrame) { + loadAndReload("btlr-frame.odt"); CPPUNIT_ASSERT_EQUAL(1, getShapes()); CPPUNIT_ASSERT_EQUAL(1, getPages()); - if (!mbExported) + if (!isExported()) { return; } @@ -706,6 +859,147 @@ DECLARE_WW8EXPORT_TEST(testPresetDash, "tdf127166_prstDash_Word97.doc") && aPresetLineDash.Distance == aShapeLineDash.Distance; CPPUNIT_ASSERT_MESSAGE("LineDash differ", bIsEqual); } + + xmlDocUniquePtr pLayout = parseLayoutDump(); + // Ensure that there is no tabstop in the first paragraph (despite chapter numbering's setting) + // This is a pre-emptive test to ensure something visibly correct is not broken. + assertXPath(pLayout, "//body/txt[1]//SwFixPortion"_ostr, 0); +} + +CPPUNIT_TEST_FIXTURE(Test, testRtlGutter) +{ + auto verify = [this]() { + uno::Reference<beans::XPropertySet> xStandard( + getStyles("PageStyles")->getByName("Standard"), uno::UNO_QUERY); + CPPUNIT_ASSERT(getProperty<bool>(xStandard, "RtlGutter")); + }; + + // Given a document with RTL gutter, when loading it: + createSwDoc("rtl-gutter.doc"); + // Then make sure the section's gutter is still RTL: + // Without the accompanying fix in place, this test would have failed as the SPRM was missing. + verify(); + saveAndReload("MS Word 97"); + verify(); +} + +DECLARE_WW8EXPORT_TEST(testTdf94326_notOutlineNumbering, "tdf94326_notOutlineNumbering.doc") +{ + // The directly applied numbering list must not be lost. + uno::Reference<beans::XPropertySet> xPara(getParagraph(2, u"ОБЩИЕ ПОЛОЖЕНИЯ"_ustr), uno::UNO_QUERY); + CPPUNIT_ASSERT_EQUAL(OUString("1."), getProperty<OUString>(xPara, "ListLabelString")); +} + +DECLARE_WW8EXPORT_TEST(testTdf106541_cancelOutline, "tdf106541_cancelOutline.doc") +{ + // The ability to cancel numbering must not be lost. + uno::Reference<beans::XPropertySet> xPara(getParagraph(1, "Cancelled by style"), uno::UNO_QUERY); + CPPUNIT_ASSERT_EQUAL(OUString(""), getProperty<OUString>(xPara, "ListLabelString")); + xPara.set(getParagraph(2, "Cancelled by inherited style"), uno::UNO_QUERY); + CPPUNIT_ASSERT_EQUAL(OUString(""), getProperty<OUString>(xPara, "ListLabelString")); + xPara.set(getParagraph(4, "Cancelled by direct paragraph formatting"), uno::UNO_QUERY); + CPPUNIT_ASSERT_EQUAL(OUString(""), getProperty<OUString>(xPara, "ListLabelString")); +} + +DECLARE_WW8EXPORT_TEST(testTdf104239_chapterNumbering, "tdf104239_chapterNumbering.doc") +{ + uno::Reference<text::XChapterNumberingSupplier> xNumberingSupplier(mxComponent, uno::UNO_QUERY); + uno::Reference<container::XIndexAccess> xNumberingRules = xNumberingSupplier->getChapterNumberingRules(); + + comphelper::SequenceAsHashMap hashMap(xNumberingRules->getByIndex(0)); + CPPUNIT_ASSERT(hashMap["HeadingStyleName"].get<OUString>().match("Heading 1")); + sal_uInt16 nNumberingType = style::NumberingType::CHARS_UPPER_LETTER_N; + CPPUNIT_ASSERT_EQUAL(nNumberingType, hashMap["NumberingType"].get<sal_uInt16>()); + + hashMap = xNumberingRules->getByIndex(5); + CPPUNIT_ASSERT(hashMap["HeadingStyleName"].get<OUString>().match("Heading 6")); + nNumberingType = style::NumberingType::ARABIC; + CPPUNIT_ASSERT_EQUAL(nNumberingType, hashMap["NumberingType"].get<sal_uInt16>()); +} + +DECLARE_WW8EXPORT_TEST(testTdf106541_inheritChapterNumbering, "tdf106541_inheritChapterNumbering.doc") +{ + // The level and numbering are inherited from Heading 1. + uno::Reference<beans::XPropertySet> xPara(getParagraph(3, "Letter A"), uno::UNO_QUERY); + CPPUNIT_ASSERT_EQUAL(OUString("a."), getProperty<OUString>(xPara, "ListLabelString")); +} + +DECLARE_WW8EXPORT_TEST(testTdf106541_inheritChapterNumberingB, "tdf106541_inheritChapterNumberingB.doc") +{ + // The level and numbering are inherited from Heading 1. + uno::Reference<beans::XPropertySet> xPara(getParagraph(1, "Chapter 1, level 1"), uno::UNO_QUERY); + CPPUNIT_ASSERT_EQUAL(OUString("1"), getProperty<OUString>(xPara, "ListLabelString")); + xPara.set(getParagraph(2, "Chapter 1, level 2"), uno::UNO_QUERY); + CPPUNIT_ASSERT_EQUAL(OUString("1.1"), getProperty<OUString>(xPara, "ListLabelString")); +} + +DECLARE_WW8EXPORT_TEST(testTdf75748_inheritChapterNumberingC, "tdf75748_inheritChapterNumberingC.doc") +{ + uno::Reference<beans::XPropertySet> xPara(getParagraph(5, "Inherited from Heading 3"), uno::UNO_QUERY); + CPPUNIT_ASSERT_EQUAL(OUString("II.B.1."), getProperty<OUString>(xPara, "ListLabelString")); +} + +DECLARE_WW8EXPORT_TEST(testTdf104239_numbering, "tdf104239_numbering.doc") +{ + // The paragraph starts with "paraksta Pieņemšanas". [Roundtrip by Word 2016 avoids the problem.] + uno::Reference<beans::XPropertySet> xPara(getParagraph(51), uno::UNO_QUERY); + CPPUNIT_ASSERT_EQUAL(OUString("3.3.1."), getProperty<OUString>(xPara, "ListLabelString")); +} + +DECLARE_WW8EXPORT_TEST(testTdf104239_chapterNumberingLevels, "tdf104239_chapterNumberingLevels.doc") +{ + uno::Reference<beans::XPropertySet> xPara(getParagraph(1, "Heading 1"), uno::UNO_QUERY); + CPPUNIT_ASSERT_EQUAL(OUString("Article I."), getProperty<OUString>(xPara, "ListLabelString")); + xPara.set(getParagraph(2, "Heading 2"), uno::UNO_QUERY); + CPPUNIT_ASSERT_EQUAL(OUString("1"), getProperty<OUString>(xPara, "ListLabelString")); + xPara.set(getParagraph(3, "Heading 3"), uno::UNO_QUERY); + CPPUNIT_ASSERT_EQUAL(OUString("First"), getProperty<OUString>(xPara, "ListLabelString")); + xPara.set(getParagraph(4, "Heading 4"), uno::UNO_QUERY); + CPPUNIT_ASSERT_EQUAL(OUString(""), getProperty<OUString>(xPara, "ListLabelString")); + xPara.set(getParagraph(8, "Heading 9"), uno::UNO_QUERY); + CPPUNIT_ASSERT_EQUAL(OUString("1.1.1.1.1.1.1.1.1."), getProperty<OUString>(xPara, "ListLabelString")); +} + +DECLARE_WW8EXPORT_TEST(testTdf104239_chapterNumberTortureTest, "tdf104239_chapterNumberTortureTest.doc") +{ + // There is no point in identifying what the wrong values where in this test, + //because EVERYTHING was wrong, and MANY different fixes are required to solve the problems. + uno::Reference<beans::XPropertySet> xPara(getParagraph(1, "No numId in style or paragraph"), uno::UNO_QUERY); + CPPUNIT_ASSERT_EQUAL(OUString(""), getProperty<OUString>(xPara, "ListLabelString")); + xPara.set(getParagraph(2, "Paragraph cancels numbering(0)"), uno::UNO_QUERY); + CPPUNIT_ASSERT_EQUAL(OUString(""), getProperty<OUString>(xPara, "ListLabelString")); + xPara.set(getParagraph(3, "First numbered line"), uno::UNO_QUERY); + CPPUNIT_ASSERT_EQUAL(OUString("1st.i.a.1.I"), getProperty<OUString>(xPara, "ListLabelString")); + xPara.set(getParagraph(7, "inheritOnly: inherit outlineLvl and listLvl."), uno::UNO_QUERY); + CPPUNIT_ASSERT_EQUAL(OUString("2nd.ii"), getProperty<OUString>(xPara, "ListLabelString")); + CPPUNIT_ASSERT_EQUAL(sal_Int16(1), getProperty<sal_Int16>(xPara, "NumberingLevel")); // Level 2 + xPara.set(getParagraph(9, "outline with Body listLvl(9)."), uno::UNO_QUERY); + if (!isExported()) + CPPUNIT_ASSERT_EQUAL(OUString(""), getProperty<OUString>(xPara, "ListLabelString")); + xPara.set(getParagraph(10, "outline with Body listLvl(9) #2."), uno::UNO_QUERY); + if (!isExported()) + CPPUNIT_ASSERT_EQUAL(OUString(""), getProperty<OUString>(xPara, "ListLabelString")); + xPara.set(getParagraph(11, "direct formatting - Body listLvl(9)."), uno::UNO_QUERY); + CPPUNIT_ASSERT_EQUAL(OUString(""), getProperty<OUString>(xPara, "ListLabelString")); + xPara.set(getParagraph(12, "direct numId, inherit listLvl."), uno::UNO_QUERY); + CPPUNIT_ASSERT_EQUAL(OUString("2nd.ii.a.1.I"), getProperty<OUString>(xPara, "ListLabelString")); + CPPUNIT_ASSERT_EQUAL(sal_Int16(4), getProperty<sal_Int16>(xPara, "NumberingLevel")); // Level 5 + xPara.set(getParagraph(13, "Style numId0 cancels inherited numbering."), uno::UNO_QUERY); + CPPUNIT_ASSERT_EQUAL(OUString(""), getProperty<OUString>(xPara, "ListLabelString")); +} + +DECLARE_WW8EXPORT_TEST(testTdf106541_inheritOutlineNumbering, "tdf106541_inheritOutlineNumbering.doc") +{ + // The level and numbering are inherited from Level2. + uno::Reference<beans::XPropertySet> xPara(getParagraph(2, "This should be a sub-point."), uno::UNO_QUERY); + CPPUNIT_ASSERT_EQUAL(OUString("1.1"), getProperty<OUString>(xPara, "ListLabelString")); +} + +DECLARE_WW8EXPORT_TEST(testTdf104239_sharedOutlineNumId, "tdf104239_sharedOutlineNumId.doc") +{ + uno::Reference<beans::XPropertySet> xPara(getParagraph(5, "Principes"), uno::UNO_QUERY); + // This was ".1." previously. + CPPUNIT_ASSERT_EQUAL(OUString("2.1."), getProperty<OUString>(xPara, "ListLabelString")); } DECLARE_WW8EXPORT_TEST(testTdf120394, "tdf120394.doc") @@ -719,12 +1013,12 @@ DECLARE_WW8EXPORT_TEST(testTdf120394, "tdf120394.doc") { uno::Reference<beans::XPropertySet> xPara(getParagraph(5), uno::UNO_QUERY); CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int16>(0), getProperty<sal_Int16>(xPara, "NumberingLevel")); - CPPUNIT_ASSERT_EQUAL(OUString(CHAR_ZWSP), getProperty<OUString>(xPara, "ListLabelString")); + CPPUNIT_ASSERT_EQUAL(OUString(), getProperty<OUString>(xPara, "ListLabelString")); } { uno::Reference<beans::XPropertySet> xPara(getParagraph(8), uno::UNO_QUERY); CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int16>(2), getProperty<sal_Int16>(xPara, "NumberingLevel")); - CPPUNIT_ASSERT_EQUAL(OUString(CHAR_ZWSP), getProperty<OUString>(xPara, "ListLabelString")); + CPPUNIT_ASSERT_EQUAL(OUString(), getProperty<OUString>(xPara, "ListLabelString")); } { uno::Reference<beans::XPropertySet> xPara(getParagraph(9), uno::UNO_QUERY); @@ -734,22 +1028,35 @@ DECLARE_WW8EXPORT_TEST(testTdf120394, "tdf120394.doc") { uno::Reference<beans::XPropertySet> xPara(getParagraph(10), uno::UNO_QUERY); CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int16>(2), getProperty<sal_Int16>(xPara, "NumberingLevel")); - CPPUNIT_ASSERT_EQUAL(OUString(CHAR_ZWSP), getProperty<OUString>(xPara, "ListLabelString")); + CPPUNIT_ASSERT_EQUAL(OUString(), getProperty<OUString>(xPara, "ListLabelString")); } } +DECLARE_WW8EXPORT_TEST(testTdf142760, "tdf142760.doc") +{ + // Without the fix in place, this test would have failed with + // - Expected: 2 + // - Actual : 6 + CPPUNIT_ASSERT_EQUAL(2, getPages()); + CPPUNIT_ASSERT_EQUAL(1, getShapes()); + + uno::Reference<text::XTextTablesSupplier> xTablesSupplier(mxComponent, uno::UNO_QUERY); + uno::Reference<container::XIndexAccess> xTables(xTablesSupplier->getTextTables( ), uno::UNO_QUERY); + CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xTables->getCount()); +} + DECLARE_WW8EXPORT_TEST(testTdf134570, "tdf134570.doc") { CPPUNIT_ASSERT_EQUAL(1, getPages()); - { - uno::Reference<beans::XPropertySet> xPara(getParagraph(1), uno::UNO_QUERY); - CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int16>(1), getProperty<sal_Int16>(xPara, "NumberingLevel")); - CPPUNIT_ASSERT_EQUAL(OUString("1"), getProperty<OUString>(xPara, "ListLabelString")); - } + uno::Reference<beans::XPropertySet> xPara(getParagraph(1), uno::UNO_QUERY); + CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int16>(1), getProperty<sal_Int16>(xPara, "NumberingLevel")); + CPPUNIT_ASSERT_EQUAL(OUString("1"), getProperty<OUString>(xPara, "ListLabelString")); } -DECLARE_WW8EXPORT_TEST(testTdf136814, "tdf136814.odt") +CPPUNIT_TEST_FIXTURE(Test, testTdf136814) { + loadAndReload("tdf136814.odt"); + CPPUNIT_ASSERT_EQUAL(1, getPages()); uno::Reference<beans::XPropertySet> xStyle(getStyles("PageStyles")->getByName("Standard"), uno::UNO_QUERY); sal_Int32 nBorderDistance = static_cast<sal_Int32>(106); @@ -759,6 +1066,65 @@ DECLARE_WW8EXPORT_TEST(testTdf136814, "tdf136814.odt") CPPUNIT_ASSERT_EQUAL(nBorderDistance, getProperty<sal_Int32>(xStyle, "LeftBorderDistance")); } +CPPUNIT_TEST_FIXTURE(Test, testTdf79186_noLayoutInCell) +{ + loadAndReload("tdf79186_noLayoutInCell.odt"); + CPPUNIT_ASSERT_EQUAL(1, getShapes()); + CPPUNIT_ASSERT_EQUAL(1, getPages()); + + CPPUNIT_ASSERT(!getProperty<bool>(getShape(1), "IsFollowingTextFlow")); + CPPUNIT_ASSERT(getProperty<bool>(getShape(1), "SurroundContour")); // tdf#140508 +} + +CPPUNIT_TEST_FIXTURE(Test, testClearingBreak) +{ + auto verify = [this]() { + uno::Reference<container::XEnumerationAccess> xParagraph(getParagraph(1), uno::UNO_QUERY); + uno::Reference<container::XEnumeration> xPortions = xParagraph->createEnumeration(); + xPortions->nextElement(); + xPortions->nextElement(); + // Without the accompanying fix in place, this test would have failed with: + // An uncaught exception of type com.sun.star.container.NoSuchElementException + // i.e. the first para was just a fly + text portion, the clearing break was lost. + uno::Reference<beans::XPropertySet> xPortion(xPortions->nextElement(), uno::UNO_QUERY); + OUString aPortionType; + xPortion->getPropertyValue("TextPortionType") >>= aPortionType; + CPPUNIT_ASSERT_EQUAL(OUString("LineBreak"), aPortionType); + uno::Reference<text::XTextContent> xLineBreak; + xPortion->getPropertyValue("LineBreak") >>= xLineBreak; + sal_Int16 eClear{}; + uno::Reference<beans::XPropertySet> xLineBreakProps(xLineBreak, uno::UNO_QUERY); + xLineBreakProps->getPropertyValue("Clear") >>= eClear; + CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int16>(SwLineBreakClear::ALL), eClear); + }; + + // Given a document with a clearing break: + // When loading that file: + createSwDoc("clearing-break.doc"); + // Then make sure that the clear property of the break is not ignored: + verify(); + saveAndReload("MS Word 97"); + // Make sure that the clear property of the break is not ignored during export: + verify(); +} + +CPPUNIT_TEST_FIXTURE(Test, testTdf142840) +{ + loadAndReload("tdf142840.odt"); + CPPUNIT_ASSERT_EQUAL(1, getPages()); + + uno::Reference<text::XBookmarksSupplier> xBookmarksSupplier(mxComponent, uno::UNO_QUERY); + uno::Reference<container::XIndexAccess> xBookmarksByIdx(xBookmarksSupplier->getBookmarks(), uno::UNO_QUERY); + uno::Reference<container::XNameAccess> xBookmarksByName = xBookmarksSupplier->getBookmarks(); + + // Ensure space are replaced by underscore in bookmark name (it was working before, but ensure this) + CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(1), xBookmarksByIdx->getCount()); + CPPUNIT_ASSERT(xBookmarksByName->hasByName("Chapter_1")); + CPPUNIT_ASSERT(!xBookmarksByName->hasByName("Chapter 1")); + + // And hyperlink is referring bookmark with underscore also (this was broken) + CPPUNIT_ASSERT_EQUAL(OUString("#Chapter_1"), getProperty<OUString>(getRun(getParagraph(1), 1), "HyperLinkURL")); +} CPPUNIT_PLUGIN_IMPLEMENT(); diff --git a/sw/qa/extras/ww8export/ww8export4.cxx b/sw/qa/extras/ww8export/ww8export4.cxx new file mode 100644 index 000000000000..d3bc9c4071d9 --- /dev/null +++ b/sw/qa/extras/ww8export/ww8export4.cxx @@ -0,0 +1,324 @@ +/* -*- 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/beans/XPropertySet.hpp> +#include <com/sun/star/container/XIndexAccess.hpp> +#include <com/sun/star/document/XDocumentPropertiesSupplier.hpp> +#include <com/sun/star/graphic/XGraphic.hpp> +#include <com/sun/star/style/ParagraphAdjust.hpp> +#include <com/sun/star/text/TextContentAnchorType.hpp> +#include <com/sun/star/text/XTextDocument.hpp> +#include <com/sun/star/text/XTextTable.hpp> + +#include <comphelper/sequenceashashmap.hxx> +#include <o3tl/string_view.hxx> +#include <svx/svdpage.hxx> + +#include <docsh.hxx> +#include <drawdoc.hxx> +#include <IDocumentDrawModelAccess.hxx> +#include <IDocumentMarkAccess.hxx> +#include <IDocumentSettingAccess.hxx> +#include <unotxdoc.hxx> +#include <ndtxt.hxx> +#include <editeng/lrspitem.hxx> +#include <wrtsh.hxx> +#include <itabenum.hxx> +#include <frmmgr.hxx> +#include <formatflysplit.hxx> +#include <fmtwrapinfluenceonobjpos.hxx> + +namespace +{ +class Test : public SwModelTestBase +{ +public: + Test() + : SwModelTestBase("/sw/qa/extras/ww8export/data/", "MS Word 97") + { + } +}; + +CPPUNIT_TEST_FIXTURE(Test, testTdf77964) +{ + loadAndReload("tdf77964.doc"); + // both images were loading as AT_PARA instead of AS_CHAR. Image2 visually had text wrapping. + CPPUNIT_ASSERT_EQUAL(text::TextContentAnchorType_AS_CHARACTER, getProperty<text::TextContentAnchorType>(getShapeByName(u"Image2"), "AnchorType")); +} + +DECLARE_WW8EXPORT_TEST(testTdf160049_anchorMargin, "tdf160049_anchorMargin.doc") +{ + // given a document with a LEFT "column/text" anchored image + + // The image takes into account the margin, so it looks like it is in the middle of the doc, + // which is "Paragraph text area"/PRINT_AREA/1, not "Entire paragraph area"/FRAME/0 + CPPUNIT_ASSERT_EQUAL(css::text::RelOrientation::PRINT_AREA, + getProperty<sal_Int16>(getShape(1), "HoriOrientRelation")); +} + +DECLARE_WW8EXPORT_TEST(testTdf150197_anlv2ListFormat, "tdf150197_anlv2ListFormat.doc") +{ + CPPUNIT_ASSERT_EQUAL(OUString("1."), getProperty<OUString>(getParagraph(2), "ListLabelString")); + CPPUNIT_ASSERT_EQUAL(OUString("2."), getProperty<OUString>(getParagraph(3), "ListLabelString")); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Did you fix me? I should be 2.1", OUString("4.1"), + getProperty<OUString>(getParagraph(4), "ListLabelString")); +} + +DECLARE_WW8EXPORT_TEST(testTdf117994_CRnumformatting, "tdf117994_CRnumformatting.doc") +{ + CPPUNIT_ASSERT_EQUAL(OUString("1."), parseDump("//body/txt[1]/SwParaPortion/SwLineLayout/child::*[@type='PortionType::Number']"_ostr, "expand"_ostr)); + //Without this fix in place, it would become 200 (and non-bold). + CPPUNIT_ASSERT_EQUAL(OUString("160"), parseDump("//body/txt[1]/SwParaPortion/SwLineLayout/child::*[@type='PortionType::Number']/SwFont"_ostr, "height"_ostr)); +} + +DECLARE_WW8EXPORT_TEST(testTdf151548_formFieldMacros, "tdf151548_formFieldMacros.doc") +{ + SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument *>(mxComponent.get()); + SwDoc* pDoc = pTextDoc->GetDocShell()->GetDoc(); + IDocumentMarkAccess* pMarkAccess = pDoc->getIDocumentMarkAccess(); + for(auto aIter = pMarkAccess->getFieldmarksBegin(); aIter != pMarkAccess->getFieldmarksEnd(); ++aIter) + { + const OUString sName = (*aIter)->GetName(); + CPPUNIT_ASSERT(sName == "Check1" || sName == "Check2" || sName == "Text1" || sName == "Dropdown1"); + } +} + +DECLARE_WW8EXPORT_TEST(testTdf141649_conditionalText, "tdf141649_conditionalText.doc") +{ + // In MS Word, the IF field is editable and requires manual update, so the most correct + // result is "manual refresh with F9" inside a text field, + // but for our purposes, a single instance of "trueResult" is appropriate. + getParagraph(1, "trueResult"); +} + +DECLARE_WW8EXPORT_TEST(testTdf90408, "tdf90408.doc") +{ + uno::Reference<beans::XPropertySet> xRun(getRun(getParagraph(1), 1), uno::UNO_QUERY_THROW); + CPPUNIT_ASSERT_EQUAL_MESSAGE("checkbox is 16pt", 16.f, getProperty<float>(xRun, "CharHeight")); + xRun.set(getRun(getParagraph(1), 2, "unchecked"), uno::UNO_QUERY_THROW); + CPPUNIT_ASSERT_EQUAL_MESSAGE("text is 12pt", 12.f, getProperty<float>(xRun, "CharHeight")); +} + +DECLARE_WW8EXPORT_TEST(testTdf90408B, "tdf90408B.doc") +{ + uno::Reference<text::XTextTablesSupplier> xTextTablesSupplier(mxComponent, uno::UNO_QUERY); + uno::Reference<container::XIndexAccess> xTables(xTextTablesSupplier->getTextTables(), uno::UNO_QUERY); + uno::Reference<text::XTextTable> xTable(xTables->getByIndex(0), uno::UNO_QUERY); + uno::Reference<text::XTextRange> xCell(xTable->getCellByName("A1"), uno::UNO_QUERY); + + uno::Reference<container::XEnumerationAccess> xParaEnumAccess(xCell->getText(), uno::UNO_QUERY); + uno::Reference<container::XEnumeration> xParaEnum = xParaEnumAccess->createEnumeration(); + uno::Reference<text::XTextRange> xPara(xParaEnum->nextElement(), uno::UNO_QUERY); + + uno::Reference<beans::XPropertySet> xRun(getRun(xPara, 1), uno::UNO_QUERY_THROW); + CPPUNIT_ASSERT_EQUAL_MESSAGE("checkbox is 28pt", 28.f, getProperty<float>(xRun, "CharHeight")); + xRun.set(getRun(xPara, 2, u" Κατάψυξη, "_ustr), uno::UNO_QUERY_THROW); + CPPUNIT_ASSERT_EQUAL_MESSAGE("text is 10pt", 10.f, getProperty<float>(xRun, "CharHeight")); +} + +DECLARE_WW8EXPORT_TEST(testTdf155465_paraAdjustDistribute, "tdf155465_paraAdjustDistribute.doc") +{ + // Without the accompanying fix in place, this test would have failed with + // 'Expected: 2; Actual : 0', i.e. the first paragraph's ParaAdjust was left, not block. + const style::ParagraphAdjust eBlock = style::ParagraphAdjust_BLOCK; + auto nAdjust = getProperty<sal_Int16>(getParagraph(1), "ParaAdjust"); + CPPUNIT_ASSERT_EQUAL(eBlock, static_cast<style::ParagraphAdjust>(nAdjust)); + + nAdjust = getProperty<sal_Int16>(getParagraph(1), "ParaLastLineAdjust"); + CPPUNIT_ASSERT_EQUAL(eBlock, static_cast<style::ParagraphAdjust>(nAdjust)); + + nAdjust = getProperty<sal_Int16>(getParagraph(2), "ParaAdjust"); + CPPUNIT_ASSERT_EQUAL(eBlock, static_cast<style::ParagraphAdjust>(nAdjust)); + + nAdjust = getProperty<sal_Int16>(getParagraph(2), "ParaLastLineAdjust"); + CPPUNIT_ASSERT_EQUAL(style::ParagraphAdjust_LEFT, static_cast<style::ParagraphAdjust>(nAdjust)); +} + +CPPUNIT_TEST_FIXTURE(Test, testDontBreakWrappedTables) +{ + // Given a document with the DO_NOT_BREAK_WRAPPED_TABLES compat mode enabled: + createSwDoc(); + { + SwDoc* pDoc = getSwDoc(); + IDocumentSettingAccess& rIDSA = pDoc->getIDocumentSettingAccess(); + rIDSA.set(DocumentSettingId::DO_NOT_BREAK_WRAPPED_TABLES, true); + } + + // When saving to doc: + saveAndReload("MS Word 97"); + + // Then make sure the compat flag is serialized: + SwDoc* pDoc = getSwDoc(); + IDocumentSettingAccess& rIDSA = pDoc->getIDocumentSettingAccess(); + bool bDontBreakWrappedTables = rIDSA.get(DocumentSettingId::DO_NOT_BREAK_WRAPPED_TABLES); + // Without the accompanying fix in place, this test would have failed, the compat flag was not + // set. + CPPUNIT_ASSERT(bDontBreakWrappedTables); +} + +CPPUNIT_TEST_FIXTURE(Test, testFloattableOverlapNeverDOCExport) +{ + // Given a document with a floating table, overlap is not allowed: + { + createSwDoc(); + SwDoc* pDoc = getSwDoc(); + SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell(); + pWrtShell->Insert2("before table"); + // Insert a table: + SwInsertTableOptions aTableOptions(SwInsertTableFlags::DefaultBorder, 0); + pWrtShell->InsertTable(aTableOptions, /*nRows=*/1, /*nCols=*/1); + pWrtShell->MoveTable(GotoPrevTable, fnTableStart); + // Select table: + pWrtShell->SelAll(); + // Wrap the table in a text frame: + SwFlyFrameAttrMgr aMgr(true, pWrtShell, Frmmgr_Type::TEXT, nullptr); + pWrtShell->StartAllAction(); + aMgr.InsertFlyFrame(RndStdIds::FLY_AT_PARA, aMgr.GetPos(), aMgr.GetSize()); + pWrtShell->EndAllAction(); + // Allow the text frame to split: + pWrtShell->StartAllAction(); + sw::FrameFormats<sw::SpzFrameFormat*>* pFlys = pDoc->GetSpzFrameFormats(); + sw::SpzFrameFormat* pFly = (*pFlys)[0]; + SwAttrSet aSet(pFly->GetAttrSet()); + aSet.Put(SwFormatFlySplit(true)); + // Don't allow overlap: + SwFormatWrapInfluenceOnObjPos aInfluence; + aInfluence.SetAllowOverlap(false); + aSet.Put(aInfluence); + pDoc->SetAttr(aSet, *pFly); + pWrtShell->EndAllAction(); + } + + // When saving to DOC: + saveAndReload("MS Word 97"); + + // Then make sure that the overlap=never markup is written: + SwDoc* pDoc = getSwDoc(); + sw::FrameFormats<sw::SpzFrameFormat*>* pFlys = pDoc->GetSpzFrameFormats(); + sw::SpzFrameFormat* pFly = (*pFlys)[0]; + // Without the accompanying fix in place, this test would have failed, i.e. TFNoAllowOverlap was + // not written. + CPPUNIT_ASSERT(!pFly->GetAttrSet().GetWrapInfluenceOnObjPos().GetAllowOverlap()); +} + +bool IsFirstLine(const SwTextNode* pTextNode) +{ + const SfxPoolItem* pItem = pTextNode->GetNoCondAttr(RES_MARGIN_FIRSTLINE, false); + return !!pItem; +} + +DECLARE_WW8EXPORT_TEST(testInlinePageBreakFirstLine, "inlinePageBreakFirstLine.doc") +{ + SwDoc* pDoc = getSwDoc(); + const SwNodes& rNodes = pDoc->GetNodes(); + + std::vector<SwTextNode*> aTextNodes; + + for (SwNodeOffset nNode(0); nNode < rNodes.Count(); ++nNode) + { + SwNode* pNode = pDoc->GetNodes()[nNode]; + SwTextNode* pTextNode = pNode->GetTextNode(); + if (!pTextNode) + continue; + aTextNodes.push_back(pTextNode); + } + + CPPUNIT_ASSERT_EQUAL(size_t(3), aTextNodes.size()); + CPPUNIT_ASSERT_EQUAL(OUString("First line"), aTextNodes[0]->GetText()); + CPPUNIT_ASSERT(IsFirstLine(aTextNodes[0])); + // Here exists an inline pagebreak (a pagebreak without a paragraph before it) + // This text node is not indented because it is not the first line of the paragraph + CPPUNIT_ASSERT_EQUAL(OUString("Should not be indented"), aTextNodes[1]->GetText()); + CPPUNIT_ASSERT(!IsFirstLine(aTextNodes[1])); + // Here is the actual second paragraph + CPPUNIT_ASSERT_EQUAL(OUString("Should be indented"), aTextNodes[2]->GetText()); + CPPUNIT_ASSERT(IsFirstLine(aTextNodes[2])); +} + +CPPUNIT_TEST_FIXTURE(Test, testLegalNumbering) +{ + auto verify = [this]() { + // Second level's numbering should use Arabic numbers for first level reference + auto xPara = getParagraph(1); + CPPUNIT_ASSERT_EQUAL(OUString("CH I"), getProperty<OUString>(xPara, "ListLabelString")); + xPara = getParagraph(2); + // Without the accompanying fix in place, this test would have failed with: + // - Expected: Sect 1.01 + // - Actual : Sect I.01 + // i.e. fLegal was ignored on import/export. + CPPUNIT_ASSERT_EQUAL(OUString("Sect 1.01"), getProperty<OUString>(xPara, "ListLabelString")); + xPara = getParagraph(3); + CPPUNIT_ASSERT_EQUAL(OUString("CH II"), getProperty<OUString>(xPara, "ListLabelString")); + xPara = getParagraph(4); + CPPUNIT_ASSERT_EQUAL(OUString("Sect 2.01"), getProperty<OUString>(xPara, "ListLabelString")); + }; + + createSwDoc("listWithLgl.doc"); + verify(); + saveAndReload(mpFilter); + verify(); +} + +DECLARE_WW8EXPORT_TEST(testNonInlinePageBreakFirstLine, "nonInlinePageBreakFirstLine.doc") +{ + SwDoc* pDoc = getSwDoc(); + const SwNodes& rNodes = pDoc->GetNodes(); + + std::vector<SwTextNode*> aTextNodes; + + for (SwNodeOffset nNode(0); nNode < rNodes.Count(); ++nNode) + { + SwNode* pNode = pDoc->GetNodes()[nNode]; + SwTextNode* pTextNode = pNode->GetTextNode(); + if (!pTextNode) + continue; + aTextNodes.push_back(pTextNode); + } + + CPPUNIT_ASSERT_EQUAL(size_t(2), aTextNodes.size()); + CPPUNIT_ASSERT_EQUAL(OUString("First line"), aTextNodes[0]->GetText()); + CPPUNIT_ASSERT(IsFirstLine(aTextNodes[0])); + // Here exists a pagebreak after a paragraph + // This text node is indented because it is the first line of a paragraph + CPPUNIT_ASSERT_EQUAL(OUString("Should be indented"), aTextNodes[1]->GetText()); + CPPUNIT_ASSERT(IsFirstLine(aTextNodes[1])); +} + +DECLARE_WW8EXPORT_TEST(testTdf104704_mangledFooter, "tdf104704_mangledFooter.odt") +{ + CPPUNIT_ASSERT_EQUAL(2, getPages()); +} + +CPPUNIT_TEST_FIXTURE(Test, testEmptyGroup) +{ + // Given a document with an empty group + createSwDoc("empty_group.docx"); + + CPPUNIT_ASSERT_EQUAL(1, getPages()); + CPPUNIT_ASSERT_EQUAL(1, getShapes()); + SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument*>(mxComponent.get()); + CPPUNIT_ASSERT(pTextDoc); + SwDoc* pDoc = pTextDoc->GetDocShell()->GetDoc(); + SdrPage* pPage = pDoc->getIDocumentDrawModelAccess().GetDrawModel()->GetPage(0); + SdrObject* pObject = pPage->GetObj(0); + + CPPUNIT_ASSERT_EQUAL(u"Empty group"_ustr, pObject->GetName()); + CPPUNIT_ASSERT(pObject->IsGroupObject()); + CPPUNIT_ASSERT_EQUAL(size_t(0), pObject->GetSubList()->GetObjCount()); + + // it must not assert/crash on save + saveAndReload(mpFilter); +} + +} // end of anonymous namespace +CPPUNIT_PLUGIN_IMPLEMENT(); + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |