From a2baea7faff31d26459dab3668a39eae85e4991b Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Mon, 15 Apr 2024 11:27:30 +0200 Subject: Adding upstream version 4:24.2.1. Signed-off-by: Daniel Baumann --- sw/CppunitTest_sw_a11y.mk | 1 + sw/CppunitTest_sw_ooxmlexport21.mk | 14 + sw/Library_sw.mk | 1 - sw/Module_sw.mk | 1 + sw/inc/IDocumentMarkAccess.hxx | 7 + sw/inc/IDocumentSettingAccess.hxx | 2 + sw/inc/anchoreddrawobject.hxx | 4 +- sw/inc/anchoredobject.hxx | 4 +- sw/inc/ndtxt.hxx | 2 +- sw/inc/unoprnms.hxx | 1 + sw/qa/core/header_footer/HeaderFooterTest.cxx | 6 +- .../data/floattable-not-wrapped-by-table.docx | Bin 0 -> 12994 bytes sw/qa/core/layout/tabfrm.cxx | 22 + sw/qa/core/text/data/tdf159336.odt | Bin 0 -> 9417 bytes sw/qa/core/text/itrform2.cxx | 40 ++ sw/qa/core/text/text.cxx | 37 +- sw/qa/extras/accessibility/dialogs.cxx | 2 + sw/qa/extras/layout/data/sdt+framePr.docx | Bin 0 -> 12343 bytes sw/qa/extras/layout/data/table-0-height-rows.fodt | 630 +++++++++++++++++++++ sw/qa/extras/layout/layout3.cxx | 54 +- .../data/footnote_spacing_hanging_para.doc | Bin 0 -> 26624 bytes .../data/footnote_spacing_hanging_para.docx | Bin 0 -> 13638 bytes .../data/footnote_spacing_hanging_para.rtf | 209 +++++++ sw/qa/extras/odfexport/data/tdf106733.fodt | 66 +++ sw/qa/extras/odfexport/odfexport2.cxx | 119 ++++ sw/qa/extras/odfimport/data/tdf123968.odt | Bin 9591 -> 8904 bytes .../extras/odfimport/data/unreferenced_stream.odt | Bin 0 -> 10311 bytes sw/qa/extras/odfimport/odfimport.cxx | 27 + .../ooxmlexport/data/tdf153909_followTextFlow.docx | Bin 0 -> 23909 bytes .../data/tdf159207_footerFramePrBorder.docx | Bin 0 -> 17262 bytes sw/qa/extras/ooxmlexport/ooxmlexport19.cxx | 1 + sw/qa/extras/ooxmlexport/ooxmlexport21.cxx | 68 +++ sw/qa/extras/ooxmlexport/ooxmlexport8.cxx | 6 + sw/qa/extras/rtfexport/data/tdf136445-1-min.rtf | 17 + sw/qa/extras/rtfexport/data/tdf158409.rtf | 12 + .../rtfexport/data/tdf158586_pageBreak1_header.rtf | 17 + sw/qa/extras/rtfexport/rtfexport3.cxx | 9 + sw/qa/extras/rtfexport/rtfexport8.cxx | 56 +- sw/qa/extras/rtfimport/rtfimport.cxx | 2 +- .../data/tdf135083-simple-text-plus-list.fodt | 34 ++ .../data/tdf159049_LineBreakRTFClipboard.fodt | 300 ++++++++++ sw/qa/extras/uiwriter/uiwriter5.cxx | 4 +- sw/qa/extras/uiwriter/uiwriter9.cxx | 56 +- sw/qa/uitest/data/tdf106733.fodt | 66 +++ sw/qa/uitest/data/tdf159102.fodt | 61 ++ sw/qa/uitest/writer_tests8/tdf106733.py | 112 ++++ sw/qa/uitest/writer_tests8/tdf159102.py | 97 ++++ sw/source/core/access/AccessibilityCheck.cxx | 4 + sw/source/core/crsr/crsrsh.cxx | 11 +- sw/source/core/crsr/crstrvl.cxx | 1 + sw/source/core/doc/DocumentSettingManager.cxx | 11 + sw/source/core/doc/docbm.cxx | 10 + sw/source/core/doc/docdraw.cxx | 17 +- sw/source/core/doc/docfmt.cxx | 18 +- sw/source/core/doc/doclay.cxx | 6 +- sw/source/core/draw/dcontact.cxx | 8 +- sw/source/core/draw/dview.cxx | 23 +- sw/source/core/fields/expfld.cxx | 20 +- sw/source/core/fields/postithelper.cxx | 4 +- sw/source/core/frmedt/fefly1.cxx | 32 +- sw/source/core/frmedt/feshview.cxx | 48 +- sw/source/core/frmedt/fetab.cxx | 4 +- sw/source/core/frmedt/fews.cxx | 4 +- sw/source/core/inc/DocumentSettingManager.hxx | 1 + sw/source/core/inc/MarkManager.hxx | 1 + sw/source/core/inc/flyfrm.hxx | 4 +- sw/source/core/inc/txtfrm.hxx | 2 +- sw/source/core/inc/unofield.hxx | 2 +- sw/source/core/layout/anchoreddrawobject.cxx | 64 ++- sw/source/core/layout/anchoredobject.cxx | 148 ++--- sw/source/core/layout/atrfrm.cxx | 2 +- sw/source/core/layout/calcmove.cxx | 8 +- sw/source/core/layout/flowfrm.cxx | 16 +- sw/source/core/layout/fly.cxx | 52 +- sw/source/core/layout/flycnt.cxx | 10 +- sw/source/core/layout/flyincnt.cxx | 2 +- sw/source/core/layout/flylay.cxx | 117 ++-- sw/source/core/layout/frmtool.cxx | 39 +- sw/source/core/layout/layact.cxx | 2 +- sw/source/core/layout/objectformattertxtfrm.cxx | 17 +- sw/source/core/layout/pagechg.cxx | 26 +- sw/source/core/layout/sortedobjs.cxx | 22 +- sw/source/core/layout/tabfrm.cxx | 165 +++++- sw/source/core/layout/trvlfrm.cxx | 74 +-- sw/source/core/layout/wsfrm.cxx | 6 +- .../objectpositioning/anchoredobjectposition.cxx | 2 +- .../tocntntanchoredobjectposition.cxx | 4 +- sw/source/core/table/swnewtable.cxx | 9 +- sw/source/core/text/EnhancedPDFExportHelper.cxx | 7 +- sw/source/core/text/frmform.cxx | 2 +- sw/source/core/text/guess.cxx | 7 +- sw/source/core/text/inftxt.cxx | 2 +- sw/source/core/text/itratr.cxx | 2 +- sw/source/core/text/itrform2.cxx | 13 +- sw/source/core/text/porfld.cxx | 14 +- sw/source/core/text/porfly.cxx | 2 +- sw/source/core/text/porlay.cxx | 2 +- sw/source/core/text/porrst.cxx | 12 + sw/source/core/text/portxt.cxx | 12 +- sw/source/core/text/txtfly.cxx | 178 +++--- sw/source/core/text/txtfrm.cxx | 6 +- sw/source/core/txtnode/ndtxt.cxx | 6 +- sw/source/core/txtnode/thints.cxx | 25 +- sw/source/core/undo/undel.cxx | 27 +- sw/source/core/unocore/unofield.cxx | 30 +- sw/source/core/unocore/unomap1.cxx | 1 + sw/source/core/unocore/unoobj2.cxx | 12 +- sw/source/core/unocore/unoportenum.cxx | 16 +- sw/source/core/unocore/unostyle.cxx | 28 +- sw/source/filter/writer/writer.cxx | 6 +- sw/source/filter/ww8/docxsdrexport.cxx | 5 + sw/source/filter/ww8/wrtww8.cxx | 6 +- sw/source/filter/ww8/ww8par.cxx | 7 +- sw/source/ui/fldui/flddok.cxx | 2 +- .../uibase/dialog/SwSpellDialogChildWindow.cxx | 5 + sw/source/uibase/docvw/edtwin.cxx | 63 ++- sw/source/uibase/inc/edtwin.hxx | 3 +- sw/source/uibase/shells/drwbassh.cxx | 16 +- .../uibase/sidebar/WriterInspectorTextPanel.cxx | 12 +- sw/source/uibase/uno/SwXDocumentSettings.cxx | 13 + sw/source/uibase/utlui/content.cxx | 4 +- 121 files changed, 3128 insertions(+), 601 deletions(-) create mode 100644 sw/CppunitTest_sw_ooxmlexport21.mk create mode 100644 sw/qa/core/layout/data/floattable-not-wrapped-by-table.docx create mode 100644 sw/qa/core/text/data/tdf159336.odt create mode 100644 sw/qa/extras/layout/data/sdt+framePr.docx create mode 100644 sw/qa/extras/layout/data/table-0-height-rows.fodt create mode 100644 sw/qa/extras/odfexport/data/footnote_spacing_hanging_para.doc create mode 100644 sw/qa/extras/odfexport/data/footnote_spacing_hanging_para.docx create mode 100644 sw/qa/extras/odfexport/data/footnote_spacing_hanging_para.rtf create mode 100644 sw/qa/extras/odfexport/data/tdf106733.fodt create mode 100644 sw/qa/extras/odfimport/data/unreferenced_stream.odt create mode 100644 sw/qa/extras/ooxmlexport/data/tdf153909_followTextFlow.docx create mode 100644 sw/qa/extras/ooxmlexport/data/tdf159207_footerFramePrBorder.docx create mode 100644 sw/qa/extras/ooxmlexport/ooxmlexport21.cxx create mode 100644 sw/qa/extras/rtfexport/data/tdf136445-1-min.rtf create mode 100644 sw/qa/extras/rtfexport/data/tdf158409.rtf create mode 100644 sw/qa/extras/rtfexport/data/tdf158586_pageBreak1_header.rtf create mode 100644 sw/qa/extras/uiwriter/data/tdf135083-simple-text-plus-list.fodt create mode 100644 sw/qa/extras/uiwriter/data/tdf159049_LineBreakRTFClipboard.fodt create mode 100644 sw/qa/uitest/data/tdf106733.fodt create mode 100644 sw/qa/uitest/data/tdf159102.fodt create mode 100644 sw/qa/uitest/writer_tests8/tdf106733.py create mode 100644 sw/qa/uitest/writer_tests8/tdf159102.py (limited to 'sw') diff --git a/sw/CppunitTest_sw_a11y.mk b/sw/CppunitTest_sw_a11y.mk index a0d76a20d5..f67f4cf89e 100644 --- a/sw/CppunitTest_sw_a11y.mk +++ b/sw/CppunitTest_sw_a11y.mk @@ -17,6 +17,7 @@ $(eval $(call gb_CppunitTest_add_exception_objects,sw_a11y, \ )) $(eval $(call gb_CppunitTest_use_libraries,sw_a11y, \ + acc \ sal \ cppu \ subsequenttest \ diff --git a/sw/CppunitTest_sw_ooxmlexport21.mk b/sw/CppunitTest_sw_ooxmlexport21.mk new file mode 100644 index 0000000000..999314b9c6 --- /dev/null +++ b/sw/CppunitTest_sw_ooxmlexport21.mk @@ -0,0 +1,14 @@ +# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*- +#************************************************************************* +# +# 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/. +# +#************************************************************************* + +$(eval $(call sw_ooxmlexport_test,21)) + +# vim: set noet sw=4 ts=4: diff --git a/sw/Library_sw.mk b/sw/Library_sw.mk index bd5d831f7f..707f5506d6 100644 --- a/sw/Library_sw.mk +++ b/sw/Library_sw.mk @@ -56,7 +56,6 @@ $(eval $(call gb_Library_use_libraries,sw,\ comphelper \ cppu \ cppuhelper \ - cui \ $(call gb_Helper_optional,DBCONNECTIVITY, \ dbtools) \ docmodel \ diff --git a/sw/Module_sw.mk b/sw/Module_sw.mk index 85d36b1ab5..7d5679e52f 100644 --- a/sw/Module_sw.mk +++ b/sw/Module_sw.mk @@ -95,6 +95,7 @@ $(eval $(call gb_Module_add_slowcheck_targets,sw,\ CppunitTest_sw_ooxmlexport18 \ CppunitTest_sw_ooxmlexport19 \ CppunitTest_sw_ooxmlexport20 \ + CppunitTest_sw_ooxmlexport21 \ CppunitTest_sw_ooxmlexport_template \ CppunitTest_sw_ooxmlfieldexport \ CppunitTest_sw_ooxmllinks \ diff --git a/sw/inc/IDocumentMarkAccess.hxx b/sw/inc/IDocumentMarkAccess.hxx index d63b58f606..bc8f2e1c03 100644 --- a/sw/inc/IDocumentMarkAccess.hxx +++ b/sw/inc/IDocumentMarkAccess.hxx @@ -279,6 +279,13 @@ class IDocumentMarkAccess */ virtual const_iterator_t findMark(const OUString& rMark) const =0; + /** Find the first Mark that does not start before. + + @returns + an iterator pointing to the mark, or pointing to getAllMarksEnd() if nothing was found. + */ + virtual const_iterator_t findFirstMarkNotStartsBefore(const SwPosition& rPos) const =0; + // interface IBookmarks (BOOKMARK, CROSSREF_NUMITEM_BOOKMARK, CROSSREF_HEADING_BOOKMARK ) /** check if the selection would delete a BOOKMARK */ diff --git a/sw/inc/IDocumentSettingAccess.hxx b/sw/inc/IDocumentSettingAccess.hxx index b808844016..74b123dc46 100644 --- a/sw/inc/IDocumentSettingAccess.hxx +++ b/sw/inc/IDocumentSettingAccess.hxx @@ -58,6 +58,8 @@ enum class DocumentSettingId DO_NOT_JUSTIFY_LINES_WITH_MANUAL_BREAK, TREAT_SINGLE_COLUMN_BREAK_AS_PAGE_BREAK, DO_NOT_RESET_PARA_ATTRS_FOR_NUM_FONT, + // tdf#159382: MS Word compatible handling of space between footnote number and text + NO_GAP_AFTER_NOTE_NUMBER, DO_NOT_CAPTURE_DRAW_OBJS_ON_PAGE, TABLE_ROW_KEEP, diff --git a/sw/inc/anchoreddrawobject.hxx b/sw/inc/anchoreddrawobject.hxx index 609582d4d3..bfc40fe07a 100644 --- a/sw/inc/anchoreddrawobject.hxx +++ b/sw/inc/anchoreddrawobject.hxx @@ -115,8 +115,8 @@ class SwAnchoredDrawObject final : public SwAnchoredObject } // accessors to the format - virtual SwFrameFormat& GetFrameFormat() override; - virtual const SwFrameFormat& GetFrameFormat() const override; + virtual SwFrameFormat* GetFrameFormat() override; + virtual const SwFrameFormat* GetFrameFormat() const override; // accessors to the object area and its position virtual SwRect GetObjRect() const override; diff --git a/sw/inc/anchoredobject.hxx b/sw/inc/anchoredobject.hxx index 19cd2e7580..48b192f69b 100644 --- a/sw/inc/anchoredobject.hxx +++ b/sw/inc/anchoredobject.hxx @@ -318,8 +318,8 @@ class SW_DLLPUBLIC SwAnchoredObject void SetCurrRelPos( Point _aRelPos ); // accessors to the format - virtual SwFrameFormat& GetFrameFormat() = 0; - virtual const SwFrameFormat& GetFrameFormat() const = 0; + virtual SwFrameFormat* GetFrameFormat() = 0; + virtual const SwFrameFormat* GetFrameFormat() const = 0; // accessors to the object area and its position virtual SwRect GetObjRect() const = 0; diff --git a/sw/inc/ndtxt.hxx b/sw/inc/ndtxt.hxx index 3f99919f77..352dad71c2 100644 --- a/sw/inc/ndtxt.hxx +++ b/sw/inc/ndtxt.hxx @@ -720,7 +720,7 @@ public: void fillSoftPageBreakList( SwSoftPageBreakList& rBreak ) const; LanguageType GetLang( const sal_Int32 nBegin, const sal_Int32 nLen = 0, - sal_uInt16 nScript = 0 ) const; + sal_uInt16 nScript = 0, bool bNoneIfNoHyphenation = false ) const; /// in ndcopy.cxx bool IsSymbolAt(sal_Int32 nBegin) const; // In itratr.cxx. diff --git a/sw/inc/unoprnms.hxx b/sw/inc/unoprnms.hxx index 2c98a87dba..fdbc3c8f36 100644 --- a/sw/inc/unoprnms.hxx +++ b/sw/inc/unoprnms.hxx @@ -205,6 +205,7 @@ inline constexpr OUString UNO_NAME_POSITION_PROTECTED = u"PositionProtected"_ust inline constexpr OUString UNO_NAME_ALTERNATIVE_TEXT = u"AlternativeText"_ustr; inline constexpr OUString UNO_NAME_PRIMARY_KEY = u"PrimaryKey"_ustr; inline constexpr OUString UNO_NAME_PRINTER_PAPER_TRAY = u"PrinterPaperTray"_ustr; +inline constexpr OUString UNO_NAME_PRINTER_PAPER_TRAY_INDEX = u"PrinterPaperTrayIndex"_ustr; inline constexpr OUString UNO_NAME_RELATIVE_WIDTH = u"RelativeWidth"_ustr; inline constexpr OUString UNO_NAME_RELATIVE_WIDTH_RELATION = u"RelativeWidthRelation"_ustr; inline constexpr OUString UNO_NAME_RELATIVE_HEIGHT = u"RelativeHeight"_ustr; diff --git a/sw/qa/core/header_footer/HeaderFooterTest.cxx b/sw/qa/core/header_footer/HeaderFooterTest.cxx index 6bb5fd6167..4d2938ef28 100644 --- a/sw/qa/core/header_footer/HeaderFooterTest.cxx +++ b/sw/qa/core/header_footer/HeaderFooterTest.cxx @@ -467,10 +467,8 @@ CPPUNIT_TEST_FIXTURE(HeaderFooterTest, testTdf112694) auto verify = [this]() { uno::Any aPageStyle = getStyles("PageStyles")->getByName("Standard"); // Header was on when header for file was for explicit first pages only - // (marked via ). - //CPPUNIT_ASSERT(!getProperty(aPageStyle, "HeaderIsOn")); - // TODO - can't disable headers/footers selectively (only fo first page) - CPPUNIT_ASSERT(getProperty(aPageStyle, "HeaderIsOn")); + // but was missing. + CPPUNIT_ASSERT(!getProperty(aPageStyle, "HeaderIsOn")); }; createSwDoc("tdf112694.docx"); diff --git a/sw/qa/core/layout/data/floattable-not-wrapped-by-table.docx b/sw/qa/core/layout/data/floattable-not-wrapped-by-table.docx new file mode 100644 index 0000000000..2c255148d3 Binary files /dev/null and b/sw/qa/core/layout/data/floattable-not-wrapped-by-table.docx differ diff --git a/sw/qa/core/layout/tabfrm.cxx b/sw/qa/core/layout/tabfrm.cxx index 9357fc2df1..61b1a25109 100644 --- a/sw/qa/core/layout/tabfrm.cxx +++ b/sw/qa/core/layout/tabfrm.cxx @@ -199,6 +199,28 @@ CPPUNIT_TEST_FIXTURE(Test, testSplitFlyWrappedByTable) // i.e. the inline table was under the floating one, not on the right of it. CPPUNIT_ASSERT_LESS(nFloatingBottom, nInlineTop); } + +CPPUNIT_TEST_FIXTURE(Test, testInlineTableThenSplitFly) +{ + // Given a document with a floating table ("right") and an inline table ("left"): + // When laying out the document: + createSwDoc("floattable-not-wrapped-by-table.docx"); + + // Then make sure the inline table is on the left (small negative offset): + SwDoc* pDoc = getSwDoc(); + SwRootFrame* pLayout = pDoc->getIDocumentLayoutAccess().GetCurrentLayout(); + auto pPage = pLayout->Lower()->DynCastPageFrame(); + CPPUNIT_ASSERT(pPage); + SwFrame* pBody = pPage->FindBodyCont(); + auto pTab = pBody->GetLower()->GetNext()->DynCastTabFrame(); + SwTwips nInlineLeft = pTab->getFramePrintArea().Left(); + // Without the accompanying fix in place, this test would have failed with: + // - Expected less than: 0 + // - Actual : 6958 + // i.e. "left" was on the right, its horizontal margin was not a small negative value but a + // large positive one. + CPPUNIT_ASSERT_LESS(static_cast(0), nInlineLeft); +} } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/qa/core/text/data/tdf159336.odt b/sw/qa/core/text/data/tdf159336.odt new file mode 100644 index 0000000000..4f396e4f2a Binary files /dev/null and b/sw/qa/core/text/data/tdf159336.odt differ diff --git a/sw/qa/core/text/itrform2.cxx b/sw/qa/core/text/itrform2.cxx index fc8e981dcf..6d59140f97 100644 --- a/sw/qa/core/text/itrform2.cxx +++ b/sw/qa/core/text/itrform2.cxx @@ -16,6 +16,10 @@ #include #include #include +#include +#include +#include +#include namespace { @@ -166,6 +170,42 @@ CPPUNIT_TEST_FIXTURE(Test, testSplitFlyAnchorLeftMargin) // i.e. the left margin was lost. CPPUNIT_ASSERT_EQUAL(static_cast(6480), pLastPara->getFramePrintArea().Left()); } + +CPPUNIT_TEST_FIXTURE(Test, testCheckedCheckboxContentControlPDF) +{ + std::shared_ptr pPDFium = vcl::pdf::PDFiumLibrary::get(); + if (!pPDFium) + return; + + // Given a file with a checked checkbox content control: + createSwDoc(); + SwDoc* pDoc = getSwDoc(); + SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell(); + pWrtShell->InsertContentControl(SwContentControlType::CHECKBOX); + // Toggle it, so we get a checked one: + SwTextContentControl* pTextContentControl = pWrtShell->CursorInsideContentControl(); + const SwFormatContentControl& rFormatContentControl = pTextContentControl->GetContentControl(); + pWrtShell->GotoContentControl(rFormatContentControl); + + // When exporting to PDF: + save("writer_pdf_Export"); + + // Then make sure that a checked checkbox form widget is emitted: + std::unique_ptr pPdfDocument = parsePDFExport(); + std::unique_ptr pPage = pPdfDocument->openPage(0); + CPPUNIT_ASSERT_EQUAL(1, pPage->getAnnotationCount()); + std::unique_ptr pAnnotation = pPage->getAnnotation(0); + CPPUNIT_ASSERT_EQUAL(vcl::pdf::PDFAnnotationSubType::Widget, pAnnotation->getSubType()); + CPPUNIT_ASSERT_EQUAL(vcl::pdf::PDFFormFieldType::CheckBox, + pAnnotation->getFormFieldType(pPdfDocument.get())); + OUString aActual = pAnnotation->getFormFieldValue(pPdfDocument.get()); + // Without the accompanying fix in place, this test would have failed with: + // - Expected: Yes + // - Actual : Off + // i.e. the /AP -> /N key of the checkbox widget annotation object didn't have a sub-key that + // would match /V, leading to not showing the checked state. + CPPUNIT_ASSERT_EQUAL(OUString("Yes"), aActual); +} } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/qa/core/text/text.cxx b/sw/qa/core/text/text.cxx index 666e6d29f2..690fc333af 100644 --- a/sw/qa/core/text/text.cxx +++ b/sw/qa/core/text/text.cxx @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -115,6 +116,40 @@ CPPUNIT_TEST_FIXTURE(SwCoreTextTest, testLastBibliographyPdfExport) CPPUNIT_ASSERT(true); } +CPPUNIT_TEST_FIXTURE(SwCoreTextTest, testTdf159336) +{ + createSwDoc("tdf159336.odt"); + save("writer_pdf_Export"); + + vcl::filter::PDFDocument aDocument; + SvFileStream aStream(maTempFile.GetURL(), StreamMode::READ); + CPPUNIT_ASSERT(aDocument.Read(aStream)); + + // The document has one page. + std::vector aPages = aDocument.GetPages(); + CPPUNIT_ASSERT_EQUAL(static_cast(1), aPages.size()); + + auto pAnnots = dynamic_cast(aPages[0]->Lookup("Annots"_ostr)); + CPPUNIT_ASSERT(pAnnots); + + CPPUNIT_ASSERT_EQUAL(static_cast(1), pAnnots->GetElements().size()); + auto pAnnotReference + = dynamic_cast(pAnnots->GetElements()[0]); + CPPUNIT_ASSERT(pAnnotReference); + vcl::filter::PDFObjectElement* pAnnot = pAnnotReference->LookupObject(); + CPPUNIT_ASSERT(pAnnot); + CPPUNIT_ASSERT_EQUAL( + "Annot"_ostr, + static_cast(pAnnot->Lookup("Type"_ostr))->GetValue()); + CPPUNIT_ASSERT_EQUAL( + "Widget"_ostr, + static_cast(pAnnot->Lookup("Subtype"_ostr))->GetValue()); + // Ff = multiline + auto pFf = dynamic_cast(pAnnot->Lookup("Ff"_ostr)); + CPPUNIT_ASSERT(pFf); + CPPUNIT_ASSERT_EQUAL(4096.0, pFf->GetValue()); +} + CPPUNIT_TEST_FIXTURE(SwCoreTextTest, testBibliographyUrlPdfExport) { // Given a document with a bibliography entry field: @@ -767,7 +802,7 @@ CPPUNIT_TEST_FIXTURE(SwCoreTextTest, testAsCharImageDocModelFromViewPoint) const SwSortedObjs& rSortedObjs = *pTextFrame->GetDrawObjs(); const SwAnchoredObject* pAnchoredObject = rSortedObjs[0]; // The content points to the start node, the next node is the graphic node. - SwNodeIndex aGraphicNode = *pAnchoredObject->GetFrameFormat().GetContent().GetContentIdx(); + SwNodeIndex aGraphicNode = *pAnchoredObject->GetFrameFormat()->GetContent().GetContentIdx(); ++aGraphicNode; tools::Rectangle aFlyFrame = pAnchoredObject->GetDrawObj()->GetLastBoundRect(); Point aDocPos = aFlyFrame.Center(); diff --git a/sw/qa/extras/accessibility/dialogs.cxx b/sw/qa/extras/accessibility/dialogs.cxx index a14eed6bdb..091e6729c9 100644 --- a/sw/qa/extras/accessibility/dialogs.cxx +++ b/sw/qa/extras/accessibility/dialogs.cxx @@ -176,6 +176,7 @@ CPPUNIT_TEST_FIXTURE(test::SwAccessibleTestBase, BasicTestFontworkDialog) collectText()); } +#if !defined(_WIN32) CPPUNIT_TEST_FIXTURE(test::SwAccessibleTestBase, BasicTestFrameDialog) { load(u"private:factory/swriter"_ustr); @@ -193,6 +194,7 @@ CPPUNIT_TEST_FIXTURE(test::SwAccessibleTestBase, BasicTestFrameDialog) rtl::OUString(""), collectText()); } +#endif //defined(_WIN32) #endif //defined(MACOSX) diff --git a/sw/qa/extras/layout/data/sdt+framePr.docx b/sw/qa/extras/layout/data/sdt+framePr.docx new file mode 100644 index 0000000000..d46bcbfaa7 Binary files /dev/null and b/sw/qa/extras/layout/data/sdt+framePr.docx differ diff --git a/sw/qa/extras/layout/data/table-0-height-rows.fodt b/sw/qa/extras/layout/data/table-0-height-rows.fodt new file mode 100644 index 0000000000..f32e2fbe99 --- /dev/null +++ b/sw/qa/extras/layout/data/table-0-height-rows.fodt @@ -0,0 +1,630 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + dfghdfgnhdfgnhdbhfghndhgbhdfbh + + + von + + + bis + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + fgdhgfhdfbhfbhfbhfgbfdbhdfbhfgbnfdbhdfbg + + + + + + + + + + + + + + + + + + + + + diff --git a/sw/qa/extras/layout/layout3.cxx b/sw/qa/extras/layout/layout3.cxx index aecea0148d..9c46d8395a 100644 --- a/sw/qa/extras/layout/layout3.cxx +++ b/sw/qa/extras/layout/layout3.cxx @@ -1572,6 +1572,20 @@ CPPUNIT_TEST_FIXTURE(SwLayoutWriter3, testTdf145826) assertXPath(pXmlDoc, "/root/page/body/section/column[2]/ftncont/ftn"_ostr, 3); } +CPPUNIT_TEST_FIXTURE(SwLayoutWriter3, testTable0HeightRows) +{ + createSwDoc("table-0-height-rows.fodt"); + + xmlDocUniquePtr pXmlDoc = parseLayoutDump(); + CPPUNIT_ASSERT(pXmlDoc); + + // the problem was that the table was erroneously split across 2 or 3 pages + assertXPath(pXmlDoc, "/root/page[1]/body/tab"_ostr, 1); + assertXPath(pXmlDoc, "/root/page[1]/body/tab/row"_ostr, 28); + assertXPath(pXmlDoc, "/root/page[1]/body/tab/row/infos/bounds[@height='0']"_ostr, 25); + assertXPath(pXmlDoc, "/root/page"_ostr, 1); +} + CPPUNIT_TEST_FIXTURE(SwLayoutWriter3, testTdf105481) { createSwDoc("tdf105481.odt"); @@ -1776,12 +1790,12 @@ static SwRect lcl_getVisibleFlyObjRect(SwWrtShell* pWrtShell) SwSortedObjs* pDrawObjs = pPage->GetDrawObjs(); CPPUNIT_ASSERT_EQUAL(static_cast(1), pDrawObjs->size()); SwAnchoredObject* pDrawObj = (*pDrawObjs)[0]; - CPPUNIT_ASSERT_EQUAL(OUString("Rahmen8"), pDrawObj->GetFrameFormat().GetName()); + CPPUNIT_ASSERT_EQUAL(OUString("Rahmen8"), pDrawObj->GetFrameFormat()->GetName()); pPage = static_cast(pPage->GetNext()); pDrawObjs = pPage->GetDrawObjs(); CPPUNIT_ASSERT_EQUAL(static_cast(1), pDrawObjs->size()); pDrawObj = (*pDrawObjs)[0]; - CPPUNIT_ASSERT_EQUAL(OUString("Rahmen123"), pDrawObj->GetFrameFormat().GetName()); + CPPUNIT_ASSERT_EQUAL(OUString("Rahmen123"), pDrawObj->GetFrameFormat()->GetName()); SwRect aFlyRect = pDrawObj->GetObjRect(); CPPUNIT_ASSERT(pPage->getFrameArea().Contains(aFlyRect)); return aFlyRect; @@ -2253,6 +2267,42 @@ CPPUNIT_TEST_FIXTURE(SwLayoutWriter3, testTdf159271) assertXPath(pXmlDoc, "/root/page/body/tab/row/cell[2]/txt//SwFieldPortion"_ostr, 1); } +CPPUNIT_TEST_FIXTURE(SwLayoutWriter3, testTdf159259) +{ + // Given a document with a block sdt with a single field, having framePr aligned to right + createSwDoc("sdt+framePr.docx"); + xmlDocUniquePtr pXmlDoc = parseLayoutDump(); + // Make sure there is only one page and one paragraph with one line and one anchored object + assertXPath(pXmlDoc, "/root/page"_ostr, 1); + // Without the fix, this would fail: there were two paragraphs + assertXPath(pXmlDoc, "/root/page/body/txt"_ostr, 1); + assertXPath(pXmlDoc, "/root/page/body/txt/SwParaPortion"_ostr, 1); + assertXPath(pXmlDoc, "/root/page/body/txt/SwParaPortion/SwLineLayout"_ostr, 1); + // Without the fix, this would fail: there was a field portion in the line + assertXPath(pXmlDoc, "/root/page/body/txt/SwParaPortion/SwLineLayout/SwFieldPortion"_ostr, 0); + // Without the fix, this would fail: there was no anchored objects + assertXPath(pXmlDoc, "/root/page/body/txt/anchored"_ostr, 1); + assertXPath(pXmlDoc, "/root/page/body/txt/anchored/fly"_ostr, 1); + + const sal_Int32 paraRight + = getXPath(pXmlDoc, "/root/page/body/txt/infos/bounds"_ostr, "right"_ostr).toInt32(); + const sal_Int32 paraHeight + = getXPath(pXmlDoc, "/root/page/body/txt/infos/bounds"_ostr, "height"_ostr).toInt32(); + + CPPUNIT_ASSERT_GREATER(sal_Int32(0), paraRight); + CPPUNIT_ASSERT_GREATER(sal_Int32(0), paraHeight); + + const sal_Int32 flyRight + = getXPath(pXmlDoc, "/root/page/body/txt/anchored/fly/infos/bounds"_ostr, "right"_ostr) + .toInt32(); + const sal_Int32 flyHeight + = getXPath(pXmlDoc, "/root/page/body/txt/anchored/fly/infos/bounds"_ostr, "height"_ostr) + .toInt32(); + + CPPUNIT_ASSERT_EQUAL(paraRight, flyRight); // The fly is right-aligned + CPPUNIT_ASSERT_EQUAL(paraHeight, flyHeight); +} + CPPUNIT_PLUGIN_IMPLEMENT(); /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/qa/extras/odfexport/data/footnote_spacing_hanging_para.doc b/sw/qa/extras/odfexport/data/footnote_spacing_hanging_para.doc new file mode 100644 index 0000000000..b381ba9b61 Binary files /dev/null and b/sw/qa/extras/odfexport/data/footnote_spacing_hanging_para.doc differ diff --git a/sw/qa/extras/odfexport/data/footnote_spacing_hanging_para.docx b/sw/qa/extras/odfexport/data/footnote_spacing_hanging_para.docx new file mode 100644 index 0000000000..8e3958983b Binary files /dev/null and b/sw/qa/extras/odfexport/data/footnote_spacing_hanging_para.docx differ diff --git a/sw/qa/extras/odfexport/data/footnote_spacing_hanging_para.rtf b/sw/qa/extras/odfexport/data/footnote_spacing_hanging_para.rtf new file mode 100644 index 0000000000..07bbc0eb43 --- /dev/null +++ b/sw/qa/extras/odfexport/data/footnote_spacing_hanging_para.rtf @@ -0,0 +1,209 @@ +{\rtf1\adeflang1025\ansi\ansicpg1252\uc1\adeff31507\deff0\stshfdbch31505\stshfloch31506\stshfhich31506\stshfbi31507\deflang1033\deflangfe2052\themelang1033\themelangfe2052\themelangcs1025{\fonttbl{\f0\fbidi \froman\fcharset204\fprq2{\*\panose 02020603050405020304}Times New Roman;} +{\f13\fbidi \fnil\fcharset134\fprq2{\*\panose 02010600030101010101}SimSun{\*\falt \'cb\'ce\'cc\'e5};}{\f34\fbidi \froman\fcharset204\fprq2{\*\panose 02040503050406030204}Cambria Math;} +{\f44\fbidi \fswiss\fcharset204\fprq2{\*\panose 020b0604020202020204}Liberation Sans;}{\f45\fbidi \fnil\fcharset134\fprq2{\*\panose 02010600030101010101}@SimSun;} +{\flomajor\f31500\fbidi \froman\fcharset204\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\fdbmajor\f31501\fbidi \fmodern\fcharset134\fprq1{\*\panose 02010600030101010101}SimHei{\*\falt \'ba\'da\'cc\'e5};} +{\fhimajor\f31502\fbidi \fswiss\fcharset204\fprq2{\*\panose 020b0604020202020204}Liberation Sans;}{\fbimajor\f31503\fbidi \froman\fcharset204\fprq2{\*\panose 02020603050405020304}Times New Roman;} +{\flominor\f31504\fbidi \froman\fcharset204\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\fdbminor\f31505\fbidi \fnil\fcharset134\fprq2{\*\panose 02010600030101010101}SimSun{\*\falt \'cb\'ce\'cc\'e5};} +{\fhiminor\f31506\fbidi \fswiss\fcharset204\fprq2{\*\panose 020b0604020202020204}Liberation Sans;}{\fbiminor\f31507\fbidi \froman\fcharset204\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\f48\fbidi \froman\fcharset0\fprq2 Times New Roman;} +{\f46\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\f49\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\f50\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\f51\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);} +{\f52\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\f53\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\f54\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);} +{\f178\fbidi \fnil\fcharset0\fprq2 SimSun Western{\*\falt \'cb\'ce\'cc\'e5};}{\f388\fbidi \froman\fcharset0\fprq2 Cambria Math;}{\f386\fbidi \froman\fcharset238\fprq2 Cambria Math CE;}{\f389\fbidi \froman\fcharset161\fprq2 Cambria Math Greek;} +{\f390\fbidi \froman\fcharset162\fprq2 Cambria Math Tur;}{\f393\fbidi \froman\fcharset186\fprq2 Cambria Math Baltic;}{\f394\fbidi \froman\fcharset163\fprq2 Cambria Math (Vietnamese);}{\f488\fbidi \fswiss\fcharset0\fprq2 Liberation Sans;} +{\f486\fbidi \fswiss\fcharset238\fprq2 Liberation Sans CE;}{\f489\fbidi \fswiss\fcharset161\fprq2 Liberation Sans Greek;}{\f490\fbidi \fswiss\fcharset162\fprq2 Liberation Sans Tur;}{\f491\fbidi \fswiss\fcharset177\fprq2 Liberation Sans (Hebrew);} +{\f493\fbidi \fswiss\fcharset186\fprq2 Liberation Sans Baltic;}{\f494\fbidi \fswiss\fcharset163\fprq2 Liberation Sans (Vietnamese);}{\f498\fbidi \fnil\fcharset0\fprq2 @SimSun Western;}{\flomajor\f31510\fbidi \froman\fcharset0\fprq2 Times New Roman;} +{\flomajor\f31508\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\flomajor\f31511\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\flomajor\f31512\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;} +{\flomajor\f31513\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\flomajor\f31514\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\flomajor\f31515\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;} +{\flomajor\f31516\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\fdbmajor\f31520\fbidi \fmodern\fcharset0\fprq1 SimHei Western{\*\falt \'ba\'da\'cc\'e5};}{\fhimajor\f31530\fbidi \fswiss\fcharset0\fprq2 Liberation Sans;} +{\fhimajor\f31528\fbidi \fswiss\fcharset238\fprq2 Liberation Sans CE;}{\fhimajor\f31531\fbidi \fswiss\fcharset161\fprq2 Liberation Sans Greek;}{\fhimajor\f31532\fbidi \fswiss\fcharset162\fprq2 Liberation Sans Tur;} +{\fhimajor\f31533\fbidi \fswiss\fcharset177\fprq2 Liberation Sans (Hebrew);}{\fhimajor\f31535\fbidi \fswiss\fcharset186\fprq2 Liberation Sans Baltic;}{\fhimajor\f31536\fbidi \fswiss\fcharset163\fprq2 Liberation Sans (Vietnamese);} +{\fbimajor\f31540\fbidi \froman\fcharset0\fprq2 Times New Roman;}{\fbimajor\f31538\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\fbimajor\f31541\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;} +{\fbimajor\f31542\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\fbimajor\f31543\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\fbimajor\f31544\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);} +{\fbimajor\f31545\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\fbimajor\f31546\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\flominor\f31550\fbidi \froman\fcharset0\fprq2 Times New Roman;} +{\flominor\f31548\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\flominor\f31551\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\flominor\f31552\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;} +{\flominor\f31553\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\flominor\f31554\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\flominor\f31555\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;} +{\flominor\f31556\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\fdbminor\f31560\fbidi \fnil\fcharset0\fprq2 SimSun Western{\*\falt \'cb\'ce\'cc\'e5};}{\fhiminor\f31570\fbidi \fswiss\fcharset0\fprq2 Liberation Sans;} +{\fhiminor\f31568\fbidi \fswiss\fcharset238\fprq2 Liberation Sans CE;}{\fhiminor\f31571\fbidi \fswiss\fcharset161\fprq2 Liberation Sans Greek;}{\fhiminor\f31572\fbidi \fswiss\fcharset162\fprq2 Liberation Sans Tur;} +{\fhiminor\f31573\fbidi \fswiss\fcharset177\fprq2 Liberation Sans (Hebrew);}{\fhiminor\f31575\fbidi \fswiss\fcharset186\fprq2 Liberation Sans Baltic;}{\fhiminor\f31576\fbidi \fswiss\fcharset163\fprq2 Liberation Sans (Vietnamese);} +{\fbiminor\f31580\fbidi \froman\fcharset0\fprq2 Times New Roman;}{\fbiminor\f31578\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\fbiminor\f31581\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;} +{\fbiminor\f31582\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\fbiminor\f31583\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\fbiminor\f31584\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);} +{\fbiminor\f31585\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\fbiminor\f31586\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}}{\colortbl;\red0\green0\blue0;\red0\green0\blue255;\red0\green255\blue255;\red0\green255\blue0; +\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255;\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;\red128\green0\blue128;\red128\green0\blue0;\red128\green128\blue0;\red128\green128\blue128; +\red192\green192\blue192;\red0\green0\blue0;\red0\green0\blue0;}{\*\defchp \fs22\kerning2\loch\af31506\hich\af31506\dbch\af31505 }{\*\defpap \ql \li0\ri0\sa160\sl259\slmult1\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 } +\noqfpromote {\stylesheet{\ql \li0\ri0\sa160\sl259\slmult1\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af31507\afs22\alang1025 \ltrch\fcs0 +\fs22\lang1033\langfe2052\kerning2\loch\f31506\hich\af31506\dbch\af31505\cgrid\langnp1033\langfenp2052 \snext0 \sqformat \spriority0 Normal;}{\*\cs10 \additive \ssemihidden \sunhideused \spriority1 Default Paragraph Font;}{\* +\ts11\tsrowd\trftsWidthB3\trpaddl108\trpaddr108\trpaddfl3\trpaddft3\trpaddfb3\trpaddfr3\trcbpat1\trcfpat1\tblind0\tblindtype3\tsvertalt\tsbrdrt\tsbrdrl\tsbrdrb\tsbrdrr\tsbrdrdgl\tsbrdrdgr\tsbrdrh\tsbrdrv \ql \li0\ri0\sa160\sl259\slmult1 +\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af31507\afs22\alang1025 \ltrch\fcs0 \fs22\lang1033\langfe2052\kerning2\loch\f31506\hich\af31506\dbch\af31505\cgrid\langnp1033\langfenp2052 +\snext11 \ssemihidden \sunhideused Normal Table;}{\s15\ql \fi-720\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin720\itap0 \rtlch\fcs1 \af31507\afs20\alang1025 \ltrch\fcs0 +\fs20\lang1033\langfe2052\kerning2\loch\f31506\hich\af31506\dbch\af31505\cgrid\langnp1033\langfenp2052 \sbasedon0 \snext15 \slink16 \sunhideused \styrsid1062006 footnote text;}{\*\cs16 \additive \rtlch\fcs1 \af0\afs20 \ltrch\fcs0 \fs20 +\sbasedon10 \slink15 \styrsid1062006 Footnote Text Char;}{\*\cs17 \additive \rtlch\fcs1 \af0 \ltrch\fcs0 \super \sbasedon10 \ssemihidden \sunhideused \styrsid1062006 footnote reference;}}{\*\rsidtbl \rsid466636\rsid920926\rsid1062006\rsid3808477 +\rsid7931512\rsid8473573\rsid16463040}{\mmathPr\mmathFont34\mbrkBin0\mbrkBinSub0\msmallFrac0\mdispDef1\mlMargin0\mrMargin0\mdefJc1\mwrapIndent1440\mintLim0\mnaryLim1}{\info{\author Mike Kaganski}{\operator Mike Kaganski} +{\creatim\yr2024\mo1\dy26\hr19\min11}{\revtim\yr2024\mo1\dy26\hr19\min11}{\version2}{\edmins0}{\nofpages1}{\nofwords1}{\nofchars12}{\nofcharsws12}{\vern87}}{\*\xmlnstbl {\xmlns1 http://schemas.microsoft.com/office/word/2003/wordml}} +\paperw12240\paperh15840\margl1701\margr850\margt1134\margb1134\gutter0\ltrsect +\widowctrl\ftnbj\aenddoc\trackmoves0\trackformatting1\donotembedsysfont1\relyonvml0\donotembedlingdata0\grfdocevents0\validatexml1\showplaceholdtext0\ignoremixedcontent0\saveinvalidxml0\showxmlerrors1\noxlattoyen +\expshrtn\noultrlspc\dntblnsbdb\nospaceforul\formshade\horzdoc\dgmargin\dghspace180\dgvspace180\dghorigin1701\dgvorigin1134\dghshow1\dgvshow1 +\jexpand\viewkind1\viewscale100\pgbrdrhead\pgbrdrfoot\splytwnine\ftnlytwnine\htmautsp\nolnhtadjtbl\useltbaln\alntblind\lytcalctblwd\lyttblrtgr\lnbrkrule\nobrkwrptbl\snaptogridincell\allowfieldendsel\wrppunct +\asianbrkrule\rsidroot1062006\newtblstyruls\nogrowautofit\usenormstyforlist\noindnmbrts\felnbrelev\nocxsptable\indrlsweleven\noafcnsttbl\afelev\utinl\hwelev\spltpgpar\notcvasp\notbrkcnstfrctbl\notvatxbx\krnprsnet\cachedcolbal \nouicompat \fet0 +{\*\wgrffmtfilter 2450}\nofeaturethrottle1\ilfomacatclnup0{\*\ftnsep \ltrpar \pard\plain \ltrpar\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid1062006 \rtlch\fcs1 \af31507\afs22\alang1025 \ltrch\fcs0 +\fs22\lang1033\langfe2052\kerning2\loch\af31506\hich\af31506\dbch\af31505\cgrid\langnp1033\langfenp2052 {\rtlch\fcs1 \af31507 \ltrch\fcs0 \insrsid16463040 \chftnsep +\par }}{\*\ftnsepc \ltrpar \pard\plain \ltrpar\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid1062006 \rtlch\fcs1 \af31507\afs22\alang1025 \ltrch\fcs0 +\fs22\lang1033\langfe2052\kerning2\loch\af31506\hich\af31506\dbch\af31505\cgrid\langnp1033\langfenp2052 {\rtlch\fcs1 \af31507 \ltrch\fcs0 \insrsid16463040 \chftnsepc +\par }}{\*\aftnsep \ltrpar \pard\plain \ltrpar\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid1062006 \rtlch\fcs1 \af31507\afs22\alang1025 \ltrch\fcs0 +\fs22\lang1033\langfe2052\kerning2\loch\af31506\hich\af31506\dbch\af31505\cgrid\langnp1033\langfenp2052 {\rtlch\fcs1 \af31507 \ltrch\fcs0 \insrsid16463040 \chftnsep +\par }}{\*\aftnsepc \ltrpar \pard\plain \ltrpar\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid1062006 \rtlch\fcs1 \af31507\afs22\alang1025 \ltrch\fcs0 +\fs22\lang1033\langfe2052\kerning2\loch\af31506\hich\af31506\dbch\af31505\cgrid\langnp1033\langfenp2052 {\rtlch\fcs1 \af31507 \ltrch\fcs0 \insrsid16463040 \chftnsepc +\par }}\ltrpar \sectd \ltrsect\linex0\endnhere\sectlinegrid360\sectdefaultcl\sftnbj {\*\pnseclvl1\pnucrm\pnqc\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl2\pnucltr\pnqc\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl3 +\pndec\pnqc\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl4\pnlcltr\pnqc\pnstart1\pnindent720\pnhang {\pntxta )}}{\*\pnseclvl5\pndec\pnqc\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl6\pnlcltr\pnqc\pnstart1\pnindent720\pnhang +{\pntxtb (}{\pntxta )}}{\*\pnseclvl7\pnlcrm\pnqc\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl8\pnlcltr\pnqc\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl9\pnlcrm\pnqc\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}} +\pard\plain \ltrpar\ql \li0\ri0\sa160\sl259\slmult1\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af31507\afs22\alang1025 \ltrch\fcs0 +\fs22\lang1033\langfe2052\kerning2\loch\af31506\hich\af31506\dbch\af31505\cgrid\langnp1033\langfenp2052 {\rtlch\fcs1 \af31507 \ltrch\fcs0 \insrsid1062006 \hich\af31506\dbch\af31505\loch\f31506 Lorem ipsum}{\rtlch\fcs1 \af31507 \ltrch\fcs0 +\cs17\super\insrsid1062006 \chftn {\footnote \ltrpar \pard\plain \ltrpar\s15\ql \fi-720\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin720\itap0\pararsid1062006 \rtlch\fcs1 \af31507\afs20\alang1025 \ltrch\fcs0 +\fs20\lang1033\langfe2052\kerning2\loch\af31506\hich\af31506\dbch\af31505\cgrid\langnp1033\langfenp2052 {\rtlch\fcs1 \af31507 \ltrch\fcs0 \cs17\super\insrsid1062006 \chftn }{\rtlch\fcs1 \af31507 \ltrch\fcs0 \insrsid1062006 +\hich\af31506\dbch\af31505\loch\f31506 Footnote for lorem ipsum, some lengthy text to create two lines here and demonstrate the numbering portion spacing behavior with the hanging paragraph settings.}}}{\rtlch\fcs1 \af31507 \ltrch\fcs0 \insrsid920926 + +\par }{\*\themedata 504b030414000600080000002100e9de0fbfff0000001c020000130000005b436f6e74656e745f54797065735d2e786d6cac91cb4ec3301045f748fc83e52d4a +9cb2400825e982c78ec7a27cc0c8992416c9d8b2a755fbf74cd25442a820166c2cd933f79e3be372bd1f07b5c3989ca74aaff2422b24eb1b475da5df374fd9ad +5689811a183c61a50f98f4babebc2837878049899a52a57be670674cb23d8e90721f90a4d2fa3802cb35762680fd800ecd7551dc18eb899138e3c943d7e503b6 +b01d583deee5f99824e290b4ba3f364eac4a430883b3c092d4eca8f946c916422ecab927f52ea42b89a1cd59c254f919b0e85e6535d135a8de20f20b8c12c3b0 +0c895fcf6720192de6bf3b9e89ecdbd6596cbcdd8eb28e7c365ecc4ec1ff1460f53fe813d3cc7f5b7f020000ffff0300504b030414000600080000002100a5d6 +a7e7c0000000360100000b0000005f72656c732f2e72656c73848fcf6ac3300c87ef85bd83d17d51d2c31825762fa590432fa37d00e1287f68221bdb1bebdb4f +c7060abb0884a4eff7a93dfeae8bf9e194e720169aaa06c3e2433fcb68e1763dbf7f82c985a4a725085b787086a37bdbb55fbc50d1a33ccd311ba548b6309512 +0f88d94fbc52ae4264d1c910d24a45db3462247fa791715fd71f989e19e0364cd3f51652d73760ae8fa8c9ffb3c330cc9e4fc17faf2ce545046e37944c69e462 +a1a82fe353bd90a865aad41ed0b5b8f9d6fd010000ffff0300504b0304140006000800000021006b799616830000008a0000001c0000007468656d652f746865 +6d652f7468656d654d616e616765722e786d6c0ccc4d0ac3201040e17da17790d93763bb284562b2cbaebbf600439c1a41c7a0d29fdbd7e5e38337cedf14d59b +4b0d592c9c070d8a65cd2e88b7f07c2ca71ba8da481cc52c6ce1c715e6e97818c9b48d13df49c873517d23d59085adb5dd20d6b52bd521ef2cdd5eb9246a3d8b +4757e8d3f729e245eb2b260a0238fd010000ffff0300504b030414000600080000002100978e38d49b040000c90f0000160000007468656d652f7468656d652f +7468656d65312e786d6ccc57db6edb38107d5f60ff81d0bb62dd6505710a59b2b00f5d2cb0cea2cf8c2e961a4a32443a8951e4df77484a32e54b9b182dd0e445 +1a9f191ece0ccf50779f5e6b829ef38e566db3d0cc1b43437993b659d56c16da7f0f893ed71065b8c930699b7ca1ed73aa7dbafff38f3b7ccbcabcce11f837f4 +162fb492b1eded6c465330637ad36ef3067e2bdaaec60c5ebbcd2cebf00bc4adc9cc320c6f56e3aad150836b08fb4f5154698e1e7848ed7e08be22f0da30ca0d +29e9d63c743ef110d8ecc9e408baa711e9d033260b0dd6c9da9787fc95698860cae0878566883f6d767f37c3b7bd1361177c15bf44fcf57ebd43f6648935bbcd +e3b8a8e3b88e178ef10580b053dcca5f792b6f8c2700384d61a792cb34a66f454e8f5540f2f14cecd88f6d738257e2db279c4397ff4ff00224e33b27f8248920 +8b13bc0049bc7b827797c1329ec6172089f74ef0be11c68e3f892f4025a99aa713b4e17a7634ec7684142df9eb2c3c709dc4b7fae0071474c3d85d7c89a26dd8 +a55eabf1d7b64b00c08104b3aa416cbfcd0b9c42177fae1ef30e6c6d83d6b8a17c217c9b6305214d293d32018349e0ba6a7ed12a87c0b0e661a362dbf5c55d17 +15216bb627f9672a364e5b52650918b99f38f1f9780ab6253cf6399ee0361d163ea86bd9978a95eb126f2169a6c6836c681f7a43d1b6a5705885f96c6c8e27bb +faef369387dd34f9c196a9a5981dec863bdaa1504ca23dffd0c0637821091b21340301eefb1112ca625312f61912fe60842a7c8f84d8d94f61119c6131e7e187 +52097185d28da9006a6355e03821cc4782eb800b38219a629267bc4e524f87ea8a62fecc4a5f4ae6a4030c98287d071c2a1d70ae17b7c777275bed1d959e9050 +da6d4a4264461c7a5ae22cefbb935bdf43e3a3b50e0e259dd0e3a9e873a1d0f0e7df63716dadb9881c69036954a5200d7a59689eed42cba478bbd00a104d78ac +b7d03bb4d96808930ddc3c52d6c9037f8db26c3bca624c4b9970213a520dea8ae51d2255bdd0f8f6c73290466888e0665a2008bf2db90064e5772307459f1639 +2f8a3c656ad9150bcfb47c0585975a71f657e17e3d987bb63b28f7bacc5ed023d975ff626831d7377902b38a321835329b590597c151c80efd7734987ad9556f +63a287a41d936d89fb89a28ab9840b111de988b73107ca5bbf6748a892927e103e6ef88055933a99a6e3d4901c2e4edd1f3bf1cc29a27998991355e153f3bc8a +4d5618c6c0512eaf1bf20aab21c5302ed5092fa5fb58728341eb8eee09e39480848ff91be7dd87068242edb0d8841a677c2ac35cb37beb74760c1bfc01b5f70c +0945f5bd21ec51dec619717639305e35f9c1efb86bc1540cf74a9169f1d5a87ed8b58f5f413c62b842ef08a3a294f0d9d661b88aacc59d44ca061c9157d61f0d +7842bbae5a68df0c377422cb8d7463eeae74c7760c7dee86b61ebaae6dae5cd38897d61b0c1656d6a62bbf58135c5764df7fb70afbc9b76b5da55d4bdb82dda4 +6d3d6bc5b7e94c1017dfaea675f9db1555203adf3c2b09ec60e9e9811d26ba132fe77a10794b3df6223f4ee2c89d07c99b869e05d809edc8f15673dd33a34877 +3c83d39f07baef5856e8f8e17ce5846ffd3506762ee5a3cf05a457f0baff1f0000ffff0300504b0304140006000800000021000dd1909fb60000001b01000027 +0000007468656d652f7468656d652f5f72656c732f7468656d654d616e616765722e786d6c2e72656c73848f4d0ac2301484f78277086f6fd3ba109126dd88d0 +add40384e4350d363f2451eced0dae2c082e8761be9969bb979dc9136332de3168aa1a083ae995719ac16db8ec8e4052164e89d93b64b060828e6f37ed156791 +4b284d262452282e3198720e274a939cd08a54f980ae38a38f56e422a3a641c8bbd048f7757da0f19b017cc524bd62107bd5001996509affb3fd381a89672f1f +165dfe514173d9850528a2c6cce0239baa4c04ca5bbabac4df000000ffff0300504b01022d0014000600080000002100e9de0fbfff0000001c02000013000000 +00000000000000000000000000005b436f6e74656e745f54797065735d2e786d6c504b01022d0014000600080000002100a5d6a7e7c0000000360100000b0000 +0000000000000000000000300100005f72656c732f2e72656c73504b01022d00140006000800000021006b799616830000008a0000001c000000000000000000 +00000000190200007468656d652f7468656d652f7468656d654d616e616765722e786d6c504b01022d0014000600080000002100978e38d49b040000c90f0000 +1600000000000000000000000000d60200007468656d652f7468656d652f7468656d65312e786d6c504b01022d00140006000800000021000dd1909fb6000000 +1b0100002700000000000000000000000000a50700007468656d652f7468656d652f5f72656c732f7468656d654d616e616765722e786d6c2e72656c73504b050600000000050005005d010000a00800000000} +{\*\colorschememapping 3c3f786d6c2076657273696f6e3d22312e302220656e636f64696e673d225554462d3822207374616e64616c6f6e653d22796573223f3e0d0a3c613a636c724d +617020786d6c6e733a613d22687474703a2f2f736368656d61732e6f70656e786d6c666f726d6174732e6f72672f64726177696e676d6c2f323030362f6d6169 +6e22206267313d226c743122207478313d22646b3122206267323d226c743222207478323d22646b322220616363656e74313d22616363656e74312220616363 +656e74323d22616363656e74322220616363656e74333d22616363656e74332220616363656e74343d22616363656e74342220616363656e74353d22616363656e74352220616363656e74363d22616363656e74362220686c696e6b3d22686c696e6b2220666f6c486c696e6b3d22666f6c486c696e6b222f3e} +{\*\latentstyles\lsdstimax376\lsdlockeddef0\lsdsemihiddendef0\lsdunhideuseddef0\lsdqformatdef0\lsdprioritydef99{\lsdlockedexcept \lsdqformat1 \lsdpriority0 \lsdlocked0 Normal;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 1; +\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 2;\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 3;\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 4; +\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 5;\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 6;\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 7; +\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 8;\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 9;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index 1; +\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index 3;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index 4;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index 5; +\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index 6;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index 7;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index 8;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index 9; +\lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 1;\lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 2;\lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 3; +\lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 4;\lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 5;\lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 6; +\lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 7;\lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 8;\lsdsemihidden1 \lsdunhideused1 \lsdpriority39 \lsdlocked0 toc 9;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Normal Indent; +\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 footnote text;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 annotation text;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 header;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 footer; +\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index heading;\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority35 \lsdlocked0 caption;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 table of figures; +\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 envelope address;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 envelope return;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 footnote reference;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 annotation reference; +\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 line number;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 page number;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 endnote reference;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 endnote text; +\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 table of authorities;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 macro;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 toa heading;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List; +\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Bullet;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Number;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List 3; +\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List 4;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List 5;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Bullet 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Bullet 3; +\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Bullet 4;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Bullet 5;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Number 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Number 3; +\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Number 4;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Number 5;\lsdqformat1 \lsdpriority10 \lsdlocked0 Title;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Closing; +\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Signature;\lsdsemihidden1 \lsdunhideused1 \lsdpriority1 \lsdlocked0 Default Paragraph Font;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Body Text;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Body Text Indent; +\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Continue;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Continue 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Continue 3;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Continue 4; +\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 List Continue 5;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Message Header;\lsdqformat1 \lsdpriority11 \lsdlocked0 Subtitle;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Salutation; +\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Date;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Body Text First Indent;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Body Text First Indent 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Note Heading; +\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Body Text 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Body Text 3;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Body Text Indent 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Body Text Indent 3; +\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Block Text;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Hyperlink;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 FollowedHyperlink;\lsdqformat1 \lsdpriority22 \lsdlocked0 Strong; +\lsdqformat1 \lsdpriority20 \lsdlocked0 Emphasis;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Document Map;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Plain Text;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 E-mail Signature; +\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Top of Form;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Bottom of Form;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Normal (Web);\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Acronym; +\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Address;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Cite;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Code;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Definition; +\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Keyboard;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Preformatted;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Sample;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Typewriter; +\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Variable;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Normal Table;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 annotation subject;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 No List; +\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Outline List 1;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Outline List 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Outline List 3;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Simple 1; +\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Simple 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Simple 3;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Classic 1;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Classic 2; +\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Classic 3;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Classic 4;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Colorful 1;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Colorful 2; +\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Colorful 3;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Columns 1;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Columns 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Columns 3; +\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Columns 4;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Columns 5;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Grid 1;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Grid 2; +\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Grid 3;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Grid 4;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Grid 5;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Grid 6; +\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Grid 7;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Grid 8;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table List 1;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table List 2; +\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table List 3;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table List 4;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table List 5;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table List 6; +\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table List 7;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table List 8;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table 3D effects 1;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table 3D effects 2; +\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table 3D effects 3;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Contemporary;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Elegant;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Professional; +\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Subtle 1;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Subtle 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Web 1;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Web 2; +\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Web 3;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Balloon Text;\lsdpriority39 \lsdlocked0 Table Grid;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Theme;\lsdsemihidden1 \lsdlocked0 Placeholder Text; +\lsdqformat1 \lsdpriority1 \lsdlocked0 No Spacing;\lsdpriority60 \lsdlocked0 Light Shading;\lsdpriority61 \lsdlocked0 Light List;\lsdpriority62 \lsdlocked0 Light Grid;\lsdpriority63 \lsdlocked0 Medium Shading 1;\lsdpriority64 \lsdlocked0 Medium Shading 2; +\lsdpriority65 \lsdlocked0 Medium List 1;\lsdpriority66 \lsdlocked0 Medium List 2;\lsdpriority67 \lsdlocked0 Medium Grid 1;\lsdpriority68 \lsdlocked0 Medium Grid 2;\lsdpriority69 \lsdlocked0 Medium Grid 3;\lsdpriority70 \lsdlocked0 Dark List; +\lsdpriority71 \lsdlocked0 Colorful Shading;\lsdpriority72 \lsdlocked0 Colorful List;\lsdpriority73 \lsdlocked0 Colorful Grid;\lsdpriority60 \lsdlocked0 Light Shading Accent 1;\lsdpriority61 \lsdlocked0 Light List Accent 1; +\lsdpriority62 \lsdlocked0 Light Grid Accent 1;\lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 1;\lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 1;\lsdpriority65 \lsdlocked0 Medium List 1 Accent 1;\lsdsemihidden1 \lsdlocked0 Revision; +\lsdqformat1 \lsdpriority34 \lsdlocked0 List Paragraph;\lsdqformat1 \lsdpriority29 \lsdlocked0 Quote;\lsdqformat1 \lsdpriority30 \lsdlocked0 Intense Quote;\lsdpriority66 \lsdlocked0 Medium List 2 Accent 1;\lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 1; +\lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 1;\lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 1;\lsdpriority70 \lsdlocked0 Dark List Accent 1;\lsdpriority71 \lsdlocked0 Colorful Shading Accent 1;\lsdpriority72 \lsdlocked0 Colorful List Accent 1; +\lsdpriority73 \lsdlocked0 Colorful Grid Accent 1;\lsdpriority60 \lsdlocked0 Light Shading Accent 2;\lsdpriority61 \lsdlocked0 Light List Accent 2;\lsdpriority62 \lsdlocked0 Light Grid Accent 2;\lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 2; +\lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 2;\lsdpriority65 \lsdlocked0 Medium List 1 Accent 2;\lsdpriority66 \lsdlocked0 Medium List 2 Accent 2;\lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 2;\lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 2; +\lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 2;\lsdpriority70 \lsdlocked0 Dark List Accent 2;\lsdpriority71 \lsdlocked0 Colorful Shading Accent 2;\lsdpriority72 \lsdlocked0 Colorful List Accent 2;\lsdpriority73 \lsdlocked0 Colorful Grid Accent 2; +\lsdpriority60 \lsdlocked0 Light Shading Accent 3;\lsdpriority61 \lsdlocked0 Light List Accent 3;\lsdpriority62 \lsdlocked0 Light Grid Accent 3;\lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 3;\lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 3; +\lsdpriority65 \lsdlocked0 Medium List 1 Accent 3;\lsdpriority66 \lsdlocked0 Medium List 2 Accent 3;\lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 3;\lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 3;\lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 3; +\lsdpriority70 \lsdlocked0 Dark List Accent 3;\lsdpriority71 \lsdlocked0 Colorful Shading Accent 3;\lsdpriority72 \lsdlocked0 Colorful List Accent 3;\lsdpriority73 \lsdlocked0 Colorful Grid Accent 3;\lsdpriority60 \lsdlocked0 Light Shading Accent 4; +\lsdpriority61 \lsdlocked0 Light List Accent 4;\lsdpriority62 \lsdlocked0 Light Grid Accent 4;\lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 4;\lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 4;\lsdpriority65 \lsdlocked0 Medium List 1 Accent 4; +\lsdpriority66 \lsdlocked0 Medium List 2 Accent 4;\lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 4;\lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 4;\lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 4;\lsdpriority70 \lsdlocked0 Dark List Accent 4; +\lsdpriority71 \lsdlocked0 Colorful Shading Accent 4;\lsdpriority72 \lsdlocked0 Colorful List Accent 4;\lsdpriority73 \lsdlocked0 Colorful Grid Accent 4;\lsdpriority60 \lsdlocked0 Light Shading Accent 5;\lsdpriority61 \lsdlocked0 Light List Accent 5; +\lsdpriority62 \lsdlocked0 Light Grid Accent 5;\lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 5;\lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 5;\lsdpriority65 \lsdlocked0 Medium List 1 Accent 5;\lsdpriority66 \lsdlocked0 Medium List 2 Accent 5; +\lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 5;\lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 5;\lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 5;\lsdpriority70 \lsdlocked0 Dark List Accent 5;\lsdpriority71 \lsdlocked0 Colorful Shading Accent 5; +\lsdpriority72 \lsdlocked0 Colorful List Accent 5;\lsdpriority73 \lsdlocked0 Colorful Grid Accent 5;\lsdpriority60 \lsdlocked0 Light Shading Accent 6;\lsdpriority61 \lsdlocked0 Light List Accent 6;\lsdpriority62 \lsdlocked0 Light Grid Accent 6; +\lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 6;\lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 6;\lsdpriority65 \lsdlocked0 Medium List 1 Accent 6;\lsdpriority66 \lsdlocked0 Medium List 2 Accent 6; +\lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 6;\lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 6;\lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 6;\lsdpriority70 \lsdlocked0 Dark List Accent 6;\lsdpriority71 \lsdlocked0 Colorful Shading Accent 6; +\lsdpriority72 \lsdlocked0 Colorful List Accent 6;\lsdpriority73 \lsdlocked0 Colorful Grid Accent 6;\lsdqformat1 \lsdpriority19 \lsdlocked0 Subtle Emphasis;\lsdqformat1 \lsdpriority21 \lsdlocked0 Intense Emphasis; +\lsdqformat1 \lsdpriority31 \lsdlocked0 Subtle Reference;\lsdqformat1 \lsdpriority32 \lsdlocked0 Intense Reference;\lsdqformat1 \lsdpriority33 \lsdlocked0 Book Title;\lsdsemihidden1 \lsdunhideused1 \lsdpriority37 \lsdlocked0 Bibliography; +\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority39 \lsdlocked0 TOC Heading;\lsdpriority41 \lsdlocked0 Plain Table 1;\lsdpriority42 \lsdlocked0 Plain Table 2;\lsdpriority43 \lsdlocked0 Plain Table 3;\lsdpriority44 \lsdlocked0 Plain Table 4; +\lsdpriority45 \lsdlocked0 Plain Table 5;\lsdpriority40 \lsdlocked0 Grid Table Light;\lsdpriority46 \lsdlocked0 Grid Table 1 Light;\lsdpriority47 \lsdlocked0 Grid Table 2;\lsdpriority48 \lsdlocked0 Grid Table 3;\lsdpriority49 \lsdlocked0 Grid Table 4; +\lsdpriority50 \lsdlocked0 Grid Table 5 Dark;\lsdpriority51 \lsdlocked0 Grid Table 6 Colorful;\lsdpriority52 \lsdlocked0 Grid Table 7 Colorful;\lsdpriority46 \lsdlocked0 Grid Table 1 Light Accent 1;\lsdpriority47 \lsdlocked0 Grid Table 2 Accent 1; +\lsdpriority48 \lsdlocked0 Grid Table 3 Accent 1;\lsdpriority49 \lsdlocked0 Grid Table 4 Accent 1;\lsdpriority50 \lsdlocked0 Grid Table 5 Dark Accent 1;\lsdpriority51 \lsdlocked0 Grid Table 6 Colorful Accent 1; +\lsdpriority52 \lsdlocked0 Grid Table 7 Colorful Accent 1;\lsdpriority46 \lsdlocked0 Grid Table 1 Light Accent 2;\lsdpriority47 \lsdlocked0 Grid Table 2 Accent 2;\lsdpriority48 \lsdlocked0 Grid Table 3 Accent 2; +\lsdpriority49 \lsdlocked0 Grid Table 4 Accent 2;\lsdpriority50 \lsdlocked0 Grid Table 5 Dark Accent 2;\lsdpriority51 \lsdlocked0 Grid Table 6 Colorful Accent 2;\lsdpriority52 \lsdlocked0 Grid Table 7 Colorful Accent 2; +\lsdpriority46 \lsdlocked0 Grid Table 1 Light Accent 3;\lsdpriority47 \lsdlocked0 Grid Table 2 Accent 3;\lsdpriority48 \lsdlocked0 Grid Table 3 Accent 3;\lsdpriority49 \lsdlocked0 Grid Table 4 Accent 3; +\lsdpriority50 \lsdlocked0 Grid Table 5 Dark Accent 3;\lsdpriority51 \lsdlocked0 Grid Table 6 Colorful Accent 3;\lsdpriority52 \lsdlocked0 Grid Table 7 Colorful Accent 3;\lsdpriority46 \lsdlocked0 Grid Table 1 Light Accent 4; +\lsdpriority47 \lsdlocked0 Grid Table 2 Accent 4;\lsdpriority48 \lsdlocked0 Grid Table 3 Accent 4;\lsdpriority49 \lsdlocked0 Grid Table 4 Accent 4;\lsdpriority50 \lsdlocked0 Grid Table 5 Dark Accent 4; +\lsdpriority51 \lsdlocked0 Grid Table 6 Colorful Accent 4;\lsdpriority52 \lsdlocked0 Grid Table 7 Colorful Accent 4;\lsdpriority46 \lsdlocked0 Grid Table 1 Light Accent 5;\lsdpriority47 \lsdlocked0 Grid Table 2 Accent 5; +\lsdpriority48 \lsdlocked0 Grid Table 3 Accent 5;\lsdpriority49 \lsdlocked0 Grid Table 4 Accent 5;\lsdpriority50 \lsdlocked0 Grid Table 5 Dark Accent 5;\lsdpriority51 \lsdlocked0 Grid Table 6 Colorful Accent 5; +\lsdpriority52 \lsdlocked0 Grid Table 7 Colorful Accent 5;\lsdpriority46 \lsdlocked0 Grid Table 1 Light Accent 6;\lsdpriority47 \lsdlocked0 Grid Table 2 Accent 6;\lsdpriority48 \lsdlocked0 Grid Table 3 Accent 6; +\lsdpriority49 \lsdlocked0 Grid Table 4 Accent 6;\lsdpriority50 \lsdlocked0 Grid Table 5 Dark Accent 6;\lsdpriority51 \lsdlocked0 Grid Table 6 Colorful Accent 6;\lsdpriority52 \lsdlocked0 Grid Table 7 Colorful Accent 6; +\lsdpriority46 \lsdlocked0 List Table 1 Light;\lsdpriority47 \lsdlocked0 List Table 2;\lsdpriority48 \lsdlocked0 List Table 3;\lsdpriority49 \lsdlocked0 List Table 4;\lsdpriority50 \lsdlocked0 List Table 5 Dark; +\lsdpriority51 \lsdlocked0 List Table 6 Colorful;\lsdpriority52 \lsdlocked0 List Table 7 Colorful;\lsdpriority46 \lsdlocked0 List Table 1 Light Accent 1;\lsdpriority47 \lsdlocked0 List Table 2 Accent 1;\lsdpriority48 \lsdlocked0 List Table 3 Accent 1; +\lsdpriority49 \lsdlocked0 List Table 4 Accent 1;\lsdpriority50 \lsdlocked0 List Table 5 Dark Accent 1;\lsdpriority51 \lsdlocked0 List Table 6 Colorful Accent 1;\lsdpriority52 \lsdlocked0 List Table 7 Colorful Accent 1; +\lsdpriority46 \lsdlocked0 List Table 1 Light Accent 2;\lsdpriority47 \lsdlocked0 List Table 2 Accent 2;\lsdpriority48 \lsdlocked0 List Table 3 Accent 2;\lsdpriority49 \lsdlocked0 List Table 4 Accent 2; +\lsdpriority50 \lsdlocked0 List Table 5 Dark Accent 2;\lsdpriority51 \lsdlocked0 List Table 6 Colorful Accent 2;\lsdpriority52 \lsdlocked0 List Table 7 Colorful Accent 2;\lsdpriority46 \lsdlocked0 List Table 1 Light Accent 3; +\lsdpriority47 \lsdlocked0 List Table 2 Accent 3;\lsdpriority48 \lsdlocked0 List Table 3 Accent 3;\lsdpriority49 \lsdlocked0 List Table 4 Accent 3;\lsdpriority50 \lsdlocked0 List Table 5 Dark Accent 3; +\lsdpriority51 \lsdlocked0 List Table 6 Colorful Accent 3;\lsdpriority52 \lsdlocked0 List Table 7 Colorful Accent 3;\lsdpriority46 \lsdlocked0 List Table 1 Light Accent 4;\lsdpriority47 \lsdlocked0 List Table 2 Accent 4; +\lsdpriority48 \lsdlocked0 List Table 3 Accent 4;\lsdpriority49 \lsdlocked0 List Table 4 Accent 4;\lsdpriority50 \lsdlocked0 List Table 5 Dark Accent 4;\lsdpriority51 \lsdlocked0 List Table 6 Colorful Accent 4; +\lsdpriority52 \lsdlocked0 List Table 7 Colorful Accent 4;\lsdpriority46 \lsdlocked0 List Table 1 Light Accent 5;\lsdpriority47 \lsdlocked0 List Table 2 Accent 5;\lsdpriority48 \lsdlocked0 List Table 3 Accent 5; +\lsdpriority49 \lsdlocked0 List Table 4 Accent 5;\lsdpriority50 \lsdlocked0 List Table 5 Dark Accent 5;\lsdpriority51 \lsdlocked0 List Table 6 Colorful Accent 5;\lsdpriority52 \lsdlocked0 List Table 7 Colorful Accent 5; +\lsdpriority46 \lsdlocked0 List Table 1 Light Accent 6;\lsdpriority47 \lsdlocked0 List Table 2 Accent 6;\lsdpriority48 \lsdlocked0 List Table 3 Accent 6;\lsdpriority49 \lsdlocked0 List Table 4 Accent 6; +\lsdpriority50 \lsdlocked0 List Table 5 Dark Accent 6;\lsdpriority51 \lsdlocked0 List Table 6 Colorful Accent 6;\lsdpriority52 \lsdlocked0 List Table 7 Colorful Accent 6;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Mention; +\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Smart Hyperlink;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Hashtag;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Unresolved Mention;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Smart Link;}}{\*\datastore 01050000 +02000000180000004d73786d6c322e534158584d4c5265616465722e362e3000000000000000000000060000 +d0cf11e0a1b11ae1000000000000000000000000000000003e000300feff090006000000000000000000000001000000010000000000000000100000feffffff00000000feffffff0000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffdfffffffeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffff52006f006f007400200045006e00740072007900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016000500ffffffffffffffffffffffff0c6ad98892f1d411a65f0040963251e5000000000000000000000000d086 +303e5950da01feffffff00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff00000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff0000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000105000000000000}} \ No newline at end of file diff --git a/sw/qa/extras/odfexport/data/tdf106733.fodt b/sw/qa/extras/odfexport/data/tdf106733.fodt new file mode 100644 index 0000000000..fa9a024405 --- /dev/null +++ b/sw/qa/extras/odfexport/data/tdf106733.fodt @@ -0,0 +1,66 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Hyphenate + The Earth is no different to any other celestial body out there in space. It merely moves along in space inertially. Even just one inch above the surface of the Earth is space, except that it has an atmosphere. + Don’t hyphenate (direct formatting) + The Earth is no different to any other celestial body out there in space. It merely moves along in space inertially. Even just one inch above the surface of the Earth is space, except that it has an atmosphere. + Don’t hyphenate (character style) + The Earth is no different to any other celestial body out there in space. It merely moves along in space inertially. Even just one inch above the surface of the Earth is space, except that it has an atmosphere. + + + + diff --git a/sw/qa/extras/odfexport/odfexport2.cxx b/sw/qa/extras/odfexport/odfexport2.cxx index 6db396c40d..37e744e9c8 100644 --- a/sw/qa/extras/odfexport/odfexport2.cxx +++ b/sw/qa/extras/odfexport/odfexport2.cxx @@ -102,6 +102,26 @@ DECLARE_ODFEXPORT_TEST(testTdf77961, "tdf77961.odt") CPPUNIT_ASSERT_EQUAL( false , getProperty(xStyle, "GridPrint")); } +CPPUNIT_TEST_FIXTURE(Test, testTdf106733) +{ + loadAndReload("tdf106733.fodt"); + CPPUNIT_ASSERT_EQUAL(1, getPages()); + xmlDocUniquePtr pXmlDoc = parseExport("content.xml"); + + // keep fo:hyphenate="false" in direct formatting + assertXPath( + pXmlDoc, + "//style:style[@style:name='T3']/style:text-properties"_ostr, + "hyphenate"_ostr, "false"); + + // keep fo:hyphenate="false" in character style + xmlDocUniquePtr pXmlDoc2 = parseExport("styles.xml"); + assertXPath( + pXmlDoc2, + "//style:style[@style:name='Strong_20_Emphasis']/style:text-properties"_ostr, + "hyphenate"_ostr, "false"); +} + DECLARE_ODFEXPORT_TEST(testReferenceLanguage, "referencelanguage.odt") { CPPUNIT_ASSERT_EQUAL(2, getPages()); @@ -1128,6 +1148,105 @@ CPPUNIT_TEST_FIXTURE(Test, testTdf150408_IsLegal) "is-legal"_ostr, "true"); } +CPPUNIT_TEST_FIXTURE(Test, testTdf159382) +{ + // Testing NoGapAfterNoteNumber compat option + + createSwDoc("footnote_spacing_hanging_para.docx"); + // 1. Make sure that DOCX import sets NoGapAfterNoteNumber option, and creates + // correct layout + { + uno::Reference xFactory(mxComponent, uno::UNO_QUERY_THROW); + uno::Reference xSettings( + xFactory->createInstance(u"com.sun.star.document.Settings"_ustr), uno::UNO_QUERY_THROW); + CPPUNIT_ASSERT_EQUAL(uno::Any(true), xSettings->getPropertyValue( + u"NoGapAfterNoteNumber"_ustr)); + + xmlDocUniquePtr pXmlDoc = parseLayoutDump(); + sal_Int32 width + = getXPath(pXmlDoc, + "/root/page/ftncont/ftn/txt/SwParaPortion/SwLineLayout/SwFieldPortion"_ostr, + "width"_ostr) + .toInt32(); + CPPUNIT_ASSERT(width); + CPPUNIT_ASSERT_LESS(sal_Int32(100), width); // It was 720, i.e. 0.5 inch + } + + saveAndReload(mpFilter); + // 2. Make sure that exported document has NoGapAfterNoteNumber option set, + // and has correct layout + { + xmlDocUniquePtr pXmlDoc = parseExport("settings.xml"); + assertXPathContent( + pXmlDoc, + "//config:config-item[@config:name='NoGapAfterNoteNumber']"_ostr, + "true"); + + uno::Reference xFactory(mxComponent, uno::UNO_QUERY_THROW); + uno::Reference xSettings( + xFactory->createInstance(u"com.sun.star.document.Settings"_ustr), uno::UNO_QUERY_THROW); + CPPUNIT_ASSERT_EQUAL(uno::Any(true), xSettings->getPropertyValue( + u"NoGapAfterNoteNumber"_ustr)); + + pXmlDoc = parseLayoutDump(); + sal_Int32 width = getXPath( + pXmlDoc, "/root/page/ftncont/ftn/txt/SwParaPortion/SwLineLayout/SwFieldPortion"_ostr, + "width"_ostr).toInt32(); + CPPUNIT_ASSERT(width); + CPPUNIT_ASSERT_LESS(sal_Int32(100), width); + } + + createSwDoc("footnote_spacing_hanging_para.doc"); + // 3. Make sure that DOC import sets NoGapAfterNoteNumber option, and creates + // correct layout + { + uno::Reference xFactory(mxComponent, uno::UNO_QUERY_THROW); + uno::Reference xSettings( + xFactory->createInstance(u"com.sun.star.document.Settings"_ustr), uno::UNO_QUERY_THROW); + CPPUNIT_ASSERT_EQUAL(uno::Any(true), xSettings->getPropertyValue( + u"NoGapAfterNoteNumber"_ustr)); + + xmlDocUniquePtr pXmlDoc = parseLayoutDump(); + sal_Int32 width + = getXPath(pXmlDoc, + "/root/page/ftncont/ftn/txt/SwParaPortion/SwLineLayout/SwFieldPortion"_ostr, + "width"_ostr) + .toInt32(); + CPPUNIT_ASSERT(width); + CPPUNIT_ASSERT_LESS(sal_Int32(100), width); + } + + createSwDoc("footnote_spacing_hanging_para.rtf"); + // 4. Make sure that RTF import sets NoGapAfterNoteNumber option, and creates + // correct layout + { + uno::Reference xFactory(mxComponent, uno::UNO_QUERY_THROW); + uno::Reference xSettings( + xFactory->createInstance(u"com.sun.star.document.Settings"_ustr), uno::UNO_QUERY_THROW); + CPPUNIT_ASSERT_EQUAL(uno::Any(true), xSettings->getPropertyValue( + u"NoGapAfterNoteNumber"_ustr)); + + xmlDocUniquePtr pXmlDoc = parseLayoutDump(); + sal_Int32 width + = getXPath(pXmlDoc, + "/root/page/ftncont/ftn/txt/SwParaPortion/SwLineLayout/SwFieldPortion"_ostr, + "width"_ostr) + .toInt32(); + CPPUNIT_ASSERT(width); + CPPUNIT_ASSERT_LESS(sal_Int32(100), width); + } + + createSwDoc(); + // 5. Make sure that a new Writer document has this setting set to false + { + uno::Reference xFactory(mxComponent, uno::UNO_QUERY_THROW); + uno::Reference xSettings( + xFactory->createInstance(u"com.sun.star.document.Settings"_ustr), uno::UNO_QUERY_THROW); + CPPUNIT_ASSERT_EQUAL(uno::Any(false), xSettings->getPropertyValue( + u"NoGapAfterNoteNumber"_ustr)); + } +} + CPPUNIT_PLUGIN_IMPLEMENT(); /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/qa/extras/odfimport/data/tdf123968.odt b/sw/qa/extras/odfimport/data/tdf123968.odt index 1c081619ea..cd1ec8a385 100644 Binary files a/sw/qa/extras/odfimport/data/tdf123968.odt and b/sw/qa/extras/odfimport/data/tdf123968.odt differ diff --git a/sw/qa/extras/odfimport/data/unreferenced_stream.odt b/sw/qa/extras/odfimport/data/unreferenced_stream.odt new file mode 100644 index 0000000000..0cdba0d485 Binary files /dev/null and b/sw/qa/extras/odfimport/data/unreferenced_stream.odt differ diff --git a/sw/qa/extras/odfimport/odfimport.cxx b/sw/qa/extras/odfimport/odfimport.cxx index 6ccc8cce3b..70c6452e3d 100644 --- a/sw/qa/extras/odfimport/odfimport.cxx +++ b/sw/qa/extras/odfimport/odfimport.cxx @@ -1167,9 +1167,21 @@ CPPUNIT_TEST_FIXTURE(Test, testTdf123968) SwTextNode& rStart = dynamic_cast(pShellCursor->Start()->GetNode()); // The field is now editable like any text, thus the field content "New value" shows up for the cursor. + // This field's variable is declared as string and used as string - typical. CPPUNIT_ASSERT_EQUAL(OUString("inputfield: " + OUStringChar(CH_TXT_ATR_INPUTFIELDSTART) + "New value" + OUStringChar(CH_TXT_ATR_INPUTFIELDEND)), rStart.GetText()); + + // This field's variable is declared as float and used as string - not + // typical; this can easily happen if the input field is in a header/footer, + // because only content.xml contains the variable-decls, styles.xml is + // imported before content.xml, and apparently the default variable type is + // numeric. + SwTextNode& rEnd = dynamic_cast(pShellCursor->End()->GetNode()); + CPPUNIT_ASSERT_EQUAL(OUString("inputfield: " + OUStringChar(CH_TXT_ATR_INPUTFIELDSTART) + + "String input for num variable" + OUStringChar(CH_TXT_ATR_INPUTFIELDEND)), + rEnd.GetText()); + } CPPUNIT_TEST_FIXTURE(Test, testTdf133459) @@ -1534,5 +1546,20 @@ CPPUNIT_TEST_FIXTURE(Test, testEmptyTrailingSpans) CPPUNIT_ASSERT_DOUBLES_EQUAL(184, height2, 1); // allow a bit of room for rounding just in case } +CPPUNIT_TEST_FIXTURE(Test, testBrokenPackage_Tdf159474) +{ + // Given an invalid ODF having a stream not referenced in manifest.xml + const OUString url = createFileURL(u"unreferenced_stream.odt"); + // It expectedly fails to load normally: + CPPUNIT_ASSERT_ASSERTION_FAIL(loadFromDesktop(url, {}, {})); + // importing it must succeed with RepairPackage set to true. + mxComponent + = loadFromDesktop(url, {}, { comphelper::makePropertyValue(u"RepairPackage"_ustr, true) }); + // The document imports in repair mode; the original broken package is used as a template, + // and the loaded document has no URL: + CPPUNIT_ASSERT(mxComponent.queryThrow()->getURL().isEmpty()); + CPPUNIT_ASSERT_EQUAL(u"Empty document"_ustr, getParagraph(1)->getString()); +} + CPPUNIT_PLUGIN_IMPLEMENT(); /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/qa/extras/ooxmlexport/data/tdf153909_followTextFlow.docx b/sw/qa/extras/ooxmlexport/data/tdf153909_followTextFlow.docx new file mode 100644 index 0000000000..712e37acea Binary files /dev/null and b/sw/qa/extras/ooxmlexport/data/tdf153909_followTextFlow.docx differ diff --git a/sw/qa/extras/ooxmlexport/data/tdf159207_footerFramePrBorder.docx b/sw/qa/extras/ooxmlexport/data/tdf159207_footerFramePrBorder.docx new file mode 100644 index 0000000000..7a4c54cc5c Binary files /dev/null and b/sw/qa/extras/ooxmlexport/data/tdf159207_footerFramePrBorder.docx differ diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport19.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport19.cxx index 0c1d1a25fb..d6193305e9 100644 --- a/sw/qa/extras/ooxmlexport/ooxmlexport19.cxx +++ b/sw/qa/extras/ooxmlexport/ooxmlexport19.cxx @@ -609,6 +609,7 @@ DECLARE_OOXMLEXPORT_TEST(testTdf97371, "tdf97371.docx") tools::Long nDiff = std::abs(pShape->GetSnapRect().Top() - pTextBox->GetSnapRect().Top()); // The top of the two shapes were 410 and 3951, now it should be 3950 and 3951. CPPUNIT_ASSERT(nDiff < 10); + CPPUNIT_ASSERT_DOUBLES_EQUAL(tools::Long(3900), pShape->GetSnapRect().Top(), 100); } CPPUNIT_TEST_FIXTURE(Test, testTdf99140) diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport21.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport21.cxx new file mode 100644 index 0000000000..cdcdfe7785 --- /dev/null +++ b/sw/qa/extras/ooxmlexport/ooxmlexport21.cxx @@ -0,0 +1,68 @@ +/* -*- 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 + +#include +#include +#include +#include +#include + +#include +#include +#include + +namespace +{ +class Test : public SwModelTestBase +{ +public: + Test() + : SwModelTestBase("/sw/qa/extras/ooxmlexport/data/", "Office Open XML Text") + { + } +}; + +DECLARE_OOXMLEXPORT_TEST(testTdf153909_followTextFlow, "tdf153909_followTextFlow.docx") +{ + // Although MSO's UI reports "layoutInCell" for the rectangle, it isn't specified or honored + CPPUNIT_ASSERT(!getProperty(getShape(1), "IsFollowingTextFlow")); + + // Given a table with a rectangle anchored in it (wrap-through) that appears above the table... + xmlDocUniquePtr pDump = parseLayoutDump(); + sal_Int32 nRectBottom + = getXPath(pDump, "//anchored/SwAnchoredDrawObject/bounds"_ostr, "bottom"_ostr).toInt32(); + sal_Int32 nTableTop = getXPath(pDump, "//tab/row/infos/bounds"_ostr, "top"_ostr).toInt32(); + // The entire table must be below the rectangle + CPPUNIT_ASSERT(nTableTop > nRectBottom); +} + +CPPUNIT_TEST_FIXTURE(Test, testTdf159207_footerFramePrBorder) +{ + loadFromFile(u"tdf159207_footerFramePrBorder.docx"); // re-imports as editeng Frame/Shape + + // given a doc with footer paragraphs frame (with a top border, but no left border) + uno::Reference xTextFramesSupplier(mxComponent, uno::UNO_QUERY); + uno::Reference xIndexAccess(xTextFramesSupplier->getTextFrames(), + uno::UNO_QUERY); + uno::Reference xFrame0(xIndexAccess->getByIndex(0), uno::UNO_QUERY); + auto aBorder = getProperty(xFrame0, "LeftBorder"); + sal_uInt32 nBorderWidth + = aBorder.OuterLineWidth + aBorder.InnerLineWidth + aBorder.LineDistance; + // Without patch it failed with Expected 0, Actual 26 + CPPUNIT_ASSERT_EQUAL_MESSAGE("Left border:", static_cast(0), nBorderWidth); + + // TODO: there SHOULD BE a top border, and even if loaded, it would be lost on re-import... +} + +} // end of anonymous namespace +CPPUNIT_PLUGIN_IMPLEMENT(); + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport8.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport8.cxx index 10fd87ebec..0ea69e6988 100644 --- a/sw/qa/extras/ooxmlexport/ooxmlexport8.cxx +++ b/sw/qa/extras/ooxmlexport/ooxmlexport8.cxx @@ -173,6 +173,12 @@ after they are loaded. CPPUNIT_ASSERT_EQUAL( OUString( "Black" ), descr1 ); CPPUNIT_ASSERT_EQUAL( OUString( "Red" ), descr2 ); CPPUNIT_ASSERT_EQUAL( OUString( "Green" ), descr3 ); + + // tdf#139915/tdf#159157 This was 826, but it should be -826 + CPPUNIT_ASSERT_EQUAL(sal_Int32(-826), getProperty(image1, "VertOrientPosition")); + sal_Int16 nExpected = text::RelOrientation::TEXT_LINE; + CPPUNIT_ASSERT_EQUAL(nExpected, getProperty(image1, "VertOrientRelation")); + } DECLARE_OOXMLEXPORT_TEST(testN750255, "n750255.docx") diff --git a/sw/qa/extras/rtfexport/data/tdf136445-1-min.rtf b/sw/qa/extras/rtfexport/data/tdf136445-1-min.rtf new file mode 100644 index 0000000000..c0abd0d293 --- /dev/null +++ b/sw/qa/extras/rtfexport/data/tdf136445-1-min.rtf @@ -0,0 +1,17 @@ +{\rtf1 +{\*\listtable +{\list\listtemplateid8 +{\listlevel\levelnfc0\leveljc0\levelstartat1\levelfollow0{\leveltext \'02E\'00;}{\levelnumbers\'02;}\fi-720\li720}\listid8} +} +{\listoverridetable{\listoverride\listid8\listoverridecount0\ls8}} + +\ltrpar \sectd +\pard\plain \ltrpar{\rtlch\hich \ltrch\loch +I ax xoixx xuxixx xxe xixxx. (Xaxxexx 1989 x.x. xaxax a)}{\rtlch\hich \ltrch\loch +{\*\atnid CL}{\*\atnauthor Christian}\chatn{\*\annotation{\*\atndate -947463118}\rtlch \ltrch\ltrpar\aspalpha\li0\ri0\lin0\rin0\fi0\sb0\sa0\sl240\slmult1\ql\loch{\rtlch\langfe2052\alang1081\dbch\dbch\ab0\ai0 \ltrch\loch\charscalex100\b0\ulnone\ulc0\strike0\i0\outl0\shad0\kerning1\expnd0\expndtw0\lang1033\accnone\scaps0\caps0\loch +sic!}}} +\par \pard\plain {\listtext\pard\plain E119\tab}\ilvl0\ls8 \li720\ri0\lin720\rin0\fi-720\ql\ltrpar{{\*\bkmkstart __RefNumPara__395941_134077278}{\*\bkmkend __RefNumPara__395941_134077278}\rtlch\hich \ltrch\loch +Xix\tab xaxa\tab x-a\tab \tab \tab xix\tab }{\rtlch\hich \ltrch\langfe0\dbch\loch\lang255\loch +x xi = xa.} +\par +} diff --git a/sw/qa/extras/rtfexport/data/tdf158409.rtf b/sw/qa/extras/rtfexport/data/tdf158409.rtf new file mode 100644 index 0000000000..a89a5ba95d --- /dev/null +++ b/sw/qa/extras/rtfexport/data/tdf158409.rtf @@ -0,0 +1,12 @@ +{\rtf1 +{\info +{\title DocTitle} +} +{\stylesheet +{\ql\fs72 Normal;} +} + +\pard\fs16 {\field{\*\fldinst TITLE}}\par +\pard\fs72 {\rtfch\fs16{\field{\*\fldinst TITLE}}}\par + +} diff --git a/sw/qa/extras/rtfexport/data/tdf158586_pageBreak1_header.rtf b/sw/qa/extras/rtfexport/data/tdf158586_pageBreak1_header.rtf new file mode 100644 index 0000000000..cd8eefabb2 --- /dev/null +++ b/sw/qa/extras/rtfexport/data/tdf158586_pageBreak1_header.rtf @@ -0,0 +1,17 @@ +{\rtf1 + +\paperw8419\paperh5953 + +\spltpgpar + +\ltrpar \sectd + +{\headerl \pard\plain \par} + +\pard\plain \wrapdefault\pvmrg\posxl\absw0\absh0\phcol \posyil\abslock\dxfrtext10 + +\page \sect \sectd \sbknone + +\pard\plain Second page +\par +} diff --git a/sw/qa/extras/rtfexport/rtfexport3.cxx b/sw/qa/extras/rtfexport/rtfexport3.cxx index 435242308a..fd25e7e575 100644 --- a/sw/qa/extras/rtfexport/rtfexport3.cxx +++ b/sw/qa/extras/rtfexport/rtfexport3.cxx @@ -707,6 +707,15 @@ CPPUNIT_TEST_FIXTURE(Test, testFloattableOverlapNeverRTFExport) CPPUNIT_ASSERT(!pFly->GetAttrSet().GetWrapInfluenceOnObjPos().GetAllowOverlap()); } +DECLARE_RTFEXPORT_TEST(testTdf158409, "tdf158409.rtf") +{ + uno::Reference xRun = getRun(getParagraph(1), 1, "DocTitle"); + CPPUNIT_ASSERT_EQUAL(8.0, getProperty(xRun, "CharHeight")); + + xRun = getRun(getParagraph(2), 1, "DocTitle"); + CPPUNIT_ASSERT_EQUAL(8.0, getProperty(xRun, "CharHeight")); +} + CPPUNIT_PLUGIN_IMPLEMENT(); /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/qa/extras/rtfexport/rtfexport8.cxx b/sw/qa/extras/rtfexport/rtfexport8.cxx index 67d48a27dc..08ca8452f9 100644 --- a/sw/qa/extras/rtfexport/rtfexport8.cxx +++ b/sw/qa/extras/rtfexport/rtfexport8.cxx @@ -52,28 +52,50 @@ DECLARE_RTFEXPORT_TEST(testTdf158586_0, "tdf158586_pageBreak0.rtf") { // The specified page break must be lost because it is in a text frame CPPUNIT_ASSERT_EQUAL(1, getPages()); - // CPPUNIT_ASSERT_EQUAL(1, getParagraphs()); + CPPUNIT_ASSERT_EQUAL(1, getParagraphs()); - // There should be no empty carriage return at the start of the second page - // const auto& pLayout = parseLayoutDump(); - // assertXPathContent(pLayout, "//page[1]/body/txt"_ostr, "First page");} + // There should be no empty paragraph at the start + const auto& pLayout = parseLayoutDump(); + assertXPath(pLayout, "//anchored"_ostr, 1); + assertXPathContent(pLayout, "/root/page[1]/body//txt"_ostr, "First page"); } DECLARE_RTFEXPORT_TEST(testTdf158586_0B, "tdf158586_pageBreak0B.rtf") { // The specified page break must be lost because it is in a text frame CPPUNIT_ASSERT_EQUAL(1, getPages()); + CPPUNIT_ASSERT_EQUAL(1, getParagraphs()); + + // There should be no empty paragraph at the start + const auto& pLayout = parseLayoutDump(); + assertXPath(pLayout, "//anchored"_ostr, 1); + assertXPathContent(pLayout, "/root/page[1]/body//txt"_ostr, "First page"); } DECLARE_RTFEXPORT_TEST(testTdf158586_1, "tdf158586_pageBreak1.rtf") { // None of the specified text frame settings initiates a real text frame - page break not lost - // CPPUNIT_ASSERT_EQUAL(2, getPages()); - // CPPUNIT_ASSERT_EQUAL(2, getParagraphs()); + CPPUNIT_ASSERT_EQUAL(2, getPages()); + CPPUNIT_ASSERT_EQUAL(2, getParagraphs()); + + // There should be no empty carriage return at the start of the second page + const auto& pLayout = parseLayoutDump(); + // on import there is a section on page 2; on reimport there is no section + // (probably not an important difference?) + assertXPathContent(pLayout, "/root/page[2]/body//txt"_ostr, "Second page"); +} + +DECLARE_RTFEXPORT_TEST(testTdf158586_1header, "tdf158586_pageBreak1_header.rtf") +{ + // None of the specified text frame settings initiates a real text frame - page break not lost + CPPUNIT_ASSERT_EQUAL(2, getPages()); + CPPUNIT_ASSERT_EQUAL(2, getParagraphs()); // There should be no empty carriage return at the start of the second page - // const auto& pLayout = parseLayoutDump(); - // assertXPathContent(pLayout, "//page[2]/body/txt"_ostr, "Second page"); + const auto& pLayout = parseLayoutDump(); + // on import there is a section on page 2; on reimport there is no section + // (probably not an important difference?) + assertXPathContent(pLayout, "/root/page[2]/body//txt"_ostr, "Second page"); } DECLARE_RTFEXPORT_TEST(testTdf158586_lostFrame, "tdf158586_lostFrame.rtf") @@ -82,9 +104,23 @@ DECLARE_RTFEXPORT_TEST(testTdf158586_lostFrame, "tdf158586_lostFrame.rtf") const auto& pLayout = parseLayoutDump(); assertXPath(pLayout, "//anchored"_ostr, 1); assertXPathContent(pLayout, "//page[1]/body//txt"_ostr, "1st page"); - // assertXPathContent(pLayout, "//page[2]/body//txt"_ostr, "2nd page"); + assertXPathContent(pLayout, "//page[2]/body//txt"_ostr, "2nd page"); - // CPPUNIT_ASSERT_EQUAL(2, getPages()); + CPPUNIT_ASSERT_EQUAL(2, getPages()); +} + +DECLARE_RTFEXPORT_TEST(testAnnotationPar, "tdf136445-1-min.rtf") +{ + // the problem was that the paragraph break following annotation was missing + CPPUNIT_ASSERT_EQUAL(2, getParagraphs()); + CPPUNIT_ASSERT_EQUAL( + OUString("Annotation"), + getProperty( + getRun(getParagraph(1, "I ax xoixx xuxixx xxe xixxx. (Xaxxexx 1989 x.x. xaxax a)"), 2), + "TextPortionType")); + CPPUNIT_ASSERT( + !getProperty(getParagraph(2, "Xix\txaxa\tx-a\t\t\txix\tx xi = xa."), "ListId") + .isEmpty()); } DECLARE_RTFEXPORT_TEST(testTdf158826_extraCR, "tdf158826_extraCR.rtf") diff --git a/sw/qa/extras/rtfimport/rtfimport.cxx b/sw/qa/extras/rtfimport/rtfimport.cxx index 3d516a0042..1a6d1c9772 100644 --- a/sw/qa/extras/rtfimport/rtfimport.cxx +++ b/sw/qa/extras/rtfimport/rtfimport.cxx @@ -1568,7 +1568,7 @@ CPPUNIT_TEST_FIXTURE(Test, testTdf108947) uno::Reference xHeaderTextLeft = getProperty>( getStyles("PageStyles")->getByName("Default Page Style"), "HeaderTextLeft"); aActual = xHeaderTextLeft->getString(); - CPPUNIT_ASSERT_EQUAL(OUString("Header Page 2 ?"), aActual); + CPPUNIT_ASSERT_EQUAL(OUString(SAL_NEWLINE_STRING "Header Page 2 ?"), aActual); #endif } diff --git a/sw/qa/extras/uiwriter/data/tdf135083-simple-text-plus-list.fodt b/sw/qa/extras/uiwriter/data/tdf135083-simple-text-plus-list.fodt new file mode 100644 index 0000000000..cf2aaac6fc --- /dev/null +++ b/sw/qa/extras/uiwriter/data/tdf135083-simple-text-plus-list.fodt @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + + + + Lorem + + + ipsum + + + dolor + + + + + \ No newline at end of file diff --git a/sw/qa/extras/uiwriter/data/tdf159049_LineBreakRTFClipboard.fodt b/sw/qa/extras/uiwriter/data/tdf159049_LineBreakRTFClipboard.fodt new file mode 100644 index 0000000000..22472c1970 --- /dev/null +++ b/sw/qa/extras/uiwriter/data/tdf159049_LineBreakRTFClipboard.fodt @@ -0,0 +1,300 @@ + + + + Regina Henschel2024-01-08T23:25:06.8490000002024-01-09T20:51:07.363000000Regina HenschelPT18M48S8LOmyBuild/24.8.0.0.alpha0$Windows_X86_64 LibreOffice_project/00eae23267bf64e07cf057f828cd85f3c38ac669 + + + 0 + 0 + 21338 + 14543 + true + false + + + view2 + 11003 + 1000 + 0 + 0 + 21336 + 14542 + 0 + 1 + false + 100 + false + false + false + false + false + false + + + + + true + + false + false + false + false + true + 1 + true + false + false + false + + false + + false + false + false + Person + 0 + false + true + true + false + false + false + IDAnredeVornameNachname + 0 + + true + high-resolution + false + false + true + true + true + false + false + true + true + false + true + true + false + false + false + true + false + true + false + false + true + false + false + false + false + false + false + 757206 + 303919 + false + false + true + true + false + true + true + false + true + true + true + false + false + false + false + true + false + true + false + false + false + false + false + true + 0 + true + false + true + true + false + false + true + false + 0 + true + false + true + true + true + false + false + false + false + false + true + + false + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + A + breakhere + second paragraph + B + + + \ No newline at end of file diff --git a/sw/qa/extras/uiwriter/uiwriter5.cxx b/sw/qa/extras/uiwriter/uiwriter5.cxx index 31aefb1128..c6353f980d 100644 --- a/sw/qa/extras/uiwriter/uiwriter5.cxx +++ b/sw/qa/extras/uiwriter/uiwriter5.cxx @@ -1291,8 +1291,8 @@ CPPUNIT_TEST_FIXTURE(SwUiWriterTest5, testImageCommentAtChar) // Get the image anchor doc model position. SwFlyFrame* pFly = pWrtShell->GetCurrFlyFrame(false); CPPUNIT_ASSERT(pFly); - SwFrameFormat& rFlyFormat = pFly->GetFrameFormat(); - const SwPosition* pImageAnchor = rFlyFormat.GetAnchor().GetContentAnchor(); + SwFrameFormat* pFlyFormat = pFly->GetFrameFormat(); + const SwPosition* pImageAnchor = pFlyFormat->GetAnchor().GetContentAnchor(); CPPUNIT_ASSERT(pImageAnchor); // Get the annotation mark doc model start. diff --git a/sw/qa/extras/uiwriter/uiwriter9.cxx b/sw/qa/extras/uiwriter/uiwriter9.cxx index b6dea5a8e7..1a3e49c257 100644 --- a/sw/qa/extras/uiwriter/uiwriter9.cxx +++ b/sw/qa/extras/uiwriter/uiwriter9.cxx @@ -68,7 +68,61 @@ CPPUNIT_TEST_FIXTURE(SwUiWriterTest9, testTdf158785) CPPUNIT_ASSERT_EQUAL(IsAttrAtPos::NONE, aContentAtPos.eContentAtPos); } -} // end of anonymouse namespace +CPPUNIT_TEST_FIXTURE(SwUiWriterTest9, testTdf159049) +{ + // The document contains a shape which has a text with a line break. When copying the text to + // clipboard the line break was missing in the RTF flavor of the clipboard. + createSwDoc("tdf159049_LineBreakRTFClipboard.fodt"); + CPPUNIT_ASSERT_EQUAL(1, getShapes()); + selectShape(1); + + // Bring shape into text edit mode + SwXTextDocument* pTextDoc = dynamic_cast(mxComponent.get()); + CPPUNIT_ASSERT(pTextDoc); + pTextDoc->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 0, KEY_RETURN); + pTextDoc->postKeyEvent(LOK_KEYEVENT_KEYUP, 0, KEY_RETURN); + Scheduler::ProcessEventsToIdle(); + // Copy text + dispatchCommand(mxComponent, ".uno:SelectAll", {}); + dispatchCommand(mxComponent, ".uno:Copy", {}); + + // Deactivate text edit mode ... + pTextDoc->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 0, KEY_ESCAPE); + pTextDoc->postKeyEvent(LOK_KEYEVENT_KEYUP, 0, KEY_ESCAPE); + Scheduler::ProcessEventsToIdle(); + // ... and deselect shape. + pTextDoc->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 0, KEY_ESCAPE); + pTextDoc->postKeyEvent(LOK_KEYEVENT_KEYUP, 0, KEY_ESCAPE); + Scheduler::ProcessEventsToIdle(); + + // Paste special as RTF + uno::Sequence aArgs(comphelper::InitPropertySequence( + { { "SelectedFormat", uno::Any(static_cast(SotClipboardFormatId::RTF)) } })); + dispatchCommand(mxComponent, ".uno:ClipboardFormatItems", aArgs); + // Without fix Actual was "Abreakhere", the line break \n was missing. + CPPUNIT_ASSERT_EQUAL(u"Abreak\nhere"_ustr, getParagraph(1)->getString()); +} + +CPPUNIT_TEST_FIXTURE(SwUiWriterTest9, testTdf135083) +{ + createSwDoc("tdf135083-simple-text-plus-list.fodt"); + + dispatchCommand(mxComponent, u".uno:SelectAll"_ustr, {}); + dispatchCommand(mxComponent, u".uno:Copy"_ustr, {}); + + // Paste special as RTF + uno::Sequence aArgs(comphelper::InitPropertySequence( + { { u"SelectedFormat"_ustr, + uno::Any(static_cast(SotClipboardFormatId::RTF)) } })); + dispatchCommand(mxComponent, ".uno:ClipboardFormatItems", aArgs); + + auto xLastPara = getParagraph(3); + CPPUNIT_ASSERT_EQUAL(u"dolor"_ustr, xLastPara->getString()); + // Without the fix in place, the last paragraph would loose its settings. ListId would be empty. + CPPUNIT_ASSERT(!getProperty(xLastPara, u"ListId"_ustr).isEmpty()); +} + +} // end of anonymous namespace CPPUNIT_PLUGIN_IMPLEMENT(); /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/qa/uitest/data/tdf106733.fodt b/sw/qa/uitest/data/tdf106733.fodt new file mode 100644 index 0000000000..fa9a024405 --- /dev/null +++ b/sw/qa/uitest/data/tdf106733.fodt @@ -0,0 +1,66 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Hyphenate + The Earth is no different to any other celestial body out there in space. It merely moves along in space inertially. Even just one inch above the surface of the Earth is space, except that it has an atmosphere. + Don’t hyphenate (direct formatting) + The Earth is no different to any other celestial body out there in space. It merely moves along in space inertially. Even just one inch above the surface of the Earth is space, except that it has an atmosphere. + Don’t hyphenate (character style) + The Earth is no different to any other celestial body out there in space. It merely moves along in space inertially. Even just one inch above the surface of the Earth is space, except that it has an atmosphere. + + + + diff --git a/sw/qa/uitest/data/tdf159102.fodt b/sw/qa/uitest/data/tdf159102.fodt new file mode 100644 index 0000000000..dfe9fc1887 --- /dev/null +++ b/sw/qa/uitest/data/tdf159102.fodt @@ -0,0 +1,61 @@ + + + + + + true + high-resolution + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + venenatis, quis commodo dolor posuere. Curabitur dignissim sapien quis cursus egestas. + venenatis, quis commodo dolor posuere. Curabitur dignissim sapien quis cursus egestas. + + + diff --git a/sw/qa/uitest/writer_tests8/tdf106733.py b/sw/qa/uitest/writer_tests8/tdf106733.py new file mode 100644 index 0000000000..201bba1c56 --- /dev/null +++ b/sw/qa/uitest/writer_tests8/tdf106733.py @@ -0,0 +1,112 @@ +# -*- tab-width: 4; indent-tabs-mode: nil; py-indent-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/. +# +from uitest.framework import UITestCase +from uitest.uihelper.common import get_state_as_dict, get_url_for_data_file +from libreoffice.uno.propertyvalue import mkPropertyValues +from libreoffice.linguistic.linguservice import get_lingu_service_manager +from com.sun.star.lang import Locale + +# handle tdf#106733 hyphenation of words disabled by character formatting + +class tdf106733(UITestCase): + def is_supported_locale(self, language, country): + xLinguServiceManager = get_lingu_service_manager(self.ui_test._xContext) + xHyphenator = xLinguServiceManager.getHyphenator() + locales = xHyphenator.getLocales() + for locale in locales: + if language != None: + if locale.Language != language: + continue + + if country != None: + if locale.Country != country: + continue + + # we found the correct combination + return True + + def set_custom_hyphenation(self): + with self.ui_test.execute_dialog_through_command(".uno:OptionsTreeDialog") as xDialog: + + xPages = xDialog.getChild("pages") + xLanguageEntry = xPages.getChild('2') # Language Settings + xLanguageEntry.executeAction("EXPAND", tuple()) + xxLanguageEntryWritingAidsEntry = xLanguageEntry.getChild('1') + xxLanguageEntryWritingAidsEntry.executeAction("SELECT", tuple()) # Writing Aids + + # add hyphenations to the custom dictionary to solve the non-accessible + # hyphenation patterns for the test + + # Select an editable dictionary (list of Ignored words) + dictionaries = xDialog.getChild("lingudicts") + hasEditableDictionary = False + for i in dictionaries.getChildren(): + entry = dictionaries.getChild(i) + entry_label = get_state_as_dict(entry)["Text"] + if entry_label == "List of Ignored Words [All]": + hasEditableDictionary = True + entry.executeAction("SELECT", tuple()) # an editable user dictionary + break + + self.assertEqual(True, hasEditableDictionary) + + # open Edit dialog window + edit = xDialog.getChild("lingudictsedit") + with self.ui_test.execute_blocking_action(edit.executeAction, args=('CLICK', ()), close_button="close") as xEdit: + # add in=ertially and ex=cept to the custom hyphenations + inputbox = xEdit.getChild("word") + inputbox.executeAction("TYPE", mkPropertyValues({"TEXT": "ex=cept"})) + add = xEdit.getChild("newreplace") + add.executeAction("CLICK", tuple()) + inputbox.executeAction("TYPE", mkPropertyValues({"TEXT": "in=ertially"})) + add.executeAction("CLICK", tuple()) + + def test_tdf106733_disable_hyphenation(self): + supported_locale = self.is_supported_locale("en", "US") + if not supported_locale: + self.skipTest("no hyphenation patterns for en_US available") + + with self.ui_test.load_file(get_url_for_data_file("tdf106733.fodt")) as writer_doc: + # we must not depend on the installed hyphenation patterns, + # so extend user dictionary temporarily with the requested hyphenations + self.set_custom_hyphenation() + + # delete the text of the first line + for i in range(5): + self.xUITest.executeCommand(".uno:GoDown") + self.xUITest.executeCommand(".uno:GoToEndOfLine") + self.xUITest.executeCommand('.uno:StartOfDocumentSel') + self.xUITest.executeCommand('.uno:Delete') + paragraphs = writer_doc.Text.createEnumeration() + para1 = paragraphs.nextElement() + # check default "ex=cept" hyphenation + self.assertEqual(True, para1.String.startswith("cept")) + + # check disabled hyphenations (by direct character formatting) + for i in range(6): + self.xUITest.executeCommand(".uno:GoDown") + self.xUITest.executeCommand(".uno:GoToEndOfLine") + self.xUITest.executeCommand('.uno:StartOfDocumentSel') + self.xUITest.executeCommand('.uno:Delete') + paragraphs = writer_doc.Text.createEnumeration() + para1 = paragraphs.nextElement() + # This was False (the line started with "cept", because of the enabled hyphenation) + self.assertEqual(True, para1.String.startswith(" except")) + + # check disabled hyphenations (by character style) + for i in range(6): + self.xUITest.executeCommand(".uno:GoDown") + self.xUITest.executeCommand(".uno:GoToEndOfLine") + self.xUITest.executeCommand('.uno:StartOfDocumentSel') + self.xUITest.executeCommand('.uno:Delete') + paragraphs = writer_doc.Text.createEnumeration() + para1 = paragraphs.nextElement() + # This was False (the line started with "cept", because of the enabled hyphenation) + self.assertEqual(True, para1.String.startswith(" except")) + diff --git a/sw/qa/uitest/writer_tests8/tdf159102.py b/sw/qa/uitest/writer_tests8/tdf159102.py new file mode 100644 index 0000000000..b1daffabfe --- /dev/null +++ b/sw/qa/uitest/writer_tests8/tdf159102.py @@ -0,0 +1,97 @@ +# -*- tab-width: 4; indent-tabs-mode: nil; py-indent-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/. +# +from uitest.framework import UITestCase +from uitest.uihelper.common import get_state_as_dict, get_url_for_data_file +from libreoffice.uno.propertyvalue import mkPropertyValues +from libreoffice.linguistic.linguservice import get_lingu_service_manager +from com.sun.star.lang import Locale + +# handle tdf#119908 smart justify with automatic hyphenation + +class tdf159102(UITestCase): + def is_supported_locale(self, language, country): + xLinguServiceManager = get_lingu_service_manager(self.ui_test._xContext) + xHyphenator = xLinguServiceManager.getHyphenator() + locales = xHyphenator.getLocales() + for locale in locales: + if language != None: + if locale.Language != language: + continue + + if country != None: + if locale.Country != country: + continue + + # we found the correct combination + return True + + def set_custom_hyphenation(self): + with self.ui_test.execute_dialog_through_command(".uno:OptionsTreeDialog") as xDialog: + + xPages = xDialog.getChild("pages") + xLanguageEntry = xPages.getChild('2') # Language Settings + xLanguageEntry.executeAction("EXPAND", tuple()) + xxLanguageEntryWritingAidsEntry = xLanguageEntry.getChild('1') + xxLanguageEntryWritingAidsEntry.executeAction("SELECT", tuple()) # Writing Aids + + # add hyphenation "cur=sus" and "ege=stas" to the custom dictionary + # to solve the non-accessible hyphenation patterns for the test + + # Select an editable dictionary (list of Ignored words) + dictionaries = xDialog.getChild("lingudicts") + hasEditableDictionary = False + for i in dictionaries.getChildren(): + entry = dictionaries.getChild(i) + entry_label = get_state_as_dict(entry)["Text"] + if entry_label == "List of Ignored Words [All]": + hasEditableDictionary = True + entry.executeAction("SELECT", tuple()) # an editable user dictionary + break + + self.assertEqual(True, hasEditableDictionary) + + # open Edit dialog window + edit = xDialog.getChild("lingudictsedit") + with self.ui_test.execute_blocking_action(edit.executeAction, args=('CLICK', ()), close_button="close") as xEdit: + # write cur=sus into the input box + inputbox = xEdit.getChild("word") + inputbox.executeAction("TYPE", mkPropertyValues({"TEXT": "cur=sus"})) + add = xEdit.getChild("newreplace") + add.executeAction("CLICK", tuple()) + inputbox.executeAction("TYPE", mkPropertyValues({"TEXT": "ege=stas"})) + add.executeAction("CLICK", tuple()) + + def test_tdf159102_smart_justify_with_automatic_hyphenation(self): + supported_locale = self.is_supported_locale("en", "US") + if not supported_locale: + self.skipTest("no hyphenation patterns for en_US available") + + xToolkit = self.xContext.ServiceManager.createInstance('com.sun.star.awt.Toolkit') + with self.ui_test.load_file(get_url_for_data_file("tdf159102.fodt")) as writer_doc: + # we must not depend on the installed hyphenation patterns, + # so extend user dictionary temporarily with the hyphenation cur=sus and ege=stas + self.set_custom_hyphenation() + xToolkit.processEventsToIdle() + # delete the text of the first line + self.xUITest.executeCommand(".uno:GoToEndOfLine") + self.xUITest.executeCommand('.uno:StartOfDocumentSel') + self.xUITest.executeCommand('.uno:Delete') + paragraphs = writer_doc.Text.createEnumeration() + para1 = paragraphs.nextElement() + # This was "stas.", i.e. too much shrinking + self.assertEqual("sus egestas.", para1.String) + + # check next paragraph (containing different text portions) + self.xUITest.executeCommand(".uno:GoDown") + self.xUITest.executeCommand(".uno:GoToEndOfLine") + self.xUITest.executeCommand('.uno:StartOfDocumentSel') + self.xUITest.executeCommand('.uno:Delete') + paragraphs = writer_doc.Text.createEnumeration() + para1 = paragraphs.nextElement() + self.assertEqual("sus egestas.", para1.String) diff --git a/sw/source/core/access/AccessibilityCheck.cxx b/sw/source/core/access/AccessibilityCheck.cxx index e4eaa089ef..e515b5cae7 100644 --- a/sw/source/core/access/AccessibilityCheck.cxx +++ b/sw/source/core/access/AccessibilityCheck.cxx @@ -344,6 +344,10 @@ public: if (!pNextTextNode) return; + SwSectionNode* pNd = pCurrentTextNode->FindSectionNode(); + if (pNd && pNd->GetSection().GetType() == SectionType::ToxContent) + return; + for (auto& rPair : m_aNumberingCombinations) { if (pCurrentTextNode->GetText().startsWith(rPair.first) diff --git a/sw/source/core/crsr/crsrsh.cxx b/sw/source/core/crsr/crsrsh.cxx index 04b263cda7..173414ed4d 100644 --- a/sw/source/core/crsr/crsrsh.cxx +++ b/sw/source/core/crsr/crsrsh.cxx @@ -2936,6 +2936,7 @@ OUString SwCursorShell::GetSelText() const } /** get the nth character of the current SSelection + in the same paragraph as the start/end. @param bEnd Start counting from the end? From start otherwise. @param nOffset position of the character @@ -2951,8 +2952,14 @@ sal_Unicode SwCursorShell::GetChar( bool bEnd, tools::Long nOffset ) if( !pTextNd ) return 0; - const sal_Int32 nPos = pPos->GetContentIndex(); - const OUString& rStr = pTextNd->GetText(); + SwTextFrame const*const pFrame(static_cast(pTextNd->getLayoutFrame(GetLayout()))); + if (!pFrame) + { + return 0; + } + + const sal_Int32 nPos(sal_Int32(pFrame->MapModelToViewPos(*pPos))); + const OUString& rStr(pFrame->GetText()); sal_Unicode cCh = 0; if (((nPos+nOffset) >= 0 ) && (nPos+nOffset) < rStr.getLength()) diff --git a/sw/source/core/crsr/crstrvl.cxx b/sw/source/core/crsr/crstrvl.cxx index db11d4ea33..81323787d7 100644 --- a/sw/source/core/crsr/crstrvl.cxx +++ b/sw/source/core/crsr/crstrvl.cxx @@ -600,6 +600,7 @@ const SwTOXMark& SwCursorShell::GotoTOXMark( const SwTOXMark& rStart, SwPosition& rPos = *GetCursor()->GetPoint(); rPos.Assign(rNewMark.GetTextTOXMark()->GetTextNode(), rNewMark.GetTextTOXMark()->GetStart() ); + GetCursor()->DeleteMark(); // tdf#158783 prevent UpdateCursor resetting point if( !m_pCurrentCursor->IsSelOvr() ) UpdateCursor( SwCursorShell::SCROLLWIN | SwCursorShell::CHKRANGE | diff --git a/sw/source/core/doc/DocumentSettingManager.cxx b/sw/source/core/doc/DocumentSettingManager.cxx index ebe116c682..baa0f29326 100644 --- a/sw/source/core/doc/DocumentSettingManager.cxx +++ b/sw/source/core/doc/DocumentSettingManager.cxx @@ -192,6 +192,7 @@ bool sw::DocumentSettingManager::get(/*[in]*/ DocumentSettingId id) const case DocumentSettingId::CONSIDER_WRAP_ON_OBJECT_POSITION: return mbConsiderWrapOnObjPos; case DocumentSettingId::DO_NOT_JUSTIFY_LINES_WITH_MANUAL_BREAK: return mbDoNotJustifyLinesWithManualBreak; case DocumentSettingId::IGNORE_FIRST_LINE_INDENT_IN_NUMBERING: return mbIgnoreFirstLineIndentInNumbering; + case DocumentSettingId::NO_GAP_AFTER_NOTE_NUMBER: return mbNoGapAfterNoteNumber; case DocumentSettingId::TABLE_ROW_KEEP: return mbTableRowKeep; case DocumentSettingId::IGNORE_TABS_AND_BLANKS_FOR_LINE_CALCULATION: return mbIgnoreTabsAndBlanksForLineCalculation; case DocumentSettingId::DO_NOT_CAPTURE_DRAW_OBJS_ON_PAGE: return mbDoNotCaptureDrawObjsOnPage; @@ -337,6 +338,9 @@ void sw::DocumentSettingManager::set(/*[in]*/ DocumentSettingId id, /*[in]*/ boo case DocumentSettingId::IGNORE_FIRST_LINE_INDENT_IN_NUMBERING: mbIgnoreFirstLineIndentInNumbering = value; break; + case DocumentSettingId::NO_GAP_AFTER_NOTE_NUMBER: + mbNoGapAfterNoteNumber = value; + break; case DocumentSettingId::TABLE_ROW_KEEP: mbTableRowKeep = value; @@ -697,6 +701,7 @@ void sw::DocumentSettingManager::ReplaceCompatibilityOptions(const DocumentSetti mbStylesNoDefault = rSource.mbStylesNoDefault; mbOldNumbering = rSource.mbOldNumbering; mbIgnoreFirstLineIndentInNumbering = rSource.mbIgnoreFirstLineIndentInNumbering; + mbNoGapAfterNoteNumber = rSource.mbNoGapAfterNoteNumber; mbDoNotJustifyLinesWithManualBreak = rSource.mbDoNotJustifyLinesWithManualBreak; mbDoNotResetParaAttrsForNumFont = rSource.mbDoNotResetParaAttrsForNumFont; mbTableRowKeep = rSource.mbTableRowKeep; @@ -880,6 +885,12 @@ void sw::DocumentSettingManager::dumpAsXml(xmlTextWriterPtr pWriter) const BAD_CAST(OString::boolean(mbIgnoreFirstLineIndentInNumbering).getStr())); (void)xmlTextWriterEndElement(pWriter); + (void)xmlTextWriterStartElement(pWriter, BAD_CAST("mbNoGapAfterNoteNumber")); + (void)xmlTextWriterWriteAttribute( + pWriter, BAD_CAST("value"), + BAD_CAST(OString::boolean(mbNoGapAfterNoteNumber).getStr())); + (void)xmlTextWriterEndElement(pWriter); + (void)xmlTextWriterStartElement(pWriter, BAD_CAST("mbDoNotJustifyLinesWithManualBreak")); (void)xmlTextWriterWriteAttribute( pWriter, BAD_CAST("value"), diff --git a/sw/source/core/doc/docbm.cxx b/sw/source/core/doc/docbm.cxx index 00681135b4..730da32625 100644 --- a/sw/source/core/doc/docbm.cxx +++ b/sw/source/core/doc/docbm.cxx @@ -1410,6 +1410,16 @@ namespace sw::mark return IDocumentMarkAccess::iterator(ret); } + // find the first Mark that does not start before + IDocumentMarkAccess::const_iterator_t MarkManager::findFirstMarkNotStartsBefore(const SwPosition& rPos) const + { + return std::lower_bound( + m_vAllMarks.begin(), + m_vAllMarks.end(), + rPos, + CompareIMarkStartsBefore()); + } + IDocumentMarkAccess::const_iterator_t MarkManager::getAllMarksBegin() const { return m_vAllMarks.begin(); } diff --git a/sw/source/core/doc/docdraw.cxx b/sw/source/core/doc/docdraw.cxx index aecbe2ac82..521ca2b0ba 100644 --- a/sw/source/core/doc/docdraw.cxx +++ b/sw/source/core/doc/docdraw.cxx @@ -463,14 +463,17 @@ bool SwDoc::DeleteSelection( SwDrawView& rDrawView ) SdrObject *pObj = rMrkList.GetMark( i )->GetMarkedSdrObj(); if( dynamic_cast( pObj) == nullptr ) { - SwDrawContact *pC = static_cast(GetUserCall(pObj)); - SwDrawFrameFormat *pFrameFormat = static_cast(pC->GetFormat()); - if( pFrameFormat && - RndStdIds::FLY_AS_CHAR == pFrameFormat->GetAnchor().GetAnchorId() ) + if (SwDrawContact* pC = static_cast(GetUserCall(pObj))) { - rDrawView.MarkObj( pObj, rDrawView.Imp().GetPageView(), true ); - --i; - getIDocumentLayoutAccess().DelLayoutFormat( pFrameFormat ); + SwDrawFrameFormat* pFrameFormat + = static_cast(pC->GetFormat()); + if (pFrameFormat + && RndStdIds::FLY_AS_CHAR == pFrameFormat->GetAnchor().GetAnchorId()) + { + rDrawView.MarkObj(pObj, rDrawView.Imp().GetPageView(), true); + --i; + getIDocumentLayoutAccess().DelLayoutFormat(pFrameFormat); + } } } } diff --git a/sw/source/core/doc/docfmt.cxx b/sw/source/core/doc/docfmt.cxx index 57c42c529e..d6c943dbcd 100644 --- a/sw/source/core/doc/docfmt.cxx +++ b/sw/source/core/doc/docfmt.cxx @@ -25,10 +25,10 @@ #include #include #include -#include #include #include #include +#include #include #include #include @@ -2036,17 +2036,11 @@ std::set SwDoc::GetDocColors() { std::set aDocColors; SwAttrPool& rPool = GetAttrPool(); - const sal_uInt16 pAttribs[] = {RES_CHRATR_COLOR, RES_CHRATR_HIGHLIGHT, RES_BACKGROUND}; - for (sal_uInt16 nAttrib : pAttribs) - { - for (const SfxPoolItem* pItem : rPool.GetItemSurrogates(nAttrib)) - { - auto pColorItem = static_cast(pItem); - Color aColor( pColorItem->GetValue() ); - if (COL_AUTO != aColor) - aDocColors.insert(aColor); - } - } + + svx::DocumentColorHelper::queryColors(RES_CHRATR_COLOR, &rPool, aDocColors); + svx::DocumentColorHelper::queryColors(RES_CHRATR_HIGHLIGHT, &rPool, aDocColors); + svx::DocumentColorHelper::queryColors(RES_CHRATR_BACKGROUND, &rPool, aDocColors); + return aDocColors; } diff --git a/sw/source/core/doc/doclay.cxx b/sw/source/core/doc/doclay.cxx index 2ecea30dc3..ebbefd9738 100644 --- a/sw/source/core/doc/doclay.cxx +++ b/sw/source/core/doc/doclay.cxx @@ -554,10 +554,8 @@ SwPosFlyFrames SwDoc::GetAllFlyFormats( const SwPaM* pCmpRange, bool bDrawAlso, for(SwAnchoredObject* pAnchoredObj : rObjs) { SwFrameFormat *pFly; - if ( pAnchoredObj->DynCastFlyFrame() != nullptr ) - pFly = &(pAnchoredObj->GetFrameFormat()); - else if ( bDrawAlso ) - pFly = &(pAnchoredObj->GetFrameFormat()); + if (bDrawAlso || pAnchoredObj->DynCastFlyFrame()) + pFly = pAnchoredObj->GetFrameFormat(); else continue; diff --git a/sw/source/core/draw/dcontact.cxx b/sw/source/core/draw/dcontact.cxx index 5c2147ed91..aac8f2393c 100644 --- a/sw/source/core/draw/dcontact.cxx +++ b/sw/source/core/draw/dcontact.cxx @@ -493,7 +493,7 @@ sal_uInt32 SwFlyDrawContact::GetOrdNumForNewRef(const SwFlyFrame* pFly, { for (SwAnchoredObject const*const pAnchoredObj : *pObjs) { - if (&pAnchoredObj->GetFrameFormat() == pDrawFormat) + if (pAnchoredObj->GetFrameFormat() == pDrawFormat) { return pAnchoredObj->GetDrawObj()->GetOrdNum() + 1; } @@ -1235,7 +1235,7 @@ void SwDrawContact::Changed_( const SdrObject& rObj, // #i31698# - determine layout direction // via draw frame format. SwFrameFormat::tLayoutDir eLayoutDir = - pAnchoredDrawObj->GetFrameFormat().GetLayoutDir(); + pAnchoredDrawObj->GetFrameFormat()->GetLayoutDir(); // use geometry of drawing object tools::Rectangle aObjRect( rObj.GetSnapRect() ); // If drawing object is a member of a group, the adjustment @@ -1967,7 +1967,7 @@ void SwDrawContact::ConnectToLayout( const SwFormatAnchor* pAnch ) { for (const SwAnchoredObject* pAnchoredObj : *pObjs) { - if (&pAnchoredObj->GetFrameFormat() == pFlyFormat) + if (pAnchoredObj->GetFrameFormat() == pFlyFormat) { SdrPage* pDrawPage = pAnchoredObj->GetDrawObj()->getSdrPageFromSdrObject(); if (pDrawPage) @@ -2359,7 +2359,7 @@ void SwDrawVirtObj::AddToDrawingPage(SwFrame const& rAnchorFrame) { for (SwAnchoredObject const*const pAnchoredObj : *pObjs) { - if (&pAnchoredObj->GetFrameFormat() == pFlyFormat) + if (pAnchoredObj->GetFrameFormat() == pFlyFormat) { assert(dynamic_cast(pAnchoredObj)); diff --git a/sw/source/core/draw/dview.cxx b/sw/source/core/draw/dview.cxx index 9d704647c3..fe0db61925 100644 --- a/sw/source/core/draw/dview.cxx +++ b/sw/source/core/draw/dview.cxx @@ -550,7 +550,7 @@ void SwDrawView::ObjOrderChanged( SdrObject* pObj, size_t nOldPos, { size_t nTmpNewPos( nNewPos ); const SwFrameFormat* pParentFrameFormat = - pParentAnchoredObj ? &(pParentAnchoredObj->GetFrameFormat()) : nullptr; + pParentAnchoredObj ? pParentAnchoredObj->GetFrameFormat() : nullptr; const SdrObject* pTmpObj = pDrawPage->GetObj( nNewPos + 1 ); while ( pTmpObj ) { @@ -562,7 +562,7 @@ void SwDrawView::ObjOrderChanged( SdrObject* pObj, size_t nOldPos, const SwFlyFrame* pTmpParentObj = pTmpAnchorFrame ? pTmpAnchorFrame->FindFlyFrame() : nullptr; if ( pTmpParentObj && - &(pTmpParentObj->GetFrameFormat()) != pParentFrameFormat ) + pTmpParentObj->GetFrameFormat() != pParentFrameFormat ) { if ( bMovedForward ) { @@ -977,16 +977,19 @@ void SwDrawView::DeleteMarked() { SdrObject *pObject = rMarkList.GetMark(i)->GetMarkedSdrObj(); SwContact* pContact = GetUserCall(pObject); - SwFrameFormat* pFormat = pContact->GetFormat(); - if (pObject->getChildrenOfSdrObject()) + if (pContact) { - auto pChildTextBoxes = SwTextBoxHelper::CollectTextBoxes(pObject, pFormat); - for (auto& rChildTextBox : pChildTextBoxes) - aTextBoxesToDelete.push_back(rChildTextBox); - } - else - if (SwFrameFormat* pTextBox = SwTextBoxHelper::getOtherTextBoxFormat(pFormat, RES_DRAWFRMFMT)) + SwFrameFormat* pFormat = pContact->GetFormat(); + if (pObject->getChildrenOfSdrObject()) + { + auto pChildTextBoxes = SwTextBoxHelper::CollectTextBoxes(pObject, pFormat); + for (auto& rChildTextBox : pChildTextBoxes) + aTextBoxesToDelete.push_back(rChildTextBox); + } + else if (SwFrameFormat* pTextBox + = SwTextBoxHelper::getOtherTextBoxFormat(pFormat, RES_DRAWFRMFMT)) aTextBoxesToDelete.push_back(pTextBox); + } } if ( pDoc->DeleteSelection( *this ) ) diff --git a/sw/source/core/fields/expfld.cxx b/sw/source/core/fields/expfld.cxx index 434f676729..6ed4cdb7c1 100644 --- a/sw/source/core/fields/expfld.cxx +++ b/sw/source/core/fields/expfld.cxx @@ -881,10 +881,9 @@ std::unique_ptr SwSetExpField::Copy() const void SwSetExpField::SetSubType(sal_uInt16 nSub) { + assert((nSub & 0xff) != (nsSwGetSetExpType::GSE_STRING|nsSwGetSetExpType::GSE_EXPR) && "SubType is illegal!"); static_cast(GetTyp())->SetType(nSub & 0xff); mnSubType = nSub & 0xff00; - - OSL_ENSURE( (nSub & 0xff) != 3, "SubType is illegal!" ); } sal_uInt16 SwSetExpField::GetSubType() const @@ -1100,8 +1099,19 @@ bool SwSetExpField::PutValue( const uno::Any& rAny, sal_uInt16 nWhichId ) break; case FIELD_PROP_SUBTYPE: nTmp32 = lcl_APIToSubType(rAny); - if(nTmp32 >= 0) - SetSubType(o3tl::narrowing((GetSubType() & 0xff00) | nTmp32)); + if (0 <= nTmp32 && nTmp32 != (GetSubType() & 0xff)) + { + auto const subType(o3tl::narrowing((GetSubType() & 0xff00) | nTmp32)); + if (((nTmp32 & nsSwGetSetExpType::GSE_STRING) != (GetSubType() & nsSwGetSetExpType::GSE_STRING)) + && GetInputFlag()) + { + SwXTextField::TransmuteLeadToInputField(*this, &subType); + } + else + { + SetSubType(subType); + } + } break; case FIELD_PROP_PAR3: rAny >>= maPText; @@ -1120,7 +1130,7 @@ bool SwSetExpField::PutValue( const uno::Any& rAny, sal_uInt16 nWhichId ) if (static_cast(GetTyp())->GetType() & nsSwGetSetExpType::GSE_STRING) { - SwXTextField::TransmuteLeadToInputField(*this); + SwXTextField::TransmuteLeadToInputField(*this, nullptr); } else { diff --git a/sw/source/core/fields/postithelper.cxx b/sw/source/core/fields/postithelper.cxx index a3f27be6f5..06fb3db7ef 100644 --- a/sw/source/core/fields/postithelper.cxx +++ b/sw/source/core/fields/postithelper.cxx @@ -97,8 +97,8 @@ SwAnchoredObject* GetAnchoredObjectOfAnnotationMark(const sw::mark::IMark& rAnno for (SwAnchoredObject* pObject : *pAnchored) { - SwFrameFormat& rFrameFormat = pObject->GetFrameFormat(); - const SwPosition* pFrameAnchor = rFrameFormat.GetAnchor().GetContentAnchor(); + SwFrameFormat* pFrameFormat = pObject->GetFrameFormat(); + const SwPosition* pFrameAnchor = pFrameFormat->GetAnchor().GetContentAnchor(); if (!pFrameAnchor) { continue; diff --git a/sw/source/core/frmedt/fefly1.cxx b/sw/source/core/frmedt/fefly1.cxx index 9e2fedcc38..93ad4212cf 100644 --- a/sw/source/core/frmedt/fefly1.cxx +++ b/sw/source/core/frmedt/fefly1.cxx @@ -286,8 +286,8 @@ void SwFEShell::UnfloatFlyFrame() return; } - SwFrameFormat& rFlyFormat = pFly->GetFrameFormat(); - const SwFormatContent& rContent = rFlyFormat.GetContent(); + SwFrameFormat* pFlyFormat = pFly->GetFrameFormat(); + const SwFormatContent& rContent = pFlyFormat->GetContent(); const SwNodeIndex* pFlyStart = rContent.GetContentIdx(); if (!pFlyStart) { @@ -315,7 +315,7 @@ void SwFEShell::UnfloatFlyFrame() } SwNodeRange aRange(pFlyStart->GetNode(), SwNodeOffset(1), *pFlyEnd, SwNodeOffset(-1)); - const SwFormatAnchor& rAnchor = rFlyFormat.GetAnchor(); + const SwFormatAnchor& rAnchor = pFlyFormat->GetAnchor(); SwNode* pAnchor = rAnchor.GetAnchorNode(); if (!pAnchor) { @@ -327,8 +327,8 @@ void SwFEShell::UnfloatFlyFrame() rIDCO.MoveNodeRange(aRange, aInsertPos.GetNode(), SwMoveFlags::CREATEUNDOOBJ); // Remove the fly frame frame. - IDocumentLayoutAccess& rIDLA = rFlyFormat.getIDocumentLayoutAccess(); - rIDLA.DelLayoutFormat(&rFlyFormat); + IDocumentLayoutAccess& rIDLA = pFlyFormat->getIDocumentLayoutAccess(); + rIDLA.DelLayoutFormat(pFlyFormat); } // Get selected fly @@ -496,8 +496,8 @@ Point SwFEShell::FindAnchorPos( const Point& rAbsPos, bool bMoveIt ) // #i28701# SwAnchoredObject* pAnchoredObj = ::GetUserCall( pObj )->GetAnchoredObj( pObj ); - SwFrameFormat& rFormat = pAnchoredObj->GetFrameFormat(); - const RndStdIds nAnchorId = rFormat.GetAnchor().GetAnchorId(); + SwFrameFormat* pFormat = pAnchoredObj->GetFrameFormat(); + const RndStdIds nAnchorId = pFormat->GetAnchor().GetAnchorId(); if ( RndStdIds::FLY_AS_CHAR == nAnchorId ) return aRet; @@ -505,9 +505,9 @@ Point SwFEShell::FindAnchorPos( const Point& rAbsPos, bool bMoveIt ) bool bFlyFrame = dynamic_cast(pObj) != nullptr; bool bTextBox = false; - if (rFormat.Which() == RES_DRAWFRMFMT) + if (pFormat->Which() == RES_DRAWFRMFMT) { - bTextBox = SwTextBoxHelper::isTextBox(&rFormat, RES_DRAWFRMFMT, pObj); + bTextBox = SwTextBoxHelper::isTextBox(pFormat, RES_DRAWFRMFMT, pObj); } SwFlyFrame* pFly = nullptr; @@ -534,7 +534,7 @@ Point SwFEShell::FindAnchorPos( const Point& rAbsPos, bool bMoveIt ) { auto pFlyFormat = dynamic_cast(SwTextBoxHelper::getOtherTextBoxFormat( - &rFormat, RES_DRAWFRMFMT, pObj)); + pFormat, RES_DRAWFRMFMT, pObj)); if (pFlyFormat) { pFly = pFlyFormat->GetFrame(); @@ -608,7 +608,7 @@ Point SwFEShell::FindAnchorPos( const Point& rAbsPos, bool bMoveIt ) if ( bMoveIt || (nAnchorId == RndStdIds::FLY_AT_CHAR) ) { - SwFormatAnchor aAnch( rFormat.GetAnchor() ); + SwFormatAnchor aAnch( pFormat->GetAnchor() ); switch ( nAnchorId ) { case RndStdIds::FLY_AT_PARA: @@ -665,24 +665,24 @@ Point SwFEShell::FindAnchorPos( const Point& rAbsPos, bool bMoveIt ) // anchor attribute is change and re-create them afterwards. { std::unique_ptr pHandleAnchorNodeChg; - SwFlyFrameFormat* pFlyFrameFormat( dynamic_cast(&rFormat) ); + SwFlyFrameFormat* pFlyFrameFormat( dynamic_cast(pFormat) ); if ( pFlyFrameFormat ) { pHandleAnchorNodeChg.reset( new SwHandleAnchorNodeChg( *pFlyFrameFormat, aAnch )); } - rFormat.GetDoc()->SetAttr( aAnch, rFormat ); - if (SwTextBoxHelper::getOtherTextBoxFormat(&rFormat, RES_DRAWFRMFMT, + pFormat->GetDoc()->SetAttr( aAnch, *pFormat ); + if (SwTextBoxHelper::getOtherTextBoxFormat(pFormat, RES_DRAWFRMFMT, pObj)) { if (SdrObjList* pObjList = pObj->getChildrenOfSdrObject()) { for (const rtl::Reference& pChild : *pObjList) - SwTextBoxHelper::changeAnchor(&rFormat, pChild.get()); + SwTextBoxHelper::changeAnchor(pFormat, pChild.get()); } else SwTextBoxHelper::syncFlyFrameAttr( - rFormat, rFormat.GetAttrSet(), pObj); + *pFormat, pFormat->GetAttrSet(), pObj); } } // #i28701# - no call of method diff --git a/sw/source/core/frmedt/feshview.cxx b/sw/source/core/frmedt/feshview.cxx index 9a18e7934c..9154758364 100644 --- a/sw/source/core/frmedt/feshview.cxx +++ b/sw/source/core/frmedt/feshview.cxx @@ -392,8 +392,8 @@ bool SwFEShell::MoveAnchor( SwMove nDir ) SwFrame* pNew = pOld; // #i28701# SwAnchoredObject* pAnchoredObj = ::GetUserCall( pObj )->GetAnchoredObj( pObj ); - SwFrameFormat& rFormat = pAnchoredObj->GetFrameFormat(); - SwFormatAnchor aAnch( rFormat.GetAnchor() ); + SwFrameFormat* pFormat = pAnchoredObj->GetFrameFormat(); + SwFormatAnchor aAnch( pFormat->GetAnchor() ); RndStdIds nAnchorId = aAnch.GetAnchorId(); if ( RndStdIds::FLY_AS_CHAR == nAnchorId ) return false; @@ -582,13 +582,13 @@ bool SwFEShell::MoveAnchor( SwMove nDir ) // anchor attribute is change and re-create them afterwards. { std::unique_ptr pHandleAnchorNodeChg; - SwFlyFrameFormat* pFlyFrameFormat( dynamic_cast(&rFormat) ); + SwFlyFrameFormat* pFlyFrameFormat( dynamic_cast(pFormat) ); if ( pFlyFrameFormat ) { pHandleAnchorNodeChg.reset( new SwHandleAnchorNodeChg( *pFlyFrameFormat, aAnch )); } - rFormat.GetDoc()->SetAttr( aAnch, rFormat ); + pFormat->GetDoc()->SetAttr( aAnch, *pFormat ); } // #i28701# - no call of method // for to-character anchored @@ -1317,8 +1317,8 @@ bool SwFEShell::ShouldObjectBeSelected(const Point& rPt) if ( pObj->GetLayer() == rIDDMA.GetHellId() ) { const SwAnchoredObject* pAnchoredObj = ::GetUserCall( pObj )->GetAnchoredObj( pObj ); - const SwFrameFormat& rFormat = pAnchoredObj->GetFrameFormat(); - const SwFormatSurround& rSurround = rFormat.GetSurround(); + const SwFrameFormat* pFormat = pAnchoredObj->GetFrameFormat(); + const SwFormatSurround& rSurround = pFormat->GetSurround(); if ( rSurround.GetSurround() == css::text::WrapTextMode_THROUGH ) { bObjInBackground = true; @@ -2221,14 +2221,16 @@ RndStdIds SwFEShell::GetAnchorId() const nRet = RndStdIds::UNKNOWN; break; } - SwDrawContact *pContact = static_cast(GetUserCall(pObj)); - RndStdIds nId = pContact->GetFormat()->GetAnchor().GetAnchorId(); - if ( nRet == RndStdIds(SHRT_MAX) ) - nRet = nId; - else if ( nRet != nId ) + if (SwDrawContact* pContact = static_cast(GetUserCall(pObj))) { - nRet = RndStdIds::UNKNOWN; - break; + RndStdIds nId = pContact->GetFormat()->GetAnchor().GetAnchorId(); + if (nRet == RndStdIds(SHRT_MAX)) + nRet = nId; + else if (nRet != nId) + { + nRet = RndStdIds::UNKNOWN; + break; + } } } } @@ -3152,17 +3154,19 @@ Color SwFEShell::GetShapeBackground() const OSL_ENSURE( dynamic_cast( pSdrObj) == nullptr, "wrong usage of SwFEShell::GetShapeBackground - selected object is not a drawing object!"); if ( dynamic_cast( pSdrObj) == nullptr ) { - // determine page frame of the frame the shape is anchored. - const SwFrame* pAnchorFrame = - static_cast(GetUserCall(pSdrObj))->GetAnchorFrame( pSdrObj ); - OSL_ENSURE( pAnchorFrame, "inconsistent model - no anchor at shape!"); - if ( pAnchorFrame ) + if (SwDrawContact* pDrawContact = static_cast(GetUserCall(pSdrObj))) { - const SwPageFrame* pPageFrame = pAnchorFrame->FindPageFrame(); - OSL_ENSURE( pPageFrame, "inconsistent model - no page!"); - if ( pPageFrame ) + // determine page frame of the frame the shape is anchored. + const SwFrame * pAnchorFrame = pDrawContact->GetAnchorFrame(pSdrObj); + OSL_ENSURE(pAnchorFrame, "inconsistent model - no anchor at shape!"); + if (pAnchorFrame) { - aRetColor = pPageFrame->GetDrawBackgroundColor(); + const SwPageFrame* pPageFrame = pAnchorFrame->FindPageFrame(); + OSL_ENSURE(pPageFrame, "inconsistent model - no page!"); + if (pPageFrame) + { + aRetColor = pPageFrame->GetDrawBackgroundColor(); + } } } } diff --git a/sw/source/core/frmedt/fetab.cxx b/sw/source/core/frmedt/fetab.cxx index 79f5eb6b5e..33b9c9327b 100644 --- a/sw/source/core/frmedt/fetab.cxx +++ b/sw/source/core/frmedt/fetab.cxx @@ -2116,8 +2116,8 @@ SwTab SwFEShell::WhichMouseTabCol( const Point &rPt ) const { while( pFrame && pFrame->Lower() && pFrame->Lower()->IsRowFrame() ) pFrame = static_cast(static_cast(pFrame->Lower())->Lower()); - if( pFrame && pFrame->GetTabBox()->GetSttNd() && - pFrame->GetTabBox()->GetSttNd()->IsInProtectSect() ) + if( pFrame && ((pFrame->GetTabBox()->GetSttNd() && + pFrame->GetTabBox()->GetSttNd()->IsInProtectSect()) || (pFrame->GetTabBox()->getRowSpan() < 0))) pFrame = nullptr; } diff --git a/sw/source/core/frmedt/fews.cxx b/sw/source/core/frmedt/fews.cxx index bce8e2bb97..539f485313 100644 --- a/sw/source/core/frmedt/fews.cxx +++ b/sw/source/core/frmedt/fews.cxx @@ -464,12 +464,12 @@ void SwFEShell::InsertLabel( const SwLabelType eType, const OUString &rText, con // This table is in a split fly, but we will insert a label, which means this is not // a floating table anymore, disable the "can split" bit, it'll be hidden on the UI // anyway. - SwFrameFormat& rFlyFormat = pFly->GetFrameFormat(); + SwFrameFormat* pFormat = pFly->GetFrameFormat(); SfxItemSetFixed aSet(GetDoc()->GetAttrPool()); SwFormatFlySplit aSplit(false); aSet.Put(aSplit); // SwUndoFormatAttr is created for us. - GetDoc()->SetFlyFrameAttr(rFlyFormat, aSet); + GetDoc()->SetFlyFrameAttr(*pFormat, aSet); } } break; diff --git a/sw/source/core/inc/DocumentSettingManager.hxx b/sw/source/core/inc/DocumentSettingManager.hxx index 284dccf9cf..3e5be92c64 100644 --- a/sw/source/core/inc/DocumentSettingManager.hxx +++ b/sw/source/core/inc/DocumentSettingManager.hxx @@ -132,6 +132,7 @@ class DocumentSettingManager final : // non-ui-compatibility flags: bool mbOldNumbering : 1; bool mbIgnoreFirstLineIndentInNumbering : 1; // #i47448# + bool mbNoGapAfterNoteNumber : 1 = false; // tdf#159382 bool mbDoNotJustifyLinesWithManualBreak : 1; // #i49277# bool mbDoNotResetParaAttrsForNumFont : 1; // #i53199# bool mbTableRowKeep : 1; diff --git a/sw/source/core/inc/MarkManager.hxx b/sw/source/core/inc/MarkManager.hxx index ef0e79d74c..dd7eb9f6f1 100644 --- a/sw/source/core/inc/MarkManager.hxx +++ b/sw/source/core/inc/MarkManager.hxx @@ -81,6 +81,7 @@ namespace sw::mark { virtual const_iterator_t getAllMarksEnd() const override; virtual sal_Int32 getAllMarksCount() const override; virtual const_iterator_t findMark(const OUString& rName) const override; + virtual const_iterator_t findFirstMarkNotStartsBefore(const SwPosition& rPos) const override; // bookmarks virtual bool isBookmarkDeleted(SwPaM const& rPaM, bool isReplace) const override; diff --git a/sw/source/core/inc/flyfrm.hxx b/sw/source/core/inc/flyfrm.hxx index d1f14591bc..dfbd7e8daf 100644 --- a/sw/source/core/inc/flyfrm.hxx +++ b/sw/source/core/inc/flyfrm.hxx @@ -266,8 +266,8 @@ public: virtual void InvalidateObjPos() override; virtual void RegisterAtPage(SwPageFrame&) override; - virtual SwFrameFormat& GetFrameFormat() override; - virtual const SwFrameFormat& GetFrameFormat() const override; + virtual SwFrameFormat* GetFrameFormat() override; + virtual const SwFrameFormat* GetFrameFormat() const override; virtual SwRect GetObjRect() const override; diff --git a/sw/source/core/inc/txtfrm.hxx b/sw/source/core/inc/txtfrm.hxx index aa2246727f..e60dbd20fb 100644 --- a/sw/source/core/inc/txtfrm.hxx +++ b/sw/source/core/inc/txtfrm.hxx @@ -588,7 +588,7 @@ public: TextFrameIndex GetDropLen(TextFrameIndex nWishLen) const; LanguageType GetLangOfChar(TextFrameIndex nIndex, sal_uInt16 nScript, - bool bNoChar = false) const; + bool bNoChar = false, bool bNoneIfNoHyphenation = false ) const; virtual void Format( vcl::RenderContext* pRenderContext, const SwBorderAttrs *pAttrs = nullptr ) override; virtual void CheckDirection( bool bVert ) override; diff --git a/sw/source/core/inc/unofield.hxx b/sw/source/core/inc/unofield.hxx index 55214020c0..313185a000 100644 --- a/sw/source/core/inc/unofield.hxx +++ b/sw/source/core/inc/unofield.hxx @@ -133,7 +133,7 @@ private: public: SwServiceType GetServiceId() const; - static void TransmuteLeadToInputField(SwSetExpField & rField); + static void TransmuteLeadToInputField(SwSetExpField & rField, sal_uInt16 const*const pSubType); /// @return an SwXTextField, either an already existing one or a new one static rtl::Reference diff --git a/sw/source/core/layout/anchoreddrawobject.cxx b/sw/source/core/layout/anchoreddrawobject.cxx index 6dc6cac5d1..5a9e1245af 100644 --- a/sw/source/core/layout/anchoreddrawobject.cxx +++ b/sw/source/core/layout/anchoreddrawobject.cxx @@ -214,13 +214,13 @@ SwAnchoredDrawObject::~SwAnchoredDrawObject() // --> #i62875# void SwAnchoredDrawObject::UpdateLayoutDir() { - SwFrameFormat::tLayoutDir nOldLayoutDir( GetFrameFormat().GetLayoutDir() ); + SwFrameFormat::tLayoutDir nOldLayoutDir( GetFrameFormat()->GetLayoutDir() ); SwAnchoredObject::UpdateLayoutDir(); if ( !NotYetPositioned() && - GetFrameFormat().GetLayoutDir() != nOldLayoutDir && - GetFrameFormat().GetDoc()->GetDocumentSettingManager().get(DocumentSettingId::DO_NOT_CAPTURE_DRAW_OBJS_ON_PAGE) && + GetFrameFormat()->GetLayoutDir() != nOldLayoutDir && + GetFrameFormat()->GetDoc()->GetDocumentSettingManager().get(DocumentSettingId::DO_NOT_CAPTURE_DRAW_OBJS_ON_PAGE) && !IsOutsidePage() ) { mbCaptureAfterLayoutDirChange = true; @@ -284,7 +284,7 @@ void SwAnchoredDrawObject::MakeObjPos() // #i44334#, #i44681# - check, if positioning // attributes already have been set. if ( dynamic_cast< const SwDrawVirtObj* >(GetDrawObj()) == nullptr && - !static_cast(GetFrameFormat()).IsPosAttrSet() ) + !static_cast(GetFrameFormat())->IsPosAttrSet() ) { SetPositioningAttr(); } @@ -395,7 +395,7 @@ void SwAnchoredDrawObject::MakeObjPosAnchoredAtPara() // Format of anchor is needed for (vertical) fly offsets, otherwise the // lack of fly portions will result in an incorrect 0 offset. - bool bAddVerticalFlyOffsets = GetFrameFormat().getIDocumentSettingAccess().get( + bool bAddVerticalFlyOffsets = GetFrameFormat()->getIDocumentSettingAccess().get( DocumentSettingId::ADD_VERTICAL_FLY_OFFSETS); bool bFormatAnchorOnce = !bJoinLocked && bAddVerticalFlyOffsets; @@ -518,11 +518,12 @@ void SwAnchoredDrawObject::SetDrawObjAnchor() // correct object position, caused by setting new anchor position DrawObj()->Move( aMove ); // Sync textbox if it wasn't done at move - if ( SwTextBoxHelper::isTextBox(&GetFrameFormat(), RES_DRAWFRMFMT) && GetFrameFormat().GetDoc() && - GetFrameFormat().GetDoc()->getIDocumentLayoutAccess().GetCurrentViewShell() && - GetFrameFormat().GetDoc()->getIDocumentLayoutAccess().GetCurrentViewShell()->IsInConstructor()) + SwFrameFormat* pObjFormat = GetFrameFormat(); + if ( SwTextBoxHelper::isTextBox(pObjFormat, RES_DRAWFRMFMT) && pObjFormat->GetDoc() && + pObjFormat->GetDoc()->getIDocumentLayoutAccess().GetCurrentViewShell() && + pObjFormat->GetDoc()->getIDocumentLayoutAccess().GetCurrentViewShell()->IsInConstructor()) { - SwTextBoxHelper::changeAnchor(&GetFrameFormat(), GetFrameFormat().FindRealSdrObject()); + SwTextBoxHelper::changeAnchor(pObjFormat, pObjFormat->FindRealSdrObject()); } // --> #i70122# - missing invalidation InvalidateObjRectWithSpaces(); @@ -543,7 +544,7 @@ void SwAnchoredDrawObject::InvalidatePage_( SwPageFrame* _pPageFrame ) // --> #i35007# - correct invalidation for as-character // anchored objects. - if ( GetFrameFormat().GetAnchor().GetAnchorId() == RndStdIds::FLY_AS_CHAR ) + if ( GetFrameFormat()->GetAnchor().GetAnchorId() == RndStdIds::FLY_AS_CHAR ) { _pPageFrame->InvalidateFlyInCnt(); } @@ -582,13 +583,14 @@ void SwAnchoredDrawObject::InvalidateObjPos() // anchored object, because its positioned by the format of its anchor frame. // --> #i44559# - assure, that text hint is already // existing in the text frame + const SwFrameFormat* pObjFormat = GetFrameFormat(); if ( GetAnchorFrame()->DynCastTextFrame() != nullptr && - (GetFrameFormat().GetAnchor().GetAnchorId() == RndStdIds::FLY_AS_CHAR) ) + (pObjFormat->GetAnchor().GetAnchorId() == RndStdIds::FLY_AS_CHAR) ) { SwTextFrame* pAnchorTextFrame( static_cast(AnchorFrame()) ); - if (pAnchorTextFrame->CalcFlyPos(&GetFrameFormat()) != TextFrameIndex(COMPLETE_STRING)) + if (pAnchorTextFrame->CalcFlyPos(pObjFormat) != TextFrameIndex(COMPLETE_STRING)) { - AnchorFrame()->Prepare( PrepareHint::FlyFrameAttributesChanged, &GetFrameFormat() ); + AnchorFrame()->Prepare(PrepareHint::FlyFrameAttributesChanged, pObjFormat); } } @@ -615,15 +617,17 @@ void SwAnchoredDrawObject::InvalidateObjPos() } } -SwFrameFormat& SwAnchoredDrawObject::GetFrameFormat() +SwFrameFormat* SwAnchoredDrawObject::GetFrameFormat() { - assert(static_cast(GetUserCall(GetDrawObj()))->GetFormat()); - return *(static_cast(GetUserCall(GetDrawObj()))->GetFormat()); + if (SwDrawContact* pDC = static_cast(GetUserCall(GetDrawObj()))) + return pDC->GetFormat(); + return nullptr; } -const SwFrameFormat& SwAnchoredDrawObject::GetFrameFormat() const +const SwFrameFormat* SwAnchoredDrawObject::GetFrameFormat() const { - assert(static_cast(GetUserCall(GetDrawObj()))->GetFormat()); - return *(static_cast(GetUserCall(GetDrawObj()))->GetFormat()); + if (SwDrawContact* pDC = static_cast(GetUserCall(GetDrawObj()))) + return pDC->GetFormat(); + return nullptr; } SwRect SwAnchoredDrawObject::GetObjRect() const @@ -807,10 +811,11 @@ void SwAnchoredDrawObject::AdjustPositioningAttr( const SwFrame* _pNewAnchorFram SwFormatHoriOrient hori(nHoriRelPos, text::HoriOrientation::NONE, text::RelOrientation::FRAME); SwFormatVertOrient vert(nVertRelPos, text::VertOrientation::NONE, text::RelOrientation::FRAME); - SfxItemSetFixed items(GetFrameFormat().GetDoc()->GetAttrPool()); + SwFrameFormat* pObjFormat = GetFrameFormat(); + SfxItemSetFixed items(pObjFormat->GetDoc()->GetAttrPool()); items.Put(hori); items.Put(vert); - GetFrameFormat().GetDoc()->SetAttr(items, GetFrameFormat()); + pObjFormat->GetDoc()->SetAttr(items, *pObjFormat); } // --> #i34748# - change return type. @@ -845,6 +850,7 @@ void SwAnchoredDrawObject::SetPositioningAttr() SwDrawContact* pDrawContact = static_cast(GetUserCall( GetDrawObj() )); + SwFrameFormat* pObjFormat = GetFrameFormat(); if ( !pDrawContact->ObjAnchoredAsChar() ) { SwRect aObjRect( GetObjRect() ); @@ -853,10 +859,10 @@ void SwAnchoredDrawObject::SetPositioningAttr() SwTwips nVertPos = aObjRect.Top(); // #i44334#, #i44681# // perform conversion only if position is in horizontal-left-to-right-layout. - if ( GetFrameFormat().GetPositionLayoutDir() == + if (pObjFormat->GetPositionLayoutDir() == text::PositionLayoutDir::PositionInHoriL2R ) { - SwFrameFormat::tLayoutDir eLayoutDir = GetFrameFormat().GetLayoutDir(); + SwFrameFormat::tLayoutDir eLayoutDir = pObjFormat->GetLayoutDir(); switch ( eLayoutDir ) { case SwFrameFormat::HORI_L2R: @@ -885,28 +891,28 @@ void SwAnchoredDrawObject::SetPositioningAttr() // --> #i71182# // only change position - do not lose other attributes - SwFormatHoriOrient aHori( GetFrameFormat().GetHoriOrient() ); + SwFormatHoriOrient aHori(pObjFormat->GetHoriOrient()); if (nHoriPos != aHori.GetPos()) { aHori.SetPos( nHoriPos ); InvalidateObjRectWithSpaces(); - GetFrameFormat().SetFormatAttr( aHori ); + pObjFormat->SetFormatAttr(aHori); } - SwFormatVertOrient aVert( GetFrameFormat().GetVertOrient() ); + SwFormatVertOrient aVert(pObjFormat->GetVertOrient()); if (nVertPos != aVert.GetPos()) { aVert.SetPos( nVertPos ); InvalidateObjRectWithSpaces(); - GetFrameFormat().SetFormatAttr( aVert ); + pObjFormat->SetFormatAttr(aVert); } // --> #i36010# - set layout direction of the position - GetFrameFormat().SetPositionLayoutDir( + pObjFormat->SetPositionLayoutDir( text::PositionLayoutDir::PositionInLayoutDirOfAnchor ); } // --> #i65798# - also for as-character anchored objects // --> #i45952# - indicate that position // attributes are set now. - static_cast(GetFrameFormat()).PosAttrSet(); + static_cast(pObjFormat)->PosAttrSet(); } void SwAnchoredDrawObject::NotifyBackground( SwPageFrame* _pPageFrame, diff --git a/sw/source/core/layout/anchoredobject.cxx b/sw/source/core/layout/anchoredobject.cxx index 42e7dd39fc..a74438afb3 100644 --- a/sw/source/core/layout/anchoredobject.cxx +++ b/sw/source/core/layout/anchoredobject.cxx @@ -32,6 +32,7 @@ #include #include #include +#include using namespace ::com::sun::star; @@ -215,7 +216,7 @@ void SwAnchoredObject::CheckCharRectAndTopOfLine( GetAnchorFrame()->IsTextFrame()) ) return; - const SwFormatAnchor& rAnch = GetFrameFormat().GetAnchor(); + const SwFormatAnchor& rAnch = GetFrameFormat()->GetAnchor(); if ( !((rAnch.GetAnchorId() == RndStdIds::FLY_AT_CHAR) && rAnch.GetAnchorNode()) ) return; @@ -262,8 +263,9 @@ void SwAnchoredObject::CheckCharRect( const SwFormatAnchor& _rAnch, { SwRectFnSet aRectFnSet(&_rAnchorCharFrame); // determine positioning and alignment - SwFormatVertOrient aVert( GetFrameFormat().GetVertOrient() ); - SwFormatHoriOrient aHori( GetFrameFormat().GetHoriOrient() ); + const SwFrameFormat* pObjFormat = GetFrameFormat(); + SwFormatVertOrient aVert( pObjFormat->GetVertOrient() ); + SwFormatHoriOrient aHori( pObjFormat->GetHoriOrient() ); // check for anchor character rectangle changes for certain // positionings and alignments // add condition to invalidate position, @@ -316,7 +318,7 @@ void SwAnchoredObject::CheckTopOfLine( const SwFormatAnchor& _rAnch, return; // check alignment for invalidation of position - if ( GetFrameFormat().GetVertOrient().GetRelationOrient() == text::RelOrientation::TEXT_LINE ) + if ( GetFrameFormat()->GetVertOrient().GetRelationOrient() == text::RelOrientation::TEXT_LINE ) { // #i26945#, #i35911# - unlock position of // anchored object, if it isn't registered at the page, @@ -373,7 +375,7 @@ void SwAnchoredObject::UpdateLayoutDir() nLayoutDir = SwFrameFormat::HORI_R2L; } } - GetFrameFormat().SetLayoutDir( nLayoutDir ); + GetFrameFormat()->SetLayoutDir( nLayoutDir ); } /** method to perform necessary invalidations for the positioning of @@ -408,29 +410,31 @@ bool SwAnchoredObject::ConsiderObjWrapInfluenceOnObjPos() const { bool bRet( false ); - const SwFrameFormat& rObjFormat = GetFrameFormat(); - - // --> #i3317# - add condition - // --> #i55204# - // - correction: wrapping style influence has been considered, if condition - // is hold, regardless of its anchor type - // or its wrapping style. - if ( IsTmpConsiderWrapInfluence() ) - { - bRet = true; - } - else if ( rObjFormat.getIDocumentSettingAccess().get(DocumentSettingId::CONSIDER_WRAP_ON_OBJECT_POSITION) ) + if (const SwFrameFormat* pObjFormat = GetFrameFormat()) { - const SwFormatAnchor& rAnchor = rObjFormat.GetAnchor(); - if ( ((rAnchor.GetAnchorId() == RndStdIds::FLY_AT_CHAR) || - (rAnchor.GetAnchorId() == RndStdIds::FLY_AT_PARA)) && - rObjFormat.GetSurround().GetSurround() != css::text::WrapTextMode_THROUGH ) + // --> #i3317# - add condition + // --> #i55204# + // - correction: wrapping style influence has been considered, if condition + // is hold, regardless of its anchor type + // or its wrapping style. + if (IsTmpConsiderWrapInfluence()) { - // --> #i34520# - text also wraps around anchored - // objects in the layer Hell - see the text formatting. - // Thus, it hasn't to be checked here. bRet = true; } + else if (pObjFormat->getIDocumentSettingAccess().get( + DocumentSettingId::CONSIDER_WRAP_ON_OBJECT_POSITION)) + { + const SwFormatAnchor& rAnchor = pObjFormat->GetAnchor(); + if (((rAnchor.GetAnchorId() == RndStdIds::FLY_AT_CHAR) + || (rAnchor.GetAnchorId() == RndStdIds::FLY_AT_PARA)) + && pObjFormat->GetSurround().GetSurround() != css::text::WrapTextMode_THROUGH) + { + // --> #i34520# - text also wraps around anchored + // objects in the layer Hell - see the text formatting. + // Thus, it hasn't to be checked here. + bRet = true; + } + } } return bRet; @@ -567,18 +571,22 @@ const SwRect& SwAnchoredObject::GetObjRectWithSpaces() const if ( !mbObjRectWithSpacesValid ) { maObjRectWithSpaces = GetObjBoundRect(); - const SwFrameFormat& rFormat = GetFrameFormat(); - const SvxULSpaceItem& rUL = rFormat.GetULSpace(); - const SvxLRSpaceItem& rLR = rFormat.GetLRSpace(); + if (const SwFrameFormat* pFormat = GetFrameFormat()) { - maObjRectWithSpaces.Top ( std::max( maObjRectWithSpaces.Top() - tools::Long(rUL.GetUpper()), tools::Long(0) )); - maObjRectWithSpaces.Left( std::max( maObjRectWithSpaces.Left()- rLR.GetLeft(), tools::Long(0) )); - maObjRectWithSpaces.AddHeight(rUL.GetLower() ); - maObjRectWithSpaces.AddWidth(rLR.GetRight() ); - } + const SvxULSpaceItem& rUL = pFormat->GetULSpace(); + const SvxLRSpaceItem& rLR = pFormat->GetLRSpace(); + { + maObjRectWithSpaces.Top(std::max( + maObjRectWithSpaces.Top() - tools::Long(rUL.GetUpper()), tools::Long(0))); + maObjRectWithSpaces.Left( + std::max(maObjRectWithSpaces.Left() - rLR.GetLeft(), tools::Long(0))); + maObjRectWithSpaces.AddHeight(rUL.GetLower()); + maObjRectWithSpaces.AddWidth(rLR.GetRight()); + } - mbObjRectWithSpacesValid = true; - maLastObjRect = GetObjRect(); + mbObjRectWithSpacesValid = true; + maLastObjRect = GetObjRect(); + } } return maObjRectWithSpaces; @@ -617,7 +625,7 @@ void SwAnchoredObject::UpdateObjInSortedList() if(!GetAnchorFrame()) return; - if ( GetFrameFormat().getIDocumentSettingAccess().get(DocumentSettingId::CONSIDER_WRAP_ON_OBJECT_POSITION) ) + if ( GetFrameFormat()->getIDocumentSettingAccess().get(DocumentSettingId::CONSIDER_WRAP_ON_OBJECT_POSITION) ) { // invalidate position of all anchored objects at anchor frame if ( GetAnchorFrame()->GetDrawObjs() ) @@ -652,7 +660,7 @@ void SwAnchoredObject::UpdateObjInSortedList() // update its position in the sorted object list of its page frame // note: as-character anchored object aren't registered at a page frame if ( GetPageFrame() && GetPageFrame()->GetSortedObjs() && - GetFrameFormat().GetAnchor().GetAnchorId() != RndStdIds::FLY_AS_CHAR ) + GetFrameFormat()->GetAnchor().GetAnchorId() != RndStdIds::FLY_AS_CHAR ) { GetPageFrame()->GetSortedObjs()->Update( *this ); } @@ -709,39 +717,43 @@ SwTextFrame* SwAnchoredObject::FindAnchorCharFrame() // --> #i44339# - check, if anchor frame exists. if ( mpAnchorFrame ) { - const SwFormatAnchor& rAnch = GetFrameFormat().GetAnchor(); - if ((rAnch.GetAnchorId() == RndStdIds::FLY_AT_CHAR) || - (rAnch.GetAnchorId() == RndStdIds::FLY_AS_CHAR)) + if (const SwFrameFormat* pFormat = GetFrameFormat()) { - SwTextFrame *const pFrame(static_cast(AnchorFrame())); - TextFrameIndex const nOffset(pFrame->MapModelToViewPos(*rAnch.GetContentAnchor())); - pAnchorCharFrame = &pFrame->GetFrameAtOfst(nOffset); - } - else if (SwFlyFrame* pFlyFrame = DynCastFlyFrame()) - { - // See if this fly is split. If so, then the anchor is also split. All anchors are - // empty, except the last follow. - if (pFlyFrame->IsFlySplitAllowed()) + const SwFormatAnchor& rAnch = pFormat->GetAnchor(); + if ((rAnch.GetAnchorId() == RndStdIds::FLY_AT_CHAR) + || (rAnch.GetAnchorId() == RndStdIds::FLY_AS_CHAR)) + { + SwTextFrame* const pFrame(static_cast(AnchorFrame())); + TextFrameIndex const nOffset(pFrame->MapModelToViewPos(*rAnch.GetContentAnchor())); + pAnchorCharFrame = &pFrame->GetFrameAtOfst(nOffset); + } + else if (SwFlyFrame* pFlyFrame = DynCastFlyFrame()) { - auto pFlyAtContentFrame = static_cast(pFlyFrame); - SwFlyAtContentFrame* pFly = pFlyAtContentFrame; - SwTextFrame* pAnchor = static_cast(AnchorFrame()); - // If we have to jump back N frames to find the master fly, then we have to step N - // frames from the master anchor to reach the correct follow anchor. - while (pFly->GetPrecede()) + // See if this fly is split. If so, then the anchor is also split. All anchors are + // empty, except the last follow. + if (pFlyFrame->IsFlySplitAllowed()) { - pFly = pFly->GetPrecede(); - if (!pAnchor) + auto pFlyAtContentFrame = static_cast(pFlyFrame); + SwFlyAtContentFrame* pFly = pFlyAtContentFrame; + SwTextFrame* pAnchor = static_cast(AnchorFrame()); + // If we have to jump back N frames to find the master fly, then we have to step N + // frames from the master anchor to reach the correct follow anchor. + while (pFly->GetPrecede()) { - SAL_WARN("sw.layout", "SwAnchoredObject::FindAnchorCharFrame: fly chain " - "length is longer then anchor chain length"); - break; + pFly = pFly->GetPrecede(); + if (!pAnchor) + { + SAL_WARN("sw.layout", + "SwAnchoredObject::FindAnchorCharFrame: fly chain " + "length is longer then anchor chain length"); + break; + } + pAnchor = pAnchor->GetFollow(); + } + if (pAnchor) + { + pAnchorCharFrame = pAnchor; } - pAnchor = pAnchor->GetFollow(); - } - if (pAnchor) - { - pAnchorCharFrame = pAnchor; } } } @@ -758,7 +770,9 @@ SwTextFrame* SwAnchoredObject::FindAnchorCharFrame() */ bool SwAnchoredObject::IsFormatPossible() const { - return GetFrameFormat().GetDoc()->getIDocumentDrawModelAccess().IsVisibleLayerId( GetDrawObj()->GetLayer() ); + if (const SwFrameFormat* pFormat = GetFrameFormat()) + return pFormat->GetDoc()->getIDocumentDrawModelAccess().IsVisibleLayerId( GetDrawObj()->GetLayer() ); + return false; } bool SwAnchoredObject::IsDraggingOffPageAllowed(const SwFrameFormat* pFrameFormat) @@ -777,7 +791,7 @@ void SwAnchoredObject::SetTmpConsiderWrapInfluence( const bool _bTmpConsiderWrap // --> #i35911# if ( mbTmpConsiderWrapInfluence ) { - SwLayouter::InsertObjForTmpConsiderWrapInfluence( *(GetFrameFormat().GetDoc()), + SwLayouter::InsertObjForTmpConsiderWrapInfluence( *(GetFrameFormat()->GetDoc()), *this ); } } @@ -787,7 +801,7 @@ void SwAnchoredObject::ClearTmpConsiderWrapInfluence() mbTmpConsiderWrapInfluence = false; mbClearedEnvironment = false; SetClearedEnvironment( false ); - SwLayouter::RemoveObjForTmpConsiderWrapInfluence( *(GetFrameFormat().GetDoc()), + SwLayouter::RemoveObjForTmpConsiderWrapInfluence( *(GetFrameFormat()->GetDoc()), *this ); } void SwAnchoredObject::SetTmpConsiderWrapInfluenceOfOtherObjs() diff --git a/sw/source/core/layout/atrfrm.cxx b/sw/source/core/layout/atrfrm.cxx index 2a1ab80763..5e95d1aaf7 100644 --- a/sw/source/core/layout/atrfrm.cxx +++ b/sw/source/core/layout/atrfrm.cxx @@ -3121,7 +3121,7 @@ void SwFlyFrameFormat::MakeFrames() // #i28701# - consider changed type of // entries. if( pObj->DynCastFlyFrame() != nullptr && - (&pObj->GetFrameFormat()) == this ) + (pObj->GetFrameFormat()) == this ) { bAdd = false; break; diff --git a/sw/source/core/layout/calcmove.cxx b/sw/source/core/layout/calcmove.cxx index 4d4b2de289..c2bbdd8904 100644 --- a/sw/source/core/layout/calcmove.cxx +++ b/sw/source/core/layout/calcmove.cxx @@ -1131,18 +1131,18 @@ void SwContentFrame::MakePrtArea( const SwBorderAttrs &rAttrs ) // #i28701# - consider changed type of // entries SwAnchoredObject* pObj = (*GetDrawObjs())[i]; - const SwFrameFormat& rFormat = pObj->GetFrameFormat(); + const SwFrameFormat* pFormat = pObj->GetFrameFormat(); const bool bFly = pObj->DynCastFlyFrame() != nullptr; if ((bFly && (FAR_AWAY == pObj->GetObjRect().Width())) - || rFormat.GetFrameSize().GetWidthPercent()) + || pFormat->GetFrameSize().GetWidthPercent()) { continue; } - if ( RndStdIds::FLY_AS_CHAR == rFormat.GetAnchor().GetAnchorId() ) + if ( RndStdIds::FLY_AS_CHAR == pFormat->GetAnchor().GetAnchorId() ) { nMinWidth = std::max( nMinWidth, - bFly ? rFormat.GetFrameSize().GetWidth() + bFly ? pFormat->GetFrameSize().GetWidth() : pObj->GetObjRect().Width() ); } } diff --git a/sw/source/core/layout/flowfrm.cxx b/sw/source/core/layout/flowfrm.cxx index 981736de70..da509e2a6b 100644 --- a/sw/source/core/layout/flowfrm.cxx +++ b/sw/source/core/layout/flowfrm.cxx @@ -217,7 +217,7 @@ bool IsNextContentFullPage(const SwFrame& rThis) continue; } - const SwFormatSurround& rSurround = pDrawObj->GetFrameFormat().GetSurround(); + const SwFormatSurround& rSurround = pDrawObj->GetFrameFormat()->GetSurround(); if (rSurround.GetSurround() != text::WrapTextMode_NONE) { continue; @@ -379,10 +379,10 @@ sal_uInt8 SwFlowFrame::BwdMoveNecessary( const SwPageFrame *pPage, const SwRect { SwAnchoredObject* pObj = rObjs[i]; - const SwFrameFormat& rFormat = pObj->GetFrameFormat(); + const SwFrameFormat* pFormat = pObj->GetFrameFormat(); const SwRect aRect( pObj->GetObjRect() ); if ( aRect.Overlaps( rRect ) && - rFormat.GetSurround().GetSurround() != css::text::WrapTextMode_THROUGH ) + pFormat->GetSurround().GetSurround() != css::text::WrapTextMode_THROUGH ) { if( m_rThis.IsLayoutFrame() && //Fly Lower of This? Is_Lower_Of( &m_rThis, pObj->GetDrawObj() ) ) @@ -404,10 +404,10 @@ sal_uInt8 SwFlowFrame::BwdMoveNecessary( const SwPageFrame *pPage, const SwRect // flow, because then I wouldn't evade it. if ( ::IsFrameInSameContext( pAnchor, &m_rThis ) ) { - if ( rFormat.GetAnchor().GetAnchorId() == RndStdIds::FLY_AT_PARA ) + if ( pFormat->GetAnchor().GetAnchorId() == RndStdIds::FLY_AT_PARA ) { // The index of the other one can be retrieved using the anchor attribute. - SwNodeOffset nTmpIndex = rFormat.GetAnchor().GetAnchorNode()->GetIndex(); + SwNodeOffset nTmpIndex = pFormat->GetAnchor().GetAnchorNode()->GetIndex(); // Now we're going to check whether the current paragraph before // the anchor of the displacing object sits in the text. If this // is the case, we don't try to evade it. @@ -1224,13 +1224,13 @@ bool SwFlowFrame::IsPrevObjMove() const // text flow to the next layout frame for (SwAnchoredObject* pObj : *pPre->GetDrawObjs()) { - + const SwFrameFormat* pObjFormat = pObj->GetFrameFormat(); // Do not consider hidden objects // i#26945 - do not consider object, which // doesn't follow the text flow. - if ( pObj->GetFrameFormat().GetDoc()->getIDocumentDrawModelAccess().IsVisibleLayerId( + if ( pObjFormat->GetDoc()->getIDocumentDrawModelAccess().IsVisibleLayerId( pObj->GetDrawObj()->GetLayer() ) && - pObj->GetFrameFormat().GetFollowTextFlow().GetValue() ) + pObjFormat->GetFollowTextFlow().GetValue() ) { const SwLayoutFrame* pVertPosOrientFrame = pObj->GetVertPosOrientFrame(); if ( pVertPosOrientFrame && diff --git a/sw/source/core/layout/fly.cxx b/sw/source/core/layout/fly.cxx index d23c30a0aa..db50a42de0 100644 --- a/sw/source/core/layout/fly.cxx +++ b/sw/source/core/layout/fly.cxx @@ -43,6 +43,7 @@ #include #include #include +#include #include #include #include @@ -99,10 +100,10 @@ SwTwips GetFlyAnchorBottom(SwFlyFrame* pFly, const SwFrame& rAnchor) return 0; } - const auto& rFrameFormat = pFly->GetFrameFormat(); - const IDocumentSettingAccess& rIDSA = rFrameFormat.getIDocumentSettingAccess(); + const auto* pFrameFormat = pFly->GetFrameFormat(); + const IDocumentSettingAccess& rIDSA = pFrameFormat->getIDocumentSettingAccess(); // Allow overlap with bottom margin / footer only in case we're relative to the page frame. - bool bVertPageFrame = rFrameFormat.GetVertOrient().GetRelationOrient() == text::RelOrientation::PAGE_FRAME; + bool bVertPageFrame = pFrameFormat->GetVertOrient().GetRelationOrient() == text::RelOrientation::PAGE_FRAME; bool bInBody = rAnchor.IsInDocBody(); bool bLegacy = rIDSA.get(DocumentSettingId::TAB_OVER_MARGIN) && (bVertPageFrame || !bInBody); if (bLegacy) @@ -1271,7 +1272,7 @@ void SwFlyFrame::ChgRelPos( const Point &rNewPos ) const SwTextFrame *pAutoFrame = nullptr; // #i34948# - handle also at-page and at-fly anchored // Writer fly frames - const RndStdIds eAnchorType = GetFrameFormat().GetAnchor().GetAnchorId(); + const RndStdIds eAnchorType = GetFrameFormat()->GetAnchor().GetAnchorId(); if ( eAnchorType == RndStdIds::FLY_AT_PAGE ) { aVert.SetVertOrient( text::VertOrientation::NONE ); @@ -1741,6 +1742,10 @@ void CalcContent( SwLayoutFrame *pLay, bool bNoColl ) if (!SwObjectFormatter::FormatObj(*pAnchoredObj, pAnchorFrame, pAnchorPageFrame, rShell.Imp()->IsAction() ? &rShell.Imp()->GetLayAction() : nullptr)) { + if (rShell.Imp()->IsAction() && rShell.Imp()->GetLayAction().IsAgain()) + { // tdf#159015 will always fail, don't loop + return; + } bRestartLayoutProcess = true; break; } @@ -1759,13 +1764,13 @@ void CalcContent( SwLayoutFrame *pLay, bool bNoColl ) { OSL_FAIL( "::CalcContent(..) - loop detected, perform attribute changes to avoid the loop" ); // Prevent oscillation - SwFrameFormat& rFormat = pAnchoredObj->GetFrameFormat(); - SwFormatSurround aAttr( rFormat.GetSurround() ); + SwFrameFormat* pFormat = pAnchoredObj->GetFrameFormat(); + SwFormatSurround aAttr( pFormat->GetSurround() ); if( css::text::WrapTextMode_THROUGH != aAttr.GetSurround() ) { // When on auto position, we can only set it to // flow through - if ((rFormat.GetAnchor().GetAnchorId() == + if ((pFormat->GetAnchor().GetAnchorId() == RndStdIds::FLY_AT_CHAR) && (css::text::WrapTextMode_PARALLEL == aAttr.GetSurround())) @@ -1776,9 +1781,9 @@ void CalcContent( SwLayoutFrame *pLay, bool bNoColl ) { aAttr.SetSurround( css::text::WrapTextMode_PARALLEL ); } - rFormat.LockModify(); - rFormat.SetFormatAttr( aAttr ); - rFormat.UnlockModify(); + pFormat->LockModify(); + pFormat->SetFormatAttr( aAttr ); + pFormat->UnlockModify(); } } else @@ -2054,7 +2059,7 @@ bool SwFlyFrame::IsShowUnfloatButton(SwWrtShell* pWrtSh) const if (pWrtSh->GetViewOptions()->IsReadonly()) return false; - const SdrObject *pObj = GetFrameFormat().FindRealSdrObject(); + const SdrObject *pObj = GetFrameFormat()->FindRealSdrObject(); if (pObj == nullptr) return false; @@ -2594,12 +2599,15 @@ void SwFrame::RemoveDrawObj( SwAnchoredObject& _rToRemoveObj ) { // Notify accessible layout. #if !ENABLE_WASM_STRIP_ACCESSIBILITY - SwViewShell* pSh = getRootFrame()->GetCurrShell(); - if( pSh ) + if (!mbInDtor) { - SwRootFrame* pLayout = getRootFrame(); - if (pLayout && pLayout->IsAnyShellAccessible()) - pSh->Imp()->DisposeAccessibleObj(_rToRemoveObj.GetDrawObj(), false); + SwViewShell* pSh = getRootFrame()->GetCurrShell(); + if (pSh) + { + SwRootFrame* pLayout = getRootFrame(); + if (pLayout && pLayout->IsAnyShellAccessible()) + pSh->Imp()->DisposeAccessibleObj(_rToRemoveObj.GetDrawObj(), false); + } } #endif @@ -2631,7 +2639,7 @@ void SwFrame::InvalidateObjs( const bool _bNoInvaOfAsCharAnchoredObjs ) for (SwAnchoredObject* pAnchoredObj : *GetDrawObjs()) { if ( _bNoInvaOfAsCharAnchoredObjs && - (pAnchoredObj->GetFrameFormat().GetAnchor().GetAnchorId() + (pAnchoredObj->GetFrameFormat()->GetAnchor().GetAnchorId() == RndStdIds::FLY_AS_CHAR) ) { continue; @@ -2738,7 +2746,7 @@ void SwLayoutFrame::NotifyLowerObjs( const bool _bUnlockPosOfObjs ) bool isPositionedByHF(false); if (IsHeaderFrame() || IsFooterFrame()) { - auto const nO(pObj->GetFrameFormat().GetVertOrient().GetRelationOrient()); + auto const nO(pObj->GetFrameFormat()->GetVertOrient().GetRelationOrient()); if (nO == text::RelOrientation::PAGE_PRINT_AREA || nO == text::RelOrientation::PAGE_PRINT_AREA_BOTTOM || nO == text::RelOrientation::PAGE_PRINT_AREA_TOP) @@ -3093,17 +3101,17 @@ void SwFlyFrame::InvalidateObjPos() InvalidateObjRectWithSpaces(); } -SwFrameFormat& SwFlyFrame::GetFrameFormat() +SwFrameFormat* SwFlyFrame::GetFrameFormat() { OSL_ENSURE( GetFormat(), " - missing frame format -> crash." ); - return *GetFormat(); + return GetFormat(); } -const SwFrameFormat& SwFlyFrame::GetFrameFormat() const +const SwFrameFormat* SwFlyFrame::GetFrameFormat() const { OSL_ENSURE( GetFormat(), " - missing frame format -> crash." ); - return *GetFormat(); + return GetFormat(); } SwRect SwFlyFrame::GetObjRect() const diff --git a/sw/source/core/layout/flycnt.cxx b/sw/source/core/layout/flycnt.cxx index a53b8841f8..2ed6fbf089 100644 --- a/sw/source/core/layout/flycnt.cxx +++ b/sw/source/core/layout/flycnt.cxx @@ -162,13 +162,13 @@ void SwFlyAtContentFrame::SwClientNotify(const SwModify& rMod, const SfxHint& rH // of the given fly frame format is registered. if(bFound && pContent && pContent->GetDrawObjs()) { - SwFrameFormat* pMyFlyFrameFormat(&GetFrameFormat()); + SwFrameFormat* pMyFlyFrameFormat(GetFrameFormat()); SwSortedObjs &rObjs = *pContent->GetDrawObjs(); for(SwAnchoredObject* rObj : rObjs) { SwFlyFrame* pFlyFrame = rObj->DynCastFlyFrame(); if (pFlyFrame && - &(pFlyFrame->GetFrameFormat()) == pMyFlyFrameFormat) + pFlyFrame->GetFrameFormat() == pMyFlyFrameFormat) { bFound = false; break; @@ -330,7 +330,8 @@ bool SwOszControl::ChkOsz() |*/ void SwFlyAtContentFrame::MakeAll(vcl::RenderContext* pRenderContext) { - if ( !GetFormat()->GetDoc()->getIDocumentDrawModelAccess().IsVisibleLayerId( GetVirtDrawObj()->GetLayer() ) ) + const SwDoc& rDoc = *(GetFormat()->GetDoc()); + if (!rDoc.getIDocumentDrawModelAccess().IsVisibleLayerId(GetVirtDrawObj()->GetLayer())) { return; } @@ -450,7 +451,6 @@ void SwFlyAtContentFrame::MakeAll(vcl::RenderContext* pRenderContext) SwTextFrame* pAnchorTextFrame( static_cast(AnchorFrame()) ); bool bInsert( true ); sal_uInt32 nAnchorFrameToPageNum( 0 ); - const SwDoc& rDoc = *(GetFrameFormat().GetDoc()); if ( SwLayouter::FrameMovedFwdByObjPos( rDoc, *pAnchorTextFrame, nAnchorFrameToPageNum ) ) { @@ -518,7 +518,7 @@ void SwFlyAtContentFrame::MakeAll(vcl::RenderContext* pRenderContext) !bConsiderWrapInfluenceDueToOverlapPrevCol && // #i40444# !bConsiderWrapInfluenceDueToMovedFwdAnchor && - GetFormat()->GetDoc()->getIDocumentDrawModelAccess().IsVisibleLayerId( GetVirtDrawObj()->GetLayer() ) ); + rDoc.getIDocumentDrawModelAccess().IsVisibleLayerId( GetVirtDrawObj()->GetLayer() ) ); // #i3317# - instead of attribute change apply // temporarily the 'straightforward positioning process'. diff --git a/sw/source/core/layout/flyincnt.cxx b/sw/source/core/layout/flyincnt.cxx index 7fb8f93f16..36c7837e95 100644 --- a/sw/source/core/layout/flyincnt.cxx +++ b/sw/source/core/layout/flyincnt.cxx @@ -191,7 +191,7 @@ void SwFlyInContentFrame::MakeObjPos() void SwFlyInContentFrame::ActionOnInvalidation( const InvalidationType _nInvalid ) { if ( INVALID_POS == _nInvalid || INVALID_ALL == _nInvalid ) - AnchorFrame()->Prepare( PrepareHint::FlyFrameAttributesChanged, &GetFrameFormat() ); + AnchorFrame()->Prepare( PrepareHint::FlyFrameAttributesChanged, GetFrameFormat() ); } void SwFlyInContentFrame::NotifyBackground( SwPageFrame *, const SwRect& rRect, diff --git a/sw/source/core/layout/flylay.cxx b/sw/source/core/layout/flylay.cxx index 457a0d41bb..7ac95d65e0 100644 --- a/sw/source/core/layout/flylay.cxx +++ b/sw/source/core/layout/flylay.cxx @@ -153,7 +153,7 @@ void SwFlyFreeFrame::MakeAll(vcl::RenderContext* /*pRenderContext*/) if ( !IsNoMoveOnCheckClip() && !( PositionLocked() && GetAnchorFrame()->IsInFly() && - GetFrameFormat().GetFollowTextFlow().GetValue() ) ) + GetFrameFormat()->GetFollowTextFlow().GetValue() ) ) { setFrameAreaPositionValid(false); } @@ -1100,7 +1100,7 @@ void SwPageFrame::AppendDrawObjToPage( SwAnchoredObject& _rNewObj ) pFlyFrame->GetVirtDrawObj()->SetOrdNum( nNewNum ); } - if ( RndStdIds::FLY_AS_CHAR == _rNewObj.GetFrameFormat().GetAnchor().GetAnchorId() ) + if ( RndStdIds::FLY_AS_CHAR == _rNewObj.GetFrameFormat()->GetAnchor().GetAnchorId() ) { return; } @@ -1140,8 +1140,9 @@ void SwPageFrame::RemoveDrawObjFromPage( SwAnchoredObject& _rToRemoveObj ) } if ( GetUpper() ) { - if (RndStdIds::FLY_AS_CHAR != - _rToRemoveObj.GetFrameFormat().GetAnchor().GetAnchorId()) + const SwFrameFormat* pObjFormat = _rToRemoveObj.GetFrameFormat(); + if (pObjFormat + && RndStdIds::FLY_AS_CHAR != pObjFormat->GetAnchor().GetAnchorId()) { static_cast(GetUpper())->SetSuperfluous(); InvalidatePage(); @@ -1454,63 +1455,67 @@ bool CalcClipRect( const SdrObject *pSdrObj, SwRect &rRect, bool bMove ) } else { - const SwDrawContact *pC = static_cast(GetUserCall(pSdrObj)); - const SwFrameFormat *pFormat = pC->GetFormat(); - const SwFormatAnchor &rAnch = pFormat->GetAnchor(); - if ( RndStdIds::FLY_AS_CHAR == rAnch.GetAnchorId() ) + if (const SwDrawContact* pC = static_cast(GetUserCall(pSdrObj))) { - const SwFrame* pAnchorFrame = pC->GetAnchorFrame( pSdrObj ); - if( !pAnchorFrame ) + const SwFrameFormat* pFormat = pC->GetFormat(); + const SwFormatAnchor& rAnch = pFormat->GetAnchor(); + if (RndStdIds::FLY_AS_CHAR == rAnch.GetAnchorId()) { - OSL_FAIL( "<::CalcClipRect(..)> - missing anchor frame." ); - const_cast(pC)->ConnectToLayout(); - pAnchorFrame = pC->GetAnchorFrame(); - } - const SwFrame* pUp = pAnchorFrame->GetUpper(); - rRect = pUp->getFramePrintArea(); - rRect += pUp->getFrameArea().Pos(); - SwRectFnSet aRectFnSet(pAnchorFrame); - tools::Long nHeight = (9*aRectFnSet.GetHeight(rRect))/10; - tools::Long nTop; - const SvxULSpaceItem &rUL = pFormat->GetULSpace(); - SwRect aSnapRect( pSdrObj->GetSnapRect() ); - tools::Long nTmpH = 0; - if( bMove ) - { - nTop = aRectFnSet.YInc( aRectFnSet.IsVert() ? pSdrObj->GetAnchorPos().X() : - pSdrObj->GetAnchorPos().Y(), -nHeight ); - tools::Long nWidth = aRectFnSet.GetWidth(aSnapRect); - aRectFnSet.SetLeftAndWidth( rRect, aRectFnSet.IsVert() ? - pSdrObj->GetAnchorPos().Y() : - pSdrObj->GetAnchorPos().X(), nWidth ); - } - else - { - // #i26791# - value of is needed to - // calculate value of . - nTmpH = aRectFnSet.IsVert() ? pSdrObj->GetCurrentBoundRect().GetWidth() : - pSdrObj->GetCurrentBoundRect().GetHeight(); - nTop = aRectFnSet.YInc( aRectFnSet.GetTop(aSnapRect), - rUL.GetLower() + nTmpH - nHeight ); - } - nHeight = 2*nHeight - nTmpH - rUL.GetLower() - rUL.GetUpper(); - aRectFnSet.SetTopAndHeight( rRect, nTop, nHeight ); - } - else - { - // restrict clip rectangle for drawing - // objects in header/footer to the page frame. - // #i26791# - const SwFrame* pAnchorFrame = pC->GetAnchorFrame( pSdrObj ); - if ( pAnchorFrame && pAnchorFrame->FindFooterOrHeader() ) - { - // clip frame is the page frame the header/footer is on. - const SwFrame* pClipFrame = pAnchorFrame->FindPageFrame(); - rRect = pClipFrame->getFrameArea(); + const SwFrame* pAnchorFrame = pC->GetAnchorFrame(pSdrObj); + if (!pAnchorFrame) + { + OSL_FAIL("<::CalcClipRect(..)> - missing anchor frame."); + const_cast(pC)->ConnectToLayout(); + pAnchorFrame = pC->GetAnchorFrame(); + } + const SwFrame* pUp = pAnchorFrame->GetUpper(); + rRect = pUp->getFramePrintArea(); + rRect += pUp->getFrameArea().Pos(); + SwRectFnSet aRectFnSet(pAnchorFrame); + tools::Long nHeight = (9 * aRectFnSet.GetHeight(rRect)) / 10; + tools::Long nTop; + const SvxULSpaceItem& rUL = pFormat->GetULSpace(); + SwRect aSnapRect(pSdrObj->GetSnapRect()); + tools::Long nTmpH = 0; + if (bMove) + { + nTop = aRectFnSet.YInc(aRectFnSet.IsVert() ? pSdrObj->GetAnchorPos().X() + : pSdrObj->GetAnchorPos().Y(), + -nHeight); + tools::Long nWidth = aRectFnSet.GetWidth(aSnapRect); + aRectFnSet.SetLeftAndWidth(rRect, + aRectFnSet.IsVert() ? pSdrObj->GetAnchorPos().Y() + : pSdrObj->GetAnchorPos().X(), + nWidth); + } + else + { + // #i26791# - value of is needed to + // calculate value of . + nTmpH = aRectFnSet.IsVert() ? pSdrObj->GetCurrentBoundRect().GetWidth() + : pSdrObj->GetCurrentBoundRect().GetHeight(); + nTop = aRectFnSet.YInc(aRectFnSet.GetTop(aSnapRect), + rUL.GetLower() + nTmpH - nHeight); + } + nHeight = 2 * nHeight - nTmpH - rUL.GetLower() - rUL.GetUpper(); + aRectFnSet.SetTopAndHeight(rRect, nTop, nHeight); } else { - bRet = false; + // restrict clip rectangle for drawing + // objects in header/footer to the page frame. + // #i26791# + const SwFrame* pAnchorFrame = pC->GetAnchorFrame(pSdrObj); + if (pAnchorFrame && pAnchorFrame->FindFooterOrHeader()) + { + // clip frame is the page frame the header/footer is on. + const SwFrame* pClipFrame = pAnchorFrame->FindPageFrame(); + rRect = pClipFrame->getFrameArea(); + } + else + { + bRet = false; + } } } } diff --git a/sw/source/core/layout/frmtool.cxx b/sw/source/core/layout/frmtool.cxx index c3fa35fcdc..eeab5c60c1 100644 --- a/sw/source/core/layout/frmtool.cxx +++ b/sw/source/core/layout/frmtool.cxx @@ -1025,7 +1025,7 @@ void SwContentNotify::ImplDestroy() SwSortedObjs* pObjs = pMasterFrame->GetDrawObjs(); for (SwAnchoredObject* pAnchoredObj : *pObjs) { - if ( pAnchoredObj->GetFrameFormat().GetAnchor().GetAnchorId() + if ( pAnchoredObj->GetFrameFormat()->GetAnchor().GetAnchorId() == RndStdIds::FLY_AT_CHAR ) { pAnchoredObj->CheckCharRectAndTopOfLine( !pMasterFrame->IsEmpty() ); @@ -2835,7 +2835,7 @@ static void lcl_RemoveObjsFromPage( SwFrame* _pFrame ) // #115759# - remove also drawing objects from page else if ( auto pDrawObj = dynamic_cast( pObj) ) { - if (pObj->GetFrameFormat().GetAnchor().GetAnchorId() != RndStdIds::FLY_AS_CHAR) + if (pObj->GetFrameFormat()->GetAnchor().GetAnchorId() != RndStdIds::FLY_AS_CHAR) { if (SwPageFrame *pPg = pObj->GetPageFrame()) pPg->RemoveDrawObjFromPage( *pDrawObj ); @@ -2996,7 +2996,7 @@ static void lcl_AddObjsToPage( SwFrame* _pFrame, SwPageFrame* _pPage ) // #115759# - remove also drawing objects from page else if ( dynamic_cast( pObj) != nullptr ) { - if (pObj->GetFrameFormat().GetAnchor().GetAnchorId() != RndStdIds::FLY_AS_CHAR) + if (pObj->GetFrameFormat()->GetAnchor().GetAnchorId() != RndStdIds::FLY_AS_CHAR) { pObj->InvalidateObjPos(); _pPage->AppendDrawObjToPage( @@ -3404,8 +3404,10 @@ void Notify_Background( const SdrObject* pObj, else { pFlyFrame = nullptr; - pAnchor = const_cast( - GetUserCall(pObj)->GetAnchoredObj( pObj )->GetAnchorFrame() ); + if (SwDrawContact* pC = static_cast(GetUserCall(pObj))) + pAnchor = const_cast(pC->GetAnchoredObj(pObj)->GetAnchorFrame()); + else + return; } if( PrepareHint::FlyFrameLeave != eHint && pAnchor->IsInFly() ) pArea = pAnchor->FindFlyFrame(); @@ -3879,7 +3881,32 @@ SwFrame* GetFrameOfModify(SwRootFrame const*const pLayout, sw::BroadcastingModif } while( bClientIterChanged ); if( pPos && pMinFrame && pMinFrame->IsTextFrame() ) - return static_cast(pMinFrame)->GetFrameAtPos( *pPos ); + { + SwTextFrame * pAtPos(static_cast(pMinFrame)->GetFrameAtPos(*pPos)); + if (!pViewPosAndCalcFrame) + { + return pAtPos; + } + TextFrameIndex nPos(pAtPos->MapModelToViewPos(*pPos)); + SwPageFrame const*const pPage(pAtPos->getRootFrame()->GetPageAtPos( + pViewPosAndCalcFrame->first, nullptr, true)); + SwFrame * pOnPage(pAtPos); // if all else fails return first one + ++nPos; // follow field portions are on follow frames that have mnOffset + // already incremented past the field, need to check that index too + while (pAtPos && pAtPos->GetOffset() <= nPos) + { + if (pAtPos->getFrameArea().Contains(pViewPosAndCalcFrame->first)) + { + return pAtPos; + } + if (pAtPos->FindPageFrame() == pPage) + { + pOnPage = pAtPos; + } + pAtPos = pAtPos->GetFollow(); + } + return pOnPage; + } return pMinFrame; } diff --git a/sw/source/core/layout/layact.cxx b/sw/source/core/layout/layact.cxx index 747470129c..a705ef2511 100644 --- a/sw/source/core/layout/layact.cxx +++ b/sw/source/core/layout/layact.cxx @@ -1673,7 +1673,7 @@ bool SwLayAction::FormatContent(SwPageFrame *const pPage) assert(pAnchorPage); if (pAnchorPage != pPage && pPage->GetPhyPageNum() < pAnchorPage->GetPhyPageNum() - && pObj->GetFrameFormat().GetAnchor().GetAnchorId() + && pObj->GetFrameFormat()->GetAnchor().GetAnchorId() != RndStdIds::FLY_AS_CHAR) { moved.emplace_back(pObj, pAnchorPage); diff --git a/sw/source/core/layout/objectformattertxtfrm.cxx b/sw/source/core/layout/objectformattertxtfrm.cxx index 6b2503d40c..9a44b0df62 100644 --- a/sw/source/core/layout/objectformattertxtfrm.cxx +++ b/sw/source/core/layout/objectformattertxtfrm.cxx @@ -148,7 +148,7 @@ bool SwObjectFormatterTextFrame::DoFormatObj( SwAnchoredObject& _rAnchoredObj, _rAnchoredObj.RestartLayoutProcess() && !( _rAnchoredObj.PositionLocked() && _rAnchoredObj.GetAnchorFrame()->IsInFly() && - _rAnchoredObj.GetFrameFormat().GetFollowTextFlow().GetValue() ); + _rAnchoredObj.GetFrameFormat()->GetFollowTextFlow().GetValue() ); if ( bRestart ) { bSuccess = false; @@ -168,7 +168,7 @@ bool SwObjectFormatterTextFrame::DoFormatObj( SwAnchoredObject& _rAnchoredObj, if ( bSuccess && _rAnchoredObj.ConsiderObjWrapInfluenceOnObjPos() && ( _bCheckForMovedFwd || - _rAnchoredObj.GetFrameFormat().GetWrapInfluenceOnObjPos(). + _rAnchoredObj.GetFrameFormat()->GetWrapInfluenceOnObjPos(). // #i35017# - handle ITERATIVE as ONCE_SUCCESSIVE GetWrapInfluenceOnObjPos( true ) == // #i35017# - constant name has changed @@ -481,10 +481,11 @@ bool SwObjectFormatterTextFrame::DoFormatObjs() void SwObjectFormatterTextFrame::InvalidatePrevObjs( SwAnchoredObject& _rAnchoredObj ) { + const SwFrameFormat* pObjFormat = _rAnchoredObj.GetFrameFormat(); // invalidate all previous objects, whose wrapping influence on the object // positioning is . // Note: list of objects at anchor frame is sorted by this property. - if ( _rAnchoredObj.GetFrameFormat().GetWrapInfluenceOnObjPos(). + if (pObjFormat->GetWrapInfluenceOnObjPos(). // #i35017# - handle ITERATIVE as ONCE_SUCCESSIVE GetWrapInfluenceOnObjPos( true ) != // #i35017# - constant name has changed @@ -501,7 +502,7 @@ void SwObjectFormatterTextFrame::InvalidatePrevObjs( SwAnchoredObject& _rAnchore { --i; SwAnchoredObject* pAnchoredObj = (*pObjs)[i]; - if ( pAnchoredObj->GetFrameFormat().GetWrapInfluenceOnObjPos(). + if (pObjFormat->GetWrapInfluenceOnObjPos(). // #i35017# - handle ITERATIVE as ONCE_SUCCESSIVE GetWrapInfluenceOnObjPos( true ) == // #i35017# - constant name has changed @@ -546,7 +547,7 @@ SwAnchoredObject* SwObjectFormatterTextFrame::GetFirstObjWithMovedFwdAnchor( { SwAnchoredObject* pAnchoredObj = GetCollectedObj(i); if ( pAnchoredObj->ConsiderObjWrapInfluenceOnObjPos() && - pAnchoredObj->GetFrameFormat().GetWrapInfluenceOnObjPos(). + pAnchoredObj->GetFrameFormat()->GetWrapInfluenceOnObjPos(). // #i35017# - handle ITERATIVE as ONCE_SUCCESSIVE GetWrapInfluenceOnObjPos( true ) == _nWrapInfluenceOnPosition ) { @@ -648,8 +649,8 @@ bool SwObjectFormatterTextFrame::CheckMovedFwdCondition( // which will be on the next page. if ( !bAnchorIsMovedForward && _bAnchoredAtMasterBeforeFormatAnchor && - ((_rAnchoredObj.GetFrameFormat().GetAnchor().GetAnchorId() == RndStdIds::FLY_AT_CHAR) || - (_rAnchoredObj.GetFrameFormat().GetAnchor().GetAnchorId() == RndStdIds::FLY_AT_PARA))) + ((_rAnchoredObj.GetFrameFormat()->GetAnchor().GetAnchorId() == RndStdIds::FLY_AT_CHAR) || + (_rAnchoredObj.GetFrameFormat()->GetAnchor().GetAnchorId() == RndStdIds::FLY_AT_PARA))) { SwFrame* pAnchorFrame = _rAnchoredObj.GetAnchorFrameContainingAnchPos(); OSL_ENSURE( pAnchorFrame->IsTextFrame(), @@ -703,7 +704,7 @@ bool SwObjectFormatterTextFrame::CheckMovedFwdCondition( if ((pObjAnchorPage == &rFromPageFrame ? _boInFollow // same-page but will move forward : rFromPageFrame.GetPhyPageNum() < pObjAnchorPage->GetPhyPageNum()) - && pObj->GetFrameFormat().GetAnchor().GetAnchorId() + && pObj->GetFrameFormat()->GetAnchor().GetAnchorId() != RndStdIds::FLY_AS_CHAR) { if (pPageFrameOfAnchor->GetPhyPageNum() < pObjAnchorPage->GetPhyPageNum()) diff --git a/sw/source/core/layout/pagechg.cxx b/sw/source/core/layout/pagechg.cxx index e70cb68469..bf4bcc45ea 100644 --- a/sw/source/core/layout/pagechg.cxx +++ b/sw/source/core/layout/pagechg.cxx @@ -1708,8 +1708,8 @@ void SwRootFrame::AssertPageFlys( SwPageFrame *pPage ) while ( pPage->GetSortedObjs() && i< pPage->GetSortedObjs()->size() ) { // #i28701# - SwFrameFormat& rFormat = (*pPage->GetSortedObjs())[i]->GetFrameFormat(); - const SwFormatAnchor &rAnch = rFormat.GetAnchor(); + SwFrameFormat* pFormat = (*pPage->GetSortedObjs())[i]->GetFrameFormat(); + const SwFormatAnchor &rAnch = pFormat->GetAnchor(); const sal_uInt16 nPg = rAnch.GetPageNum(); if ((rAnch.GetAnchorId() == RndStdIds::FLY_AT_PAGE) && nPg != pPage->GetPhyPageNum() ) @@ -1722,12 +1722,12 @@ void SwRootFrame::AssertPageFlys( SwPageFrame *pPage ) // It can move by itself. Just send a modify to its anchor attribute. #if OSL_DEBUG_LEVEL > 1 const size_t nCnt = pPage->GetSortedObjs()->size(); - rFormat.CallSwClientNotify(sw::LegacyModifyHint(nullptr, &rAnch)); + pFormat->CallSwClientNotify(sw::LegacyModifyHint(nullptr, &rAnch)); OSL_ENSURE( !pPage->GetSortedObjs() || nCnt != pPage->GetSortedObjs()->size(), "Object couldn't be reattached!" ); #else - rFormat.CallSwClientNotify(sw::LegacyModifyHint(nullptr, &rAnch)); + pFormat->CallSwClientNotify(sw::LegacyModifyHint(nullptr, &rAnch)); #endif // Do not increment index, in this case continue; @@ -1853,19 +1853,19 @@ void SwRootFrame::ImplCalcBrowseWidth() { // #i28701# SwAnchoredObject* pAnchoredObj = (*pFrame->GetDrawObjs())[i]; - const SwFrameFormat& rFormat = pAnchoredObj->GetFrameFormat(); + const SwFrameFormat* pFormat = pAnchoredObj->GetFrameFormat(); const bool bFly = pAnchoredObj->DynCastFlyFrame() != nullptr; if ((bFly && (FAR_AWAY == pAnchoredObj->GetObjRect().Width())) - || rFormat.GetFrameSize().GetWidthPercent()) + || pFormat->GetFrameSize().GetWidthPercent()) { continue; } tools::Long nWidth = 0; - switch ( rFormat.GetAnchor().GetAnchorId() ) + switch ( pFormat->GetAnchor().GetAnchorId() ) { case RndStdIds::FLY_AS_CHAR: - nWidth = bFly ? rFormat.GetFrameSize().GetWidth() : + nWidth = bFly ? pFormat->GetFrameSize().GetWidth() : pAnchoredObj->GetObjRect().Width(); break; case RndStdIds::FLY_AT_PARA: @@ -1877,8 +1877,8 @@ void SwRootFrame::ImplCalcBrowseWidth() // at position FAR_AWAY. if ( bFly ) { - nWidth = rFormat.GetFrameSize().GetWidth(); - const SwFormatHoriOrient &rHori = rFormat.GetHoriOrient(); + nWidth = pFormat->GetFrameSize().GetWidth(); + const SwFormatHoriOrient &rHori = pFormat->GetHoriOrient(); switch ( rHori.GetHoriOrient() ) { case text::HoriOrientation::NONE: @@ -2013,8 +2013,8 @@ static void lcl_MoveAllLowerObjs( SwFrame* pFrame, const Point& rOffset ) for (size_t i = 0; i < pSortedObj->size(); ++i) { SwAnchoredObject *const pAnchoredObj = (*pSortedObj)[i]; - const SwFrameFormat& rObjFormat = pAnchoredObj->GetFrameFormat(); - const SwFormatAnchor& rAnchor = rObjFormat.GetAnchor(); + const SwFrameFormat* pObjFormat = pAnchoredObj->GetFrameFormat(); + const SwFormatAnchor& rAnchor = pObjFormat->GetAnchor(); // all except from the as character anchored objects are moved // when processing the page frame: @@ -2070,7 +2070,7 @@ static void lcl_MoveAllLowerObjs( SwFrame* pFrame, const Point& rOffset ) pAnchoredDrawObj->SetLastObjRect( pAnchoredDrawObj->GetObjRect().SVRect() ); // clear contour cache - if ( pAnchoredDrawObj->GetFrameFormat().GetSurround().IsContour() ) + if ( pAnchoredDrawObj->GetFrameFormat()->GetSurround().IsContour() ) ClrContourCache( pAnchoredDrawObj->GetDrawObj() ); } // #i92511# diff --git a/sw/source/core/layout/sortedobjs.cxx b/sw/source/core/layout/sortedobjs.cxx index ce581bb663..e0c29d5180 100644 --- a/sw/source/core/layout/sortedobjs.cxx +++ b/sw/source/core/layout/sortedobjs.cxx @@ -78,12 +78,16 @@ struct ObjAnchorOrder const SwAnchoredObject* _pNewAnchoredObj ) { // get attributes of listed object - const SwFrameFormat& rFormatListed = _pListedAnchoredObj->GetFrameFormat(); - const SwFormatAnchor* pAnchorListed = &(rFormatListed.GetAnchor()); + const SwFrameFormat* pFormatListed = _pListedAnchoredObj->GetFrameFormat(); + if (!pFormatListed) + return false; + const SwFormatAnchor* pAnchorListed = &(pFormatListed->GetAnchor()); // get attributes of new object - const SwFrameFormat& rFormatNew = _pNewAnchoredObj->GetFrameFormat(); - const SwFormatAnchor* pAnchorNew = &(rFormatNew.GetAnchor()); + const SwFrameFormat* pFormatNew = _pNewAnchoredObj->GetFrameFormat(); + if (!pFormatNew) + return false; + const SwFormatAnchor* pAnchorNew = &(pFormatNew->GetAnchor()); // check for to-page anchored objects if ((pAnchorListed->GetAnchorId() == RndStdIds::FLY_AT_PAGE) && @@ -156,15 +160,15 @@ struct ObjAnchorOrder // objects anchored at the same content and at the same content anchor // node position with the same anchor type // Thus, compare its wrapping style including its layer - const IDocumentDrawModelAccess& rIDDMA = rFormatListed.getIDocumentDrawModelAccess(); + const IDocumentDrawModelAccess& rIDDMA = pFormatListed->getIDocumentDrawModelAccess(); const SdrLayerID nHellId = rIDDMA.GetHellId(); const SdrLayerID nInvisibleHellId = rIDDMA.GetInvisibleHellId(); const bool bWrapThroughOrHellListed = - rFormatListed.GetSurround().GetSurround() == css::text::WrapTextMode_THROUGH || + pFormatListed->GetSurround().GetSurround() == css::text::WrapTextMode_THROUGH || _pListedAnchoredObj->GetDrawObj()->GetLayer() == nHellId || _pListedAnchoredObj->GetDrawObj()->GetLayer() == nInvisibleHellId; const bool bWrapThroughOrHellNew = - rFormatNew.GetSurround().GetSurround() == css::text::WrapTextMode_THROUGH || + pFormatNew->GetSurround().GetSurround() == css::text::WrapTextMode_THROUGH || _pNewAnchoredObj->GetDrawObj()->GetLayer() == nHellId || _pNewAnchoredObj->GetDrawObj()->GetLayer() == nInvisibleHellId; if ( bWrapThroughOrHellListed != bWrapThroughOrHellNew ) @@ -179,9 +183,9 @@ struct ObjAnchorOrder // objects anchored at the same content with a set text wrapping // Thus, compare wrap influences on object position const SwFormatWrapInfluenceOnObjPos* pWrapInfluenceOnObjPosListed = - &(rFormatListed.GetWrapInfluenceOnObjPos()); + &(pFormatListed->GetWrapInfluenceOnObjPos()); const SwFormatWrapInfluenceOnObjPos* pWrapInfluenceOnObjPosNew = - &(rFormatNew.GetWrapInfluenceOnObjPos()); + &(pFormatNew->GetWrapInfluenceOnObjPos()); // #i35017# - handle ITERATIVE as ONCE_SUCCESSIVE if ( pWrapInfluenceOnObjPosListed->GetWrapInfluenceOnObjPos( true ) != pWrapInfluenceOnObjPosNew->GetWrapInfluenceOnObjPos( true ) ) diff --git a/sw/source/core/layout/tabfrm.cxx b/sw/source/core/layout/tabfrm.cxx index c1acc0c9e9..f757824561 100644 --- a/sw/source/core/layout/tabfrm.cxx +++ b/sw/source/core/layout/tabfrm.cxx @@ -286,12 +286,12 @@ static void lcl_InvalidateLowerObjs( SwLayoutFrame& _rLayoutFrame, // that anchored object is correctly positioned. pAnchoredObj->ClearCharRectAndTopOfLine(); pAnchoredObj->SetCurrRelPos( Point( 0, 0 ) ); - if ( pAnchoredObj->GetFrameFormat().GetAnchor().GetAnchorId() - == RndStdIds::FLY_AS_CHAR ) + const SwFrameFormat* pObjFormat = pAnchoredObj->GetFrameFormat(); + if (pObjFormat->GetAnchor().GetAnchorId() == RndStdIds::FLY_AS_CHAR) { pAnchoredObj->AnchorFrame() ->Prepare( PrepareHint::FlyFrameAttributesChanged, - &(pAnchoredObj->GetFrameFormat()) ); + pObjFormat ); } if ( pFly != nullptr ) { @@ -1451,7 +1451,102 @@ namespace return true; } -} + + auto IsAllHiddenSection(SwSectionFrame const& rSection) -> bool + { + for (SwFrame const* pFrame = rSection.Lower(); pFrame; pFrame = pFrame->GetNext()) + { + if (pFrame->IsColumnFrame()) + { + return false; // adds some padding + } + else if (pFrame->IsSctFrame()) + { + assert(false); // these aren't nested? + if (!IsAllHiddenSection(*static_cast(pFrame))) + { + return false; + } + } + else if (pFrame->IsTabFrame()) + { + return false; // presumably + } + else if (pFrame->IsTextFrame()) + { + if (!static_cast(pFrame)->IsHiddenNow()) + { + return false; + } + } + } + return true; + } + + auto IsAllHiddenRow(SwRowFrame const& rRow, SwTabFrame const& rTab) -> bool; + + auto IsAllHiddenCell(SwCellFrame const& rCell, SwRowFrame const& rRow, SwTabFrame const& rTab) -> bool + { + for (SwFrame const* pFrame = rCell.Lower(); pFrame; pFrame = pFrame->GetNext()) + { + if (pFrame->IsRowFrame()) + { + if (!IsAllHiddenRow(*static_cast(pFrame), rTab)) + { + return false; + } + } + else if (pFrame->IsSctFrame()) + { + if (!IsAllHiddenSection(*static_cast(pFrame))) + { + return false; + } + } + else if (pFrame->IsTabFrame()) + { + return false; // presumably + } + else if (pFrame->IsTextFrame()) + { + if (!static_cast(pFrame)->IsHiddenNow()) + { + return false; + } + } + } + if (rTab.IsCollapsingBorders() && !rCell.Lower()->IsRowFrame()) + { + if (rRow.GetTopMarginForLowers() != 0 + || rRow.GetBottomMarginForLowers() != 0) + { + return false; + } + } + else + { + SwBorderAttrAccess border(SwFrame::GetCache(), &rCell); + if (border.Get()->CalcTop() != 0 || border.Get()->CalcBottom() != 0) + { + return false; + } + } + return true; + } + + auto IsAllHiddenRow(SwRowFrame const& rRow, SwTabFrame const& rTab) -> bool + { + for (SwFrame const* pCell = rRow.Lower(); pCell; pCell = pCell->GetNext()) + { + if (!IsAllHiddenCell(*static_cast(pCell), rRow, rTab)) + { + return false; + } + } + return true; + } + +} // namespace void SwTabFrame::Join() { @@ -1471,11 +1566,20 @@ void SwTabFrame::Join() SwFrame* pPrv = GetLastLower(); SwTwips nHeight = 0; //Total height of the inserted rows as return value. + bool isAllHidden(true); while ( pRow ) { pNxt = pRow->GetNext(); nHeight += aRectFnSet.GetHeight(pRow->getFrameArea()); + if (nHeight != 0) + { + isAllHidden = false; + } + if (isAllHidden) + { + isAllHidden = IsAllHiddenRow(*static_cast(pRow), *this); + } pRow->RemoveFromLayout(); pRow->InvalidateAll_(); pRow->InsertBehind( this, pPrv ); @@ -1489,6 +1593,18 @@ void SwTabFrame::Join() SwFrame::DestroyFrame(pFoll); Grow( nHeight ); + + // In case the row does not have a height, Grow(nHeight) did nothing. + // If this is not invalidated, subsequent follows may never be joined. + // Try to guess if the height of the row will be 0. If the document + // was just loaded, it will be 0 in any case, but probably it's not a good + // idea to join *all* follows for a newly loaded document, it would be + // easier not to split the table in the first place; presumably it is split + // because that improves performance. + if (isAllHidden) + { + InvalidateSize_(); + } } static void SwInvalidatePositions( SwFrame *pFrame, tools::Long nBottom ) @@ -3180,6 +3296,7 @@ bool SwTabFrame::CalcFlyOffsets( SwTwips& rUpper, bool bShiftDown = css::text::WrapTextMode_NONE == nSurround; bool bSplitFly = pFly->IsFlySplitAllowed(); + const SwRect aFlyRectWithoutSpaces = pFly->GetObjRect(); if (!bShiftDown && bAddVerticalFlyOffsets) { if (nSurround == text::WrapTextMode_PARALLEL && isHoriOrientShiftDown) @@ -3194,7 +3311,6 @@ bool SwTabFrame::CalcFlyOffsets( SwTwips& rUpper, // Ignore spacing when determining the left/right edge of the fly, like // Word does. - const SwRect aFlyRectWithoutSpaces = pFly->GetObjRect(); basegfx::B1DRange aFlyRange(aRectFnSet.GetLeft(aFlyRectWithoutSpaces), aRectFnSet.GetRight(aFlyRectWithoutSpaces)); @@ -3257,9 +3373,16 @@ bool SwTabFrame::CalcFlyOffsets( SwTwips& rUpper, bool bFlyHoriOrientLeft = text::HoriOrientation::LEFT == rHori.GetHoriOrient(); if (bSplitFly && !bFlyHoriOrientLeft) { - // If a split fly is oriented "from left", we already checked if it has enough space on - // the right, so from-left and left means the same here. - bFlyHoriOrientLeft = rHori.GetHoriOrient() == text::HoriOrientation::NONE; + // Only shift to the right if we don't have enough space on the left. + SwTwips nTabWidth = getFramePrintArea().Width(); + SwTwips nWidthDeadline = aFlyRectWithoutSpaces.Left() + - pFly->GetAnchorFrame()->GetUpper()->getFrameArea().Left(); + if (nTabWidth > nWidthDeadline) + { + // If a split fly is oriented "from left", we already checked if it has enough space on + // the right, so from-left and left means the same here. + bFlyHoriOrientLeft = rHori.GetHoriOrient() == text::HoriOrientation::NONE; + } } if ((css::text::WrapTextMode_RIGHT == nSurround || css::text::WrapTextMode_PARALLEL == nSurround) @@ -4447,8 +4570,8 @@ tools::Long CalcHeightWithFlys( const SwFrame *pFrame ) { // OD 30.09.2003 #i18732# - only objects, which follow // the text flow have to be considered. - const SwFrameFormat& rFrameFormat = pAnchoredObj->GetFrameFormat(); - bool bFollowTextFlow = rFrameFormat.GetFollowTextFlow().GetValue(); + const SwFrameFormat* pFrameFormat = pAnchoredObj->GetFrameFormat(); + bool bFollowTextFlow = pFrameFormat->GetFollowTextFlow().GetValue(); bool bIsFarAway = pAnchoredObj->GetObjRect().Top() != FAR_AWAY; const SwPageFrame* pPageFrm = pTmp->FindPageFrame(); bool bIsAnchoredToTmpFrm = false; @@ -4456,14 +4579,14 @@ tools::Long CalcHeightWithFlys( const SwFrame *pFrame ) bIsAnchoredToTmpFrm = pAnchoredObj->GetPageFrame() == pPageFrm || (pPageFrm->GetFormatPage().GetPhyPageNum() == pAnchoredObj->GetPageFrame()->GetFormatPage().GetPhyPageNum() + 1); const bool bConsiderObj = - (rFrameFormat.GetAnchor().GetAnchorId() != RndStdIds::FLY_AS_CHAR) && + (pFrameFormat->GetAnchor().GetAnchorId() != RndStdIds::FLY_AS_CHAR) && bIsFarAway && bFollowTextFlow && bIsAnchoredToTmpFrm; - bool bWrapThrough = rFrameFormat.GetSurround().GetValue() == text::WrapTextMode_THROUGH; - bool bInBackground = !rFrameFormat.GetOpaque().GetValue(); + bool bWrapThrough = pFrameFormat->GetSurround().GetValue() == text::WrapTextMode_THROUGH; + bool bInBackground = !pFrameFormat->GetOpaque().GetValue(); // Legacy render requires in-background setting, the new mode does not. bool bConsiderFollowTextFlow = bInBackground - || !rFrameFormat.getIDocumentSettingAccess().get( + || !pFrameFormat->getIDocumentSettingAccess().get( DocumentSettingId::USE_FORMER_TEXT_WRAPPING); if (pFrame->IsInTab() && bFollowTextFlow && bWrapThrough && bConsiderFollowTextFlow) { @@ -4475,7 +4598,7 @@ tools::Long CalcHeightWithFlys( const SwFrame *pFrame ) if ( bConsiderObj ) { - const SwFormatFrameSize &rSz = rFrameFormat.GetFrameSize(); + const SwFormatFrameSize &rSz = pFrameFormat->GetFrameSize(); if( !rSz.GetHeightPercent() ) { const SwTwips nDistOfFlyBottomToAnchorTop = @@ -5428,7 +5551,7 @@ static bool lcl_ArrangeLowers( SwLayoutFrame *pLay, tools::Long lYStart, bool bI // from its anchor frame. bool bVertPosDepOnAnchor( true ); { - SwFormatVertOrient aVert( pAnchoredObj->GetFrameFormat().GetVertOrient() ); + SwFormatVertOrient aVert( pAnchoredObj->GetFrameFormat()->GetVertOrient() ); switch ( aVert.GetRelationOrient() ) { case text::RelOrientation::PAGE_FRAME: @@ -5528,7 +5651,7 @@ static bool lcl_ArrangeLowers( SwLayoutFrame *pLay, tools::Long lYStart, bool bI if ( pTabFrame && !( pTabFrame->IsFollow() && pTabFrame->FindMaster()->IsRebuildLastLine() ) && - (pAnchoredObj->GetFrameFormat().GetAnchor().GetAnchorId() + (pAnchoredObj->GetFrameFormat()->GetAnchor().GetAnchorId() != RndStdIds::FLY_AS_CHAR)) { SwPageFrame* pPageFrame = pAnchoredObj->GetPageFrame(); @@ -5546,7 +5669,7 @@ static bool lcl_ArrangeLowers( SwLayoutFrame *pLay, tools::Long lYStart, bool bI // #i52904# - re-introduce direct move // of drawing objects const bool bDirectMove = - static_cast(pAnchoredObj->GetFrameFormat()).IsPosAttrSet() && + static_cast(pAnchoredObj->GetFrameFormat())->IsPosAttrSet() && bVertPosDepOnAnchor && !pAnchoredObj->ConsiderObjWrapInfluenceOnObjPos(); if ( bDirectMove ) @@ -5804,8 +5927,8 @@ void SwCellFrame::Format( vcl::RenderContext* /*pRenderContext*/, const SwBorder const SwFrame* pAnch = pAnchoredObj->GetAnchorFrame(); if ( (bConsiderWrapOnObjPos && IsAnLower( pAnch )) || (!bConsiderWrapOnObjPos && aTmp.Overlaps( aRect )) ) { - const SwFrameFormat& rAnchoredObjFrameFormat = pAnchoredObj->GetFrameFormat(); - const SwFormatSurround &rSur = rAnchoredObjFrameFormat.GetSurround(); + const SwFrameFormat* pAnchoredObjFrameFormat = pAnchoredObj->GetFrameFormat(); + const SwFormatSurround &rSur = pAnchoredObjFrameFormat->GetSurround(); if ( bConsiderWrapOnObjPos || css::text::WrapTextMode_THROUGH != rSur.GetSurround() ) { @@ -5825,7 +5948,7 @@ void SwCellFrame::Format( vcl::RenderContext* /*pRenderContext*/, const SwBorder if ( bConsiderWrapOnObjPos || !IsAnLower( pAnch ) || pAnchoredObj->IsTmpConsiderWrapInfluence() || - !rAnchoredObjFrameFormat.GetFollowTextFlow().GetValue() ) + !pAnchoredObjFrameFormat->GetFollowTextFlow().GetValue() ) { bVertDir = false; break; diff --git a/sw/source/core/layout/trvlfrm.cxx b/sw/source/core/layout/trvlfrm.cxx index 5f8e3aa995..a8445e90dd 100644 --- a/sw/source/core/layout/trvlfrm.cxx +++ b/sw/source/core/layout/trvlfrm.cxx @@ -70,8 +70,9 @@ namespace { const SwVirtFlyDrawObj* pObj = static_cast(aIter()); const SwAnchoredObject* pAnchoredObj = GetUserCall( aIter() )->GetAnchoredObj( aIter() ); - const SwFormatSurround& rSurround = pAnchoredObj->GetFrameFormat().GetSurround(); - const SvxOpaqueItem& rOpaque = pAnchoredObj->GetFrameFormat().GetOpaque(); + const SwFrameFormat* pObjFormat = pAnchoredObj->GetFrameFormat(); + const SwFormatSurround& rSurround = pObjFormat->GetSurround(); + const SvxOpaqueItem& rOpaque = pObjFormat->GetOpaque(); bool bInBackground = ( rSurround.GetSurround() == css::text::WrapTextMode_THROUGH ) && !rOpaque.GetValue(); bool bBackgroundMatches = bInBackground == bSearchBackground; @@ -2599,40 +2600,49 @@ void SwRootFrame::CalcFrameRects(SwShellCursor const& rCursor, SwRects & rRects, // splitting of portions vertically (causes spurious extra PDF annotations) if (eMode == RectsMode::NoAnchoredFlys) { - assert(pStartFrame == pEndFrame); // link or field all in 1 frame - assert(pStartFrame->IsTextFrame()); - SwTextGridItem const*const pGrid(GetGridItem(pStartFrame->FindPageFrame())); - SwTextPaintInfo info(static_cast(pStartFrame), pStartFrame->FindPageFrame()->getFrameArea()); - SwTextPainter painter(static_cast(pStartFrame), &info); - // because nothing outside the start/end has been added, it doesn't - // matter to match exactly the start/end, subtracting outside is no-op - painter.CharToLine(static_cast(pStartFrame)->MapModelToViewPos(*pStartPos)); - do - { - info.SetPos(painter.GetTopLeft()); - bool const bAdjustBaseLine( - painter.GetLineInfo().HasSpecialAlign(pStartFrame->IsVertical()) - || nullptr != pGrid || painter.GetCurr()->GetHangingBaseline()); - SwTwips nAscent, nHeight; - painter.CalcAscentAndHeight(nAscent, nHeight); - SwTwips const nOldY(info.Y()); - for (SwLinePortion const* pLP = painter.GetCurr()->GetFirstPortion(); - pLP; pLP = pLP->GetNextPortion()) + for (SwContentFrame * pFrame = pStartFrame; ; pFrame = pFrame->GetFollow()) + { + assert(pFrame->IsTextFrame()); + SwTextGridItem const*const pGrid(GetGridItem(pFrame->FindPageFrame())); + SwTextPaintInfo info(static_cast(pFrame), pFrame->FindPageFrame()->getFrameArea()); + SwTextPainter painter(static_cast(pFrame), &info); + // because nothing outside the start/end has been added, it doesn't + // matter to match exactly the start/end, subtracting outside is no-op + if (pFrame == pStartFrame) { - if (pLP->IsFlyPortion()) + painter.CharToLine(static_cast(pFrame)->MapModelToViewPos(*pStartPos)); + } + do + { + info.SetPos(painter.GetTopLeft()); + bool const bAdjustBaseLine( + painter.GetLineInfo().HasSpecialAlign(pFrame->IsVertical()) + || nullptr != pGrid || painter.GetCurr()->GetHangingBaseline()); + SwTwips nAscent, nHeight; + painter.CalcAscentAndHeight(nAscent, nHeight); + SwTwips const nOldY(info.Y()); + for (SwLinePortion const* pLP = painter.GetCurr()->GetFirstPortion(); + pLP; pLP = pLP->GetNextPortion()) { - info.Y(info.Y() + (bAdjustBaseLine - ? painter.AdjustBaseLine(*painter.GetCurr(), pLP) - : nAscent)); - SwRect flyPortion; - info.CalcRect(*pLP, &flyPortion); - Sub(aRegion, flyPortion); - info.Y(nOldY); + if (pLP->IsFlyPortion()) + { + info.Y(info.Y() + (bAdjustBaseLine + ? painter.AdjustBaseLine(*painter.GetCurr(), pLP) + : nAscent)); + SwRect flyPortion; + info.CalcRect(*pLP, &flyPortion); + Sub(aRegion, flyPortion); + info.Y(nOldY); + } + pLP->Move(info); } - pLP->Move(info); + } + while (painter.Next()); + if (pFrame == pEndFrame) + { + break; } } - while (painter.Next()); } else while (pPage) { @@ -2646,7 +2656,7 @@ void SwRootFrame::CalcFrameRects(SwShellCursor const& rCursor, SwRects & rRects, continue; const SwVirtFlyDrawObj* pObj = pFly->GetVirtDrawObj(); const SwFormatSurround &rSur = pFly->GetFormat()->GetSurround(); - SwFormatAnchor const& rAnchor(pAnchoredObj->GetFrameFormat().GetAnchor()); + SwFormatAnchor const& rAnchor(pAnchoredObj->GetFrameFormat()->GetAnchor()); const SwPosition* anchoredAt = rAnchor.GetContentAnchor(); bool inSelection = ( anchoredAt != nullptr diff --git a/sw/source/core/layout/wsfrm.cxx b/sw/source/core/layout/wsfrm.cxx index 1cd01d53c6..aa108e16b6 100644 --- a/sw/source/core/layout/wsfrm.cxx +++ b/sw/source/core/layout/wsfrm.cxx @@ -2347,8 +2347,8 @@ SwTwips SwContentFrame::ShrinkFrame( SwTwips nDist, bool bTst, bool bInfo ) if( aBound.Overlaps( aRect ) ) { - const SwFrameFormat& rFormat = pAnchoredObj->GetFrameFormat(); - if( css::text::WrapTextMode_THROUGH != rFormat.GetSurround().GetSurround() ) + const SwFrameFormat* pFormat = pAnchoredObj->GetFrameFormat(); + if( css::text::WrapTextMode_THROUGH != pFormat->GetSurround().GetSurround() ) { const SwFrame* pAnchor = pAnchoredObj->GetAnchorFrame(); if ( pAnchor && pAnchor->FindFooterOrHeader() == GetUpper() ) @@ -4327,7 +4327,7 @@ void SwRootFrame::InvalidateAllObjPos() const SwSortedObjs& rObjs = *(pPageFrame->GetSortedObjs()); for (SwAnchoredObject* pAnchoredObj : rObjs) { - const SwFormatAnchor& rAnch = pAnchoredObj->GetFrameFormat().GetAnchor(); + const SwFormatAnchor& rAnch = pAnchoredObj->GetFrameFormat()->GetAnchor(); if ((rAnch.GetAnchorId() != RndStdIds::FLY_AT_PARA) && (rAnch.GetAnchorId() != RndStdIds::FLY_AT_CHAR)) { diff --git a/sw/source/core/objectpositioning/anchoredobjectposition.cxx b/sw/source/core/objectpositioning/anchoredobjectposition.cxx index e530e36df3..ab35ae7af7 100644 --- a/sw/source/core/objectpositioning/anchoredobjectposition.cxx +++ b/sw/source/core/objectpositioning/anchoredobjectposition.cxx @@ -106,7 +106,7 @@ void SwAnchoredObjectPosition::GetInfoAboutObj() // determine format the object belongs to { // #i28701# - mpFrameFormat = &mpAnchoredObj->GetFrameFormat(); + mpFrameFormat = mpAnchoredObj->GetFrameFormat(); assert(mpFrameFormat && "GetFrameFormat(), RES_FLYFRMFMT)) + if (SwTextBoxHelper::isTextBox(pAnchoredObj->GetFrameFormat(), RES_FLYFRMFMT)) { // Overlapping with the frame of a textbox is fine. continue; @@ -1276,7 +1276,7 @@ void SwToContentAnchoredObjectPosition::CalcOverlap(const SwTextFrame* pAnchorFr } } - css::text::WrapTextMode eWrap = pAnchoredObj->GetFrameFormat().GetSurround().GetSurround(); + css::text::WrapTextMode eWrap = pAnchoredObj->GetFrameFormat()->GetSurround().GetSurround(); if (eWrap == css::text::WrapTextMode_THROUGH) { // The other object is wrap through: allowed to overlap. diff --git a/sw/source/core/table/swnewtable.cxx b/sw/source/core/table/swnewtable.cxx index 3cc2e36707..785ef79d3b 100644 --- a/sw/source/core/table/swnewtable.cxx +++ b/sw/source/core/table/swnewtable.cxx @@ -1739,7 +1739,11 @@ void SwTable::CreateSelection( const SwNode* pStartNd, const SwNode* pEndNd, rBoxes.insert( pBox ); if( nFound ) { - nBottom = nRow; + //if box is hiding cells bottom needs to be moved + if (pBox->getRowSpan() > 1) + nBottom = std::max(nBottom, size_t(nRow + pBox->getRowSpan() - 1)); + else + nBottom = std::max(nRow, nBottom); lcl_CheckMinMax( nLowerMin, nLowerMax, *pLine, nCol, true ); ++nFound; break; @@ -1747,6 +1751,9 @@ void SwTable::CreateSelection( const SwNode* pStartNd, const SwNode* pEndNd, else { nTop = nRow; + //if box is hiding cells bottom needs to be moved + if (pBox->getRowSpan() > 1) + nBottom = nRow + pBox->getRowSpan() - 1; lcl_CheckMinMax( nUpperMin, nUpperMax, *pLine, nCol, true ); ++nFound; // If start and end node are identical, we're nearly done... diff --git a/sw/source/core/text/EnhancedPDFExportHelper.cxx b/sw/source/core/text/EnhancedPDFExportHelper.cxx index 499dcc2417..8ff764d92f 100644 --- a/sw/source/core/text/EnhancedPDFExportHelper.cxx +++ b/sw/source/core/text/EnhancedPDFExportHelper.cxx @@ -364,7 +364,10 @@ bool lcl_TryMoveToNonHiddenField(SwEditShell& rShell, const SwTextNode& rNd, con && *pStart <= pos && pos <= *pEnd) { SwRect charRect; - if (rShell.GetCurrFrame(false)->GetCharRect(charRect, pos, &cms, false) + std::pair const tmp(center, false); + SwContentFrame const*const pFrame( + pos.nNode.GetNode().GetTextNode()->getLayoutFrame(rShell.GetLayout(), &pos, &tmp)); + if (pFrame->GetCharRect(charRect, pos, &cms, false) && rRect.Overlaps(charRect)) { ret.push_back(rRect); @@ -1626,7 +1629,7 @@ void SwTaggedPDFHelper::BeginBlockStructureElements() { const SwFlyFrame* pFly = static_cast(pFrame); if (pFly->GetAnchorFrame()->FindFooterOrHeader() != nullptr - || pFly->GetFrameFormat().GetAttrSet().Get(RES_DECORATIVE).GetValue()) + || pFly->GetFrameFormat()->GetAttrSet().Get(RES_DECORATIVE).GetValue()) { nPDFType = vcl::PDFWriter::NonStructElement; } diff --git a/sw/source/core/text/frmform.cxx b/sw/source/core/text/frmform.cxx index 76a1df5621..e19b834a56 100644 --- a/sw/source/core/text/frmform.cxx +++ b/sw/source/core/text/frmform.cxx @@ -1120,7 +1120,7 @@ void SwTextFrame::FormatAdjust( SwTextFormatter &rLine, bool bOnlyContainsAsCharAnchoredObj = !IsFollow() && nStrLen == TextFrameIndex(1) && GetDrawObjs() && GetDrawObjs()->size() == 1 && - (*GetDrawObjs())[0]->GetFrameFormat().GetAnchor().GetAnchorId() == RndStdIds::FLY_AS_CHAR; + (*GetDrawObjs())[0]->GetFrameFormat()->GetAnchor().GetAnchorId() == RndStdIds::FLY_AS_CHAR; // Still try split text frame if we have columns. if (FindColFrame()) diff --git a/sw/source/core/text/guess.cxx b/sw/source/core/text/guess.cxx index 3346fe345a..c3a94187a7 100644 --- a/sw/source/core/text/guess.cxx +++ b/sw/source/core/text/guess.cxx @@ -585,7 +585,12 @@ bool SwTextGuess::Guess( const SwTextPortion& rPor, SwTextFormatInfo &rInf, m_nBreakStart = m_nBreakPos; - bHyph = BreakType::HYPHENATION == aResult.breakType; + bHyph = BreakType::HYPHENATION == aResult.breakType && + // allow hyphenation of the word only if it's not disabled by character formatting + LANGUAGE_NONE != rInf.GetTextFrame()->GetLangOfChar( + TextFrameIndex( sal_Int32(m_nBreakPos) + + aResult.rHyphenatedWord->getHyphenationPos() ), + 1, true, /*bNoneIfNoHyphenation=*/true ); if (bHyph && m_nBreakPos != TextFrameIndex(COMPLETE_STRING)) { diff --git a/sw/source/core/text/inftxt.cxx b/sw/source/core/text/inftxt.cxx index 3d9121ef1e..8eced32e89 100644 --- a/sw/source/core/text/inftxt.cxx +++ b/sw/source/core/text/inftxt.cxx @@ -1426,8 +1426,8 @@ void SwTextPaintInfo::DrawViewOpt( const SwLinePortion &rPor, || m_pFrame->GetTextNodeForParaProps()->HasMarkedLabel())) // #i27615# { bDraw = PortionType::Footnote != nWhich || m_pFrame->IsFootnoteAllowed(); + bDraw &= GetOpt().IsHardBlank(); } - bDraw &= GetOpt().IsHardBlank(); break; case PortionType::Bookmark: // no shading diff --git a/sw/source/core/text/itratr.cxx b/sw/source/core/text/itratr.cxx index 24203ecb53..bb008d24a3 100644 --- a/sw/source/core/text/itratr.cxx +++ b/sw/source/core/text/itratr.cxx @@ -1576,7 +1576,7 @@ bool SwTextFrame::IsEmptyWithSplitFly() const } // It has a split fly anchored to it. - if (pFlyFrame->GetFrameFormat().GetVertOrient().GetPos() >= 0) + if (pFlyFrame->GetFrameFormat()->GetVertOrient().GetPos() >= 0) { return false; } diff --git a/sw/source/core/text/itrform2.cxx b/sw/source/core/text/itrform2.cxx index c0b4894f8a..6623000c33 100644 --- a/sw/source/core/text/itrform2.cxx +++ b/sw/source/core/text/itrform2.cxx @@ -420,7 +420,7 @@ void SwTextFormatter::BuildPortions( SwTextFormatInfo &rInf ) if (pAnchoredObj->RestartLayoutProcess() && !pAnchoredObj->IsTmpConsiderWrapInfluence()) { - SwFormatAnchor const& rAnchor(pAnchoredObj->GetFrameFormat().GetAnchor()); + SwFormatAnchor const& rAnchor(pAnchoredObj->GetFrameFormat()->GetAnchor()); assert(rAnchor.GetAnchorId() == RndStdIds::FLY_AT_CHAR || rAnchor.GetAnchorId() == RndStdIds::FLY_AT_PARA); TextFrameIndex const nAnchor(GetTextFrame()->MapModelToViewPos(*rAnchor.GetContentAnchor())); if (pFollow->GetOffset() <= nAnchor @@ -1009,6 +1009,8 @@ bool SwContentControlPortion::DescribePDFControl(const SwTextPaintInfo& rInf) co case SwContentControlType::PLAIN_TEXT: { pDescriptor = std::make_unique(); + auto pEditWidget = static_cast(pDescriptor.get()); + pEditWidget->MultiLine = true; break; } case SwContentControlType::CHECKBOX: @@ -1016,8 +1018,13 @@ bool SwContentControlPortion::DescribePDFControl(const SwTextPaintInfo& rInf) co pDescriptor = std::make_unique(); auto pCheckBoxWidget = static_cast(pDescriptor.get()); pCheckBoxWidget->Checked = pContentControl->GetChecked(); - pCheckBoxWidget->OnValue = pContentControl->GetCheckedState(); - pCheckBoxWidget->OffValue = pContentControl->GetUncheckedState(); + // If it's checked already, then leave the default "Yes" OnValue unchanged, so the + // appropriate appearance is found by PDF readers. + if (!pCheckBoxWidget->Checked) + { + pCheckBoxWidget->OnValue = pContentControl->GetCheckedState(); + pCheckBoxWidget->OffValue = pContentControl->GetUncheckedState(); + } break; } case SwContentControlType::DROP_DOWN_LIST: diff --git a/sw/source/core/text/porfld.cxx b/sw/source/core/text/porfld.cxx index 1a30a4ecd7..d2ae4be00d 100644 --- a/sw/source/core/text/porfld.cxx +++ b/sw/source/core/text/porfld.cxx @@ -402,10 +402,13 @@ bool SwFieldPortion::Format( SwTextFormatInfo &rInf ) // These characters should not be contained in the follow // field portion. They are handled via the HookChar mechanism. const sal_Unicode nNew = !aNew.isEmpty() ? aNew[0] : 0; - auto IsHook = [](const sal_Unicode cNew) -> bool + auto IsHook = [](const sal_Unicode cNew, bool const isSpace = false) -> bool { switch (cNew) { + case ' ': // tdf#159101 this one is not in ScanPortionEnd + // but is required for justified text + return isSpace; case CH_BREAK: case CH_TAB: case CHAR_HARDHYPHEN: // non-breaking hyphen @@ -422,7 +425,7 @@ bool SwFieldPortion::Format( SwTextFormatInfo &rInf ) return false; } }; - if (IsHook(nNew)) + if (IsHook(nNew, true)) { if (nNew == CH_BREAK) { @@ -599,9 +602,12 @@ bool SwNumberPortion::Format( SwTextFormatInfo &rInf ) if ( !mbLabelAlignmentPosAndSpaceModeActive ) { - if (!rInf.GetTextFrame()->GetDoc().getIDocumentSettingAccess().get(DocumentSettingId::IGNORE_FIRST_LINE_INDENT_IN_NUMBERING) && + if ((!rInf.GetTextFrame()->GetDoc().getIDocumentSettingAccess().get(DocumentSettingId::IGNORE_FIRST_LINE_INDENT_IN_NUMBERING) && // #i32902# - !IsFootnoteNumPortion() ) + !IsFootnoteNumPortion()) || + // tdf#159382 + (IsFootnoteNumPortion() && + rInf.GetTextFrame()->GetDoc().getIDocumentSettingAccess().get(DocumentSettingId::NO_GAP_AFTER_NOTE_NUMBER))) { nDiff = rInf.Left() + rInf.GetTextFrame()->GetTextNodeForParaProps()-> diff --git a/sw/source/core/text/porfly.cxx b/sw/source/core/text/porfly.cxx index 14d1bf6eaa..19ac692cf4 100644 --- a/sw/source/core/text/porfly.cxx +++ b/sw/source/core/text/porfly.cxx @@ -168,7 +168,7 @@ void SwTextFrame::MoveFlyInCnt(SwTextFrame *pNew, { // Consider changed type of entries SwAnchoredObject* pAnchoredObj = (*pObjs)[i]; - const SwFormatAnchor& rAnch = pAnchoredObj->GetFrameFormat().GetAnchor(); + const SwFormatAnchor& rAnch = pAnchoredObj->GetFrameFormat()->GetAnchor(); if (rAnch.GetAnchorId() == RndStdIds::FLY_AS_CHAR) { const SwPosition* pPos = rAnch.GetContentAnchor(); diff --git a/sw/source/core/text/porlay.cxx b/sw/source/core/text/porlay.cxx index cae54845be..2ba2fcf75f 100644 --- a/sw/source/core/text/porlay.cxx +++ b/sw/source/core/text/porlay.cxx @@ -748,7 +748,7 @@ void SwLineLayout::CalcLine( SwTextFormatter &rLine, SwTextFormatInfo &rInf ) { bool bDeleted = false; size_t nAuthor = std::string::npos; - const SwFormatAnchor& rAnchor = pAnchoredObj->GetFrameFormat().GetAnchor(); + const SwFormatAnchor& rAnchor = pAnchoredObj->GetFrameFormat()->GetAnchor(); if ( rAnchor.GetAnchorId() == RndStdIds::FLY_AT_CHAR ) { SwPosition aAnchor = *rAnchor.GetContentAnchor(); diff --git a/sw/source/core/text/porrst.cxx b/sw/source/core/text/porrst.cxx index 029adca753..a4a0d3c713 100644 --- a/sw/source/core/text/porrst.cxx +++ b/sw/source/core/text/porrst.cxx @@ -22,6 +22,7 @@ #include #include #include +#include #include #include @@ -47,6 +48,7 @@ #include #include #include +#include #include #include @@ -74,6 +76,16 @@ void SwTmpEndPortion::Paint( const SwTextPaintInfo &rInf ) const SwFont aFont(*pOldFnt); + const SwDoc& rDoc = rInf.GetTextFrame()->GetDoc(); + if (aFont.IsSymbol(rDoc.getIDocumentLayoutAccess().GetCurrentViewShell())) + { + const SvxFontItem& rFontItem = rDoc.GetDefault(RES_CHRATR_FONT); + aFont.SetName( rFontItem.GetFamilyName(), SwFontScript::Latin ); + aFont.SetStyleName( rFontItem.GetStyleName(), SwFontScript::Latin ); + aFont.SetFamily( rFontItem.GetFamily(), SwFontScript::Latin ); + aFont.SetPitch( rFontItem.GetPitch(), SwFontScript::Latin ); + aFont.SetCharSet( rFontItem.GetCharSet(), SwFontScript::Latin ); + } // Paint strikeout/underline based on redline color and settings // (with an extra pilcrow in the background, because there is // no SetStrikeoutColor(), also SetUnderColor() doesn't work()). diff --git a/sw/source/core/text/portxt.cxx b/sw/source/core/text/portxt.cxx index 85691ef21e..e58021ef09 100644 --- a/sw/source/core/text/portxt.cxx +++ b/sw/source/core/text/portxt.cxx @@ -325,14 +325,20 @@ bool SwTextPortion::Format_( SwTextFormatInfo &rInf ) // call with an extra space: shrinking can result a new word in the line // and a new space before that, which is also a shrank space - // (except if the line was already broken at a soft hyphen, i.e. inside a word) - if ( aGuess.BreakPos() < TextFrameIndex(rInf.GetText().getLength()) && + // (except if the line was already broken inside a word with hyphenation) + // TODO: handle the case, if the line contains extra amount of spaces + if ( + // no automatic hyphenation + !aGuess.HyphWord().is() && + // no hyphenation at soft hyphen + aGuess.BreakPos() < TextFrameIndex(rInf.GetText().getLength()) && rInf.GetText()[sal_Int32(aGuess.BreakPos())] != CHAR_SOFTHYPHEN ) { ++nSpacesInLine; } - bFull = !aGuess.Guess( *this, rInf, Height(), nSpacesInLine ); + if ( nSpacesInLine > 0 ) + bFull = !aGuess.Guess( *this, rInf, Height(), nSpacesInLine ); } // these are the possible cases: diff --git a/sw/source/core/text/txtfly.cxx b/sw/source/core/text/txtfly.cxx index ff5566f537..7c4d9a2e16 100644 --- a/sw/source/core/text/txtfly.cxx +++ b/sw/source/core/text/txtfly.cxx @@ -162,7 +162,7 @@ SwRect SwContourCache::CalcBoundRect( const SwAnchoredObject* pAnchoredObj, const bool bRight ) { SwRect aRet; - const SwFrameFormat* pFormat = &(pAnchoredObj->GetFrameFormat()); + const SwFrameFormat* pFormat = pAnchoredObj->GetFrameFormat(); bool bHandleContour(pFormat->GetSurround().IsContour()); if(!bHandleContour) @@ -594,7 +594,7 @@ void SwTextFly::DrawFlyRect( OutputDevice* pOut, const SwRect &rRect ) if (pFly) { // #i68520# - const SwFormatSurround& rSur = pAnchoredObjTmp->GetFrameFormat().GetSurround(); + const SwFormatSurround& rSur = pAnchoredObjTmp->GetFrameFormat()->GetSurround(); // OD 24.01.2003 #106593# - correct clipping of fly frame area. // Consider that fly frame background/shadow can be transparent @@ -655,8 +655,8 @@ bool SwTextFly::GetTop( const SwAnchoredObject* _pAnchoredObj, if( ( bInFootnote || bInFooterOrHeader ) && m_bTopRule ) { // #i26945# - const SwFrameFormat& rFrameFormat = _pAnchoredObj->GetFrameFormat(); - const SwFormatAnchor& rNewA = rFrameFormat.GetAnchor(); + const SwFrameFormat* pFrameFormat = _pAnchoredObj->GetFrameFormat(); + const SwFormatAnchor& rNewA = pFrameFormat->GetAnchor(); if (RndStdIds::FLY_AT_PAGE == rNewA.GetAnchorId()) { if ( bInFootnote ) @@ -664,7 +664,7 @@ bool SwTextFly::GetTop( const SwAnchoredObject* _pAnchoredObj, if ( bInFooterOrHeader ) { - const SwFormatVertOrient& aVert( rFrameFormat.GetVertOrient() ); + const SwFormatVertOrient& aVert(pFrameFormat->GetVertOrient()); bool bVertPrt = aVert.GetRelationOrient() == text::RelOrientation::PRINT_AREA || aVert.GetRelationOrient() == text::RelOrientation::PAGE_PRINT_AREA; if( bVertPrt ) @@ -710,13 +710,14 @@ bool SwTextFly::GetTop( const SwAnchoredObject* _pAnchoredObj, { // Within chained Flys we only avoid Lower // #i68520# - const SwFormatChain &rChain = mpCurrAnchoredObj->GetFrameFormat().GetChain(); + const SwFrameFormat* pCurObjFormat = mpCurrAnchoredObj->GetFrameFormat(); + const SwFormatChain& rChain = pCurObjFormat->GetChain(); if ( !rChain.GetPrev() && !rChain.GetNext() ) { // #i26945# - const SwFormatAnchor& rNewA = _pAnchoredObj->GetFrameFormat().GetAnchor(); + const SwFormatAnchor& rNewA = _pAnchoredObj->GetFrameFormat()->GetAnchor(); // #i68520# - const SwFormatAnchor& rCurrA = mpCurrAnchoredObj->GetFrameFormat().GetAnchor(); + const SwFormatAnchor& rCurrA = pCurObjFormat->GetAnchor(); // If is anchored as character, its content // does not wrap around pNew @@ -768,78 +769,85 @@ bool SwTextFly::GetTop( const SwAnchoredObject* _pAnchoredObj, if ( bEvade ) { // #i26945# - const SwFormatAnchor& rNewA = _pAnchoredObj->GetFrameFormat().GetAnchor(); - OSL_ENSURE( RndStdIds::FLY_AS_CHAR != rNewA.GetAnchorId(), - "Don't call GetTop with a FlyInContentFrame" ); - if (RndStdIds::FLY_AT_PAGE == rNewA.GetAnchorId()) - return true; // We always avoid page anchored ones - - // If Flys anchored at paragraph are caught in a FlyCnt, then - // their influence ends at the borders of the FlyCnt! - // If we are currently formatting the text of the FlyCnt, then - // it has to get out of the way of the Frame anchored at paragraph! - // m_pCurrFrame is the anchor of pNew? - // #i26945# - const SwFrame* pTmp = _pAnchoredObj->GetAnchorFrame(); - if (pTmp == m_pCurrFrame) - return true; - if( pTmp->IsTextFrame() && ( pTmp->IsInFly() || pTmp->IsInFootnote() ) ) + if (const SwFrameFormat* pAnchoredObjFormat = _pAnchoredObj->GetFrameFormat()) { + const SwFormatAnchor& rNewA = pAnchoredObjFormat->GetAnchor(); + OSL_ENSURE(RndStdIds::FLY_AS_CHAR != rNewA.GetAnchorId(), + "Don't call GetTop with a FlyInContentFrame"); + if (RndStdIds::FLY_AT_PAGE == rNewA.GetAnchorId()) + return true; // We always avoid page anchored ones + + // If Flys anchored at paragraph are caught in a FlyCnt, then + // their influence ends at the borders of the FlyCnt! + // If we are currently formatting the text of the FlyCnt, then + // it has to get out of the way of the Frame anchored at paragraph! + // m_pCurrFrame is the anchor of pNew? // #i26945# - Point aPos = _pAnchoredObj->GetObjRect().Pos(); - pTmp = GetVirtualUpper( pTmp, aPos ); - } - // #i26945# - // If is a text frame inside a table, take the upper - // of the anchor frame, which contains the anchor position. - else if ( pTmp->IsTextFrame() && pTmp->IsInTab() ) - { - pTmp = const_cast(_pAnchoredObj) - ->GetAnchorFrameContainingAnchPos()->GetUpper(); - } - // #i28701# - consider all objects in same context, - // if wrapping style is considered on object positioning. - // Thus, text will wrap around negative positioned objects. - // #i3317# - remove condition on checking, - // if wrappings style is considered on object positioning. - // Thus, text is wrapping around negative positioned objects. - // #i35640# - no consideration of negative - // positioned objects, if wrapping style isn't considered on - // object position and former text wrapping is applied. - // This condition is typically for documents imported from the - // OpenOffice.org file format. - const IDocumentSettingAccess* pIDSA = &m_pCurrFrame->GetDoc().getIDocumentSettingAccess(); - if ( ( pIDSA->get(DocumentSettingId::CONSIDER_WRAP_ON_OBJECT_POSITION) || - !pIDSA->get(DocumentSettingId::USE_FORMER_TEXT_WRAPPING) ) && - ::FindContext( pTmp, SwFrameType::None ) == ::FindContext(m_pCurrFrame, SwFrameType::None)) - { - return true; - } - - const SwFrame* pHeader = nullptr; - if (m_pCurrFrame->GetNext() != pTmp && - (IsFrameInSameContext( pTmp, m_pCurrFrame ) || - // #i13832#, #i24135# wrap around objects in page header - ( !pIDSA->get(DocumentSettingId::USE_FORMER_TEXT_WRAPPING) && - nullptr != ( pHeader = pTmp->FindFooterOrHeader() ) && - m_pCurrFrame->IsInDocBody()))) - { - if( pHeader || RndStdIds::FLY_AT_FLY == rNewA.GetAnchorId() ) + const SwFrame* pTmp = _pAnchoredObj->GetAnchorFrame(); + if (pTmp == m_pCurrFrame) return true; - - // Compare indices: - // The Index of the other is retrieved from the anchor attr. - SwNodeOffset nTmpIndex = rNewA.GetAnchorNode()->GetIndex(); - // Now check whether the current paragraph is before the anchor - // of the displaced object in the text, then we don't have to - // get out of its way. - // If possible determine Index via SwFormatAnchor because - // otherwise it's quite expensive. - if (NODE_OFFSET_MAX == m_nCurrFrameNodeIndex) - m_nCurrFrameNodeIndex = m_pCurrFrame->GetTextNodeFirst()->GetIndex(); - - if (FrameContainsNode(*m_pCurrFrame, nTmpIndex) || nTmpIndex < m_nCurrFrameNodeIndex) + if (pTmp->IsTextFrame() && (pTmp->IsInFly() || pTmp->IsInFootnote())) + { + // #i26945# + Point aPos = _pAnchoredObj->GetObjRect().Pos(); + pTmp = GetVirtualUpper(pTmp, aPos); + } + // #i26945# + // If is a text frame inside a table, take the upper + // of the anchor frame, which contains the anchor position. + else if (pTmp->IsTextFrame() && pTmp->IsInTab()) + { + pTmp = const_cast(_pAnchoredObj) + ->GetAnchorFrameContainingAnchPos() + ->GetUpper(); + } + // #i28701# - consider all objects in same context, + // if wrapping style is considered on object positioning. + // Thus, text will wrap around negative positioned objects. + // #i3317# - remove condition on checking, + // if wrappings style is considered on object positioning. + // Thus, text is wrapping around negative positioned objects. + // #i35640# - no consideration of negative + // positioned objects, if wrapping style isn't considered on + // object position and former text wrapping is applied. + // This condition is typically for documents imported from the + // OpenOffice.org file format. + const IDocumentSettingAccess* pIDSA + = &m_pCurrFrame->GetDoc().getIDocumentSettingAccess(); + if ((pIDSA->get(DocumentSettingId::CONSIDER_WRAP_ON_OBJECT_POSITION) + || !pIDSA->get(DocumentSettingId::USE_FORMER_TEXT_WRAPPING)) + && ::FindContext(pTmp, SwFrameType::None) + == ::FindContext(m_pCurrFrame, SwFrameType::None)) + { return true; + } + + const SwFrame* pHeader = nullptr; + if (m_pCurrFrame->GetNext() != pTmp + && (IsFrameInSameContext(pTmp, m_pCurrFrame) || + // #i13832#, #i24135# wrap around objects in page header + (!pIDSA->get(DocumentSettingId::USE_FORMER_TEXT_WRAPPING) + && nullptr != (pHeader = pTmp->FindFooterOrHeader()) + && m_pCurrFrame->IsInDocBody()))) + { + if (pHeader || RndStdIds::FLY_AT_FLY == rNewA.GetAnchorId()) + return true; + + // Compare indices: + // The Index of the other is retrieved from the anchor attr. + SwNodeOffset nTmpIndex = rNewA.GetAnchorNode()->GetIndex(); + // Now check whether the current paragraph is before the anchor + // of the displaced object in the text, then we don't have to + // get out of its way. + // If possible determine Index via SwFormatAnchor because + // otherwise it's quite expensive. + if (NODE_OFFSET_MAX == m_nCurrFrameNodeIndex) + m_nCurrFrameNodeIndex = m_pCurrFrame->GetTextNodeFirst()->GetIndex(); + + if (FrameContainsNode(*m_pCurrFrame, nTmpIndex) + || nTmpIndex < m_nCurrFrameNodeIndex) + return true; + } } } } @@ -919,7 +927,7 @@ SwAnchoredObjList& SwTextFly::InitAnchoredObjList() !pAnchoredObj->ConsiderForTextWrap() || ( mbIgnoreObjsInHeaderFooter && !bFooterHeader && pAnchoredObj->GetAnchorFrame()->FindFooterOrHeader() ) || - ( bAllowCompatWrap && !pAnchoredObj->GetFrameFormat().GetFollowTextFlow().GetValue() ) + ( bAllowCompatWrap && !pAnchoredObj->GetFrameFormat()->GetFollowTextFlow().GetValue() ) ) { continue; @@ -957,13 +965,13 @@ SwAnchoredObjList& SwTextFly::InitAnchoredObjList() mpAnchoredObjList->insert( aInsPosIter, pAnchoredObj ); } - const SwFormatSurround &rFlyFormat = pAnchoredObj->GetFrameFormat().GetSurround(); + const SwFrameFormat* pObjFormat = pAnchoredObj->GetFrameFormat(); + const SwFormatSurround& rFlyFormat = pObjFormat->GetSurround(); // #i68520# if ( rFlyFormat.IsAnchorOnly() && pAnchoredObj->GetAnchorFrame() == GetMaster() ) { - const SwFormatVertOrient &rTmpFormat = - pAnchoredObj->GetFrameFormat().GetVertOrient(); + const SwFormatVertOrient &rTmpFormat = pObjFormat->GetVertOrient(); if( text::VertOrientation::BOTTOM != rTmpFormat.GetVertOrient() ) m_nMinBottom = ( aRectFnSet.IsVert() && m_nMinBottom ) ? std::min( m_nMinBottom, aBound.Left() ) : @@ -998,11 +1006,11 @@ SwTwips SwTextFly::CalcMinBottom() const for( size_t i = 0; i < nCount; ++i ) { SwAnchoredObject* pAnchoredObj = (*pDrawObj)[ i ]; - const SwFormatSurround &rFlyFormat = pAnchoredObj->GetFrameFormat().GetSurround(); + const SwFrameFormat* pObjFormat = pAnchoredObj->GetFrameFormat(); + const SwFormatSurround& rFlyFormat = pObjFormat->GetSurround(); if( rFlyFormat.IsAnchorOnly() ) { - const SwFormatVertOrient &rTmpFormat = - pAnchoredObj->GetFrameFormat().GetVertOrient(); + const SwFormatVertOrient &rTmpFormat = pObjFormat->GetVertOrient(); if( text::VertOrientation::BOTTOM != rTmpFormat.GetVertOrient() ) { const SwRect& aBound( pAnchoredObj->GetObjRectWithSpaces() ); @@ -1118,7 +1126,7 @@ bool SwTextFly::ForEach( const SwRect &rRect, SwRect* pRect, bool bAvoid ) const if ( mpCurrAnchoredObj != pAnchoredObj && aRect.Overlaps( rRect ) ) { // #i68520# - const SwFormat* pFormat( &(pAnchoredObj->GetFrameFormat()) ); + const SwFormat* pFormat(pAnchoredObj->GetFrameFormat()); const SwFormatSurround &rSur = pFormat->GetSurround(); if( bAvoid ) { @@ -1405,7 +1413,7 @@ SwRect SwTextFly::AnchoredObjToRect( const SwAnchoredObject* pAnchoredObj, css::text::WrapTextMode SwTextFly::GetSurroundForTextWrap( const SwAnchoredObject* pAnchoredObj ) const { - const SwFrameFormat* pFormat = &(pAnchoredObj->GetFrameFormat()); + const SwFrameFormat* pFormat = pAnchoredObj->GetFrameFormat(); const SwFormatSurround &rFlyFormat = pFormat->GetSurround(); css::text::WrapTextMode eSurroundForTextWrap = rFlyFormat.GetSurround(); diff --git a/sw/source/core/text/txtfrm.cxx b/sw/source/core/text/txtfrm.cxx index 18eb78db83..302302a9a2 100644 --- a/sw/source/core/text/txtfrm.cxx +++ b/sw/source/core/text/txtfrm.cxx @@ -1459,11 +1459,11 @@ SwDoc const& SwTextFrame::GetDoc() const } LanguageType SwTextFrame::GetLangOfChar(TextFrameIndex const nIndex, - sal_uInt16 const nScript, bool const bNoChar) const + sal_uInt16 const nScript, bool const bNoChar, bool const bNoneIfNoHyphenation) const { // a single character can be mapped uniquely! std::pair const pos(MapViewToModel(nIndex)); - return pos.first->GetLang(pos.second, bNoChar ? 0 : 1, nScript); + return pos.first->GetLang(pos.second, bNoChar ? 0 : 1, nScript, bNoneIfNoHyphenation); } void SwTextFrame::ResetPreps() @@ -3104,7 +3104,7 @@ bool SwTextFrame::Prepare( const PrepareHint ePrep, const void* pVoid, SwAnchoredObject* pAnchoredObj = (*GetDrawObjs())[i]; // i#28701 - consider all // to-character anchored objects - if ( pAnchoredObj->GetFrameFormat().GetAnchor().GetAnchorId() + if ( pAnchoredObj->GetFrameFormat()->GetAnchor().GetAnchorId() == RndStdIds::FLY_AT_CHAR ) { bFormat = true; diff --git a/sw/source/core/txtnode/ndtxt.cxx b/sw/source/core/txtnode/ndtxt.cxx index 47bff5e08b..77dbe2e029 100644 --- a/sw/source/core/txtnode/ndtxt.cxx +++ b/sw/source/core/txtnode/ndtxt.cxx @@ -412,12 +412,12 @@ void MoveMergedFlysAndFootnotes(std::vector const& rFrames, } for (SwAnchoredObject *const pObj : objs) { - SwFrameFormat & rFormat(pObj->GetFrameFormat()); - SwFormatAnchor const& rAnchor(rFormat.GetAnchor()); + SwFrameFormat* pFormat(pObj->GetFrameFormat()); + SwFormatAnchor const& rAnchor(pFormat->GetAnchor()); if (rFirstNode.GetIndex() < rAnchor.GetAnchorNode()->GetIndex()) { // move it to the new frame of "this" - rFormat.CallSwClientNotify(sw::LegacyModifyHint(&rAnchor, &rAnchor)); + pFormat->CallSwClientNotify(sw::LegacyModifyHint(&rAnchor, &rAnchor)); // note pObjs will be deleted if it becomes empty assert(!pFrame->GetDrawObjs() || !pObjs->Contains(*pObj)); } diff --git a/sw/source/core/txtnode/thints.cxx b/sw/source/core/txtnode/thints.cxx index 0556facafe..cf5e1ff1cc 100644 --- a/sw/source/core/txtnode/thints.cxx +++ b/sw/source/core/txtnode/thints.cxx @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -3487,7 +3488,7 @@ void SwTextNode::ClearSwpHintsArr( bool bDelFields ) } LanguageType SwTextNode::GetLang( const sal_Int32 nBegin, const sal_Int32 nLen, - sal_uInt16 nScript ) const + sal_uInt16 nScript, bool const bNoneIfNoHyphenation ) const { LanguageType nRet = LANGUAGE_DONTKNOW; @@ -3497,7 +3498,9 @@ LanguageType SwTextNode::GetLang( const sal_Int32 nBegin, const sal_Int32 nLen, } // #i91465# Consider nScript if pSwpHints == 0 - const TypedWhichId nWhichId = GetWhichOfScript( RES_CHRATR_LANGUAGE, nScript ); + const sal_uInt16 nWhichId = bNoneIfNoHyphenation + ? RES_CHRATR_NOHYPHEN + : GetWhichOfScript( RES_CHRATR_LANGUAGE, nScript ); if ( HasHints() ) { @@ -3531,8 +3534,18 @@ LanguageType SwTextNode::GetLang( const sal_Int32 nBegin, const sal_Int32 nLen, if( pHt->DontExpand() ? nBegin >= *pEndIdx : nBegin > *pEndIdx) continue; } - const SvxLanguageItem* pItem = CharFormat::GetItem( *pHt, nWhichId ); - const LanguageType nLng = pItem->GetLanguage(); + const SfxPoolItem* pItem = CharFormat::GetItem( *pHt, nWhichId ); + + if ( RES_CHRATR_NOHYPHEN == nWhichId ) + { + // bNoneIfNoHyphenation = true: return with LANGUAGE_NONE, + // if the hyphenation is disabled by character formatting + if ( static_cast(pItem)->GetValue() ) + return LANGUAGE_NONE; + continue; + } + + const LanguageType nLng = static_cast(pItem)->GetLanguage(); // does the attribute completely cover the range? if( nAttrStart <= nBegin && nEnd <= *pEndIdx ) @@ -3542,9 +3555,9 @@ LanguageType SwTextNode::GetLang( const sal_Int32 nBegin, const sal_Int32 nLen, } } } - if( LANGUAGE_DONTKNOW == nRet ) + if( LANGUAGE_DONTKNOW == nRet && !bNoneIfNoHyphenation ) { - nRet = GetSwAttrSet().Get( nWhichId ).GetLanguage(); + nRet = static_cast(GetSwAttrSet().Get( nWhichId )).GetLanguage(); if( LANGUAGE_DONTKNOW == nRet ) nRet = GetAppLanguage(); } diff --git a/sw/source/core/undo/undel.cxx b/sw/source/core/undo/undel.cxx index 4c199c8ac3..7661b59517 100644 --- a/sw/source/core/undo/undel.cxx +++ b/sw/source/core/undo/undel.cxx @@ -1152,14 +1152,25 @@ void SwUndoDelete::UndoImpl(::sw::UndoRedoContext & rContext) SwNode& start(*rDoc.GetNodes()[m_nSttNode + ((m_bDelFullPara || !rDoc.GetNodes()[m_nSttNode]->IsTextNode() || pInsNd) ? 0 : 1)]); - // don't include end node in the range: it may have been merged already - // by the start node, or it may be merged by one of the moved nodes, - // but if it isn't merged, its current frame(s) should be good... - SwNode& end(*rDoc.GetNodes()[ m_bDelFullPara - ? delFullParaEndNode - // tdf#147310 SwDoc::DeleteRowCol() may delete whole table - end must be node following table! - : (m_nEndNode + (rDoc.GetNodes()[m_nSttNode]->IsTableNode() && rDoc.GetNodes()[m_nEndNode]->IsEndNode() ? 1 : 0))]); - ::MakeFrames(&rDoc, start, end); + // tdf#158740 fix crash by checking the end node's index + // I don't know why m_nEndNode is larger than the size of the node + // array, but adjusting m_nEndNode to the last element in the node + // array stops the crashing. + SwNodeOffset nCount(rDoc.GetNodes().Count()); + if (nCount > SwNodeOffset(0)) + { + if (m_nEndNode > nCount - 1) + m_nEndNode = nCount - 1; + + // don't include end node in the range: it may have been merged already + // by the start node, or it may be merged by one of the moved nodes, + // but if it isn't merged, its current frame(s) should be good... + SwNode& end(*rDoc.GetNodes()[ m_bDelFullPara + ? delFullParaEndNode + // tdf#147310 SwDoc::DeleteRowCol() may delete whole table - end must be node following table! + : (m_nEndNode + (rDoc.GetNodes()[m_nSttNode]->IsTableNode() && rDoc.GetNodes()[m_nEndNode]->IsEndNode() ? 1 : 0))]); + ::MakeFrames(&rDoc, start, end); + } } if (pMovedNode) diff --git a/sw/source/core/unocore/unofield.cxx b/sw/source/core/unocore/unofield.cxx index d73c0b59b3..b3452890e0 100644 --- a/sw/source/core/unocore/unofield.cxx +++ b/sw/source/core/unocore/unofield.cxx @@ -1238,20 +1238,34 @@ SwServiceType SwXTextField::GetServiceId() const it has to be disconnected first and at the end connected to the new instance! */ -void SwXTextField::TransmuteLeadToInputField(SwSetExpField & rField) -{ - assert(rField.GetFormatField()->Which() == (rField.GetInputFlag() ? RES_TXTATR_INPUTFIELD : RES_TXTATR_FIELD)); +void SwXTextField::TransmuteLeadToInputField(SwSetExpField & rField, + sal_uInt16 const*const pSubType) +{ +#ifndef NDEBUG + auto const oldWhich( + (pSubType ? (rField.GetSubType() & nsSwGetSetExpType::GSE_STRING) != 0 : rField.GetInputFlag()) + ? RES_TXTATR_INPUTFIELD : RES_TXTATR_FIELD); + auto const newWhich(oldWhich == RES_TXTATR_FIELD ? RES_TXTATR_INPUTFIELD : RES_TXTATR_FIELD); +#endif + assert(rField.GetFormatField()->Which() == oldWhich); rtl::Reference const pXField( rField.GetFormatField()->GetXTextField()); if (pXField) pXField->m_pImpl->SetFormatField(nullptr, nullptr); SwTextField *const pOldAttr(rField.GetFormatField()->GetTextField()); SwSetExpField tempField(rField); - tempField.SetInputFlag(!rField.GetInputFlag()); + if (pSubType) + { + tempField.SetSubType(*pSubType); + } + else + { + tempField.SetInputFlag(!rField.GetInputFlag()); + } SwFormatField tempFormat(tempField); assert(tempFormat.GetField() != &rField); assert(tempFormat.GetField() != &tempField); // this copies it again? - assert(tempFormat.Which() == (static_cast(tempFormat.GetField())->GetInputFlag() ? RES_TXTATR_INPUTFIELD : RES_TXTATR_FIELD)); + assert(tempFormat.Which() == newWhich); SwTextNode & rNode(pOldAttr->GetTextNode()); std::shared_ptr pPamForTextField; IDocumentContentOperations & rIDCO(rNode.GetDoc().getIDocumentContentOperations()); @@ -1266,8 +1280,10 @@ void SwXTextField::TransmuteLeadToInputField(SwSetExpField & rField) SwTextField const* pNewAttr(rNode.GetFieldTextAttrAt(nStart, ::sw::GetTextAttrMode::Default)); assert(pNewAttr); SwFormatField const& rNewFormat(pNewAttr->GetFormatField()); - assert(rNewFormat.Which() == (static_cast(rNewFormat.GetField())->GetInputFlag() ? RES_TXTATR_INPUTFIELD : RES_TXTATR_FIELD)); - assert(static_cast(rNewFormat.GetField())->GetInputFlag() == (dynamic_cast(pNewAttr) != nullptr)); + assert(rNewFormat.Which() == newWhich); + assert((dynamic_cast(pNewAttr) != nullptr) + == ((static_cast(rNewFormat.GetField())->GetSubType() & nsSwGetSetExpType::GSE_STRING) + && static_cast(rNewFormat.GetField())->GetInputFlag())); if (pXField) { pXField->m_pImpl->SetFormatField(const_cast(&rNewFormat), &rNode.GetDoc()); diff --git a/sw/source/core/unocore/unomap1.cxx b/sw/source/core/unocore/unomap1.cxx index ee4422a22e..12db464a87 100644 --- a/sw/source/core/unocore/unomap1.cxx +++ b/sw/source/core/unocore/unomap1.cxx @@ -537,6 +537,7 @@ std::span SwUnoPropertyMapProvider::GetPageStyleP { UNO_NAME_NUMBERING_TYPE, SID_ATTR_PAGE, cppu::UnoType::get(), PROPERTY_NONE , MID_PAGE_NUMTYPE }, { UNO_NAME_PAGE_STYLE_LAYOUT, SID_ATTR_PAGE, cppu::UnoType::get(), PROPERTY_NONE ,MID_PAGE_LAYOUT }, { UNO_NAME_PRINTER_PAPER_TRAY, RES_PAPER_BIN, cppu::UnoType::get(), PROPERTY_NONE , 0 }, + { UNO_NAME_PRINTER_PAPER_TRAY_INDEX, RES_PAPER_BIN, cppu::UnoType::get(), PROPERTY_NONE , 0 }, // { UNO_NAME_REGISTER_MODE_ACTIVE, SID_SWREGISTER_MODE, cppu::UnoType::get(), PROPERTY_NONE , 0 }, { UNO_NAME_REGISTER_PARAGRAPH_STYLE, SID_SWREGISTER_COLLECTION, cppu::UnoType::get(), PROPERTY_NONE , 0 }, { UNO_NAME_SIZE, SID_ATTR_PAGE_SIZE, cppu::UnoType::get(), PROPERTY_NONE, MID_SIZE_SIZE|CONVERT_TWIPS}, diff --git a/sw/source/core/unocore/unoobj2.cxx b/sw/source/core/unocore/unoobj2.cxx index 7614f0a314..5cb73bf7b8 100644 --- a/sw/source/core/unocore/unoobj2.cxx +++ b/sw/source/core/unocore/unoobj2.cxx @@ -121,9 +121,9 @@ struct FrameClientSortListLess return; for(const auto pAnchoredObj : *pObjs) { - SwFrameFormat& rFormat = pAnchoredObj->GetFrameFormat(); + SwFrameFormat* pFormat = pAnchoredObj->GetFrameFormat(); // Filter out textboxes, which are not interesting at a UNO level. - if(SwTextBoxHelper::isTextBox(&rFormat, RES_FLYFRMFMT)) + if(SwTextBoxHelper::isTextBox(pFormat, RES_FLYFRMFMT)) continue; if (nAnchorType == RndStdIds::FLY_AT_PARA) @@ -137,11 +137,11 @@ struct FrameClientSortListLess } } - if(rFormat.GetAnchor().GetAnchorId() == nAnchorType) + if(pFormat->GetAnchor().GetAnchorId() == nAnchorType) { - const sal_Int32 nIdx = rFormat.GetAnchor().GetAnchorContentOffset(); - const auto nOrder = rFormat.GetAnchor().GetOrder(); - rFrames.emplace_back(nIdx, nOrder, std::make_unique(&rFormat)); + const sal_Int32 nIdx = pFormat->GetAnchor().GetAnchorContentOffset(); + const auto nOrder = pFormat->GetAnchor().GetOrder(); + rFrames.emplace_back(nIdx, nOrder, std::make_unique(pFormat)); } } } diff --git a/sw/source/core/unocore/unoportenum.cxx b/sw/source/core/unocore/unoportenum.cxx index 4b50a72cf5..186b5c5b23 100644 --- a/sw/source/core/unocore/unoportenum.cxx +++ b/sw/source/core/unocore/unoportenum.cxx @@ -133,12 +133,18 @@ namespace void lcl_FillBookmark(sw::mark::IMark* const pBkmk, const SwNode& rOwnNode, SwDoc& rDoc, SwXBookmarkPortion_ImplList& rBkmArr) { bool const hasOther = pBkmk->IsExpanded(); - const SwPosition& rStartPos = pBkmk->GetMarkStart(); - if(rStartPos.GetNode() == rOwnNode) + const SwPosition& rEndPos = pBkmk->GetMarkEnd(); + bool const bStartPosInNode = rStartPos.GetNode() == rOwnNode; + bool const bEndPosInNode = rEndPos.GetNode() == rOwnNode; + sw::mark::CrossRefBookmark* const pCrossRefMark + = !hasOther && (bStartPosInNode || bEndPosInNode) + ? dynamic_cast(pBkmk) + : nullptr; + + if (bStartPosInNode) { // #i109272#: cross reference marks: need special handling! - ::sw::mark::CrossRefBookmark *const pCrossRefMark(dynamic_cast< ::sw::mark::CrossRefBookmark*>(pBkmk)); BkmType const nType = (hasOther || pCrossRefMark) ? BkmType::Start : BkmType::StartEnd; rBkmArr.insert(std::make_shared( @@ -146,13 +152,11 @@ namespace nType, rStartPos)); } - const SwPosition& rEndPos = pBkmk->GetMarkEnd(); - if(rEndPos.GetNode() != rOwnNode) + if (!bEndPosInNode) return; std::optional oCrossRefEndPos; const SwPosition* pEndPos = nullptr; - ::sw::mark::CrossRefBookmark *const pCrossRefMark(dynamic_cast< ::sw::mark::CrossRefBookmark*>(pBkmk)); if(hasOther) { pEndPos = &rEndPos; diff --git a/sw/source/core/unocore/unostyle.cxx b/sw/source/core/unocore/unostyle.cxx index 94219281b5..665c1d2c6a 100644 --- a/sw/source/core/unocore/unostyle.cxx +++ b/sw/source/core/unocore/unostyle.cxx @@ -1669,27 +1669,37 @@ void SwXStyle::SetPropertyValue(const SfxItemPropertyMapE template<> void SwXStyle::SetPropertyValue(const SfxItemPropertyMapEntry& rEntry, const SfxItemPropertySet& rPropSet, const uno::Any& rValue, SwStyleBase_Impl& o_rStyleBase) { - if(!rValue.has()) + if (!rValue.has() && !rValue.has()) throw lang::IllegalArgumentException(); SfxPrinter* pPrinter = m_pDoc->getIDocumentDeviceAccess().getPrinter(true); - OUString sValue(rValue.get()); using printeridx_t = decltype(pPrinter->GetPaperBinCount()); printeridx_t nBin = std::numeric_limits::max(); - if(sValue == "[From printer settings]") - nBin = std::numeric_limits::max()-1; - else if(pPrinter) + if(rValue.has()) { - for(sal_uInt16 i=0, nEnd = pPrinter->GetPaperBinCount(); i < nEnd; ++i) + OUString sValue(rValue.get()); + if(sValue == "[From printer settings]") + nBin = std::numeric_limits::max()-1; + else if(pPrinter) { - if (sValue == pPrinter->GetPaperBinName(i)) + for(printeridx_t i=0, nEnd = pPrinter->GetPaperBinCount(); i < nEnd; ++i) { - nBin = i; - break; + if (sValue == pPrinter->GetPaperBinName(i)) + { + nBin = i; + break; + } } } } + else if (rValue.has() && pPrinter) + { + sal_Int32 nValue (rValue.get()); + nBin = pPrinter->GetPaperBinBySourceIndex(nValue); + } + if(nBin == std::numeric_limits::max()) throw lang::IllegalArgumentException(); + SfxItemSet& rStyleSet = o_rStyleBase.GetItemSet(); SfxItemSet aSet(*rStyleSet.GetPool(), rEntry.nWID, rEntry.nWID); aSet.SetParent(&rStyleSet); diff --git a/sw/source/filter/writer/writer.cxx b/sw/source/filter/writer/writer.cxx index 1671f27e0b..f59531764e 100644 --- a/sw/source/filter/writer/writer.cxx +++ b/sw/source/filter/writer/writer.cxx @@ -160,9 +160,9 @@ bool Writer::CopyNextPam( SwPaM ** ppPam ) sal_Int32 Writer::FindPos_Bkmk(const SwPosition& rPos) const { const IDocumentMarkAccess* const pMarkAccess = m_pDoc->getIDocumentMarkAccess(); - const IDocumentMarkAccess::const_iterator_t ppBkmk = pMarkAccess->findFirstBookmarkStartsAfter(rPos); - if(ppBkmk != pMarkAccess->getBookmarksEnd()) - return ppBkmk - pMarkAccess->getBookmarksBegin(); + const IDocumentMarkAccess::const_iterator_t ppBkmk = pMarkAccess->findFirstMarkNotStartsBefore(rPos); + if(ppBkmk != pMarkAccess->getAllMarksEnd()) + return ppBkmk - pMarkAccess->getAllMarksBegin(); return -1; } diff --git a/sw/source/filter/ww8/docxsdrexport.cxx b/sw/source/filter/ww8/docxsdrexport.cxx index 0c42d28fc6..5c746f6afe 100644 --- a/sw/source/filter/ww8/docxsdrexport.cxx +++ b/sw/source/filter/ww8/docxsdrexport.cxx @@ -939,6 +939,11 @@ void DocxSdrExport::startDMLAnchorInline(const SwFrameFormat* pFrameFormat, cons relativeFromV = "paragraph"; break; case text::RelOrientation::TEXT_LINE: + relativeFromV = "line"; + // Word's "line" is "below the bottom of the line", our TEXT_LINE is + // "towards top, from the bottom of the line", so invert the vertical position. + aPos.Y *= -1; + break; default: relativeFromV = "line"; break; diff --git a/sw/source/filter/ww8/wrtww8.cxx b/sw/source/filter/ww8/wrtww8.cxx index 38fbfb2166..74e9d27c09 100644 --- a/sw/source/filter/ww8/wrtww8.cxx +++ b/sw/source/filter/ww8/wrtww8.cxx @@ -3517,8 +3517,10 @@ bool SwWW8Writer::InitStd97CodecUpdateMedium( ::msfilter::MSCodec_Std97& rCodec // Generate random number with a seed of time as salt. rtlRandomPool aRandomPool = rtl_random_createPool (); sal_uInt8 pDocId[ 16 ]; - rtl_random_getBytes( aRandomPool, pDocId, 16 ); - + if (rtl_random_getBytes(aRandomPool, pDocId, 16) != rtl_Random_E_None) + { + throw uno::RuntimeException("rtl_random_getBytes failed"); + } rtl_random_destroyPool( aRandomPool ); sal_uInt16 aPassword[16] = {}; diff --git a/sw/source/filter/ww8/ww8par.cxx b/sw/source/filter/ww8/ww8par.cxx index 9418fa0646..10ccaa4878 100644 --- a/sw/source/filter/ww8/ww8par.cxx +++ b/sw/source/filter/ww8/ww8par.cxx @@ -1912,6 +1912,7 @@ void SwWW8ImplReader::ImportDop() m_rDoc.getIDocumentSettingAccess().set(DocumentSettingId::ADD_EXT_LEADING, !m_xWDop->fNoLeading); m_rDoc.getIDocumentSettingAccess().set(DocumentSettingId::OLD_NUMBERING, false); m_rDoc.getIDocumentSettingAccess().set(DocumentSettingId::IGNORE_FIRST_LINE_INDENT_IN_NUMBERING, false); // #i47448# + m_rDoc.getIDocumentSettingAccess().set(DocumentSettingId::NO_GAP_AFTER_NOTE_NUMBER, true); // tdf#159382 m_rDoc.getIDocumentSettingAccess().set(DocumentSettingId::DO_NOT_JUSTIFY_LINES_WITH_MANUAL_BREAK, !m_xWDop->fExpShRtn); // #i49277#, #i56856# m_rDoc.getIDocumentSettingAccess().set(DocumentSettingId::DO_NOT_RESET_PARA_ATTRS_FOR_NUM_FONT, false); // #i53199# m_rDoc.getIDocumentSettingAccess().set(DocumentSettingId::OLD_LINE_SPACING, false); @@ -5663,8 +5664,10 @@ namespace rtlRandomPool aRandomPool = rtl_random_createPool(); sal_uInt8 pDocId[ 16 ]; - rtl_random_getBytes( aRandomPool, pDocId, 16 ); - + if (rtl_random_getBytes(aRandomPool, pDocId, 16) != rtl_Random_E_None) + { + throw uno::RuntimeException("rtl_random_getBytes failed"); + } rtl_random_destroyPool( aRandomPool ); sal_uInt16 pStd97Pass[16] = {}; diff --git a/sw/source/ui/fldui/flddok.cxx b/sw/source/ui/fldui/flddok.cxx index 1a2857bedb..5cb38a38ac 100644 --- a/sw/source/ui/fldui/flddok.cxx +++ b/sw/source/ui/fldui/flddok.cxx @@ -601,7 +601,7 @@ bool SwFieldDokPage::FillItemSet(SfxItemSet* ) } case SwFieldTypesEnum::Chapter: - aVal = OUString::number(m_xLevelED->get_active()); + aVal = m_xLevelED->get_active_text(); break; default: diff --git a/sw/source/uibase/dialog/SwSpellDialogChildWindow.cxx b/sw/source/uibase/dialog/SwSpellDialogChildWindow.cxx index 5af09a6adf..869a0fba00 100644 --- a/sw/source/uibase/dialog/SwSpellDialogChildWindow.cxx +++ b/sw/source/uibase/dialog/SwSpellDialogChildWindow.cxx @@ -821,6 +821,11 @@ bool SwSpellDialogChildWindow::SpellDrawText_Impl(SwWrtShell& rSh, svx::SpellPor void SwSpellDialogChildWindow::LockFocusNotification(bool bLock) { + if (!m_pSpellState) + { + return; + } + OSL_ENSURE(m_pSpellState->m_bLockFocus != bLock, "invalid locking - no change of state"); m_pSpellState->m_bLockFocus = bLock; } diff --git a/sw/source/uibase/docvw/edtwin.cxx b/sw/source/uibase/docvw/edtwin.cxx index 322928eb4e..073b6b5964 100644 --- a/sw/source/uibase/docvw/edtwin.cxx +++ b/sw/source/uibase/docvw/edtwin.cxx @@ -896,6 +896,25 @@ void SwEditWin::FlushInBuffer() return; SwWrtShell& rSh = m_rView.GetWrtShell(); + uno::Reference xRecorder + = m_rView.GetViewFrame().GetBindings().GetRecorder(); + + comphelper::ScopeGuard showTooltipGuard( + [this, &rSh] + { + SvxAutoCorrCfg& rACfg = SvxAutoCorrCfg::Get(); + const bool bAutoTextShown + = rACfg.IsAutoTextTip() && ShowAutoText(rSh.GetChunkForAutoText()); + if (!bAutoTextShown) + { + SvxAutoCorrect* pACorr = rACfg.GetAutoCorrect(); + if (pACorr && pACorr->GetSwFlags().bAutoCompleteWords) + ShowAutoCorrectQuickHelp(rSh.GetPrevAutoCorrWord(*pACorr), *pACorr); + } + }); + if (!m_bMaybeShowTooltipAfterBufferFlush || xRecorder) + showTooltipGuard.dismiss(); + m_bMaybeShowTooltipAfterBufferFlush = false; // generate new sequence input checker if not already done if ( !pCheckIt ) @@ -993,8 +1012,6 @@ void SwEditWin::FlushInBuffer() } } - uno::Reference< frame::XDispatchRecorder > xRecorder = - m_rView.GetViewFrame().GetBindings().GetRecorder(); if ( xRecorder.is() ) { // determine shell @@ -1381,6 +1398,9 @@ void SwEditWin::KeyInput(const KeyEvent &rKEvt) } } + // Do not show autotext / word completion tooltips in intermediate flushes + m_bMaybeShowTooltipAfterBufferFlush = false; + sal_uInt16 nKey = rKEvt.GetKeyCode().GetCode(); if (nKey == KEY_ESCAPE) @@ -2821,19 +2841,12 @@ KEYINPUT_CHECKTABLE_INSDEL: if( KEY_UP == nKey || KEY_DOWN == nKey || KEY_PAGEUP == nKey || KEY_PAGEDOWN == nKey ) GetView().GetViewFrame().GetBindings().Update( FN_STAT_PAGE ); + m_bMaybeShowTooltipAfterBufferFlush = bNormalChar; + // in case the buffered characters are inserted if( bFlushBuffer && !m_aInBuffer.isEmpty() ) { FlushInBuffer(); - - // maybe show Tip-Help - if (bNormalChar) - { - const bool bAutoTextShown - = pACfg && pACfg->IsAutoTextTip() && ShowAutoText(rSh.GetChunkForAutoText()); - if (!bAutoTextShown && pACorr && pACorr->GetSwFlags().bAutoCompleteWords) - ShowAutoCorrectQuickHelp(rSh.GetPrevAutoCorrWord(*pACorr), *pACorr); - } } // get the word count dialog to update itself @@ -4662,19 +4675,23 @@ void SwEditWin::MouseButtonUp(const MouseEvent& rMEvt) SdrObject* pObj = pSdrView ? pSdrView->PickObj(aDocPos, pSdrView->getHitTolLog(), pPV, SdrSearchOptions::ALSOONMASTER) : nullptr; if (pObj) { - SwFrameFormat* pFormat = GetUserCall(pObj)->GetFormat(); - SwFrameFormat* pShapeFormat = SwTextBoxHelper::getOtherTextBoxFormat(pFormat, RES_FLYFRMFMT); - if (!pShapeFormat) - { - pSdrView->UnmarkAllObj(); - pSdrView->MarkObj(pObj,pPV); - } - else + if (SwDrawContact* pContact = static_cast(GetUserCall(pObj))) { - // If the fly frame is a textbox of a shape, then select the shape instead. - SdrObject* pShape = pShapeFormat->FindSdrObject(); - pSdrView->UnmarkAllObj(); - pSdrView->MarkObj(pShape, pPV); + SwFrameFormat* pFormat = pContact->GetFormat(); + SwFrameFormat* pShapeFormat + = SwTextBoxHelper::getOtherTextBoxFormat(pFormat, RES_FLYFRMFMT); + if (!pShapeFormat) + { + pSdrView->UnmarkAllObj(); + pSdrView->MarkObj(pObj, pPV); + } + else + { + // If the fly frame is a textbox of a shape, then select the shape instead. + SdrObject* pShape = pShapeFormat->FindSdrObject(); + pSdrView->UnmarkAllObj(); + pSdrView->MarkObj(pShape, pPV); + } } } } diff --git a/sw/source/uibase/inc/edtwin.hxx b/sw/source/uibase/inc/edtwin.hxx index 714e6bcc3b..ceaa98657f 100644 --- a/sw/source/uibase/inc/edtwin.hxx +++ b/sw/source/uibase/inc/edtwin.hxx @@ -122,7 +122,8 @@ class SW_DLLPUBLIC SwEditWin final : public vcl::DocWindow, selection position depending on what has changed lately */ m_bUseInputLanguage: 1, - m_bObjectSelect : 1; + m_bObjectSelect : 1, + m_bMaybeShowTooltipAfterBufferFlush : 1 = false; sal_uInt16 m_nKS_NUMDOWN_Count; // #i23725# sal_uInt16 m_nKS_NUMINDENTINC_Count; diff --git a/sw/source/uibase/shells/drwbassh.cxx b/sw/source/uibase/shells/drwbassh.cxx index a5a63a6634..d5eec21320 100644 --- a/sw/source/uibase/shells/drwbassh.cxx +++ b/sw/source/uibase/shells/drwbassh.cxx @@ -836,8 +836,12 @@ void SwDrawBaseShell::GetState(SfxItemSet& rSet) SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj(); SwFrameFormat* pFrameFormat = FindFrameFormat(pObj); - SwFormatHoriOrient aHOrient(pFrameFormat->GetFormatAttr(RES_HORI_ORIENT)); - rSet.Put(SfxBoolItem(nWhich, aHOrient.GetHoriOrient() == nHoriOrient)); + if (pFrameFormat) + { + SwFormatHoriOrient aHOrient( + pFrameFormat->GetFormatAttr(RES_HORI_ORIENT)); + rSet.Put(SfxBoolItem(nWhich, aHOrient.GetHoriOrient() == nHoriOrient)); + } } if (bVert && !bDisableThis && rMarkList.GetMarkCount() == 1) @@ -860,8 +864,12 @@ void SwDrawBaseShell::GetState(SfxItemSet& rSet) SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj(); SwFrameFormat* pFrameFormat = FindFrameFormat(pObj); - SwFormatVertOrient aVOrient(pFrameFormat->GetFormatAttr(RES_VERT_ORIENT)); - rSet.Put(SfxBoolItem(nWhich, aVOrient.GetVertOrient() == nVertOrient)); + if (pFrameFormat) + { + SwFormatVertOrient aVOrient( + pFrameFormat->GetFormatAttr(RES_VERT_ORIENT)); + rSet.Put(SfxBoolItem(nWhich, aVOrient.GetVertOrient() == nVertOrient)); + } } } break; diff --git a/sw/source/uibase/sidebar/WriterInspectorTextPanel.cxx b/sw/source/uibase/sidebar/WriterInspectorTextPanel.cxx index 49086fa9a0..c6376910f1 100644 --- a/sw/source/uibase/sidebar/WriterInspectorTextPanel.cxx +++ b/sw/source/uibase/sidebar/WriterInspectorTextPanel.cxx @@ -758,12 +758,18 @@ IMPL_LINK(WriterInspectorTextPanel, AttrChangedNotify, LinkParamNone*, pLink, vo if (m_oldLink.IsSet()) m_oldLink.Call(pLink); + if (m_pShell->IsViewLocked()) + { + return; // tdf#142806 avoid slowdown when storing files + } + SwDocShell* pDocSh = m_pShell->GetDoc()->GetDocShell(); std::vector aStore; - SwEditShell* pEditSh = pDocSh ? pDocSh->GetDoc()->GetEditShell() : nullptr; - if (pEditSh && pEditSh->GetCursor()->GetPointNode().GetTextNode()) - UpdateTree(*pDocSh, *pEditSh, aStore, m_nParIdx); + if (m_pShell->GetCursor()->GetPointNode().GetTextNode()) + { + UpdateTree(*pDocSh, *m_pShell, aStore, m_nParIdx); + } updateEntries(aStore, m_nParIdx); } diff --git a/sw/source/uibase/uno/SwXDocumentSettings.cxx b/sw/source/uibase/uno/SwXDocumentSettings.cxx index 3e40989828..66f3eef7db 100644 --- a/sw/source/uibase/uno/SwXDocumentSettings.cxx +++ b/sw/source/uibase/uno/SwXDocumentSettings.cxx @@ -101,6 +101,7 @@ enum SwDocumentSettingsPropertyHandles HANDLE_CHANGES_PASSWORD, HANDLE_CONSIDER_WRAP_ON_OBJPOS, HANDLE_IGNORE_FIRST_LINE_INDENT_IN_NUMBERING, + HANDLE_NO_GAP_AFTER_NOTE_NUMBER, HANDLE_DO_NOT_JUSTIFY_LINES_WITH_MANUAL_BREAK, HANDLE_DO_NOT_RESET_PARA_ATTRS_FOR_NUM_FONT, HANDLE_TABLE_ROW_KEEP, @@ -205,6 +206,7 @@ static rtl::Reference lcl_createSettingsInfo() { OUString("RedlineProtectionKey"), HANDLE_CHANGES_PASSWORD, cppu::UnoType< cppu::UnoSequenceType >::get(), 0}, { OUString("ConsiderTextWrapOnObjPos"), HANDLE_CONSIDER_WRAP_ON_OBJPOS, cppu::UnoType::get(), 0}, { OUString("IgnoreFirstLineIndentInNumbering"), HANDLE_IGNORE_FIRST_LINE_INDENT_IN_NUMBERING, cppu::UnoType::get(), 0}, + { u"NoGapAfterNoteNumber"_ustr, HANDLE_NO_GAP_AFTER_NOTE_NUMBER, cppu::UnoType::get(), 0}, { OUString("DoNotJustifyLinesWithManualBreak"), HANDLE_DO_NOT_JUSTIFY_LINES_WITH_MANUAL_BREAK, cppu::UnoType::get(), 0}, { OUString("DoNotResetParaAttrsForNumFont"), HANDLE_DO_NOT_RESET_PARA_ATTRS_FOR_NUM_FONT, cppu::UnoType::get(), 0}, { OUString("TableRowKeep"), HANDLE_TABLE_ROW_KEEP, cppu::UnoType::get(), 0}, @@ -699,6 +701,12 @@ void SwXDocumentSettings::_setSingleValue( const comphelper::PropertyInfo & rInf mpDoc->getIDocumentSettingAccess().set(DocumentSettingId::IGNORE_FIRST_LINE_INDENT_IN_NUMBERING, bTmp); } break; + case HANDLE_NO_GAP_AFTER_NOTE_NUMBER: + { + bool bTmp = *o3tl::doAccess(rValue); + mpDoc->getIDocumentSettingAccess().set(DocumentSettingId::NO_GAP_AFTER_NOTE_NUMBER, bTmp); + } + break; case HANDLE_DO_NOT_JUSTIFY_LINES_WITH_MANUAL_BREAK: { bool bTmp = *o3tl::doAccess(rValue); @@ -1379,6 +1387,11 @@ void SwXDocumentSettings::_getSingleValue( const comphelper::PropertyInfo & rInf rValue <<= mpDoc->getIDocumentSettingAccess().get(DocumentSettingId::IGNORE_FIRST_LINE_INDENT_IN_NUMBERING); } break; + case HANDLE_NO_GAP_AFTER_NOTE_NUMBER: + { + rValue <<= mpDoc->getIDocumentSettingAccess().get(DocumentSettingId::NO_GAP_AFTER_NOTE_NUMBER); + } + break; case HANDLE_DO_NOT_JUSTIFY_LINES_WITH_MANUAL_BREAK: { rValue <<= mpDoc->getIDocumentSettingAccess().get(DocumentSettingId::DO_NOT_JUSTIFY_LINES_WITH_MANUAL_BREAK); diff --git a/sw/source/uibase/utlui/content.cxx b/sw/source/uibase/utlui/content.cxx index 3bf29979dd..4e67041403 100644 --- a/sw/source/uibase/utlui/content.cxx +++ b/sw/source/uibase/utlui/content.cxx @@ -6085,13 +6085,13 @@ void SwContentTree::BringEntryToAttention(const weld::TreeIter& rEntry) for (auto n = pFormats->size(); 1 < n;) { SwIterator aIter(*(*pFormats)[--n]); - for (SwTextINetFormat* pFnd = aIter.First(); pFnd; pFnd = aIter.Next() ) + for (SwTextINetFormat* pFnd = aIter.First(); pFnd; pFnd = aIter.Next()) { if (pTextINetFormat == pFnd) { BringURLFieldsToAttention(SwGetINetAttrs {SwGetINetAttr(pCnt->GetName(), *pTextINetFormat)}); - break; + return; } } } -- cgit v1.2.3