summaryrefslogtreecommitdiffstats
path: root/sw
diff options
context:
space:
mode:
Diffstat (limited to 'sw')
-rw-r--r--sw/CppunitTest_sw_core_layout.mk1
-rw-r--r--sw/CppunitTest_sw_core_text.mk1
-rw-r--r--sw/inc/IDocumentSettingAccess.hxx1
-rw-r--r--sw/inc/PostItMgr.hxx3
-rw-r--r--sw/inc/crsrsh.hxx12
-rw-r--r--sw/inc/doc.hxx30
-rw-r--r--sw/inc/ftninfo.hxx5
-rw-r--r--sw/inc/pagedesc.hxx2
-rw-r--r--sw/inc/viewsh.hxx7
-rw-r--r--sw/qa/core/frmedt/frmedt.cxx35
-rw-r--r--sw/qa/core/layout/calcmove.cxx87
-rw-r--r--sw/qa/core/layout/data/endnote-cont-separator.docxbin0 -> 16350 bytes
-rw-r--r--sw/qa/core/layout/data/fly-rel-width-rounding.odtbin0 -> 15475 bytes
-rw-r--r--sw/qa/core/layout/data/ignore-top-margin-fly.odtbin0 -> 11395 bytes
-rw-r--r--sw/qa/core/layout/data/ignore-top-margin-table.docxbin0 -> 12465 bytes
-rw-r--r--sw/qa/core/layout/data/ignore-top-margin.docxbin0 -> 14904 bytes
-rw-r--r--sw/qa/core/layout/data/inline-endnote-and-footnote.docbin0 -> 24576 bytes
-rw-r--r--sw/qa/core/layout/data/inline-endnote-and-section.odtbin0 -> 19899 bytes
-rw-r--r--sw/qa/core/layout/data/inline-endnote-position.docxbin0 -> 15242 bytes
-rw-r--r--sw/qa/core/layout/data/inline-endnote-section-delete.docxbin0 -> 20294 bytes
-rw-r--r--sw/qa/core/layout/fly.cxx25
-rw-r--r--sw/qa/core/layout/ftnfrm.cxx90
-rw-r--r--sw/qa/core/layout/layout.cxx4
-rw-r--r--sw/qa/core/layout/paintfrm.cxx57
-rw-r--r--sw/qa/core/objectpositioning/objectpositioning.cxx48
-rw-r--r--sw/qa/core/text/data/Broken indent demo.odtbin0 -> 9970 bytes
-rw-r--r--sw/qa/core/text/data/clearing-break-wrap-through.docxbin0 -> 13056 bytes
-rw-r--r--sw/qa/core/text/data/tdf156146.fodt281
-rw-r--r--sw/qa/core/text/text.cxx62
-rw-r--r--sw/qa/core/text/txtfly.cxx52
-rw-r--r--sw/qa/core/txtnode/data/plain-content-control-copy.docxbin0 -> 12178 bytes
-rw-r--r--sw/qa/core/txtnode/txtnode.cxx23
-rw-r--r--sw/qa/extras/layout/data/tdf160958_orphans_move_section.fodt52
-rw-r--r--sw/qa/extras/layout/data/tdf160958_page_break.fodt39
-rw-r--r--sw/qa/extras/layout/layout2.cxx5
-rw-r--r--sw/qa/extras/layout/layout3.cxx168
-rw-r--r--sw/qa/extras/odfexport/odfexport2.cxx6
-rw-r--r--sw/qa/extras/ooxmlexport/data/StyleRef-DE.docxbin0 -> 19230 bytes
-rw-r--r--sw/qa/extras/ooxmlexport/ooxmlexport17.cxx12
-rw-r--r--sw/qa/extras/ooxmlexport/ooxmlexport5.cxx6
-rw-r--r--sw/qa/extras/ooxmlexport/ooxmlexport9.cxx4
-rw-r--r--sw/qa/extras/ooxmlexport/ooxmlfieldexport.cxx2
-rw-r--r--sw/qa/extras/uiwriter/data/stylewithlistandindents.fodt182
-rw-r--r--sw/qa/extras/uiwriter/data/table-in-table.fodt29
-rw-r--r--sw/qa/extras/uiwriter/data/tdf160842.fodt75
-rw-r--r--sw/qa/extras/uiwriter/data/tdf161172.fodt35
-rw-r--r--sw/qa/extras/uiwriter/uiwriter3.cxx5
-rw-r--r--sw/qa/extras/uiwriter/uiwriter6.cxx167
-rw-r--r--sw/qa/extras/uiwriter/uiwriter8.cxx121
-rw-r--r--sw/qa/extras/uiwriter/uiwriter9.cxx84
-rw-r--r--sw/qa/extras/unowriter/data/tdf161035.fodt9
-rw-r--r--sw/qa/extras/unowriter/unowriter.cxx27
-rw-r--r--sw/qa/extras/ww8export/data/draw-obj-rtl-no-mirror-vml.docxbin0 -> 14534 bytes
-rw-r--r--sw/qa/extras/ww8export/ww8export4.cxx24
-rw-r--r--sw/qa/filter/ww8/ww8.cxx37
-rw-r--r--sw/qa/uibase/uno/uno.cxx24
-rw-r--r--sw/qa/uitest/writer_tests2/formatParagraph.py2
-rw-r--r--sw/source/core/access/accfrmobj.cxx15
-rw-r--r--sw/source/core/crsr/crsrsh.cxx33
-rw-r--r--sw/source/core/crsr/viscrs.cxx27
-rw-r--r--sw/source/core/doc/DocumentContentOperationsManager.cxx16
-rw-r--r--sw/source/core/doc/DocumentSettingManager.cxx10
-rw-r--r--sw/source/core/doc/docdraw.cxx12
-rw-r--r--sw/source/core/doc/docfmt.cxx10
-rw-r--r--sw/source/core/doc/docftn.cxx19
-rw-r--r--sw/source/core/doc/docnew.cxx1
-rw-r--r--sw/source/core/doc/docnum.cxx98
-rw-r--r--sw/source/core/doc/doctxm.cxx3
-rw-r--r--sw/source/core/draw/dcontact.cxx21
-rw-r--r--sw/source/core/draw/dview.cxx129
-rw-r--r--sw/source/core/edit/autofmt.cxx2
-rw-r--r--sw/source/core/edit/ednumber.cxx12
-rw-r--r--sw/source/core/fields/reffld.cxx66
-rw-r--r--sw/source/core/frmedt/fecopy.cxx25
-rw-r--r--sw/source/core/frmedt/fefly1.cxx60
-rw-r--r--sw/source/core/frmedt/feshview.cxx59
-rw-r--r--sw/source/core/inc/DocumentSettingManager.hxx1
-rw-r--r--sw/source/core/inc/frame.hxx7
-rw-r--r--sw/source/core/inc/ftnfrm.hxx1
-rw-r--r--sw/source/core/inc/pagefrm.hxx1
-rw-r--r--sw/source/core/inc/sectfrm.hxx4
-rw-r--r--sw/source/core/inc/txtfrm.hxx2
-rw-r--r--sw/source/core/layout/anchoreddrawobject.cxx4
-rw-r--r--sw/source/core/layout/anchoredobject.cxx11
-rw-r--r--sw/source/core/layout/calcmove.cxx44
-rw-r--r--sw/source/core/layout/findfrm.cxx45
-rw-r--r--sw/source/core/layout/flowfrm.cxx53
-rw-r--r--sw/source/core/layout/fly.cxx9
-rw-r--r--sw/source/core/layout/flylay.cxx41
-rw-r--r--sw/source/core/layout/frmtool.cxx40
-rw-r--r--sw/source/core/layout/ftnfrm.cxx110
-rw-r--r--sw/source/core/layout/pagechg.cxx19
-rw-r--r--sw/source/core/layout/paintfrm.cxx46
-rw-r--r--sw/source/core/layout/sectfrm.cxx56
-rw-r--r--sw/source/core/layout/tabfrm.cxx13
-rw-r--r--sw/source/core/layout/trvlfrm.cxx55
-rw-r--r--sw/source/core/objectpositioning/anchoredobjectposition.cxx5
-rw-r--r--sw/source/core/text/guess.cxx35
-rw-r--r--sw/source/core/text/guess.hxx4
-rw-r--r--sw/source/core/text/inftxt.hxx6
-rw-r--r--sw/source/core/text/itratr.hxx2
-rw-r--r--sw/source/core/text/itrtxt.hxx2
-rw-r--r--sw/source/core/text/txtfly.cxx7
-rw-r--r--sw/source/core/text/txtftn.cxx10
-rw-r--r--sw/source/core/txtnode/atrflyin.cxx3
-rw-r--r--sw/source/core/txtnode/thints.cxx4
-rw-r--r--sw/source/core/txtnode/txtedt.cxx8
-rw-r--r--sw/source/core/undo/undraw.cxx31
-rw-r--r--sw/source/core/undo/unins.cxx12
-rw-r--r--sw/source/core/undo/unnum.cxx4
-rw-r--r--sw/source/core/unocore/unocrsrhelper.cxx8
-rw-r--r--sw/source/core/unocore/unoportenum.cxx4
-rw-r--r--sw/source/filter/basflt/fltshell.cxx2
-rw-r--r--sw/source/filter/html/htmlctxt.cxx3
-rw-r--r--sw/source/filter/ww8/docxattributeoutput.cxx23
-rw-r--r--sw/source/filter/ww8/docxattributeoutput.hxx2
-rw-r--r--sw/source/filter/ww8/docxexport.cxx4
-rw-r--r--sw/source/filter/ww8/wrtw8esh.cxx6
-rw-r--r--sw/source/filter/ww8/wrtww8.cxx4
-rw-r--r--sw/source/filter/ww8/ww8par.cxx11
-rw-r--r--sw/source/filter/xml/xmlexp.cxx1
-rw-r--r--sw/source/filter/xml/xmlimp.cxx10
-rw-r--r--sw/source/ui/frmdlg/frmpage.cxx3
-rw-r--r--sw/source/ui/misc/pgfnote.cxx29
-rw-r--r--sw/source/ui/table/instable.cxx8
-rw-r--r--sw/source/uibase/docvw/AnnotationWin.cxx9
-rw-r--r--sw/source/uibase/docvw/AnnotationWin2.cxx23
-rw-r--r--sw/source/uibase/docvw/PostItMgr.cxx45
-rw-r--r--sw/source/uibase/docvw/edtwin.cxx10
-rw-r--r--sw/source/uibase/inc/pgfnote.hxx4
-rw-r--r--sw/source/uibase/inc/swruler.hxx3
-rw-r--r--sw/source/uibase/misc/swruler.cxx60
-rw-r--r--sw/source/uibase/shells/drwbassh.cxx86
-rw-r--r--sw/source/uibase/shells/frmsh.cxx15
-rw-r--r--sw/source/uibase/sidebar/A11yCheckIssuesPanel.cxx254
-rw-r--r--sw/source/uibase/sidebar/A11yCheckIssuesPanel.hxx62
-rw-r--r--sw/source/uibase/uiview/view.cxx14
-rw-r--r--sw/source/uibase/uiview/viewtab.cxx10
-rw-r--r--sw/source/uibase/uno/SwXDocumentSettings.cxx18
-rw-r--r--sw/source/uibase/utlui/content.cxx2
-rw-r--r--sw/source/uibase/utlui/uitool.cxx7
-rw-r--r--sw/source/uibase/utlui/unotools.cxx2
-rw-r--r--sw/uiconfig/swriter/ui/a11ycheckissuespanel.ui26
-rw-r--r--sw/uiconfig/swriter/ui/footnoteareapage.ui8
144 files changed, 3318 insertions, 712 deletions
diff --git a/sw/CppunitTest_sw_core_layout.mk b/sw/CppunitTest_sw_core_layout.mk
index 5eb874400d53..d64a43f7d3fb 100644
--- a/sw/CppunitTest_sw_core_layout.mk
+++ b/sw/CppunitTest_sw_core_layout.mk
@@ -14,6 +14,7 @@ $(eval $(call gb_CppunitTest_CppunitTest,sw_core_layout))
$(eval $(call gb_CppunitTest_use_common_precompiled_header,sw_core_layout))
$(eval $(call gb_CppunitTest_add_exception_objects,sw_core_layout, \
+ sw/qa/core/layout/calcmove \
sw/qa/core/layout/fly \
sw/qa/core/layout/flycnt \
sw/qa/core/layout/frmtool \
diff --git a/sw/CppunitTest_sw_core_text.mk b/sw/CppunitTest_sw_core_text.mk
index ce27696b3c4c..5e623d3b0cd0 100644
--- a/sw/CppunitTest_sw_core_text.mk
+++ b/sw/CppunitTest_sw_core_text.mk
@@ -20,6 +20,7 @@ $(eval $(call gb_CppunitTest_add_exception_objects,sw_core_text, \
sw/qa/core/text/porlay \
sw/qa/core/text/porrst \
sw/qa/core/text/text \
+ sw/qa/core/text/txtfly \
))
$(eval $(call gb_CppunitTest_use_libraries,sw_core_text, \
diff --git a/sw/inc/IDocumentSettingAccess.hxx b/sw/inc/IDocumentSettingAccess.hxx
index 0dd9467bdf13..264860b854c4 100644
--- a/sw/inc/IDocumentSettingAccess.hxx
+++ b/sw/inc/IDocumentSettingAccess.hxx
@@ -99,6 +99,7 @@ enum class DocumentSettingId
// tdf#119908 new paragraph justification
JUSTIFY_LINES_WITH_SHRINKING,
APPLY_TEXT_ATTR_TO_EMPTY_LINE_AT_END_OF_PARAGRAPH,
+ DO_NOT_MIRROR_RTL_DRAW_OBJS,
// COMPATIBILITY FLAGS END
BROWSE_MODE,
HTML_MODE,
diff --git a/sw/inc/PostItMgr.hxx b/sw/inc/PostItMgr.hxx
index 98d9f4f2ef30..5a877a6c8afe 100644
--- a/sw/inc/PostItMgr.hxx
+++ b/sw/inc/PostItMgr.hxx
@@ -172,6 +172,8 @@ class SAL_DLLPUBLIC_RTTI SwPostItMgr final : public SfxListener
SwSidebarItem* InsertItem( SfxBroadcaster* pItem, bool bCheckExistence, bool bFocus);
void RemoveItem( SfxBroadcaster* pBroadcast );
+ VclPtr<sw::annotation::SwAnnotationWin> GetOrCreateAnnotationWindow(SwSidebarItem& rItem);
+
public:
SwPostItMgr(SwView* aDoc);
virtual ~SwPostItMgr() override;
@@ -231,6 +233,7 @@ class SAL_DLLPUBLIC_RTTI SwPostItMgr final : public SfxListener
sw::annotation::SwAnnotationWin* GetNextPostIt( sal_uInt16 aDirection,
sw::annotation::SwAnnotationWin* aPostIt);
SwPostItField* GetLatestPostItField();
+ sw::annotation::SwAnnotationWin* GetOrCreateAnnotationWindowForLatestPostItField();
tools::Long GetNextBorder();
diff --git a/sw/inc/crsrsh.hxx b/sw/inc/crsrsh.hxx
index 03afe5006ad6..97248572c762 100644
--- a/sw/inc/crsrsh.hxx
+++ b/sw/inc/crsrsh.hxx
@@ -23,6 +23,7 @@
#include <rtl/ustring.hxx>
#include <tools/link.hxx>
+#include <vcl/idle.hxx>
#include <vcl/keycod.hxx>
#include <o3tl/typed_flags_set.hxx>
@@ -243,8 +244,14 @@ private:
bool m_bMacroExecAllowed : 1;
+ // SwViewShell::LayoutIdle needs to be called on cursor update to repeat a spell check,
+ // because previous attempt marked a word as pending, because the word had cursor
+ bool m_bNeedLayoutOnCursorUpdate : 1 = false;
+
SwFrame* m_oldColFrame;
+ Idle m_aLayoutIdle; // An idle to schedule another SwViewShell::LayoutIdle call
+
SAL_DLLPRIVATE void MoveCursorToNum();
SAL_DLLPRIVATE void ParkPams( SwPaM* pDelRg, SwShellCursor** ppDelRing );
@@ -285,6 +292,9 @@ private:
SAL_DLLPRIVATE const SwRangeRedline* GotoRedline_( SwRedlineTable::size_type nArrPos, bool bSelect );
SAL_DLLPRIVATE void sendLOKCursorUpdates();
+
+ DECL_LINK(DoLayoutIdle, Timer*, void); // calls SwViewShell::LayoutIdle
+
protected:
inline SwMoveFnCollection const & MakeFindRange( SwDocPositions, SwDocPositions, SwPaM* ) const;
@@ -308,6 +318,8 @@ protected:
protected:
virtual void SwClientNotify(const SwModify&, const SfxHint&) override;
+ virtual void OnSpellWrongStatePending() override { m_bNeedLayoutOnCursorUpdate = true; }
+
public:
SwCursorShell( SwDoc& rDoc, vcl::Window *pWin, const SwViewOption *pOpt );
// disguised copy constructor
diff --git a/sw/inc/doc.hxx b/sw/inc/doc.hxx
index 99cb33c75826..946c96fd29db 100644
--- a/sw/inc/doc.hxx
+++ b/sw/inc/doc.hxx
@@ -1052,23 +1052,30 @@ public:
bool GotoOutline(SwPosition& rPos, const OUString& rName, SwRootFrame const* = nullptr) const;
- /** Accept changes of outline styles for OutlineRule.
- @param bResetIndentAttrs Optional parameter - default value false:
- If <bResetIndentAttrs> equals true, the indent attributes "before text"
- and "first line indent" are additionally reset at the provided PaM, if
- the list style makes use of the new list level attributes.
- @param bCreateNewList indicates if a new list is created by applying the given list style.
+ enum class SetNumRuleMode {
+ Default = 0,
+ /// indicates if a new list is created by applying the given list style.
+ CreateNewList = 1,
+ DontSetItem = 2,
+ /** If enabled, the indent attributes "before text" and
+ "first line indent" are additionally reset at the provided PaM,
+ if the list style makes use of the new list level attributes. */
+ ResetIndentAttrs = 4,
+ DontSetIfAlreadyApplied = 8
+ };
+
+ /** Set or change numbering rule on text nodes, as direct formatting.
@param sContinuedListId If bCreateNewList is false, may contain the
list Id of a list which has to be continued by applying the given list style
@return the set ListId if bSetItem is true */
OUString SetNumRule( const SwPaM&,
const SwNumRule&,
- bool bCreateNewList,
+ SetNumRuleMode mode,
SwRootFrame const* pLayout = nullptr,
const OUString& sContinuedListId = OUString(),
- bool bSetItem = true,
- const bool bResetIndentAttrs = false );
+ SvxTextLeftMarginItem const* pTextLeftMarginToPropagate = nullptr,
+ SvxFirstLineIndentItem const* pFirstLineIndentToPropagate = nullptr);
void SetCounted(const SwPaM&, bool bCounted, SwRootFrame const* pLayout);
void MakeUniqueNumRules(const SwPaM & rPaM);
@@ -1145,7 +1152,9 @@ public:
int nNonEmptyAllowed,
OUString& sListId,
SwRootFrame const* pLayout,
- const bool bInvestigateStartNode = false );
+ const bool bInvestigateStartNode = false,
+ SvxTextLeftMarginItem const** o_ppTextLeftMargin = nullptr,
+ SvxFirstLineIndentItem const** o_ppFirstLineIndent = nullptr);
// Paragraphs without numbering but with indents.
bool NoNum( const SwPaM& );
@@ -1704,6 +1713,7 @@ private:
namespace o3tl {
template<> struct typed_flags<SwDoc::RowColMode> : is_typed_flags<SwDoc::RowColMode, 3> {};
+ template<> struct typed_flags<SwDoc::SetNumRuleMode> : is_typed_flags<SwDoc::SetNumRuleMode, 0x0f> {};
}
// This method is called in Dtor of SwDoc and deletes cache of ContourObjects.
diff --git a/sw/inc/ftninfo.hxx b/sw/inc/ftninfo.hxx
index 17742687c944..c5490ed885d0 100644
--- a/sw/inc/ftninfo.hxx
+++ b/sw/inc/ftninfo.hxx
@@ -28,12 +28,14 @@ class SwTextFormatColl;
class SwPageDesc;
class SwCharFormat;
class SwDoc;
+class SwSection;
class SW_DLLPUBLIC SwEndNoteInfo : public SwClient
{
mutable sw::WriterMultiListener m_aDepends;
mutable SwTextFormatColl* m_pTextFormatColl;
mutable SwPageDesc* m_pPageDesc;
+ mutable std::unique_ptr<SwSection> m_pSwSection;
mutable SwCharFormat* m_pCharFormat;
mutable SwCharFormat* m_pAnchorFormat;
OUString m_sPrefix;
@@ -51,6 +53,9 @@ public:
bool KnowsPageDesc() const;
bool DependsOn(const SwPageDesc*) const;
+ SwSection* GetSwSection(SwDoc& rDoc) const;
+ void ResetSwSection();
+
void SetFootnoteTextColl(SwTextFormatColl& rColl);
SwTextFormatColl* GetFootnoteTextColl() const { return m_pTextFormatColl; } // can be 0.
diff --git a/sw/inc/pagedesc.hxx b/sw/inc/pagedesc.hxx
index ddc7e659a5bb..d9b58a4bb357 100644
--- a/sw/inc/pagedesc.hxx
+++ b/sw/inc/pagedesc.hxx
@@ -399,7 +399,7 @@ public:
namespace sw {
class PageFootnoteHint final : public SfxHint {};
- SW_DLLPUBLIC SwTwips FootnoteSeparatorHeight(SwPageFootnoteInfo const&);
+ SW_DLLPUBLIC SwTwips FootnoteSeparatorHeight(SwDoc& rDoc, SwPageFootnoteInfo const&);
}
typedef boost::multi_index_container<
diff --git a/sw/inc/viewsh.hxx b/sw/inc/viewsh.hxx
index fcd697124046..ed3cbfee3b4d 100644
--- a/sw/inc/viewsh.hxx
+++ b/sw/inc/viewsh.hxx
@@ -600,6 +600,13 @@ public:
void GetFirstLastVisPageNumbers(SwVisiblePageNumbers& rVisiblePageNumbers, SwView& rView);
virtual void dumpAsXml(xmlTextWriterPtr pWriter) const;
+
+ // SwTextFrame::AutoSpell_ calls this, to notify the shell, that a word has a spelling error,
+ // but that couldn't be drawn, because the cursor was in that word (so that the user is not
+ // annoyed while typing). The shell's task is to re-run the spell check (i.e., call LayoutIdle,
+ // which internally does the spell check), when the cursor leaves that word (implemented in
+ // SwCursorShell).
+ virtual void OnSpellWrongStatePending() {}
};
// manages global ShellPointer
diff --git a/sw/qa/core/frmedt/frmedt.cxx b/sw/qa/core/frmedt/frmedt.cxx
index b2a53e60db27..37425c13060e 100644
--- a/sw/qa/core/frmedt/frmedt.cxx
+++ b/sw/qa/core/frmedt/frmedt.cxx
@@ -250,6 +250,41 @@ CPPUNIT_TEST_FIXTURE(SwCoreFrmedtTest, testSplitFlyUnfloat)
CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), pDoc->GetTableFrameFormatCount(/*bUsed=*/true));
}
+CPPUNIT_TEST_FIXTURE(SwCoreFrmedtTest, testInsertOnGrfNodeAsChar)
+{
+ // Given a selected as-char image:
+ createSwDoc();
+ SwDoc* pDoc = getSwDocShell()->GetDoc();
+ SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
+ {
+ SfxItemSet aFrameSet(pDoc->GetAttrPool(), svl::Items<RES_FRMATR_BEGIN, RES_FRMATR_END - 1>);
+ SwFormatAnchor aAnchor(RndStdIds::FLY_AS_CHAR);
+ aFrameSet.Put(aAnchor);
+ Graphic aGrf;
+ pWrtShell->SwFEShell::Insert(OUString(), OUString(), &aGrf, &aFrameSet);
+ }
+
+ // When inserting another as-char image:
+ SfxItemSet aFrameSet(pDoc->GetAttrPool(), svl::Items<RES_FRMATR_BEGIN, RES_FRMATR_END - 1>);
+ SwFormatAnchor aAnchor(RndStdIds::FLY_AS_CHAR);
+ aFrameSet.Put(aAnchor);
+ Graphic aGrf;
+ // Without the accompanying fix in place, this call crashed, we try to set a graphic node as an
+ // anchor of an as-char image (which should be a text node).
+ pWrtShell->SwFEShell::Insert(OUString(), OUString(), &aGrf, &aFrameSet);
+
+ // Then make sure that the anchor of the second image is next to the first anchor:
+ CPPUNIT_ASSERT(pDoc->GetSpzFrameFormats());
+ sw::FrameFormats<sw::SpzFrameFormat*>& rFormats = *pDoc->GetSpzFrameFormats();
+ CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(2), rFormats.size());
+ const sw::SpzFrameFormat& rFormat1 = *rFormats[0];
+ const SwPosition* pAnchor1 = rFormat1.GetAnchor().GetContentAnchor();
+ const sw::SpzFrameFormat& rFormat2 = *rFormats[1];
+ const SwPosition* pAnchor2 = rFormat2.GetAnchor().GetContentAnchor();
+ CPPUNIT_ASSERT_EQUAL(pAnchor1->nNode, pAnchor2->nNode);
+ CPPUNIT_ASSERT_EQUAL(pAnchor1->GetContentIndex() + 1, pAnchor2->GetContentIndex());
+}
+
CPPUNIT_PLUGIN_IMPLEMENT();
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/qa/core/layout/calcmove.cxx b/sw/qa/core/layout/calcmove.cxx
new file mode 100644
index 000000000000..ad53df9bd0f4
--- /dev/null
+++ b/sw/qa/core/layout/calcmove.cxx
@@ -0,0 +1,87 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <swmodeltestbase.hxx>
+
+#include <test/xmldocptr.hxx>
+
+namespace
+{
+/// Covers sw/source/core/layout/calcmove.cxx fixes.
+class Test : public SwModelTestBase
+{
+public:
+ Test()
+ : SwModelTestBase("/sw/qa/core/layout/data/")
+ {
+ }
+};
+
+CPPUNIT_TEST_FIXTURE(Test, testIgnoreTopMargin)
+{
+ // Given a DOCX (>= Word 2013) file, with 2 pages:
+ // When loading that document:
+ createSwDoc("ignore-top-margin.docx");
+
+ // Then make sure that the paragraph on the 2nd page has no top margin:
+ xmlDocUniquePtr pXmlDoc = parseLayoutDump();
+ sal_Int32 nParaTopMargin
+ = getXPath(pXmlDoc, "/root/page[2]/body/txt/infos/prtBounds"_ostr, "top"_ostr).toInt32();
+ // Without the accompanying fix in place, this test would have failed with:
+ // - Expected: 0
+ // - Actual : 2400
+ // i.e. the top margin in the first para of a non-first page wasn't ignored, like in Word.
+ CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(0), nParaTopMargin);
+}
+
+CPPUNIT_TEST_FIXTURE(Test, testIgnoreTopMarginTable)
+{
+ // Given a DOCX (>= Word 2013) file, with 2 pages:
+ // When loading that document:
+ createSwDoc("ignore-top-margin-table.docx");
+
+ // Then make sure that the paragraph on the 2nd page in B1 has a top margin:
+ xmlDocUniquePtr pXmlDoc = parseLayoutDump();
+ sal_Int32 nParaTopMargin
+ = getXPath(pXmlDoc, "/root/page[2]/body/tab/row/cell[2]/txt/infos/prtBounds"_ostr,
+ "top"_ostr)
+ .toInt32();
+ // Without the accompanying fix in place, this test would have failed with:
+ // - Expected: 2000
+ // - Actual : 0
+ // i.e. the top margin in B1's first paragraph was ignored, but not in Word.
+ CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(2000), nParaTopMargin);
+}
+
+CPPUNIT_TEST_FIXTURE(Test, testIgnoreTopMarginFly)
+{
+ // Given a document with compat flags like DOCX (>= Word 2013), 2 pages, multi-col fly frame on
+ // page 2:
+ createSwDoc("ignore-top-margin-fly.odt");
+
+ // When laying out that document:
+ xmlDocUniquePtr pXmlDoc = parseLayoutDump();
+
+ // Then make sure that the top margin is not ignored inside shape text:
+ sal_Int32 nParaTopMargin
+ = getXPath(
+ pXmlDoc,
+ "/root/page[2]/body/section/column[2]/body/txt/anchored/fly/column/body/txt/infos/prtBounds"_ostr,
+ "top"_ostr)
+ .toInt32();
+ // Without the accompanying fix in place, this test would have failed with:
+ // - Expected: 4000
+ // - Actual : 0
+ // i.e. the top margin was ignored inside shape text for Word compat, while multi-col shape text
+ // is a Writer feature.
+ CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(4000), nParaTopMargin);
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/qa/core/layout/data/endnote-cont-separator.docx b/sw/qa/core/layout/data/endnote-cont-separator.docx
new file mode 100644
index 000000000000..2e01a5c91354
--- /dev/null
+++ b/sw/qa/core/layout/data/endnote-cont-separator.docx
Binary files differ
diff --git a/sw/qa/core/layout/data/fly-rel-width-rounding.odt b/sw/qa/core/layout/data/fly-rel-width-rounding.odt
new file mode 100644
index 000000000000..b70b9e51a917
--- /dev/null
+++ b/sw/qa/core/layout/data/fly-rel-width-rounding.odt
Binary files differ
diff --git a/sw/qa/core/layout/data/ignore-top-margin-fly.odt b/sw/qa/core/layout/data/ignore-top-margin-fly.odt
new file mode 100644
index 000000000000..51bda8fe40a9
--- /dev/null
+++ b/sw/qa/core/layout/data/ignore-top-margin-fly.odt
Binary files differ
diff --git a/sw/qa/core/layout/data/ignore-top-margin-table.docx b/sw/qa/core/layout/data/ignore-top-margin-table.docx
new file mode 100644
index 000000000000..c82f6d63c13f
--- /dev/null
+++ b/sw/qa/core/layout/data/ignore-top-margin-table.docx
Binary files differ
diff --git a/sw/qa/core/layout/data/ignore-top-margin.docx b/sw/qa/core/layout/data/ignore-top-margin.docx
new file mode 100644
index 000000000000..d05a1358db1e
--- /dev/null
+++ b/sw/qa/core/layout/data/ignore-top-margin.docx
Binary files differ
diff --git a/sw/qa/core/layout/data/inline-endnote-and-footnote.doc b/sw/qa/core/layout/data/inline-endnote-and-footnote.doc
new file mode 100644
index 000000000000..39c5636e1e12
--- /dev/null
+++ b/sw/qa/core/layout/data/inline-endnote-and-footnote.doc
Binary files differ
diff --git a/sw/qa/core/layout/data/inline-endnote-and-section.odt b/sw/qa/core/layout/data/inline-endnote-and-section.odt
new file mode 100644
index 000000000000..4518904f6009
--- /dev/null
+++ b/sw/qa/core/layout/data/inline-endnote-and-section.odt
Binary files differ
diff --git a/sw/qa/core/layout/data/inline-endnote-position.docx b/sw/qa/core/layout/data/inline-endnote-position.docx
new file mode 100644
index 000000000000..3905208f9f0e
--- /dev/null
+++ b/sw/qa/core/layout/data/inline-endnote-position.docx
Binary files differ
diff --git a/sw/qa/core/layout/data/inline-endnote-section-delete.docx b/sw/qa/core/layout/data/inline-endnote-section-delete.docx
new file mode 100644
index 000000000000..bf3d3e60d890
--- /dev/null
+++ b/sw/qa/core/layout/data/inline-endnote-section-delete.docx
Binary files differ
diff --git a/sw/qa/core/layout/fly.cxx b/sw/qa/core/layout/fly.cxx
index 47cfb40fa6e7..81df20af3b35 100644
--- a/sw/qa/core/layout/fly.cxx
+++ b/sw/qa/core/layout/fly.cxx
@@ -86,6 +86,31 @@ CPPUNIT_TEST_FIXTURE(Test, testSplitFlyNegativeHeight)
}
}
}
+
+CPPUNIT_TEST_FIXTURE(Test, testFlyRelWithRounding)
+{
+ // Given a document where page width is 21.001cm (11906 twips), and the image width is 48% of
+ // the page width:
+ createSwDoc("fly-rel-width-rounding.odt");
+
+ // When laying out that document:
+ SwDoc* pDoc = getSwDoc();
+ SwRootFrame* pLayout = pDoc->getIDocumentLayoutAccess().GetCurrentLayout();
+
+ // Then make sure that we calculate the width of the fly correctly:
+ auto pPage = pLayout->GetLower()->DynCastPageFrame();
+ CPPUNIT_ASSERT(pPage->GetSortedObjs());
+ SwSortedObjs& rPageObjs = *pPage->GetSortedObjs();
+ CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), rPageObjs.size());
+ auto pFly = rPageObjs[0]->DynCastFlyFrame()->DynCastFlyAtContentFrame();
+ CPPUNIT_ASSERT(pFly);
+ tools::Long nFlyWidth = pFly->getFrameArea().Width();
+ // Without the accompanying fix in place, this test would have failed with:
+ // - Expected: 5715
+ // - Actual : 5714
+ // i.e. 5714.88 was truncated, not rounded.
+ CPPUNIT_ASSERT_EQUAL(static_cast<tools::Long>(5715), nFlyWidth);
+}
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/qa/core/layout/ftnfrm.cxx b/sw/qa/core/layout/ftnfrm.cxx
index 4c874202da3f..98387be6a983 100644
--- a/sw/qa/core/layout/ftnfrm.cxx
+++ b/sw/qa/core/layout/ftnfrm.cxx
@@ -17,6 +17,8 @@
#include <rootfrm.hxx>
#include <view.hxx>
#include <wrtsh.hxx>
+#include <bodyfrm.hxx>
+#include <sectfrm.hxx>
/// Covers sw/source/core/layout/ftnfrm.cxx fixes.
class Test : public SwModelTestBase
@@ -63,4 +65,92 @@ CPPUNIT_TEST_FIXTURE(Test, testFlySplitFootnoteLayout)
CPPUNIT_ASSERT(pPage->FindFootnoteCont());
}
+CPPUNIT_TEST_FIXTURE(Test, testInlineEndnoteAndFootnote)
+{
+ // Given a DOC file with an endnote and then a footnote:
+ createSwDoc("inline-endnote-and-footnote.doc");
+
+ // When laying out that document:
+ xmlDocUniquePtr pXmlDoc = parseLayoutDump();
+
+ // Then make sure the footnote is below the endnote:
+ // Without the accompanying fix in place, this test would have failed with:
+ // - xpath should match exactly 1 node
+ // i.e. the endnote was also in the footnote container, not at the end of the body text.
+ sal_Int32 nEndnoteTop
+ = parseDump("/root/page/body/section/column/ftncont/ftn/infos/bounds"_ostr, "top"_ostr)
+ .toInt32();
+ sal_Int32 nFootnoteTop
+ = parseDump("/root/page/ftncont/ftn/infos/bounds"_ostr, "top"_ostr).toInt32();
+ // Endnote at the end of body text, footnote at page bottom.
+ CPPUNIT_ASSERT_LESS(nFootnoteTop, nEndnoteTop);
+}
+
+CPPUNIT_TEST_FIXTURE(Test, testInlineEndnoteAndSection)
+{
+ // Given a document ending with a section, ContinuousEndnotes is true:
+ createSwDoc("inline-endnote-and-section.odt");
+
+ // When laying out that document:
+ xmlDocUniquePtr pXmlDoc = parseLayoutDump();
+
+ // Then make sure the endnote section is after the section at the end of the document, not
+ // inside it:
+ int nToplevelSections = countXPathNodes(pXmlDoc, "/root/page/body/section"_ostr);
+ // Without the accompanying fix in place, this test would have failed with:
+ // - Expected: 2
+ // - Actual : 1
+ // and we even crashed on shutdown.
+ CPPUNIT_ASSERT_EQUAL(2, nToplevelSections);
+}
+
+CPPUNIT_TEST_FIXTURE(Test, testInlineEndnotePosition)
+{
+ // Given a document, ContinuousEndnotes is true:
+ createSwDoc("inline-endnote-position.docx");
+
+ // When laying out that document:
+ xmlDocUniquePtr pXmlDoc = parseLayoutDump();
+
+ // Then make sure the endnote separator (line + spacing around it) is large enough, so the
+ // endnote text below the separator has the correct position:
+ sal_Int32 nEndnoteContTopMargin
+ = parseDump("//column/ftncont/infos/prtBounds"_ostr, "top"_ostr).toInt32();
+ // Without the accompanying fix in place, this test would have failed with:
+ // - Expected: 269
+ // - Actual : 124
+ // i.e. the top margin wasn't the default font size with its spacing, but the Writer default,
+ // which shifted endnote text up, incorrectly.
+ CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(269), nEndnoteContTopMargin);
+}
+
+CPPUNIT_TEST_FIXTURE(Test, testInlineEndnoteSectionDelete)
+{
+ // Given a document, ContinuousEndnotes is true, 3 pages, endnodes start on page 2:
+ // When laying out that document:
+ createSwDoc("inline-endnote-section-delete.docx");
+
+ // First page: just body text:
+ SwDoc* pDoc = getSwDoc();
+ SwRootFrame* pLayout = pDoc->getIDocumentLayoutAccess().GetCurrentLayout();
+ auto pPage = pLayout->Lower()->DynCastPageFrame();
+ CPPUNIT_ASSERT(pPage->GetLower()->IsBodyFrame());
+ auto pBodyFrame = static_cast<SwBodyFrame*>(pPage->GetLower());
+ CPPUNIT_ASSERT(!pBodyFrame->GetLastLower()->IsSctFrame());
+ // Second page: ends with endnotes:
+ pPage = pPage->GetNext()->DynCastPageFrame();
+ CPPUNIT_ASSERT(pPage->GetLower()->IsBodyFrame());
+ pBodyFrame = static_cast<SwBodyFrame*>(pPage->GetLower());
+ CPPUNIT_ASSERT(pBodyFrame->GetLastLower()->IsSctFrame());
+ auto pSection = static_cast<SwSectionFrame*>(pBodyFrame->GetLastLower());
+ CPPUNIT_ASSERT(pSection->IsEndNoteSection());
+ // Third page: just endnotes:
+ pPage = pPage->GetNext()->DynCastPageFrame();
+ CPPUNIT_ASSERT(pPage->GetLower()->IsBodyFrame());
+ pBodyFrame = static_cast<SwBodyFrame*>(pPage->GetLower());
+ CPPUNIT_ASSERT(pBodyFrame->GetLower()->IsSctFrame());
+ pSection = static_cast<SwSectionFrame*>(pBodyFrame->GetLower());
+ CPPUNIT_ASSERT(pSection->IsEndNoteSection());
+}
+
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/qa/core/layout/layout.cxx b/sw/qa/core/layout/layout.cxx
index 5971e870304d..9cae825b38b4 100644
--- a/sw/qa/core/layout/layout.cxx
+++ b/sw/qa/core/layout/layout.cxx
@@ -179,9 +179,9 @@ CPPUNIT_TEST_FIXTURE(SwCoreLayoutTest, testContinuousEndnotesMoveBackwards)
// - Expected: 0
// - Actual : 1
// i.e. there were unexpected endnotes on page 1.
- assertXPath(pLayout, "/root/page[1]/ftncont"_ostr, 0);
+ assertXPath(pLayout, "/root/page[1]//ftncont"_ostr, 0);
// All endnotes are in a container on page 2.
- assertXPath(pLayout, "/root/page[2]/ftncont"_ostr, 1);
+ assertXPath(pLayout, "/root/page[2]//ftncont"_ostr, 1);
}
CPPUNIT_TEST_FIXTURE(SwCoreLayoutTest, testAnchorPositionBasedOnParagraph)
diff --git a/sw/qa/core/layout/paintfrm.cxx b/sw/qa/core/layout/paintfrm.cxx
index b5990648b20f..464979c988a6 100644
--- a/sw/qa/core/layout/paintfrm.cxx
+++ b/sw/qa/core/layout/paintfrm.cxx
@@ -10,6 +10,7 @@
#include <swmodeltestbase.hxx>
#include <o3tl/string_view.hxx>
+#include <svtools/DocumentToGraphicRenderer.hxx>
#include <docsh.hxx>
#include <unotxdoc.hxx>
@@ -158,6 +159,62 @@ CPPUNIT_TEST_FIXTURE(Test, testSplitTableMergedBorder)
// bottom border.
CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(2), aHorizontalBorderEnds.size());
}
+
+CPPUNIT_TEST_FIXTURE(Test, testInlineEndnoteSeparatorPosition)
+{
+ // Given a document with a Word-style endnote separator:
+ createSwDoc("inline-endnote-position.docx");
+ SwDocShell* pDocShell = getSwDocShell();
+
+ // When rendering that document:
+ std::shared_ptr<GDIMetaFile> xMetaFile = pDocShell->GetPreviewMetaFile();
+
+ // Then make sure the separator upper spacing is 60% of all space, matching Word:
+ MetafileXmlDump aDumper;
+ xmlDocUniquePtr pXmlDoc = dumpAndParse(aDumper, *xMetaFile);
+ auto nEndnoteSeparatorY = getXPath(pXmlDoc, "//polygon/point[1]"_ostr, "y"_ostr).toInt32();
+ // Without the accompanying fix in place, this test would have failed with:
+ // - Expected: 2164
+ // - Actual : 2060
+ // i.e. the upper spacing was too low.
+ CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(2164), nEndnoteSeparatorY);
+
+ // Also make sure the separator length is correct:
+ auto nEndnoteSeparatorStart = getXPath(pXmlDoc, "//polygon/point[1]"_ostr, "x"_ostr).toInt32();
+ auto nEndnoteSeparatorEnd = getXPath(pXmlDoc, "//polygon/point[2]"_ostr, "x"_ostr).toInt32();
+ sal_Int32 nEndnoteSeparatorLength = nEndnoteSeparatorEnd - nEndnoteSeparatorStart;
+ // Without the accompanying fix in place, this test would have failed with:
+ // - Expected: 2880
+ // - Actual : 2340
+ // i.e. the separator wasn't 2 inches long, but was shorter vs Word.
+ CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(2880), nEndnoteSeparatorLength);
+}
+
+CPPUNIT_TEST_FIXTURE(Test, testEndnoteContSeparator)
+{
+ // Given a document with a Word-style endnote continuation separator:
+ createSwDoc("endnote-cont-separator.docx");
+
+ // When rendering page 2:
+ sal_Int32 nPage = 2;
+ DocumentToGraphicRenderer aRenderer(mxComponent, /*bSelectionOnly=*/false);
+ Size aSize = aRenderer.getDocumentSizeInPixels(nPage);
+ Graphic aGraphic = aRenderer.renderToGraphic(nPage, aSize, aSize, COL_WHITE,
+ /*bExtOutDevData=*/false);
+ auto& xMetaFile = const_cast<GDIMetaFile&>(aGraphic.GetGDIMetaFile());
+
+ // Then make sure the separator length is correct:
+ MetafileXmlDump aDumper;
+ xmlDocUniquePtr pXmlDoc = dumpAndParse(aDumper, xMetaFile);
+ auto nEndnoteSeparatorStart = getXPath(pXmlDoc, "//polygon/point[1]"_ostr, "x"_ostr).toInt32();
+ auto nEndnoteSeparatorEnd = getXPath(pXmlDoc, "//polygon/point[2]"_ostr, "x"_ostr).toInt32();
+ sal_Int32 nEndnoteSeparatorLength = nEndnoteSeparatorEnd - nEndnoteSeparatorStart;
+ // Without the accompanying fix in place, this test would have failed with:
+ // - Expected: 9360 (page print area width)
+ // - Actual : 2880 (2 inches)
+ // i.e. the separator was too short vs Word.
+ CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(9360), nEndnoteSeparatorLength);
+}
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/qa/core/objectpositioning/objectpositioning.cxx b/sw/qa/core/objectpositioning/objectpositioning.cxx
index bf560cbdaf90..a1805bf4508e 100644
--- a/sw/qa/core/objectpositioning/objectpositioning.cxx
+++ b/sw/qa/core/objectpositioning/objectpositioning.cxx
@@ -24,6 +24,10 @@
#include <anchoredobject.hxx>
#include <flyfrm.hxx>
#include <frmatr.hxx>
+#include <IDocumentSettingAccess.hxx>
+#include <view.hxx>
+#include <fmtanchr.hxx>
+#include <fmtfsize.hxx>
namespace
{
@@ -404,6 +408,50 @@ CPPUNIT_TEST_FIXTURE(Test, testFloatingTableOverlapCell)
CPPUNIT_ASSERT(pPage1);
CPPUNIT_ASSERT(!pPage1->GetNext());
}
+
+CPPUNIT_TEST_FIXTURE(Test, testDoNotMirrorRtlDrawObjsLayout)
+{
+ // Given a document with an RTL paragraph, Word-style compat flag is enabled:
+ createSwDoc();
+ SwDoc* pDoc = getSwDoc();
+ auto& rIDSA = pDoc->getIDocumentSettingAccess();
+ rIDSA.set(DocumentSettingId::DO_NOT_MIRROR_RTL_DRAW_OBJS, true);
+ SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
+ SwView& rView = pWrtShell->GetView();
+ SfxItemSetFixed<RES_FRMATR_BEGIN, RES_FRMATR_END> aSet(rView.GetPool());
+ SvxFrameDirectionItem aDirection(SvxFrameDirection::Horizontal_RL_TB, RES_FRAMEDIR);
+ aSet.Put(aDirection);
+ pWrtShell->SetAttrSet(aSet, SetAttrMode::DEFAULT, nullptr, /*bParagraphSetting=*/true);
+ SwRootFrame* pLayout = pDoc->getIDocumentLayoutAccess().GetCurrentLayout();
+ auto pPageFrame = pLayout->Lower()->DynCastPageFrame();
+ SwFrame* pBodyFrame = pPageFrame->GetLower();
+
+ // When inserting a graphic on the middle of the right margin:
+ SfxItemSet aFrameSet(pDoc->GetAttrPool(), svl::Items<RES_FRMATR_BEGIN, RES_FRMATR_END - 1>);
+ SwFormatAnchor aAnchor(RndStdIds::FLY_AT_CHAR);
+ aFrameSet.Put(aAnchor);
+ // Default margin is 1440, this is 1440/2.
+ SwFormatFrameSize aSize(SwFrameSize::Fixed, 720, 720);
+ aFrameSet.Put(aSize);
+ // This is 1440/4.
+ SwFormatHoriOrient aOrient(pBodyFrame->getFrameArea().Right() + 360);
+ aFrameSet.Put(aOrient);
+ Graphic aGrf;
+ pWrtShell->SwFEShell::Insert(OUString(), OUString(), &aGrf, &aFrameSet);
+
+ // Then make sure that the image is on the right margin:
+ SwTwips nBodyRight = pBodyFrame->getFrameArea().Right();
+ CPPUNIT_ASSERT(pPageFrame->GetSortedObjs());
+ const SwSortedObjs& rPageObjs = *pPageFrame->GetSortedObjs();
+ CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), rPageObjs.size());
+ const SwAnchoredObject* pAnchored = rPageObjs[0];
+ Point aAnchoredCenter = pAnchored->GetDrawObj()->GetLastBoundRect().Center();
+ // Without the accompanying fix in place, this test would have failed with:
+ // - Expected greater than: 11389
+ // - Actual : 643
+ // i.e. the graphic was on the left margin, not on the right margin.
+ CPPUNIT_ASSERT_GREATER(nBodyRight, aAnchoredCenter.getX());
+}
}
CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/sw/qa/core/text/data/Broken indent demo.odt b/sw/qa/core/text/data/Broken indent demo.odt
new file mode 100644
index 000000000000..af5928bfa556
--- /dev/null
+++ b/sw/qa/core/text/data/Broken indent demo.odt
Binary files differ
diff --git a/sw/qa/core/text/data/clearing-break-wrap-through.docx b/sw/qa/core/text/data/clearing-break-wrap-through.docx
new file mode 100644
index 000000000000..c96e8c27da5e
--- /dev/null
+++ b/sw/qa/core/text/data/clearing-break-wrap-through.docx
Binary files differ
diff --git a/sw/qa/core/text/data/tdf156146.fodt b/sw/qa/core/text/data/tdf156146.fodt
new file mode 100644
index 000000000000..1587cd945e49
--- /dev/null
+++ b/sw/qa/core/text/data/tdf156146.fodt
@@ -0,0 +1,281 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<office:document xmlns:css3t="http://www.w3.org/TR/css3-text/" xmlns:grddl="http://www.w3.org/2003/g/data-view#" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xforms="http://www.w3.org/2002/xforms" xmlns:dom="http://www.w3.org/2001/xml-events" xmlns:script="urn:oasis:names:tc:opendocument:xmlns:script:1.0" xmlns:form="urn:oasis:names:tc:opendocument:xmlns:form:1.0" xmlns:math="http://www.w3.org/1998/Math/MathML" xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" xmlns:ooo="http://openoffice.org/2004/office" xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0" xmlns:config="urn:oasis:names:tc:opendocument:xmlns:config:1.0" xmlns:ooow="http://openoffice.org/2004/writer" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:drawooo="http://openoffice.org/2010/draw" xmlns:oooc="http://openoffice.org/2004/calc" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:calcext="urn:org:documentfoundation:names:experimental:calc:xmlns:calcext:1.0" xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0" xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" xmlns:of="urn:oasis:names:tc:opendocument:xmlns:of:1.2" xmlns:tableooo="http://openoffice.org/2009/table" xmlns:draw="urn:oasis:names:tc:opendocument:xmlns:drawing:1.0" xmlns:dr3d="urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0" xmlns:rpt="http://openoffice.org/2005/report" xmlns:formx="urn:openoffice:names:experimental:ooxml-odf-interop:xmlns:form:1.0" xmlns:svg="urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0" xmlns:chart="urn:oasis:names:tc:opendocument:xmlns:chart:1.0" xmlns:officeooo="http://openoffice.org/2009/office" xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0" xmlns:field="urn:openoffice:names:experimental:ooo-ms-interop:xmlns:field:1.0" xmlns:number="urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0" xmlns:meta="urn:oasis:names:tc:opendocument:xmlns:meta:1.0" xmlns:loext="urn:org:documentfoundation:names:experimental:office:xmlns:loext:1.0" office:version="1.3" office:mimetype="application/vnd.oasis.opendocument.text">
+ <office:meta><meta:creation-date>2023-06-14T01:10:01.497511077</meta:creation-date><dc:date>2024-04-18T18:00:26.359273842</dc:date><meta:editing-duration>PT14M47S</meta:editing-duration><meta:editing-cycles>2</meta:editing-cycles><meta:generator>ZetaOffice/7.4.8.0.0$Linux_X86_64 LibreOffice_project/b82f1163cc2fc696cf86209d94d838d04998350f</meta:generator><meta:document-statistic meta:table-count="0" meta:image-count="0" meta:object-count="0" meta:page-count="1" meta:paragraph-count="1" meta:word-count="154" meta:character-count="806" meta:non-whitespace-character-count="653"/></office:meta>
+ <office:settings>
+ <config:config-item-set config:name="ooo:configuration-settings">
+ <config:config-item config:name="PrintProspect" config:type="boolean">false</config:config-item>
+ <config:config-item config:name="PrintReversed" config:type="boolean">false</config:config-item>
+ <config:config-item config:name="PrintSingleJobs" config:type="boolean">false</config:config-item>
+ <config:config-item config:name="PrintLeftPages" config:type="boolean">true</config:config-item>
+ <config:config-item config:name="PrintTables" config:type="boolean">true</config:config-item>
+ <config:config-item config:name="PrintControls" config:type="boolean">true</config:config-item>
+ <config:config-item config:name="PrintPageBackground" config:type="boolean">true</config:config-item>
+ <config:config-item config:name="PrintDrawings" config:type="boolean">true</config:config-item>
+ <config:config-item config:name="PrintBlackFonts" config:type="boolean">false</config:config-item>
+ <config:config-item config:name="PrintAnnotationMode" config:type="short">0</config:config-item>
+ <config:config-item config:name="PrintTextPlaceholder" config:type="boolean">false</config:config-item>
+ <config:config-item config:name="ProtectFields" config:type="boolean">false</config:config-item>
+ <config:config-item config:name="ProtectBookmarks" config:type="boolean">false</config:config-item>
+ <config:config-item config:name="EmptyDbFieldHidesPara" config:type="boolean">true</config:config-item>
+ <config:config-item config:name="DisableOffPagePositioning" config:type="boolean">false</config:config-item>
+ <config:config-item config:name="SubtractFlysAnchoredAtFlys" config:type="boolean">false</config:config-item>
+ <config:config-item config:name="PropLineSpacingShrinksFirstLine" config:type="boolean">true</config:config-item>
+ <config:config-item config:name="ApplyParagraphMarkFormatToNumbering" config:type="boolean">false</config:config-item>
+ <config:config-item config:name="GutterAtTop" config:type="boolean">false</config:config-item>
+ <config:config-item config:name="TreatSingleColumnBreakAsPageBreak" config:type="boolean">false</config:config-item>
+ <config:config-item config:name="EmbedSystemFonts" config:type="boolean">false</config:config-item>
+ <config:config-item config:name="EmbedComplexScriptFonts" config:type="boolean">true</config:config-item>
+ <config:config-item config:name="EmbedAsianScriptFonts" config:type="boolean">true</config:config-item>
+ <config:config-item config:name="EmbedLatinScriptFonts" config:type="boolean">true</config:config-item>
+ <config:config-item config:name="EmbedOnlyUsedFonts" config:type="boolean">false</config:config-item>
+ <config:config-item config:name="WordLikeWrapForAsCharFlys" config:type="boolean">false</config:config-item>
+ <config:config-item config:name="ContinuousEndnotes" config:type="boolean">false</config:config-item>
+ <config:config-item config:name="EmbedFonts" config:type="boolean">false</config:config-item>
+ <config:config-item config:name="ClippedPictures" config:type="boolean">false</config:config-item>
+ <config:config-item config:name="FloattableNomargins" config:type="boolean">false</config:config-item>
+ <config:config-item config:name="UnbreakableNumberings" config:type="boolean">false</config:config-item>
+ <config:config-item config:name="HeaderSpacingBelowLastPara" config:type="boolean">false</config:config-item>
+ <config:config-item config:name="AllowPrintJobCancel" config:type="boolean">true</config:config-item>
+ <config:config-item config:name="UseOldPrinterMetrics" config:type="boolean">false</config:config-item>
+ <config:config-item config:name="TabOverMargin" config:type="boolean">false</config:config-item>
+ <config:config-item config:name="TabsRelativeToIndent" config:type="boolean">true</config:config-item>
+ <config:config-item config:name="UseOldNumbering" config:type="boolean">false</config:config-item>
+ <config:config-item config:name="InvertBorderSpacing" config:type="boolean">false</config:config-item>
+ <config:config-item config:name="PrintPaperFromSetup" config:type="boolean">false</config:config-item>
+ <config:config-item config:name="UpdateFromTemplate" config:type="boolean">true</config:config-item>
+ <config:config-item config:name="CurrentDatabaseCommandType" config:type="int">0</config:config-item>
+ <config:config-item config:name="LinkUpdateMode" config:type="short">1</config:config-item>
+ <config:config-item config:name="AddParaSpacingToTableCells" config:type="boolean">true</config:config-item>
+ <config:config-item config:name="FrameAutowidthWithMorePara" config:type="boolean">false</config:config-item>
+ <config:config-item config:name="CurrentDatabaseCommand" config:type="string"/>
+ <config:config-item config:name="PrinterIndependentLayout" config:type="string">high-resolution</config:config-item>
+ <config:config-item config:name="ApplyUserData" config:type="boolean">true</config:config-item>
+ <config:config-item config:name="PrintFaxName" config:type="string"/>
+ <config:config-item config:name="CurrentDatabaseDataSource" config:type="string"/>
+ <config:config-item config:name="ClipAsCharacterAnchoredWriterFlyFrames" config:type="boolean">false</config:config-item>
+ <config:config-item config:name="IsKernAsianPunctuation" config:type="boolean">false</config:config-item>
+ <config:config-item config:name="SaveThumbnail" config:type="boolean">true</config:config-item>
+ <config:config-item config:name="UseFormerTextWrapping" config:type="boolean">false</config:config-item>
+ <config:config-item config:name="AutoFirstLineIndentDisregardLineSpace" config:type="boolean">true</config:config-item>
+ <config:config-item config:name="AddExternalLeading" config:type="boolean">true</config:config-item>
+ <config:config-item config:name="AddParaTableSpacing" config:type="boolean">true</config:config-item>
+ <config:config-item config:name="StylesNoDefault" config:type="boolean">false</config:config-item>
+ <config:config-item config:name="ChartAutoUpdate" config:type="boolean">true</config:config-item>
+ <config:config-item config:name="PrinterSetup" config:type="base64Binary"/>
+ <config:config-item config:name="AddParaTableSpacingAtStart" config:type="boolean">true</config:config-item>
+ <config:config-item config:name="Rsid" config:type="int">910346</config:config-item>
+ <config:config-item config:name="EmbeddedDatabaseName" config:type="string"/>
+ <config:config-item config:name="FieldAutoUpdate" config:type="boolean">true</config:config-item>
+ <config:config-item config:name="OutlineLevelYieldsNumbering" config:type="boolean">false</config:config-item>
+ <config:config-item config:name="FootnoteInColumnToPageEnd" config:type="boolean">true</config:config-item>
+ <config:config-item config:name="AlignTabStopPosition" config:type="boolean">true</config:config-item>
+ <config:config-item config:name="CharacterCompressionType" config:type="short">0</config:config-item>
+ <config:config-item config:name="PrinterName" config:type="string"/>
+ <config:config-item config:name="SaveGlobalDocumentLinks" config:type="boolean">false</config:config-item>
+ <config:config-item config:name="PrinterPaperFromSetup" config:type="boolean">false</config:config-item>
+ <config:config-item config:name="UseFormerLineSpacing" config:type="boolean">false</config:config-item>
+ <config:config-item config:name="AddParaLineSpacingToTableCells" config:type="boolean">true</config:config-item>
+ <config:config-item config:name="UseFormerObjectPositioning" config:type="boolean">false</config:config-item>
+ <config:config-item config:name="PrintGraphics" config:type="boolean">true</config:config-item>
+ <config:config-item config:name="ImagePreferredDPI" config:type="int">0</config:config-item>
+ <config:config-item config:name="SurroundTextWrapSmall" config:type="boolean">false</config:config-item>
+ <config:config-item config:name="ConsiderTextWrapOnObjPos" config:type="boolean">false</config:config-item>
+ <config:config-item config:name="MsWordCompTrailingBlanks" config:type="boolean">false</config:config-item>
+ <config:config-item config:name="TabAtLeftIndentForParagraphsInList" config:type="boolean">false</config:config-item>
+ <config:config-item config:name="PrintRightPages" config:type="boolean">true</config:config-item>
+ <config:config-item config:name="TabOverSpacing" config:type="boolean">false</config:config-item>
+ <config:config-item config:name="IgnoreFirstLineIndentInNumbering" config:type="boolean">false</config:config-item>
+ <config:config-item config:name="NoNumberingShowFollowBy" config:type="boolean">false</config:config-item>
+ <config:config-item config:name="RedlineProtectionKey" config:type="base64Binary"/>
+ <config:config-item config:name="DoNotJustifyLinesWithManualBreak" config:type="boolean">false</config:config-item>
+ <config:config-item config:name="PrintProspectRTL" config:type="boolean">false</config:config-item>
+ <config:config-item config:name="PrintEmptyPages" config:type="boolean">true</config:config-item>
+ <config:config-item config:name="DoNotResetParaAttrsForNumFont" config:type="boolean">false</config:config-item>
+ <config:config-item config:name="AddFrameOffsets" config:type="boolean">false</config:config-item>
+ <config:config-item config:name="IgnoreTabsAndBlanksForLineCalculation" config:type="boolean">false</config:config-item>
+ <config:config-item config:name="LoadReadonly" config:type="boolean">false</config:config-item>
+ <config:config-item config:name="DoNotCaptureDrawObjsOnPage" config:type="boolean">false</config:config-item>
+ <config:config-item config:name="AddVerticalFrameOffsets" config:type="boolean">false</config:config-item>
+ <config:config-item config:name="UnxForceZeroExtLeading" config:type="boolean">false</config:config-item>
+ <config:config-item config:name="IsLabelDocument" config:type="boolean">false</config:config-item>
+ <config:config-item config:name="TableRowKeep" config:type="boolean">false</config:config-item>
+ <config:config-item config:name="RsidRoot" config:type="int">811422</config:config-item>
+ <config:config-item config:name="PrintHiddenText" config:type="boolean">false</config:config-item>
+ <config:config-item config:name="ProtectForm" config:type="boolean">false</config:config-item>
+ <config:config-item config:name="MsWordCompMinLineHeightByFly" config:type="boolean">false</config:config-item>
+ <config:config-item config:name="BackgroundParaOverDrawings" config:type="boolean">false</config:config-item>
+ <config:config-item config:name="SaveVersionOnClose" config:type="boolean">false</config:config-item>
+ <config:config-item config:name="MathBaselineAlignment" config:type="boolean">true</config:config-item>
+ <config:config-item config:name="SmallCapsPercentage66" config:type="boolean">false</config:config-item>
+ <config:config-item config:name="CollapseEmptyCellPara" config:type="boolean">true</config:config-item>
+ <config:config-item config:name="TabOverflow" config:type="boolean">true</config:config-item>
+ </config:config-item-set>
+ </office:settings>
+ <office:font-face-decls>
+ <style:font-face style:name="Arial Unicode MS1" svg:font-family="'Arial Unicode MS'" style:font-family-generic="system" style:font-pitch="variable"/>
+ <style:font-face style:name="Liberation Serif" svg:font-family="'Liberation Serif'" style:font-family-generic="roman" style:font-pitch="variable"/>
+ <style:font-face style:name="SimSun" svg:font-family="SimSun" style:font-family-generic="system" style:font-pitch="variable"/>
+ </office:font-face-decls>
+ <office:styles>
+ <style:default-style style:family="graphic">
+ <style:graphic-properties svg:stroke-color="#3465a4" draw:fill-color="#729fcf" fo:wrap-option="no-wrap" draw:shadow-offset-x="0.3cm" draw:shadow-offset-y="0.3cm" draw:start-line-spacing-horizontal="0.283cm" draw:start-line-spacing-vertical="0.283cm" draw:end-line-spacing-horizontal="0.283cm" draw:end-line-spacing-vertical="0.283cm" style:flow-with-text="false"/>
+ <style:paragraph-properties style:text-autospace="ideograph-alpha" style:line-break="strict" style:font-independent-line-spacing="false">
+ <style:tab-stops/>
+ </style:paragraph-properties>
+ <style:text-properties style:use-window-font-color="true" loext:opacity="0%" loext:color-lum-mod="100%" loext:color-lum-off="0%" style:font-name="Liberation Serif" fo:font-size="12pt" fo:language="en" fo:country="US" style:letter-kerning="true" style:font-name-asian="SimSun" style:font-size-asian="10.5pt" style:language-asian="zh" style:country-asian="CN" style:font-name-complex="Arial Unicode MS1" style:font-size-complex="12pt" style:language-complex="hi" style:country-complex="IN"/>
+ </style:default-style>
+ <style:default-style style:family="paragraph">
+ <style:paragraph-properties fo:orphans="2" fo:widows="2" fo:hyphenation-ladder-count="no-limit" style:text-autospace="ideograph-alpha" style:punctuation-wrap="hanging" style:line-break="strict" style:tab-stop-distance="1.251cm" style:writing-mode="page"/>
+ <style:text-properties style:use-window-font-color="true" loext:opacity="0%" style:font-name="Liberation Serif" fo:font-size="12pt" fo:language="en" fo:country="US" style:letter-kerning="true" style:font-name-asian="SimSun" style:font-size-asian="10.5pt" style:language-asian="zh" style:country-asian="CN" style:font-name-complex="Arial Unicode MS1" style:font-size-complex="12pt" style:language-complex="hi" style:country-complex="IN" fo:hyphenate="false" fo:hyphenation-remain-char-count="2" fo:hyphenation-push-char-count="2" loext:hyphenation-no-caps="false" loext:hyphenation-no-last-word="false" loext:hyphenation-word-char-count="5" loext:hyphenation-zone="no-limit"/>
+ </style:default-style>
+ <style:default-style style:family="table">
+ <style:table-properties table:border-model="collapsing"/>
+ </style:default-style>
+ <style:default-style style:family="table-row">
+ <style:table-row-properties fo:keep-together="auto"/>
+ </style:default-style>
+ <style:style style:name="Standard" style:family="paragraph" style:class="text"/>
+ <style:style style:name="Numbered_20_paragraph" style:display-name="Numbered paragraph" style:family="paragraph" style:parent-style-name="Standard" style:default-outline-level="1" style:list-style-name="Numbering_20_123">
+ <style:paragraph-properties fo:margin-left="0cm" fo:margin-right="0cm" fo:text-indent="0cm" style:auto-text-indent="false" text:number-lines="false" text:line-number="0"/>
+ </style:style>
+ <style:style style:name="Numbering_20_Symbols" style:display-name="Numbering Symbols" style:family="text"/>
+ <text:outline-style style:name="Outline">
+ <text:outline-level-style text:level="1" loext:num-list-format="%1%" style:num-format="">
+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment">
+ <style:list-level-label-alignment text:label-followed-by="listtab"/>
+ </style:list-level-properties>
+ </text:outline-level-style>
+ <text:outline-level-style text:level="2" loext:num-list-format="%2%" style:num-format="">
+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment">
+ <style:list-level-label-alignment text:label-followed-by="listtab"/>
+ </style:list-level-properties>
+ </text:outline-level-style>
+ <text:outline-level-style text:level="3" loext:num-list-format="%3%" style:num-format="">
+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment">
+ <style:list-level-label-alignment text:label-followed-by="listtab"/>
+ </style:list-level-properties>
+ </text:outline-level-style>
+ <text:outline-level-style text:level="4" loext:num-list-format="%4%" style:num-format="">
+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment">
+ <style:list-level-label-alignment text:label-followed-by="listtab"/>
+ </style:list-level-properties>
+ </text:outline-level-style>
+ <text:outline-level-style text:level="5" loext:num-list-format="%5%" style:num-format="">
+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment">
+ <style:list-level-label-alignment text:label-followed-by="listtab"/>
+ </style:list-level-properties>
+ </text:outline-level-style>
+ <text:outline-level-style text:level="6" loext:num-list-format="%6%" style:num-format="">
+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment">
+ <style:list-level-label-alignment text:label-followed-by="listtab"/>
+ </style:list-level-properties>
+ </text:outline-level-style>
+ <text:outline-level-style text:level="7" loext:num-list-format="%7%" style:num-format="">
+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment">
+ <style:list-level-label-alignment text:label-followed-by="listtab"/>
+ </style:list-level-properties>
+ </text:outline-level-style>
+ <text:outline-level-style text:level="8" loext:num-list-format="%8%" style:num-format="">
+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment">
+ <style:list-level-label-alignment text:label-followed-by="listtab"/>
+ </style:list-level-properties>
+ </text:outline-level-style>
+ <text:outline-level-style text:level="9" loext:num-list-format="%9%" style:num-format="">
+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment">
+ <style:list-level-label-alignment text:label-followed-by="listtab"/>
+ </style:list-level-properties>
+ </text:outline-level-style>
+ <text:outline-level-style text:level="10" loext:num-list-format="%10%" style:num-format="">
+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment">
+ <style:list-level-label-alignment text:label-followed-by="listtab"/>
+ </style:list-level-properties>
+ </text:outline-level-style>
+ </text:outline-style>
+ <text:list-style style:name="Numbering_20_123" style:display-name="Numbering 123">
+ <text:list-level-style-number text:level="1" text:style-name="Numbering_20_Symbols" loext:num-list-format="%1%." style:num-suffix="." style:num-format="1">
+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment">
+ <style:list-level-label-alignment text:label-followed-by="listtab" fo:text-indent="-0.7cm" fo:margin-left="1.33cm"/>
+ </style:list-level-properties>
+ </text:list-level-style-number>
+ <text:list-level-style-number text:level="2" text:style-name="Numbering_20_Symbols" loext:num-list-format="%2%." style:num-suffix="." style:num-format="1">
+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment">
+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="1.401cm" fo:text-indent="-0.7cm" fo:margin-left="2.03cm"/>
+ </style:list-level-properties>
+ </text:list-level-style-number>
+ <text:list-level-style-number text:level="3" text:style-name="Numbering_20_Symbols" loext:num-list-format="%3%." style:num-suffix="." style:num-format="1">
+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment">
+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="2.101cm" fo:text-indent="-0.7cm" fo:margin-left="2.731cm"/>
+ </style:list-level-properties>
+ </text:list-level-style-number>
+ <text:list-level-style-number text:level="4" text:style-name="Numbering_20_Symbols" loext:num-list-format="%4%." style:num-suffix="." style:num-format="1">
+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment">
+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="2.801cm" fo:text-indent="-0.7cm" fo:margin-left="3.431cm"/>
+ </style:list-level-properties>
+ </text:list-level-style-number>
+ <text:list-level-style-number text:level="5" text:style-name="Numbering_20_Symbols" loext:num-list-format="%5%." style:num-suffix="." style:num-format="1">
+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment">
+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="3.501cm" fo:text-indent="-0.7cm" fo:margin-left="4.131cm"/>
+ </style:list-level-properties>
+ </text:list-level-style-number>
+ <text:list-level-style-number text:level="6" text:style-name="Numbering_20_Symbols" loext:num-list-format="%6%." style:num-suffix="." style:num-format="1">
+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment">
+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="4.2cm" fo:text-indent="-0.7cm" fo:margin-left="4.83cm"/>
+ </style:list-level-properties>
+ </text:list-level-style-number>
+ <text:list-level-style-number text:level="7" text:style-name="Numbering_20_Symbols" loext:num-list-format="%7%." style:num-suffix="." style:num-format="1">
+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment">
+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="4.9cm" fo:text-indent="-0.7cm" fo:margin-left="5.53cm"/>
+ </style:list-level-properties>
+ </text:list-level-style-number>
+ <text:list-level-style-number text:level="8" text:style-name="Numbering_20_Symbols" loext:num-list-format="%8%." style:num-suffix="." style:num-format="1">
+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment">
+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="5.6cm" fo:text-indent="-0.7cm" fo:margin-left="6.23cm"/>
+ </style:list-level-properties>
+ </text:list-level-style-number>
+ <text:list-level-style-number text:level="9" text:style-name="Numbering_20_Symbols" loext:num-list-format="%9%." style:num-suffix="." style:num-format="1">
+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment">
+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="6.301cm" fo:text-indent="-0.7cm" fo:margin-left="6.93cm"/>
+ </style:list-level-properties>
+ </text:list-level-style-number>
+ <text:list-level-style-number text:level="10" text:style-name="Numbering_20_Symbols" loext:num-list-format="%10%." style:num-suffix="." style:num-format="1">
+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment">
+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="7.001cm" fo:text-indent="-0.7cm" fo:margin-left="7.631cm"/>
+ </style:list-level-properties>
+ </text:list-level-style-number>
+ </text:list-style>
+ <text:notes-configuration text:note-class="footnote" style:num-format="1" text:start-value="0" text:footnotes-position="page" text:start-numbering-at="document"/>
+ <text:notes-configuration text:note-class="endnote" style:num-format="i" text:start-value="0"/>
+ <text:linenumbering-configuration text:number-lines="false" text:offset="0.499cm" style:num-format="1" text:number-position="left" text:increment="5"/>
+ </office:styles>
+ <office:automatic-styles>
+ <style:page-layout style:name="pm1">
+ <style:page-layout-properties fo:page-width="21.59cm" fo:page-height="27.94cm" style:num-format="1" style:print-orientation="portrait" fo:margin-top="2cm" fo:margin-bottom="2cm" fo:margin-left="2cm" fo:margin-right="2cm" style:writing-mode="lr-tb" style:layout-grid-color="#c0c0c0" style:layout-grid-lines="20" style:layout-grid-base-height="0.706cm" style:layout-grid-ruby-height="0.353cm" style:layout-grid-mode="none" style:layout-grid-ruby-below="false" style:layout-grid-print="false" style:layout-grid-display="false" style:footnote-max-height="0cm" loext:margin-gutter="0cm">
+ <style:footnote-sep style:width="0.018cm" style:distance-before-sep="0.101cm" style:distance-after-sep="0.101cm" style:line-style="solid" style:adjustment="left" style:rel-width="25%" style:color="#000000"/>
+ </style:page-layout-properties>
+ <style:header-style/>
+ <style:footer-style/>
+ </style:page-layout>
+ <style:style style:name="dp1" style:family="drawing-page">
+ <style:drawing-page-properties draw:background-size="full"/>
+ </style:style>
+ </office:automatic-styles>
+ <office:master-styles>
+ <style:master-page style:name="Standard" style:page-layout-name="pm1" draw:style-name="dp1"/>
+ </office:master-styles>
+ <office:body>
+ <office:text>
+ <text:sequence-decls>
+ <text:sequence-decl text:display-outline-level="0" text:name="Illustration"/>
+ <text:sequence-decl text:display-outline-level="0" text:name="Table"/>
+ <text:sequence-decl text:display-outline-level="0" text:name="Text"/>
+ <text:sequence-decl text:display-outline-level="0" text:name="Drawing"/>
+ <text:sequence-decl text:display-outline-level="0" text:name="Figure"/>
+ </text:sequence-decls>
+ <text:list text:style-name="Numbering_20_123">
+ <text:list-item>
+ <text:h text:style-name="Numbered_20_paragraph" text:outline-level="1">He heard quiet steps behind him. That didn't bode well. Who could be following him this late at night and in this deadbeat part of town? And at this particular moment, just after he pulled off the big time and was making off with the greenbacks. Was there another crook who'd had the same idea, and was now watching him and waiting for a chance to grab the fruit of his labor? Or did the steps behind him mean that one of many law officers in town was on to him and just waiting to pounce and snap those cuffs on his wrists? He nervously looked all around. Suddenly he saw the alley. Like lightning he darted off to the left and disappeared between the two warehouses almost falling over the trash can lying in the middle of the sidewalk. He tried to nervously tap his way along in the inky darkness and </text:h>
+ </text:list-item>
+ </text:list>
+ </office:text>
+ </office:body>
+</office:document>
diff --git a/sw/qa/core/text/text.cxx b/sw/qa/core/text/text.cxx
index 690fc333afb5..f18c4fd531f8 100644
--- a/sw/qa/core/text/text.cxx
+++ b/sw/qa/core/text/text.cxx
@@ -22,6 +22,7 @@
#include <vcl/filter/PDFiumLibrary.hxx>
#include <vcl/filter/pdfdocument.hxx>
#include <comphelper/propertyvalue.hxx>
+#include <comphelper/sequenceashashmap.hxx>
#include <editeng/fhgtitem.hxx>
#include <editeng/wghtitem.hxx>
@@ -45,6 +46,8 @@
#include <txatbase.hxx>
#include <textcontentcontrol.hxx>
#include <pagefrm.hxx>
+#include <inftxt.hxx>
+#include <itrtxt.hxx>
/// Covers sw/source/core/text/ fixes.
class SwCoreTextTest : public SwModelTestBase
@@ -116,6 +119,65 @@ CPPUNIT_TEST_FIXTURE(SwCoreTextTest, testLastBibliographyPdfExport)
CPPUNIT_ASSERT(true);
}
+CPPUNIT_TEST_FIXTURE(SwCoreTextTest, testTdf156146)
+{
+ createSwDoc("tdf156146.fodt");
+
+ uno::Reference<container::XIndexAccess> const xLevels1(
+ getProperty<uno::Reference<container::XIndexAccess>>(getParagraph(1), "NumberingRules"));
+ uno::Reference<container::XNamed> const xNum1(xLevels1, uno::UNO_QUERY);
+ ::comphelper::SequenceAsHashMap props1(xLevels1->getByIndex(0));
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(-700), props1["FirstLineIndent"].get<sal_Int32>());
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(1330), props1["IndentAt"].get<sal_Int32>());
+
+ // common style applies list-style-name and margin-left
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(0),
+ getProperty<sal_Int32>(getParagraph(1), "ParaFirstLineIndent"));
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(0), getProperty<sal_Int32>(getParagraph(1), "ParaLeftMargin"));
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(0), getProperty<sal_Int32>(getParagraph(1), "ParaRightMargin"));
+
+ SwTextFrame* const pFrame(dynamic_cast<SwTextFrame*>(
+ static_cast<SwPageFrame*>(getSwDoc()->GetDocShell()->GetWrtShell()->GetLayout()->GetLower())
+ ->FindFirstBodyContent()));
+ CPPUNIT_ASSERT(pFrame);
+ // this appears to be the only way to get the actual computed margins
+ SwTextSizeInfo info(pFrame);
+ SwTextMargin tm(pFrame, &info);
+ // this was wrong, 357
+ CPPUNIT_ASSERT_EQUAL(SwTwips(0), tm.FirstLeft() - pFrame->getFrameArea().Left());
+ // this was wrong, 754
+ CPPUNIT_ASSERT_EQUAL(SwTwips(0), tm.Left() - pFrame->getFrameArea().Left());
+}
+
+CPPUNIT_TEST_FIXTURE(SwCoreTextTest, testTdf159903)
+{
+ createSwDoc("Broken indent demo.odt");
+
+ uno::Reference<container::XIndexAccess> const xLevels1(
+ getProperty<uno::Reference<container::XIndexAccess>>(getParagraph(1), "NumberingRules"));
+ uno::Reference<container::XNamed> const xNum1(xLevels1, uno::UNO_QUERY);
+ ::comphelper::SequenceAsHashMap props1(xLevels1->getByIndex(0));
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(-4001), props1["FirstLineIndent"].get<sal_Int32>());
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(4001), props1["IndentAt"].get<sal_Int32>());
+
+ // common style applies list-style-name, parent style margin-left
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(0),
+ getProperty<sal_Int32>(getParagraph(1), "ParaFirstLineIndent"));
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(0), getProperty<sal_Int32>(getParagraph(1), "ParaLeftMargin"));
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(0), getProperty<sal_Int32>(getParagraph(1), "ParaRightMargin"));
+
+ SwTextFrame* const pFrame(dynamic_cast<SwTextFrame*>(
+ static_cast<SwPageFrame*>(getSwDoc()->GetDocShell()->GetWrtShell()->GetLayout()->GetLower())
+ ->FindFirstBodyContent()));
+ CPPUNIT_ASSERT(pFrame);
+ // this appears to be the only way to get the actual computed margins
+ SwTextSizeInfo info(pFrame);
+ SwTextMargin tm(pFrame, &info);
+ CPPUNIT_ASSERT_EQUAL(SwTwips(0), tm.FirstLeft() - pFrame->getFrameArea().Left());
+ // left was wrong, was same as first
+ CPPUNIT_ASSERT_EQUAL(SwTwips(2268), tm.Left() - pFrame->getFrameArea().Left());
+}
+
CPPUNIT_TEST_FIXTURE(SwCoreTextTest, testTdf159336)
{
createSwDoc("tdf159336.odt");
diff --git a/sw/qa/core/text/txtfly.cxx b/sw/qa/core/text/txtfly.cxx
new file mode 100644
index 000000000000..461ed81e2203
--- /dev/null
+++ b/sw/qa/core/text/txtfly.cxx
@@ -0,0 +1,52 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <swmodeltestbase.hxx>
+
+#include <memory>
+
+#include <IDocumentLayoutAccess.hxx>
+#include <doc.hxx>
+#include <frame.hxx>
+#include <pagefrm.hxx>
+#include <rootfrm.hxx>
+
+namespace
+{
+/// Covers sw/source/core/text/txtfly.cxx fixes.
+class Test : public SwModelTestBase
+{
+public:
+ Test()
+ : SwModelTestBase("/sw/qa/core/text/data/")
+ {
+ }
+};
+
+CPPUNIT_TEST_FIXTURE(Test, testClearingBreakWrapThrough)
+{
+ // Given a document with a clearing break, then a shape in the next paragraph:
+ createSwDoc("clearing-break-wrap-through.docx");
+
+ // When laying out that document:
+ calcLayout();
+
+ // Then make sure we layout these 2 paragraphs on a single page, since there is enough space for
+ // them:
+ SwDoc* pDoc = getSwDoc();
+ SwRootFrame* pLayout = pDoc->getIDocumentLayoutAccess().GetCurrentLayout();
+ auto pPage = pLayout->Lower()->DynCastPageFrame();
+ CPPUNIT_ASSERT(pPage);
+ // Without the accompanying fix in place, this test would have failed, we had an unexpected 2nd
+ // page.
+ CPPUNIT_ASSERT(!pPage->GetNext());
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/qa/core/txtnode/data/plain-content-control-copy.docx b/sw/qa/core/txtnode/data/plain-content-control-copy.docx
new file mode 100644
index 000000000000..80fecae26d5b
--- /dev/null
+++ b/sw/qa/core/txtnode/data/plain-content-control-copy.docx
Binary files differ
diff --git a/sw/qa/core/txtnode/txtnode.cxx b/sw/qa/core/txtnode/txtnode.cxx
index c2df8a407e69..be4d97190251 100644
--- a/sw/qa/core/txtnode/txtnode.cxx
+++ b/sw/qa/core/txtnode/txtnode.cxx
@@ -539,6 +539,29 @@ CPPUNIT_TEST_FIXTURE(SwCoreTxtnodeTest, testSplitFlyAnchorSplit)
CPPUNIT_ASSERT_EQUAL(OUString("PortionType::Fly"), aPortionType);
}
+CPPUNIT_TEST_FIXTURE(SwCoreTxtnodeTest, testPlainContentControlCopy)
+{
+ // Given a document with a plain text content control, all text selected and copied to the
+ // clipboard:
+ createSwDoc("plain-content-control-copy.docx");
+ SwDocShell* pDocShell = getSwDocShell();
+ SwWrtShell* pWrtShell = pDocShell->GetWrtShell();
+ pWrtShell->SelAll();
+ {
+ rtl::Reference<SwTransferable> xTransfer = new SwTransferable(*pWrtShell);
+ xTransfer->Copy();
+ }
+
+ // When closing that document, then make sure we don't crash on shutdown:
+ uno::Reference<frame::XModel> xModel(mxComponent, uno::UNO_QUERY);
+ uno::Reference<util::XCloseable> xFrame(xModel->getCurrentController()->getFrame(),
+ uno::UNO_QUERY);
+ // Without the accompanying fix in place, this resulted in an assertion failure, a char style
+ // still had clients by the time it was deleted.
+ xFrame->close(false);
+ mxComponent.clear();
+}
+
CPPUNIT_PLUGIN_IMPLEMENT();
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/qa/extras/layout/data/tdf160958_orphans_move_section.fodt b/sw/qa/extras/layout/data/tdf160958_orphans_move_section.fodt
new file mode 100644
index 000000000000..1306cfa6226d
--- /dev/null
+++ b/sw/qa/extras/layout/data/tdf160958_orphans_move_section.fodt
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<office:document xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0" xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0" xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" xmlns:svg="urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0" office:version="1.3" office:mimetype="application/vnd.oasis.opendocument.text">
+ <office:font-face-decls>
+ <style:font-face style:name="Liberation Serif" svg:font-family="&apos;Liberation Serif&apos;" style:font-family-generic="roman" style:font-pitch="variable"/>
+ </office:font-face-decls>
+ <office:styles>
+ <style:default-style style:family="paragraph">
+ <style:paragraph-properties fo:orphans="2" fo:widows="2"/>
+ <style:text-properties style:font-name="Liberation Serif" fo:font-size="12pt"/>
+ </style:default-style>
+ </office:styles>
+ <office:automatic-styles>
+ <style:page-layout style:name="pm1">
+ <style:page-layout-properties fo:page-width="21cm" fo:page-height="297mm" style:print-orientation="portrait" fo:margin-top="2cm" fo:margin-bottom="2cm" fo:margin-left="2cm" fo:margin-right="2cm"/>
+ </style:page-layout>
+ </office:automatic-styles>
+ <office:master-styles>
+ <style:master-page style:name="Standard" style:page-layout-name="pm1"/>
+ </office:master-styles>
+ <office:body>
+ <office:text>
+ <text:p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum consequat mi quis pretium semper. Proin luctus orci ac neque venenatis, quis commodo dolor posuere. Curabitur dignissim sapien quis cursus egestas. Donec blandit auctor arcu, nec pellentesque eros molestie eget. In consectetur aliquam hendrerit. Sed cursus mauris vitae ligula pellentesque, non pellentesque urna aliquet. Fusce placerat mauris enim, nec rutrum purus semper vel. Praesent tincidunt neque eu pellentesque pharetra. Fusce pellentesque est orci.</text:p>
+ <text:p>Integer sodales tincidunt tristique. Sed a metus posuere, adipiscing nunc et, viverra odio. Donec auctor molestie sem, sit amet tristique lectus hendrerit sed. Cras sodales nisl sed orci mattis iaculis. Nunc eget dolor accumsan, pharetra risus a, vestibulum mauris. Nunc vulputate lobortis mollis. Vivamus nec tellus faucibus, tempor magna nec, facilisis felis. Donec commodo enim a vehicula pellentesque. Nullam vehicula vestibulum est vel ultricies.</text:p>
+ <text:p>Aliquam velit massa, laoreet vel leo nec, volutpat facilisis eros. Donec consequat arcu ut diam tempor luctus. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Praesent vitae lacus vel leo sodales pharetra a a nibh. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Nam luctus tempus nibh, fringilla dictum augue consectetur eget. Curabitur at ante sit amet tortor pharetra molestie eu nec ante. Mauris tincidunt, nibh eu sollicitudin molestie, dolor sapien congue tortor, a pulvinar sapien turpis sed ante. Donec nec est elementum, euismod nulla in, mollis nunc.</text:p>
+ <text:p>He heard quiet steps behind him. That didn&apos;t bode well. Who could be following him this late at night and in this deadbeat part of town? And at this particular moment, just after he pulled off the big time and was making off with the greenbacks. Was there another crook who&apos;d had the same idea, and was now watching him and waiting for a chance to grab the fruit of his labor? Or did the steps behind him mean that one of many law officers in town was on to him and just waiting to pounce and snap those cuffs on his wrists? He nervously looked all around. Suddenly he saw the alley. Like lightning he darted off to the left and disappeared between the two warehouses almost falling over the trash can lying in the middle of the sidewalk. He tried to nervously tap his way along in the inky darkness and suddenly stiffened: it was a dead-end, he would have to go back the way he had come. The steps got louder and louder, he saw the black outline of a figure coming around the corner. Is this the end of the line? he thought pressing himself back against the wall trying to make himself invisible in the dark, was all that planning and energy wasted? He was dripping with sweat now, cold and wet, he could smell the fear coming off his clothes. Suddenly next to him, with a barely noticeable squeak, a door swung quietly to and fro in the night&apos;s breeze. Could this be the haven he&apos;d prayed for? Slowly he slid toward the door, pressing himself more and more into the wall, into the dark, away from his enemy. Would this door save his hide?</text:p>
+ <text:p>foo</text:p>
+ <text:p>bar</text:p>
+ <text:p>baz</text:p>
+ <text:p>foo</text:p>
+ <text:p>bar</text:p>
+ <text:p>baz</text:p>
+ <text:p>foo</text:p>
+ <text:p>bar</text:p>
+ <text:p>baz</text:p>
+ <text:p>foo</text:p>
+ <text:p>bar</text:p>
+ <text:p>baz</text:p>
+ <text:p>foo</text:p>
+ <text:p>bar</text:p>
+ <text:p>baz</text:p>
+ <text:p>foo</text:p>
+ <text:p>bar</text:p>
+ <text:section text:name="Section1">
+ <text:p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum consequat mi quis pretium semper. Proin luctus orci ac neque venenatis, quis commodo dolor posuere. Curabitur dignissim sapien quis cursus egestas. Donec blandit auctor arcu, nec pellentesque eros molestie eget. In consectetur aliquam hendrerit. Sed cursus mauris vitae ligula pellentesque, non pellentesque urna aliquet. Fusce placerat mauris enim, nec rutrum purus semper vel. Praesent tincidunt neque eu pellentesque pharetra. Fusce pellentesque est orci.</text:p>
+ <text:p>Integer sodales tincidunt tristique. Sed a metus posuere, adipiscing nunc et, viverra odio. Donec auctor molestie sem, sit amet tristique lectus hendrerit sed. Cras sodales nisl sed orci mattis iaculis. Nunc eget dolor accumsan, pharetra risus a, vestibulum mauris. Nunc vulputate lobortis mollis. Vivamus nec tellus faucibus, tempor magna nec, facilisis felis. Donec commodo enim a vehicula pellentesque. Nullam vehicula vestibulum est vel ultricies.</text:p>
+ <text:p>Aliquam velit massa, laoreet vel leo nec, volutpat facilisis eros. Donec consequat arcu ut diam tempor luctus. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Praesent vitae lacus vel leo sodales pharetra a a nibh. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Nam luctus tempus nibh, fringilla dictum augue consectetur eget. Curabitur at ante sit amet tortor pharetra molestie eu nec ante. Mauris tincidunt, nibh eu sollicitudin molestie, dolor sapien congue tortor, a pulvinar sapien turpis sed ante. Donec nec est elementum, euismod nulla in, mollis nunc.</text:p>
+ </text:section>
+ <text:p>baz</text:p>
+ </office:text>
+ </office:body>
+</office:document> \ No newline at end of file
diff --git a/sw/qa/extras/layout/data/tdf160958_page_break.fodt b/sw/qa/extras/layout/data/tdf160958_page_break.fodt
new file mode 100644
index 000000000000..1d4d8863b073
--- /dev/null
+++ b/sw/qa/extras/layout/data/tdf160958_page_break.fodt
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<office:document xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0" xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0" xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" xmlns:svg="urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0" office:version="1.3" office:mimetype="application/vnd.oasis.opendocument.text">
+ <office:font-face-decls>
+ <style:font-face style:name="Liberation Serif" svg:font-family="&apos;Liberation Serif&apos;" style:font-family-generic="roman" style:font-pitch="variable"/>
+ </office:font-face-decls>
+ <office:styles>
+ <style:default-style style:family="paragraph">
+ <style:text-properties style:use-window-font-color="true" style:font-name="Liberation Serif" fo:font-size="12pt"/>
+ </style:default-style>
+ </office:styles>
+ <office:automatic-styles>
+ <style:style style:name="P1" style:family="paragraph" style:master-page-name="">
+ <style:paragraph-properties style:page-number="auto" fo:break-before="page"/>
+ </style:style>
+ <style:page-layout style:name="pm1">
+ <style:page-layout-properties fo:page-width="21cm" fo:page-height="297mm" style:num-format="1" style:print-orientation="portrait" fo:margin-top="2cm" fo:margin-bottom="2cm" fo:margin-left="2cm" fo:margin-right="2cm"/>
+ </style:page-layout>
+ </office:automatic-styles>
+ <office:master-styles>
+ <style:master-page style:name="Standard" style:page-layout-name="pm1"/>
+ </office:master-styles>
+ <office:body>
+ <office:text>
+ <text:p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum consequat mi quis pretium semper. Proin luctus orci ac neque venenatis, quis commodo dolor posuere. Curabitur dignissim sapien quis cursus egestas. Donec blandit auctor arcu, nec pellentesque eros molestie eget. In consectetur aliquam hendrerit. Sed cursus mauris vitae ligula pellentesque, non pellentesque urna aliquet. Fusce placerat mauris enim, nec rutrum purus semper vel. Praesent tincidunt neque eu pellentesque pharetra. Fusce pellentesque est orci.</text:p>
+ <text:section text:name="Section1">
+ <text:p text:style-name="P1"/>
+ <text:p/>
+ <text:p/>
+ <text:p>Integer sodales tincidunt tristique. Sed a metus posuere, adipiscing nunc et, viverra odio. Donec auctor molestie sem, sit amet tristique lectus hendrerit sed. Cras sodales nisl sed orci mattis iaculis. Nunc eget dolor accumsan, pharetra risus a, vestibulum mauris. Nunc vulputate lobortis mollis. <text:soft-page-break/>Vivamus nec tellus faucibus, tempor magna nec, facilisis felis. Donec commodo enim a vehicula pellentesque. Nullam vehicula vestibulum est vel ultricies.</text:p>
+ <text:p/>
+ <text:p/>
+ <text:p/>
+ </text:section>
+ <text:p>Aliquam velit massa, laoreet vel leo nec, volutpat facilisis eros. Donec consequat arcu ut diam tempor luctus. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Praesent vitae lacus vel leo sodales pharetra a a nibh. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Nam luctus tempus nibh, fringilla dictum augue consectetur eget. Curabitur at ante sit amet tortor pharetra molestie eu nec ante. Mauris tincidunt, nibh eu sollicitudin molestie, dolor sapien congue tortor, a pulvinar sapien turpis sed ante. Donec nec est elementum, euismod nulla in, mollis nunc.</text:p>
+ <text:p/>
+ </office:text>
+ </office:body>
+</office:document> \ No newline at end of file
diff --git a/sw/qa/extras/layout/layout2.cxx b/sw/qa/extras/layout/layout2.cxx
index 800e5749fe2c..2e46ebfbfc29 100644
--- a/sw/qa/extras/layout/layout2.cxx
+++ b/sw/qa/extras/layout/layout2.cxx
@@ -856,7 +856,7 @@ CPPUNIT_TEST_FIXTURE(SwLayoutWriter2, testTdf152872)
assertXPath(pXmlDoc, "/root/page[1]/body/txt"_ostr, 2);
assertXPath(pXmlDoc, "/root/page/body/txt[1]/SwParaPortion/SwLineLayout"_ostr, "portion"_ostr,
"C DE");
- assertXPath(pXmlDoc, "/root/page/body/txt[2]/SwParaPortion"_ostr, 0); // 5 is empty and hidden
+ // 5 is empty and hidden
assertXPath(pXmlDoc, "/root/page/body/txt[2]/infos/bounds"_ostr, "height"_ostr, "0");
dispatchCommand(mxComponent, ".uno:ControlCodes", {});
@@ -878,7 +878,6 @@ CPPUNIT_TEST_FIXTURE(SwLayoutWriter2, testTdf152872)
// 5 is an empty paragraph with RES_CHRATR_HIDDEN which results in 0-height
// frame; ideally it should only be hidden when control codes are hidden
// and be a full-height frame now, but that needs more work...
- assertXPath(pXmlDoc, "/root/page/body/txt[5]/SwParaPortion"_ostr, 0); // 5 is empty
assertXPath(pXmlDoc, "/root/page/body/txt[5]/infos/bounds"_ostr, "height"_ostr, "0");
dispatchCommand(mxComponent, ".uno:ControlCodes", {});
@@ -889,7 +888,7 @@ CPPUNIT_TEST_FIXTURE(SwLayoutWriter2, testTdf152872)
assertXPath(pXmlDoc, "/root/page[1]/body/txt"_ostr, 2);
assertXPath(pXmlDoc, "/root/page/body/txt[1]/SwParaPortion/SwLineLayout"_ostr, "portion"_ostr,
"C DE");
- assertXPath(pXmlDoc, "/root/page/body/txt[2]/SwParaPortion"_ostr, 0); // 5 is empty and hidden
+ // 5 is empty and hidden
assertXPath(pXmlDoc, "/root/page/body/txt[2]/infos/bounds"_ostr, "height"_ostr, "0");
}
diff --git a/sw/qa/extras/layout/layout3.cxx b/sw/qa/extras/layout/layout3.cxx
index 98c77b18ecdf..8f555e0bf6ba 100644
--- a/sw/qa/extras/layout/layout3.cxx
+++ b/sw/qa/extras/layout/layout3.cxx
@@ -11,6 +11,7 @@
#include <comphelper/propertysequence.hxx>
#include <com/sun/star/linguistic2/XHyphenator.hpp>
#include <com/sun/star/text/WrapTextMode.hpp>
+#include <com/sun/star/text/XTextSectionsSupplier.hpp>
#include <vcl/event.hxx>
#include <vcl/scheduler.hxx>
#include <editeng/fontitem.hxx>
@@ -1315,7 +1316,7 @@ CPPUNIT_TEST_FIXTURE(SwLayoutWriter3, testTdf124601)
// i.e. there was a separate endnote page, even when the ContinuousEndnotes compat option was
// on.
assertXPath(pXmlDoc, "/root/page"_ostr, 2);
- assertXPath(pXmlDoc, "/root/page[2]/ftncont"_ostr, 1);
+ assertXPath(pXmlDoc, "/root/page[2]//ftncont"_ostr, 1);
}
CPPUNIT_TEST_FIXTURE(SwLayoutWriter3, testTdf124601b)
@@ -1425,7 +1426,7 @@ CPPUNIT_TEST_FIXTURE(SwLayoutWriter3, testContinuousEndnotesInsertPageAtStart)
// - Expected: 1
// - Actual : 0
// i.e. the footnote container remained on page 2.
- assertXPath(pXmlDoc, "/root/page[3]/ftncont"_ostr, 1);
+ assertXPath(pXmlDoc, "/root/page[3]//ftncont"_ostr, 1);
}
CPPUNIT_TEST_FIXTURE(SwLayoutWriter3, testContinuousEndnotesDeletePageAtStart)
@@ -1452,7 +1453,7 @@ CPPUNIT_TEST_FIXTURE(SwLayoutWriter3, testContinuousEndnotesDeletePageAtStart)
// - Actual : 2
// i.e. the endnote remained on an (otherwise) empty 2nd page.
assertXPath(pXmlDoc, "/root/page"_ostr, 1);
- assertXPath(pXmlDoc, "/root/page[1]/ftncont"_ostr, 1);
+ assertXPath(pXmlDoc, "/root/page[1]//ftncont"_ostr, 1);
}
CPPUNIT_TEST_FIXTURE(SwLayoutWriter3, testTdf128399)
@@ -2374,6 +2375,167 @@ CPPUNIT_TEST_FIXTURE(SwLayoutWriter3, testTdf160526)
assertXPath(pExportDump, "//page[2]/body/txt/anchored/SwAnchoredDrawObject"_ostr);
}
+CPPUNIT_TEST_FIXTURE(SwLayoutWriter3, testTdf160958_page_break)
+{
+ // Given a document with a section with the first paragraph having a page break
+ createSwDoc("tdf160958_page_break.fodt");
+ auto pExportDump = parseLayoutDump();
+ assertXPath(pExportDump, "//page"_ostr, 2);
+ // A single paragraph on the first page, with 6 lines
+ assertXPath(pExportDump, "//page[1]/body/txt"_ostr, 1);
+ assertXPath(pExportDump, "//page[1]/body/txt/SwParaPortion/SwLineLayout"_ostr, 6);
+ // A section with 7 paragraphs, and two more paragraphs after the section
+ assertXPath(pExportDump, "//page[2]/body/section"_ostr, 1);
+ assertXPath(pExportDump, "//page[2]/body/section/txt"_ostr, 7);
+ assertXPath(pExportDump, "//page[2]/body/section/txt[1]/SwParaPortion"_ostr, 0);
+ assertXPath(pExportDump, "//page[2]/body/section/txt[2]/SwParaPortion"_ostr, 0);
+ assertXPath(pExportDump, "//page[2]/body/section/txt[3]/SwParaPortion"_ostr, 0);
+ assertXPath(pExportDump, "//page[2]/body/section/txt[4]/SwParaPortion/SwLineLayout"_ostr, 5);
+ assertXPath(pExportDump, "//page[2]/body/section/txt[5]/SwParaPortion"_ostr, 0);
+ assertXPath(pExportDump, "//page[2]/body/section/txt[6]/SwParaPortion"_ostr, 0);
+ assertXPath(pExportDump, "//page[2]/body/section/txt[7]/SwParaPortion"_ostr, 0);
+ assertXPath(pExportDump, "//page[2]/body/txt"_ostr, 2);
+ assertXPath(pExportDump, "//page[2]/body/txt[1]/SwParaPortion/SwLineLayout"_ostr, 7);
+ assertXPath(pExportDump, "//page[2]/body/txt[2]/SwParaPortion"_ostr, 0);
+
+ // Hide the section
+ auto xTextSectionsSupplier = mxComponent.queryThrow<css::text::XTextSectionsSupplier>();
+ auto xSections = xTextSectionsSupplier->getTextSections();
+ CPPUNIT_ASSERT(xSections);
+ auto xSection = xSections->getByName(u"Section1"_ustr).queryThrow<css::beans::XPropertySet>();
+ xSection->setPropertyValue(u"IsVisible"_ustr, css::uno::Any(false));
+
+ discardDumpedLayout();
+ calcLayout();
+ pExportDump = parseLayoutDump();
+ assertXPath(pExportDump, "//page"_ostr, 1);
+ // Three paragraphs and a hidden section on the first page
+ assertXPath(pExportDump, "//page/body/txt"_ostr, 3);
+ assertXPath(pExportDump, "//page/body/section"_ostr, 1);
+
+ assertXPath(pExportDump, "//page/body/section/infos/bounds"_ostr, "height"_ostr, "0");
+ assertXPath(pExportDump, "//page/body/txt[1]/SwParaPortion/SwLineLayout"_ostr, 6);
+ assertXPath(pExportDump, "//page/body/section/txt"_ostr, 7);
+
+ assertXPath(pExportDump, "//page/body/txt[2]/SwParaPortion/SwLineLayout"_ostr, 7);
+ assertXPath(pExportDump, "//page/body/txt[3]/SwParaPortion"_ostr, 0);
+
+ // Show the section again
+ xSection->setPropertyValue(u"IsVisible"_ustr, css::uno::Any(true));
+
+ // Check that the layout has been restored
+ discardDumpedLayout();
+ calcLayout();
+ pExportDump = parseLayoutDump();
+ assertXPath(pExportDump, "//page"_ostr, 2);
+ assertXPath(pExportDump, "//page[1]/body/txt"_ostr, 1);
+ assertXPath(pExportDump, "//page[1]/body/txt/SwParaPortion/SwLineLayout"_ostr, 6);
+ assertXPath(pExportDump, "//page[2]/body/section"_ostr, 1);
+ assertXPath(pExportDump, "//page[2]/body/section/txt"_ostr, 7);
+ assertXPath(pExportDump, "//page[2]/body/section/txt[1]/SwParaPortion"_ostr, 0);
+ assertXPath(pExportDump, "//page[2]/body/section/txt[2]/SwParaPortion"_ostr, 0);
+ assertXPath(pExportDump, "//page[2]/body/section/txt[3]/SwParaPortion"_ostr, 0);
+ assertXPath(pExportDump, "//page[2]/body/section/txt[4]/SwParaPortion/SwLineLayout"_ostr, 5);
+ assertXPath(pExportDump, "//page[2]/body/section/txt[5]/SwParaPortion"_ostr, 0);
+ assertXPath(pExportDump, "//page[2]/body/section/txt[6]/SwParaPortion"_ostr, 0);
+ assertXPath(pExportDump, "//page[2]/body/section/txt[7]/SwParaPortion"_ostr, 0);
+ assertXPath(pExportDump, "//page[2]/body/txt"_ostr, 2);
+ assertXPath(pExportDump, "//page[2]/body/txt[1]/SwParaPortion/SwLineLayout"_ostr, 7);
+ assertXPath(pExportDump, "//page[2]/body/txt[2]/SwParaPortion"_ostr, 0);
+}
+
+CPPUNIT_TEST_FIXTURE(SwLayoutWriter3, testTdf160958_orphans)
+{
+ // Given a document with a section which moves to the next page as a whole, because of orphans
+ createSwDoc("tdf160958_orphans_move_section.fodt");
+ auto pExportDump = parseLayoutDump();
+ assertXPath(pExportDump, "//page"_ostr, 2);
+ // 21 paragraphs on the first page
+ assertXPath(pExportDump, "//page[1]/body/txt"_ostr, 21);
+ assertXPath(pExportDump, "//page[1]/body/txt[1]/SwParaPortion/SwLineLayout"_ostr, 6);
+ assertXPath(pExportDump, "//page[1]/body/txt[2]/SwParaPortion/SwLineLayout"_ostr, 5);
+ assertXPath(pExportDump, "//page[1]/body/txt[3]/SwParaPortion/SwLineLayout"_ostr, 7);
+ assertXPath(pExportDump, "//page[1]/body/txt[4]/SwParaPortion/SwLineLayout"_ostr, 16);
+ assertXPath(pExportDump, "//page[1]/body/txt[5]/SwParaPortion/SwLineLayout"_ostr, 1);
+ assertXPath(pExportDump, "//page[1]/body/txt[6]/SwParaPortion/SwLineLayout"_ostr, 1);
+ assertXPath(pExportDump, "//page[1]/body/txt[7]/SwParaPortion/SwLineLayout"_ostr, 1);
+ assertXPath(pExportDump, "//page[1]/body/txt[8]/SwParaPortion/SwLineLayout"_ostr, 1);
+ assertXPath(pExportDump, "//page[1]/body/txt[9]/SwParaPortion/SwLineLayout"_ostr, 1);
+ assertXPath(pExportDump, "//page[1]/body/txt[10]/SwParaPortion/SwLineLayout"_ostr, 1);
+ assertXPath(pExportDump, "//page[1]/body/txt[11]/SwParaPortion/SwLineLayout"_ostr, 1);
+ assertXPath(pExportDump, "//page[1]/body/txt[12]/SwParaPortion/SwLineLayout"_ostr, 1);
+ assertXPath(pExportDump, "//page[1]/body/txt[13]/SwParaPortion/SwLineLayout"_ostr, 1);
+ assertXPath(pExportDump, "//page[1]/body/txt[14]/SwParaPortion/SwLineLayout"_ostr, 1);
+ assertXPath(pExportDump, "//page[1]/body/txt[15]/SwParaPortion/SwLineLayout"_ostr, 1);
+ assertXPath(pExportDump, "//page[1]/body/txt[16]/SwParaPortion/SwLineLayout"_ostr, 1);
+ assertXPath(pExportDump, "//page[1]/body/txt[17]/SwParaPortion/SwLineLayout"_ostr, 1);
+ assertXPath(pExportDump, "//page[1]/body/txt[18]/SwParaPortion/SwLineLayout"_ostr, 1);
+ assertXPath(pExportDump, "//page[1]/body/txt[19]/SwParaPortion/SwLineLayout"_ostr, 1);
+ assertXPath(pExportDump, "//page[1]/body/txt[20]/SwParaPortion/SwLineLayout"_ostr, 1);
+ assertXPath(pExportDump, "//page[1]/body/txt[21]/SwParaPortion/SwLineLayout"_ostr, 1);
+ // A section and one more paragraph after the section
+ assertXPath(pExportDump, "//page[2]/body/section"_ostr, 1);
+ assertXPath(pExportDump, "//page[2]/body/section/txt"_ostr, 3);
+ assertXPath(pExportDump, "//page[2]/body/section/txt[1]/SwParaPortion/SwLineLayout"_ostr, 6);
+ assertXPath(pExportDump, "//page[2]/body/section/txt[2]/SwParaPortion/SwLineLayout"_ostr, 5);
+ assertXPath(pExportDump, "//page[2]/body/section/txt[3]/SwParaPortion/SwLineLayout"_ostr, 7);
+ assertXPath(pExportDump, "//page[2]/body/txt"_ostr, 1);
+ assertXPath(pExportDump, "//page[2]/body/txt[1]/SwParaPortion/SwLineLayout"_ostr, 1);
+
+ // Hide the section
+ auto xTextSectionsSupplier = mxComponent.queryThrow<css::text::XTextSectionsSupplier>();
+ auto xSections = xTextSectionsSupplier->getTextSections();
+ CPPUNIT_ASSERT(xSections);
+ auto xSection = xSections->getByName(u"Section1"_ustr).queryThrow<css::beans::XPropertySet>();
+ xSection->setPropertyValue(u"IsVisible"_ustr, css::uno::Any(false));
+
+ discardDumpedLayout();
+ calcLayout();
+ pExportDump = parseLayoutDump();
+ assertXPath(pExportDump, "//page"_ostr, 1);
+ assertXPath(pExportDump, "//page/body/txt"_ostr, 22);
+ assertXPath(pExportDump, "//page/body/section"_ostr, 1);
+ assertXPath(pExportDump, "//page/body/section/infos/bounds"_ostr, "height"_ostr, "0");
+
+ // Show the section again
+ xSection->setPropertyValue(u"IsVisible"_ustr, css::uno::Any(true));
+
+ // Check that the layout has been restored
+ discardDumpedLayout();
+ calcLayout();
+ pExportDump = parseLayoutDump();
+ assertXPath(pExportDump, "//page"_ostr, 2);
+ assertXPath(pExportDump, "//page[1]/body/txt"_ostr, 21);
+ assertXPath(pExportDump, "//page[1]/body/txt[1]/SwParaPortion/SwLineLayout"_ostr, 6);
+ assertXPath(pExportDump, "//page[1]/body/txt[2]/SwParaPortion/SwLineLayout"_ostr, 5);
+ assertXPath(pExportDump, "//page[1]/body/txt[3]/SwParaPortion/SwLineLayout"_ostr, 7);
+ assertXPath(pExportDump, "//page[1]/body/txt[4]/SwParaPortion/SwLineLayout"_ostr, 16);
+ assertXPath(pExportDump, "//page[1]/body/txt[5]/SwParaPortion/SwLineLayout"_ostr, 1);
+ assertXPath(pExportDump, "//page[1]/body/txt[6]/SwParaPortion/SwLineLayout"_ostr, 1);
+ assertXPath(pExportDump, "//page[1]/body/txt[7]/SwParaPortion/SwLineLayout"_ostr, 1);
+ assertXPath(pExportDump, "//page[1]/body/txt[8]/SwParaPortion/SwLineLayout"_ostr, 1);
+ assertXPath(pExportDump, "//page[1]/body/txt[9]/SwParaPortion/SwLineLayout"_ostr, 1);
+ assertXPath(pExportDump, "//page[1]/body/txt[10]/SwParaPortion/SwLineLayout"_ostr, 1);
+ assertXPath(pExportDump, "//page[1]/body/txt[11]/SwParaPortion/SwLineLayout"_ostr, 1);
+ assertXPath(pExportDump, "//page[1]/body/txt[12]/SwParaPortion/SwLineLayout"_ostr, 1);
+ assertXPath(pExportDump, "//page[1]/body/txt[13]/SwParaPortion/SwLineLayout"_ostr, 1);
+ assertXPath(pExportDump, "//page[1]/body/txt[14]/SwParaPortion/SwLineLayout"_ostr, 1);
+ assertXPath(pExportDump, "//page[1]/body/txt[15]/SwParaPortion/SwLineLayout"_ostr, 1);
+ assertXPath(pExportDump, "//page[1]/body/txt[16]/SwParaPortion/SwLineLayout"_ostr, 1);
+ assertXPath(pExportDump, "//page[1]/body/txt[17]/SwParaPortion/SwLineLayout"_ostr, 1);
+ assertXPath(pExportDump, "//page[1]/body/txt[18]/SwParaPortion/SwLineLayout"_ostr, 1);
+ assertXPath(pExportDump, "//page[1]/body/txt[19]/SwParaPortion/SwLineLayout"_ostr, 1);
+ assertXPath(pExportDump, "//page[1]/body/txt[20]/SwParaPortion/SwLineLayout"_ostr, 1);
+ assertXPath(pExportDump, "//page[1]/body/txt[21]/SwParaPortion/SwLineLayout"_ostr, 1);
+ assertXPath(pExportDump, "//page[2]/body/section"_ostr, 1);
+ assertXPath(pExportDump, "//page[2]/body/section/txt"_ostr, 3);
+ assertXPath(pExportDump, "//page[2]/body/section/txt[1]/SwParaPortion/SwLineLayout"_ostr, 6);
+ assertXPath(pExportDump, "//page[2]/body/section/txt[2]/SwParaPortion/SwLineLayout"_ostr, 5);
+ assertXPath(pExportDump, "//page[2]/body/section/txt[3]/SwParaPortion/SwLineLayout"_ostr, 7);
+ assertXPath(pExportDump, "//page[2]/body/txt"_ostr, 1);
+ assertXPath(pExportDump, "//page[2]/body/txt[1]/SwParaPortion/SwLineLayout"_ostr, 1);
+}
+
CPPUNIT_PLUGIN_IMPLEMENT();
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/qa/extras/odfexport/odfexport2.cxx b/sw/qa/extras/odfexport/odfexport2.cxx
index f654821acf6a..fb45d5c8e93c 100644
--- a/sw/qa/extras/odfexport/odfexport2.cxx
+++ b/sw/qa/extras/odfexport/odfexport2.cxx
@@ -885,9 +885,9 @@ DECLARE_ODFEXPORT_TEST(testTdf114287, "tdf114287.odt")
xmlDocUniquePtr pXmlDoc = parseLayoutDump();
assertXPath(pXmlDoc, "/root/page[1]/body/txt[2]/infos/prtBounds"_ostr, "left"_ostr, "2268");
assertXPath(pXmlDoc, "/root/page[1]/body/txt[2]/infos/prtBounds"_ostr, "right"_ostr, "11339");
- // the problem was that the list style name of the list must override the
- // paragraph style even though it's the same list style
- assertXPath(pXmlDoc, "/root/page[1]/body/txt[9]/infos/prtBounds"_ostr, "left"_ostr, "357");
+ // the list style name of the list is the same as the list style name of the
+ // paragraph, but in any case the margins of the paragraph take precedence
+ assertXPath(pXmlDoc, "/root/page[1]/body/txt[9]/infos/prtBounds"_ostr, "left"_ostr, "2268");
assertXPath(pXmlDoc, "/root/page[1]/body/txt[9]/infos/prtBounds"_ostr, "right"_ostr, "11339");
assertXPath(pXmlDoc, "/root/page[1]/body/txt[16]/infos/prtBounds"_ostr, "left"_ostr, "357");
assertXPath(pXmlDoc, "/root/page[1]/body/txt[16]/infos/prtBounds"_ostr, "right"_ostr, "11339");
diff --git a/sw/qa/extras/ooxmlexport/data/StyleRef-DE.docx b/sw/qa/extras/ooxmlexport/data/StyleRef-DE.docx
new file mode 100644
index 000000000000..800ef6413fe6
--- /dev/null
+++ b/sw/qa/extras/ooxmlexport/data/StyleRef-DE.docx
Binary files differ
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport17.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport17.cxx
index 49d974b01159..dee26b595c08 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport17.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport17.cxx
@@ -229,7 +229,7 @@ CPPUNIT_TEST_FIXTURE(Test, testParaStyleNumLevel)
// - Expected: 1
// - Actual : 0
// i.e. a custom list level in a para style was lost on import+export.
- assertXPath(pXmlDoc, "/w:styles/w:style[@w:styleId='Mystyle']/w:pPr/w:numPr/w:ilvl"_ostr, "val"_ostr, "1");
+ assertXPath(pXmlDoc, "/w:styles/w:style[@w:styleId='mystyle']/w:pPr/w:numPr/w:ilvl"_ostr, "val"_ostr, "1");
}
CPPUNIT_TEST_FIXTURE(Test, testClearingBreak)
@@ -741,6 +741,16 @@ DECLARE_OOXMLEXPORT_TEST(testTdf153082_comma, "custom-styles-TOC-comma.docx")
CPPUNIT_ASSERT(tocContent.indexOf("Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas.") != -1);
}
+DECLARE_OOXMLEXPORT_TEST(testTdf160402, "StyleRef-DE.docx")
+{
+ xmlDocUniquePtr pLayout = parseLayoutDump();
+ assertXPath(pLayout, "/root/page[1]/header/txt[1]/SwParaPortion/SwLineLayout/SwFieldPortion"_ostr, "expand"_ostr, "Heading 1");
+ assertXPath(pLayout, "/root/page[2]/header/txt[1]/SwParaPortion/SwLineLayout/SwFieldPortion"_ostr, "expand"_ostr, "Nunc viverra imperdiet enim. Fusce est. Vivamus a tellus.");
+ assertXPath(pLayout, "/root/page[3]/header/txt[1]/SwParaPortion/SwLineLayout/SwFieldPortion"_ostr, "expand"_ostr, "Cras faucibus condimentum odio. Sed ac ligula. Aliquam at eros.");
+ assertXPath(pLayout, "/root/page[4]/header/txt[1]/SwParaPortion/SwLineLayout/SwFieldPortion"_ostr, "expand"_ostr, "Nunc viverra imperdiet enim. Fusce est. Vivamus a tellus.");
+ assertXPath(pLayout, "/root/page[5]/header/txt[1]/SwParaPortion/SwLineLayout/SwFieldPortion"_ostr, "expand"_ostr, "Aenean nec lorem. In porttitor. Donec laoreet nonummy augue.");
+}
+
DECLARE_OOXMLEXPORT_TEST(testTdf142407, "tdf142407.docx")
{
uno::Reference<container::XNameAccess> xPageStyles = getStyles("PageStyles");
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport5.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport5.cxx
index db504be317c1..4a2ac4bbbfd2 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport5.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport5.cxx
@@ -319,6 +319,12 @@ CPPUNIT_TEST_FIXTURE(Test, testOldComplexMergeTableInTable)
{
loadAndSave("ooo96040-2.odt");
parseExport("word/document.xml");
+
+ // Check tdf#161202 - this document has all kinds of tables inside hidden sections.
+ // The page count must be 13, but for unclear reason, it is 12 in some tests on Linux
+ // (maybe the layout hasn't finished?).
+ // Without the fix, it was 52.
+ CPPUNIT_ASSERT_LESSEQUAL(13, getPages());
}
CPPUNIT_TEST_FIXTURE(Test, testHyperlinkContainingPlaceholderField)
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport9.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport9.cxx
index ad3bba49df49..91f0deb4bb05 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport9.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport9.cxx
@@ -563,7 +563,7 @@ DECLARE_OOXMLEXPORT_TEST(testTdf104061_tableSectionColumns,"tdf104061_tableSecti
//tdf#95114 - follow style is Text Body - DOCX test
uno::Reference< beans::XPropertySet > properties(getStyles("ParagraphStyles")->getByName("annotation subject"), uno::UNO_QUERY);
- CPPUNIT_ASSERT_EQUAL(OUString("annotation text"), getProperty<OUString>(properties, "FollowStyle"));
+ CPPUNIT_ASSERT_EQUAL(OUString("Marginalia"), getProperty<OUString>(properties, "FollowStyle"));
}
DECLARE_OOXMLEXPORT_TEST(testTdf46940_dontEquallyDistributeColumns, "tdf46940_dontEquallyDistributeColumns.docx")
@@ -690,7 +690,7 @@ CPPUNIT_TEST_FIXTURE(Test, testTdf109310_endnoteStyleForMSO)
xmlDocUniquePtr pXmlDoc = parseExport("word/endnotes.xml");
// Check w:rStyle element has w:val attribute - note that w: is not specified for attribute
assertXPath(pXmlDoc, "/w:endnotes/w:endnote[@w:id='2']/w:p/w:r[1]/w:rPr/w:rStyle"_ostr, "val"_ostr,
- "EndnoteCharacters");
+ "EndnoteCharacters1");
}
CPPUNIT_TEST_FIXTURE(Test, testTdf103389)
diff --git a/sw/qa/extras/ooxmlexport/ooxmlfieldexport.cxx b/sw/qa/extras/ooxmlexport/ooxmlfieldexport.cxx
index a97d8e8b841c..66faba5f3e59 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlfieldexport.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlfieldexport.cxx
@@ -177,6 +177,8 @@ CPPUNIT_TEST_FIXTURE(Test, testFDO77715)
xTOC->update();
OUString const tocContent(xTOC->getAnchor()->getString());
CPPUNIT_ASSERT(tocContent.startsWith("National Infrastructure Bank Aff/Neg Index"));
+ // check that 1st paragraph has outline level 1
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(1), getProperty<sal_Int32>(getParagraph(1), "OutlineLevel"));
}
CPPUNIT_TEST_FIXTURE(Test, testTOCFlag_u)
diff --git a/sw/qa/extras/uiwriter/data/stylewithlistandindents.fodt b/sw/qa/extras/uiwriter/data/stylewithlistandindents.fodt
new file mode 100644
index 000000000000..afb7ae06aac2
--- /dev/null
+++ b/sw/qa/extras/uiwriter/data/stylewithlistandindents.fodt
@@ -0,0 +1,182 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<office:document xmlns:css3t="http://www.w3.org/TR/css3-text/" xmlns:grddl="http://www.w3.org/2003/g/data-view#" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xforms="http://www.w3.org/2002/xforms" xmlns:dom="http://www.w3.org/2001/xml-events" xmlns:script="urn:oasis:names:tc:opendocument:xmlns:script:1.0" xmlns:form="urn:oasis:names:tc:opendocument:xmlns:form:1.0" xmlns:math="http://www.w3.org/1998/Math/MathML" xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" xmlns:ooo="http://openoffice.org/2004/office" xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0" xmlns:config="urn:oasis:names:tc:opendocument:xmlns:config:1.0" xmlns:ooow="http://openoffice.org/2004/writer" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:drawooo="http://openoffice.org/2010/draw" xmlns:oooc="http://openoffice.org/2004/calc" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:calcext="urn:org:documentfoundation:names:experimental:calc:xmlns:calcext:1.0" xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0" xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" xmlns:of="urn:oasis:names:tc:opendocument:xmlns:of:1.2" xmlns:tableooo="http://openoffice.org/2009/table" xmlns:draw="urn:oasis:names:tc:opendocument:xmlns:drawing:1.0" xmlns:dr3d="urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0" xmlns:rpt="http://openoffice.org/2005/report" xmlns:formx="urn:openoffice:names:experimental:ooxml-odf-interop:xmlns:form:1.0" xmlns:svg="urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0" xmlns:chart="urn:oasis:names:tc:opendocument:xmlns:chart:1.0" xmlns:officeooo="http://openoffice.org/2009/office" xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0" xmlns:field="urn:openoffice:names:experimental:ooo-ms-interop:xmlns:field:1.0" xmlns:number="urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0" xmlns:meta="urn:oasis:names:tc:opendocument:xmlns:meta:1.0" xmlns:loext="urn:org:documentfoundation:names:experimental:office:xmlns:loext:1.0" office:version="1.3" office:mimetype="application/vnd.oasis.opendocument.text">
+ <office:meta><meta:creation-date>2024-05-16T18:27:43.913131212</meta:creation-date><dc:date>2024-05-16T18:30:43.721654337</dc:date><meta:editing-duration>PT3M</meta:editing-duration><meta:editing-cycles>1</meta:editing-cycles><meta:document-statistic meta:table-count="0" meta:image-count="0" meta:object-count="0" meta:page-count="1" meta:paragraph-count="2" meta:word-count="4" meta:character-count="12" meta:non-whitespace-character-count="12"/><meta:generator>LibreOfficeDev/24.8.0.0.alpha0$Linux_X86_64 LibreOffice_project/a2e7a65b22857abc945af33c7673d9d8b50688d5</meta:generator></office:meta>
+ <office:font-face-decls>
+ <style:font-face style:name="Liberation Serif" svg:font-family="'Liberation Serif'" style:font-family-generic="roman" style:font-pitch="variable"/>
+ <style:font-face style:name="Noto Sans1" svg:font-family="'Noto Sans'" style:font-family-generic="system" style:font-pitch="variable"/>
+ <style:font-face style:name="Noto Serif CJK SC" svg:font-family="'Noto Serif CJK SC'" style:font-family-generic="system" style:font-pitch="variable"/>
+ </office:font-face-decls>
+ <office:styles>
+ <style:default-style style:family="graphic">
+ <style:graphic-properties svg:stroke-color="#3465a4" draw:fill-color="#729fcf" fo:wrap-option="no-wrap" draw:shadow-offset-x="0.3cm" draw:shadow-offset-y="0.3cm" draw:start-line-spacing-horizontal="0.283cm" draw:start-line-spacing-vertical="0.283cm" draw:end-line-spacing-horizontal="0.283cm" draw:end-line-spacing-vertical="0.283cm" style:flow-with-text="false"/>
+ <style:paragraph-properties style:text-autospace="ideograph-alpha" style:line-break="strict" loext:tab-stop-distance="0cm" style:writing-mode="lr-tb" style:font-independent-line-spacing="false">
+ <style:tab-stops/>
+ </style:paragraph-properties>
+ <style:text-properties style:use-window-font-color="true" loext:opacity="0%" style:font-name="Liberation Serif" fo:font-size="12pt" fo:language="de" fo:country="DE" style:letter-kerning="true" style:font-name-asian="Noto Serif CJK SC" style:font-size-asian="10.5pt" style:language-asian="zh" style:country-asian="CN" style:font-name-complex="Noto Sans1" style:font-size-complex="12pt" style:language-complex="hi" style:country-complex="IN"/>
+ </style:default-style>
+ <style:default-style style:family="paragraph">
+ <style:paragraph-properties fo:orphans="2" fo:widows="2" fo:hyphenation-ladder-count="no-limit" fo:hyphenation-keep="auto" style:text-autospace="ideograph-alpha" style:punctuation-wrap="hanging" style:line-break="strict" style:tab-stop-distance="1.251cm" style:writing-mode="page"/>
+ <style:text-properties style:use-window-font-color="true" loext:opacity="0%" style:font-name="Liberation Serif" fo:font-size="12pt" fo:language="de" fo:country="DE" style:letter-kerning="true" style:font-name-asian="Noto Serif CJK SC" style:font-size-asian="10.5pt" style:language-asian="zh" style:country-asian="CN" style:font-name-complex="Noto Sans1" style:font-size-complex="12pt" style:language-complex="hi" style:country-complex="IN" fo:hyphenate="false" fo:hyphenation-remain-char-count="2" fo:hyphenation-push-char-count="2" loext:hyphenation-no-caps="false" loext:hyphenation-no-last-word="false" loext:hyphenation-word-char-count="5" loext:hyphenation-zone="no-limit" loext:hyphenation-keep-type="column"/>
+ </style:default-style>
+ <style:default-style style:family="table">
+ <style:table-properties table:border-model="collapsing"/>
+ </style:default-style>
+ <style:default-style style:family="table-row">
+ <style:table-row-properties fo:keep-together="auto"/>
+ </style:default-style>
+ <style:style style:name="Standard" style:family="paragraph" style:class="text"/>
+ <style:style style:name="Text_20_body" style:display-name="Text body" style:family="paragraph" style:parent-style-name="Standard" style:class="text">
+ <style:paragraph-properties fo:margin-top="0cm" fo:margin-bottom="0.247cm" style:contextual-spacing="false" fo:line-height="115%"/>
+ </style:style>
+ <style:style style:name="ListAndIndents" style:family="paragraph" style:parent-style-name="Text_20_body" style:list-style-name="Numbering_20_ABC">
+ <style:paragraph-properties fo:margin-left="3cm" fo:text-indent="5.001cm" style:auto-text-indent="false"/>
+ </style:style>
+ <style:style style:name="Numbering_20_Symbols" style:display-name="Numbering Symbols" style:family="text"/>
+ <text:outline-style style:name="Outline">
+ <text:outline-level-style text:level="1" style:num-format="">
+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment">
+ <style:list-level-label-alignment text:label-followed-by="listtab"/>
+ </style:list-level-properties>
+ </text:outline-level-style>
+ <text:outline-level-style text:level="2" style:num-format="">
+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment">
+ <style:list-level-label-alignment text:label-followed-by="listtab"/>
+ </style:list-level-properties>
+ </text:outline-level-style>
+ <text:outline-level-style text:level="3" style:num-format="">
+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment">
+ <style:list-level-label-alignment text:label-followed-by="listtab"/>
+ </style:list-level-properties>
+ </text:outline-level-style>
+ <text:outline-level-style text:level="4" style:num-format="">
+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment">
+ <style:list-level-label-alignment text:label-followed-by="listtab"/>
+ </style:list-level-properties>
+ </text:outline-level-style>
+ <text:outline-level-style text:level="5" style:num-format="">
+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment">
+ <style:list-level-label-alignment text:label-followed-by="listtab"/>
+ </style:list-level-properties>
+ </text:outline-level-style>
+ <text:outline-level-style text:level="6" style:num-format="">
+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment">
+ <style:list-level-label-alignment text:label-followed-by="listtab"/>
+ </style:list-level-properties>
+ </text:outline-level-style>
+ <text:outline-level-style text:level="7" style:num-format="">
+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment">
+ <style:list-level-label-alignment text:label-followed-by="listtab"/>
+ </style:list-level-properties>
+ </text:outline-level-style>
+ <text:outline-level-style text:level="8" style:num-format="">
+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment">
+ <style:list-level-label-alignment text:label-followed-by="listtab"/>
+ </style:list-level-properties>
+ </text:outline-level-style>
+ <text:outline-level-style text:level="9" style:num-format="">
+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment">
+ <style:list-level-label-alignment text:label-followed-by="listtab"/>
+ </style:list-level-properties>
+ </text:outline-level-style>
+ <text:outline-level-style text:level="10" style:num-format="">
+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment">
+ <style:list-level-label-alignment text:label-followed-by="listtab"/>
+ </style:list-level-properties>
+ </text:outline-level-style>
+ </text:outline-style>
+ <text:list-style style:name="Numbering_20_ABC" style:display-name="Numbering ABC">
+ <text:list-level-style-number text:level="1" text:style-name="Numbering_20_Symbols" loext:num-list-format="%1%." style:num-suffix="." style:num-format="A">
+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment">
+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="1.33cm" fo:text-indent="-0.7cm" fo:margin-left="1.33cm"/>
+ </style:list-level-properties>
+ </text:list-level-style-number>
+ <text:list-level-style-number text:level="2" text:style-name="Numbering_20_Symbols" loext:num-list-format="%2%." style:num-suffix="." style:num-format="A">
+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment">
+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="2.03cm" fo:text-indent="-0.7cm" fo:margin-left="2.03cm"/>
+ </style:list-level-properties>
+ </text:list-level-style-number>
+ <text:list-level-style-number text:level="3" text:style-name="Numbering_20_Symbols" loext:num-list-format="%3%." style:num-suffix="." style:num-format="A">
+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment">
+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="2.731cm" fo:text-indent="-0.7cm" fo:margin-left="2.731cm"/>
+ </style:list-level-properties>
+ </text:list-level-style-number>
+ <text:list-level-style-number text:level="4" text:style-name="Numbering_20_Symbols" loext:num-list-format="%4%." style:num-suffix="." style:num-format="A">
+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment">
+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="3.431cm" fo:text-indent="-0.7cm" fo:margin-left="3.431cm"/>
+ </style:list-level-properties>
+ </text:list-level-style-number>
+ <text:list-level-style-number text:level="5" text:style-name="Numbering_20_Symbols" loext:num-list-format="%5%." style:num-suffix="." style:num-format="A">
+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment">
+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="4.131cm" fo:text-indent="-0.7cm" fo:margin-left="4.131cm"/>
+ </style:list-level-properties>
+ </text:list-level-style-number>
+ <text:list-level-style-number text:level="6" text:style-name="Numbering_20_Symbols" loext:num-list-format="%6%." style:num-suffix="." style:num-format="A">
+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment">
+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="4.831cm" fo:text-indent="-0.7cm" fo:margin-left="4.831cm"/>
+ </style:list-level-properties>
+ </text:list-level-style-number>
+ <text:list-level-style-number text:level="7" text:style-name="Numbering_20_Symbols" loext:num-list-format="%7%." style:num-suffix="." style:num-format="A">
+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment">
+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="5.532cm" fo:text-indent="-0.7cm" fo:margin-left="5.532cm"/>
+ </style:list-level-properties>
+ </text:list-level-style-number>
+ <text:list-level-style-number text:level="8" text:style-name="Numbering_20_Symbols" loext:num-list-format="%8%." style:num-suffix="." style:num-format="A">
+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment">
+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="6.232cm" fo:text-indent="-0.7cm" fo:margin-left="6.232cm"/>
+ </style:list-level-properties>
+ </text:list-level-style-number>
+ <text:list-level-style-number text:level="9" text:style-name="Numbering_20_Symbols" loext:num-list-format="%9%." style:num-suffix="." style:num-format="A">
+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment">
+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="6.932cm" fo:text-indent="-0.7cm" fo:margin-left="6.932cm"/>
+ </style:list-level-properties>
+ </text:list-level-style-number>
+ <text:list-level-style-number text:level="10" text:style-name="Numbering_20_Symbols" loext:num-list-format="%10%." style:num-suffix="." style:num-format="A">
+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment">
+ <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="7.632cm" fo:text-indent="-0.7cm" fo:margin-left="7.632cm"/>
+ </style:list-level-properties>
+ </text:list-level-style-number>
+ </text:list-style>
+ <text:notes-configuration text:note-class="footnote" style:num-format="1" text:start-value="0" text:footnotes-position="page" text:start-numbering-at="document"/>
+ <text:notes-configuration text:note-class="endnote" style:num-format="i" text:start-value="0"/>
+ <text:linenumbering-configuration text:number-lines="false" text:offset="0.499cm" style:num-format="1" text:number-position="left" text:increment="5"/>
+ </office:styles>
+ <office:automatic-styles>
+ <style:style style:name="P1" style:family="paragraph" style:parent-style-name="Standard">
+ <style:text-properties/>
+ </style:style>
+ <style:style style:name="P2" style:family="paragraph" style:parent-style-name="ListAndIndents">
+ <style:text-properties/>
+ </style:style>
+ <style:page-layout style:name="pm1">
+ <style:page-layout-properties fo:page-width="21.001cm" fo:page-height="29.7cm" style:num-format="1" style:print-orientation="portrait" fo:margin-top="2cm" fo:margin-bottom="2cm" fo:margin-left="2cm" fo:margin-right="2cm" style:writing-mode="lr-tb" style:footnote-max-height="0cm" loext:margin-gutter="0cm">
+ <style:footnote-sep style:width="0.018cm" style:distance-before-sep="0.101cm" style:distance-after-sep="0.101cm" style:line-style="solid" style:adjustment="left" style:rel-width="25%" style:color="#000000"/>
+ </style:page-layout-properties>
+ <style:header-style/>
+ <style:footer-style/>
+ </style:page-layout>
+ </office:automatic-styles>
+ <office:master-styles>
+ <style:master-page style:name="Standard" style:page-layout-name="pm1"/>
+ </office:master-styles>
+ <office:body>
+ <office:text>
+ <text:sequence-decls>
+ <text:sequence-decl text:display-outline-level="0" text:name="Illustration"/>
+ <text:sequence-decl text:display-outline-level="0" text:name="Table"/>
+ <text:sequence-decl text:display-outline-level="0" text:name="Text"/>
+ <text:sequence-decl text:display-outline-level="0" text:name="Drawing"/>
+ <text:sequence-decl text:display-outline-level="0" text:name="Figure"/>
+ </text:sequence-decls>
+ <text:p text:style-name="P1"/>
+ <text:list text:style-name="Numbering_20_ABC">
+ <text:list-item>
+ <text:p text:style-name="ListAndIndents">Item</text:p>
+ </text:list-item>
+ <text:list-item>
+ <text:p text:style-name="P2">more</text:p>
+ </text:list-item>
+ </text:list>
+ <text:p text:style-name="Standard"/>
+ </office:text>
+ </office:body>
+</office:document> \ No newline at end of file
diff --git a/sw/qa/extras/uiwriter/data/table-in-table.fodt b/sw/qa/extras/uiwriter/data/table-in-table.fodt
new file mode 100644
index 000000000000..e055d343b847
--- /dev/null
+++ b/sw/qa/extras/uiwriter/data/table-in-table.fodt
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<office:document xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0" xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0" xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0" office:version="1.3" office:mimetype="application/vnd.oasis.opendocument.text">
+ <office:automatic-styles>
+ <style:style style:name="border" style:family="table-cell">
+ <style:table-cell-properties fo:padding="1mm" fo:border="0.5pt solid #000000"/>
+ </style:style>
+ </office:automatic-styles>
+ <office:body>
+ <office:text>
+ <text:p/>
+ <table:table>
+ <table:table-column/>
+ <table:table-row>
+ <table:table-cell table:style-name="border">
+ <table:table>
+ <table:table-column/>
+ <table:table-row>
+ <table:table-cell table:style-name="border"/>
+ </table:table-row>
+ </table:table>
+ <text:p/>
+ </table:table-cell>
+ </table:table-row>
+ </table:table>
+ <text:p/>
+ </office:text>
+ </office:body>
+</office:document> \ No newline at end of file
diff --git a/sw/qa/extras/uiwriter/data/tdf160842.fodt b/sw/qa/extras/uiwriter/data/tdf160842.fodt
new file mode 100644
index 000000000000..217b9c1a9570
--- /dev/null
+++ b/sw/qa/extras/uiwriter/data/tdf160842.fodt
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<office:document xmlns:css3t="http://www.w3.org/TR/css3-text/" xmlns:grddl="http://www.w3.org/2003/g/data-view#" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xforms="http://www.w3.org/2002/xforms" xmlns:dom="http://www.w3.org/2001/xml-events" xmlns:script="urn:oasis:names:tc:opendocument:xmlns:script:1.0" xmlns:form="urn:oasis:names:tc:opendocument:xmlns:form:1.0" xmlns:math="http://www.w3.org/1998/Math/MathML" xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" xmlns:ooo="http://openoffice.org/2004/office" xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0" xmlns:config="urn:oasis:names:tc:opendocument:xmlns:config:1.0" xmlns:ooow="http://openoffice.org/2004/writer" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:drawooo="http://openoffice.org/2010/draw" xmlns:oooc="http://openoffice.org/2004/calc" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:calcext="urn:org:documentfoundation:names:experimental:calc:xmlns:calcext:1.0" xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0" xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" xmlns:of="urn:oasis:names:tc:opendocument:xmlns:of:1.2" xmlns:tableooo="http://openoffice.org/2009/table" xmlns:draw="urn:oasis:names:tc:opendocument:xmlns:drawing:1.0" xmlns:dr3d="urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0" xmlns:rpt="http://openoffice.org/2005/report" xmlns:formx="urn:openoffice:names:experimental:ooxml-odf-interop:xmlns:form:1.0" xmlns:svg="urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0" xmlns:chart="urn:oasis:names:tc:opendocument:xmlns:chart:1.0" xmlns:officeooo="http://openoffice.org/2009/office" xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0" xmlns:field="urn:openoffice:names:experimental:ooo-ms-interop:xmlns:field:1.0" xmlns:number="urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0" xmlns:meta="urn:oasis:names:tc:opendocument:xmlns:meta:1.0" xmlns:loext="urn:org:documentfoundation:names:experimental:office:xmlns:loext:1.0" office:version="1.3" office:mimetype="application/vnd.oasis.opendocument.text">
+ <office:styles>
+ <style:default-style style:family="graphic">
+ <style:graphic-properties svg:stroke-color="#3465a4" draw:fill-color="#729fcf" fo:wrap-option="no-wrap" draw:shadow-offset-x="0.3cm" draw:shadow-offset-y="0.3cm" draw:start-line-spacing-horizontal="0.283cm" draw:start-line-spacing-vertical="0.283cm" draw:end-line-spacing-horizontal="0.283cm" draw:end-line-spacing-vertical="0.283cm" style:writing-mode="lr-tb" style:flow-with-text="false"/>
+ <style:paragraph-properties style:text-autospace="ideograph-alpha" style:line-break="strict" loext:tab-stop-distance="0cm" style:writing-mode="lr-tb" style:font-independent-line-spacing="false">
+ <style:tab-stops/>
+ </style:paragraph-properties>
+ <style:text-properties style:use-window-font-color="true" loext:opacity="0%" style:font-name="DejaVu Sans" fo:font-size="12pt" fo:language="en" fo:country="US" style:letter-kerning="true" style:font-size-complex="12pt"/>
+ </style:default-style>
+ <style:style style:name="Frame_20_contents" style:display-name="Frame contents" style:family="paragraph" style:parent-style-name="Standard" style:class="extra"/>
+ <style:style style:name="Graphics" style:family="graphic">
+ <style:graphic-properties text:anchor-type="paragraph" svg:x="0cm" svg:y="0cm" style:wrap="dynamic" style:number-wrapped-paragraphs="no-limit" style:wrap-contour="false" style:vertical-pos="top" style:vertical-rel="paragraph" style:horizontal-pos="center" style:horizontal-rel="paragraph" fo:background-color="transparent" draw:fill="none" draw:fill-color="#729fcf"/>
+ </style:style>
+ <style:style style:name="Frame" style:family="graphic">
+ <style:graphic-properties text:anchor-type="paragraph" svg:x="0cm" svg:y="0cm" fo:margin-left="0.201cm" fo:margin-right="0.201cm" fo:margin-top="0.201cm" fo:margin-bottom="0.201cm" style:wrap="parallel" style:number-wrapped-paragraphs="no-limit" style:wrap-contour="false" style:vertical-pos="top" style:vertical-rel="paragraph-content" style:horizontal-pos="center" style:horizontal-rel="paragraph-content" fo:background-color="transparent" draw:fill="none" draw:fill-color="#729fcf" fo:padding="0.15cm" fo:border="0.06pt solid #000000"/>
+ </style:style>
+ </office:styles>
+ <office:automatic-styles>
+ <style:style style:name="Table1" style:family="table">
+ <style:table-properties style:width="8.707cm" table:align="margins" style:writing-mode="lr-tb"/>
+ </style:style>
+ <style:style style:name="Table1.A" style:family="table-column">
+ <style:table-column-properties style:column-width="8.707cm" style:rel-column-width="65535*"/>
+ </style:style>
+ <style:style style:name="Table1.1" style:family="table-row">
+ <style:table-row-properties style:row-height="6.897cm" fo:keep-together="always"/>
+ </style:style>
+ <style:style style:name="Table1.A1" style:family="table-cell">
+ <style:table-cell-properties style:vertical-align="top" fo:padding="0cm" fo:border="0.05pt solid #000000" style:writing-mode="lr-tb"/>
+ </style:style>
+ <style:style style:name="Table1.2" style:family="table-row">
+ <style:table-row-properties style:min-row-height="0.109cm" fo:keep-together="always"/>
+ </style:style>
+ <style:style style:name="Table1.A2" style:family="table-cell">
+ <style:table-cell-properties style:vertical-align="top" fo:padding="0cm" fo:border="none" style:writing-mode="lr-tb"/>
+ </style:style>
+ <style:style style:name="fr1" style:family="graphic" style:parent-style-name="Frame">
+ <style:graphic-properties fo:margin-left="0cm" fo:margin-right="0cm" fo:margin-top="0cm" fo:margin-bottom="0cm" style:vertical-pos="top" style:vertical-rel="paragraph" style:horizontal-pos="left" style:horizontal-rel="paragraph" fo:padding="0cm" fo:border="none" draw:wrap-influence-on-position="once-concurrent" loext:allow-overlap="true"/>
+ </style:style>
+ <style:style style:name="fr2" style:family="graphic" style:parent-style-name="Graphics">
+ <style:graphic-properties fo:margin-left="0cm" fo:margin-right="0cm" fo:margin-top="0cm" fo:margin-bottom="0cm" style:vertical-pos="from-top" style:horizontal-pos="center" style:horizontal-rel="paragraph" fo:padding="0cm" fo:border="none" style:mirror="none" fo:clip="rect(0cm, 0cm, 0cm, 0cm)" draw:luminance="0%" draw:contrast="0%" draw:red="0%" draw:green="0%" draw:blue="0%" draw:gamma="100%" draw:color-inversion="false" draw:image-opacity="100%" draw:color-mode="standard"/>
+ </style:style>
+ </office:automatic-styles>
+ <office:master-styles>
+ <style:master-page style:name="Standard" style:page-layout-name="pm1" draw:style-name="dp1"/>
+ </office:master-styles>
+ <office:body>
+ <office:text>
+ <text:p text:style-name="P3"><draw:frame draw:style-name="fr1" draw:name="Frame1" text:anchor-type="paragraph" svg:width="8.707cm" draw:z-index="0">
+ <draw:text-box fo:min-height="6.765cm">
+ <table:table table:name="Table1" table:style-name="Table1">
+ <table:table-column table:style-name="Table1.A"/>
+ <table:table-row table:style-name="Table1.1">
+ <table:table-cell table:style-name="Table1.A1" office:value-type="string">
+ <text:p text:style-name="P1"><draw:frame draw:style-name="fr2" draw:name="Image1" text:anchor-type="as-char" svg:y="-10.984cm" svg:width="11.234cm" svg:height="8.398cm" draw:z-index="1"><draw:image draw:mime-type="image/png">
+ <office:binary-data>iVBORw0KGgoAAAANSUhEUgAAAAIAAAACCAIAAAD91JpzAAAAFklEQVQI12P2Ytilf46NeWX3
+ a804HgAg7QTAqXPBTwAAAABJRU5ErkJggg==
+ </office:binary-data>
+ </draw:image>
+ </draw:frame><text:span text:style-name="T1"><text:s/></text:span></text:p>
+ </table:table-cell>
+ </table:table-row>
+ <table:table-row table:style-name="Table1.2">
+ <table:table-cell table:style-name="Table1.A2" office:value-type="string">
+ <text:p text:style-name="P2">Lorem ipsum dolor sit amet, consectetur adipiscing.</text:p>
+ </table:table-cell>
+ </table:table-row>
+ </table:table>
+ </draw:text-box>
+ </draw:frame></text:p>
+ </office:text>
+ </office:body>
+</office:document>
diff --git a/sw/qa/extras/uiwriter/data/tdf161172.fodt b/sw/qa/extras/uiwriter/data/tdf161172.fodt
new file mode 100644
index 000000000000..08cea575cc60
--- /dev/null
+++ b/sw/qa/extras/uiwriter/data/tdf161172.fodt
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<office:document xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0" xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" office:version="1.3" office:mimetype="application/vnd.oasis.opendocument.text">
+ <office:styles>
+ <style:style style:name="Num_1_lvl2" style:family="paragraph" style:list-style-name="Num_1" style:list-level="2"/>
+ <style:style style:name="No_list" style:family="paragraph" style:list-style-name=""/>
+ <text:list-style style:name="Num_1">
+ <text:list-level-style-number text:level="1" style:num-prefix="Num1_lvl1_" style:num-format="1">
+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment">
+ <style:list-level-label-alignment text:label-followed-by="space"/>
+ </style:list-level-properties>
+ </text:list-level-style-number>
+ <text:list-level-style-number text:level="2" style:num-prefix="Num1_lvl2_" style:num-format="1">
+ <style:list-level-properties text:list-level-position-and-space-mode="label-alignment">
+ <style:list-level-label-alignment text:label-followed-by="space"/>
+ </style:list-level-properties>
+ </text:list-level-style-number>
+ </text:list-style>
+ </office:styles>
+ <office:automatic-styles>
+ <style:style style:name="P1" style:family="paragraph" style:parent-style-name="No_list" style:list-style-name="Num_1"/>
+ </office:automatic-styles>
+ <office:master-styles>
+ <style:master-page style:name="Standard"/>
+ </office:master-styles>
+ <office:body>
+ <office:text>
+ <text:list text:style-name="Num_1">
+ <text:list-item>
+ <text:p text:style-name="P1">foo</text:p>
+ </text:list-item>
+ </text:list>
+ </office:text>
+ </office:body>
+</office:document> \ No newline at end of file
diff --git a/sw/qa/extras/uiwriter/uiwriter3.cxx b/sw/qa/extras/uiwriter/uiwriter3.cxx
index 9b781e47feb9..ba8d03ae7e6c 100644
--- a/sw/qa/extras/uiwriter/uiwriter3.cxx
+++ b/sw/qa/extras/uiwriter/uiwriter3.cxx
@@ -1333,8 +1333,7 @@ CPPUNIT_TEST_FIXTURE(SwUiWriterTest3, testTdf131963)
{
createSwDoc("tdf131963.docx");
- int nStartPages = getPages();
- CPPUNIT_ASSERT_GREATER(10, nStartPages);
+ CPPUNIT_ASSERT(11 == getPages() || 12 == getPages());
dispatchCommand(mxComponent, ".uno:SelectAll", {});
@@ -1349,7 +1348,7 @@ CPPUNIT_TEST_FIXTURE(SwUiWriterTest3, testTdf131963)
// Without the fix in place, this test would have crashed here
// tdf#133169: without the fix in place, it would have been 2 instead of 11
- CPPUNIT_ASSERT_EQUAL(nStartPages, getPages());
+ CPPUNIT_ASSERT(11 == getPages() || 12 == getPages());
}
CPPUNIT_TEST_FIXTURE(SwUiWriterTest3, testTdf132596)
diff --git a/sw/qa/extras/uiwriter/uiwriter6.cxx b/sw/qa/extras/uiwriter/uiwriter6.cxx
index 5b4140e02967..606728a94f1e 100644
--- a/sw/qa/extras/uiwriter/uiwriter6.cxx
+++ b/sw/qa/extras/uiwriter/uiwriter6.cxx
@@ -13,6 +13,7 @@
#include <itabenum.hxx>
#include <ndtxt.hxx>
#include <wrtsh.hxx>
+#include <edtwin.hxx>
#include <drawdoc.hxx>
#include <view.hxx>
#include <com/sun/star/text/XTextColumns.hpp>
@@ -54,6 +55,10 @@
#include <wrthtml.hxx>
#include <dbmgr.hxx>
#include <rootfrm.hxx>
+#include <pagefrm.hxx>
+#include <sortedobjs.hxx>
+#include <flyfrms.hxx>
+#include <tabfrm.hxx>
#include <unotxdoc.hxx>
#include <wrong.hxx>
#include <com/sun/star/linguistic2/LinguServiceManager.hpp>
@@ -1406,6 +1411,158 @@ CPPUNIT_TEST_FIXTURE(SwUiWriterTest6, testTdf154771_MovingMultipleColumns)
CPPUNIT_ASSERT_EQUAL(sal_Int32(4), xTable1->getColumns()->getCount());
}
+CPPUNIT_TEST_FIXTURE(SwUiWriterTest6, testTdf44773)
+{
+ // allow resizing table rows, if cursor outside the table
+ createSwDoc();
+ SwDoc* pDoc = getSwDoc();
+ CPPUNIT_ASSERT(pDoc);
+ SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
+ CPPUNIT_ASSERT(pWrtShell);
+
+ // insert an empty paragraph
+ pWrtShell->SplitNode();
+
+ // create a table
+ SwInsertTableOptions TableOpt(SwInsertTableFlags::DefaultBorder, 0);
+ (void)&pWrtShell->InsertTable(TableOpt, 2, 1);
+
+ // the cursor is not inside the table
+ CPPUNIT_ASSERT(!pWrtShell->IsCursorInTable());
+
+ uno::Reference<text::XTextTablesSupplier> xTablesSupplier(mxComponent, uno::UNO_QUERY);
+ uno::Reference<container::XNameAccess> xTableNames = xTablesSupplier->getTextTables();
+ CPPUNIT_ASSERT(xTableNames->hasByName("Table1"));
+ uno::Reference<text::XTextTable> xTable1(xTableNames->getByName("Table1"), uno::UNO_QUERY);
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(2), xTable1->getRows()->getCount());
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xTable1->getColumns()->getCount());
+
+ Scheduler::ProcessEventsToIdle();
+
+ // set table row height by drag & drop
+ SwRootFrame* pLayout = pDoc->getIDocumentLayoutAccess().GetCurrentLayout();
+
+ SwFrame* pPage = pLayout->Lower();
+ SwFrame* pBody = pPage->GetLower();
+ SwFrame* pTable = pBody->GetLower()->GetNext();
+ SwFrame* pRow1 = pTable->GetLower();
+ CPPUNIT_ASSERT(pRow1->IsRowFrame());
+ SwFrame* pCellA1 = pRow1->GetLower();
+ const SwRect& rCellA1Rect = pCellA1->getFrameArea();
+ auto nRowHeight = rCellA1Rect.Height();
+ // select center of the bottom border of the first table cell
+ Point ptFrom(rCellA1Rect.Left() + rCellA1Rect.Width() / 2, rCellA1Rect.Top() + nRowHeight);
+ // double the row height
+ Point ptTo(rCellA1Rect.Left() + rCellA1Rect.Width() / 2, rCellA1Rect.Top() + 2 * nRowHeight);
+ vcl::Window& rEditWin = pDoc->GetDocShell()->GetView()->GetEditWin();
+ Point aFrom = rEditWin.LogicToPixel(ptFrom);
+ MouseEvent aClickEvent(aFrom, 1, MouseEventModifiers::SIMPLECLICK | MouseEventModifiers::SELECT,
+ MOUSE_LEFT);
+ rEditWin.MouseButtonDown(aClickEvent);
+ Point aTo = rEditWin.LogicToPixel(ptTo);
+ MouseEvent aMoveEvent(aTo, 1, MouseEventModifiers::SIMPLECLICK | MouseEventModifiers::SELECT,
+ MOUSE_LEFT);
+ TrackingEvent aTEvt(aMoveEvent, TrackingEventFlags::Repeat);
+ // drag & drop of cell border inside the document (and outside the table)
+ // still based on the ruler code, use that to simulate dragging
+ pDoc->GetDocShell()->GetView()->GetVRuler().Tracking(aTEvt);
+ TrackingEvent aTEvt2(aMoveEvent, TrackingEventFlags::End);
+ pDoc->GetDocShell()->GetView()->GetVRuler().Tracking(aTEvt2);
+ Scheduler::ProcessEventsToIdle();
+ rEditWin.CaptureMouse();
+ rEditWin.ReleaseMouse();
+
+ // this was 396 (not modified row height previously)
+ CPPUNIT_ASSERT_EQUAL(tools::Long(810), pCellA1->getFrameArea().Height());
+}
+
+CPPUNIT_TEST_FIXTURE(SwUiWriterTest6, testTdf160842)
+{
+ createSwDoc("tdf160842.fodt");
+ SwDoc* pDoc = getSwDoc();
+ CPPUNIT_ASSERT(pDoc);
+ SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
+ CPPUNIT_ASSERT(pWrtShell);
+ // the cursor is not in the table
+ CPPUNIT_ASSERT(!pWrtShell->IsCursorInTable());
+
+ SwRootFrame* pLayout = pDoc->getIDocumentLayoutAccess().GetCurrentLayout();
+ auto pPage = dynamic_cast<SwPageFrame*>(pLayout->Lower());
+ CPPUNIT_ASSERT(pPage);
+ const SwSortedObjs& rPageObjs = *pPage->GetSortedObjs();
+ CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), rPageObjs.size());
+ auto pPageFly = dynamic_cast<SwFlyAtContentFrame*>(rPageObjs[0]);
+ CPPUNIT_ASSERT(pPageFly);
+ auto pTable = dynamic_cast<SwTabFrame*>(pPageFly->GetLower());
+ CPPUNIT_ASSERT(pTable);
+ auto pRow2 = pTable->GetLower()->GetNext();
+ CPPUNIT_ASSERT(pRow2->IsRowFrame());
+ auto pCellA2 = pRow2->GetLower();
+ CPPUNIT_ASSERT(pCellA2);
+ const SwRect& rCellA2Rect = pCellA2->getFrameArea();
+ auto nRowHeight = rCellA2Rect.Height();
+ // select center of the bottom cell
+ Point ptFrom(rCellA2Rect.Left() + rCellA2Rect.Width() / 2, rCellA2Rect.Top() + nRowHeight / 2);
+ vcl::Window& rEditWin = pDoc->GetDocShell()->GetView()->GetEditWin();
+ Point aFrom = rEditWin.LogicToPixel(ptFrom);
+ MouseEvent aClickEvent(aFrom, 1, MouseEventModifiers::SIMPLECLICK, MOUSE_LEFT);
+ rEditWin.MouseButtonDown(aClickEvent);
+ rEditWin.MouseButtonUp(aClickEvent);
+
+ // the cursor is in the table
+ CPPUNIT_ASSERT(pWrtShell->IsCursorInTable());
+}
+
+CPPUNIT_TEST_FIXTURE(SwUiWriterTest6, testTdf160836)
+{
+ createSwDoc("tdf160842.fodt");
+ SwDoc* pDoc = getSwDoc();
+ CPPUNIT_ASSERT(pDoc);
+ SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
+ CPPUNIT_ASSERT(pWrtShell);
+
+ // set table row height by drag & drop at images cropped by the fixed row height
+ SwRootFrame* pLayout = pDoc->getIDocumentLayoutAccess().GetCurrentLayout();
+ auto pPage = dynamic_cast<SwPageFrame*>(pLayout->Lower());
+ CPPUNIT_ASSERT(pPage);
+ const SwSortedObjs& rPageObjs = *pPage->GetSortedObjs();
+ CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), rPageObjs.size());
+ auto pPageFly = dynamic_cast<SwFlyAtContentFrame*>(rPageObjs[0]);
+ CPPUNIT_ASSERT(pPageFly);
+ auto pTable = dynamic_cast<SwTabFrame*>(pPageFly->GetLower());
+ CPPUNIT_ASSERT(pTable);
+ auto pRow1 = pTable->GetLower();
+ CPPUNIT_ASSERT(pRow1->IsRowFrame());
+ auto pCellA1 = pRow1->GetLower();
+ CPPUNIT_ASSERT(pCellA1);
+ const SwRect& rCellA1Rect = pCellA1->getFrameArea();
+ auto nRowHeight = rCellA1Rect.Height();
+ // select center of the bottom border of the first table cell
+ Point ptFrom(rCellA1Rect.Left() + rCellA1Rect.Width() / 2, rCellA1Rect.Top() + nRowHeight);
+ // halve the row height
+ Point ptTo(rCellA1Rect.Left() + rCellA1Rect.Width() / 2, rCellA1Rect.Top() + 0.5 * nRowHeight);
+ vcl::Window& rEditWin = pDoc->GetDocShell()->GetView()->GetEditWin();
+ Point aFrom = rEditWin.LogicToPixel(ptFrom);
+ MouseEvent aClickEvent(aFrom, 1, MouseEventModifiers::SIMPLECLICK | MouseEventModifiers::SELECT,
+ MOUSE_LEFT);
+ rEditWin.MouseButtonDown(aClickEvent);
+ Point aTo = rEditWin.LogicToPixel(ptTo);
+ MouseEvent aMoveEvent(aTo, 1, MouseEventModifiers::SIMPLECLICK | MouseEventModifiers::SELECT,
+ MOUSE_LEFT);
+ TrackingEvent aTEvt(aMoveEvent, TrackingEventFlags::Repeat);
+ // drag & drop of cell border inside the document (and outside the table)
+ // still based on the ruler code, use that to simulate dragging
+ pDoc->GetDocShell()->GetView()->GetVRuler().Tracking(aTEvt);
+ TrackingEvent aTEvt2(aMoveEvent, TrackingEventFlags::End);
+ pDoc->GetDocShell()->GetView()->GetVRuler().Tracking(aTEvt2);
+ Scheduler::ProcessEventsToIdle();
+ rEditWin.CaptureMouse();
+ rEditWin.ReleaseMouse();
+
+ // this was 3910 (not modified row height previously)
+ CPPUNIT_ASSERT_EQUAL(tools::Long(1980), pCellA1->getFrameArea().Height());
+}
+
CPPUNIT_TEST_FIXTURE(SwUiWriterTest6, testTdf115132)
{
createSwDoc();
@@ -1887,16 +2044,9 @@ CPPUNIT_TEST_FIXTURE(SwUiWriterTest6, testTdf124603)
bool bPending = !pNode->GetWrong() || !pNode->GetWrong()->Count();
CPPUNIT_ASSERT(bPending);
- // Move right, leave the bad word
+ // Move right, leave the bad word - since the fix for tdf#136294, this triggers the check
pWrtShell->Right(SwCursorSkipMode::Chars, /*bSelect=*/false, 1, /*bBasicCall=*/false);
- // tdf#92036 still pending spell checking
- bPending = !pNode->GetWrong() || !pNode->GetWrong()->Count();
- CPPUNIT_ASSERT(bPending);
-
- // Move down to trigger spell checking
-
- pWrtShell->Down(/*bSelect=*/false, 1);
Scheduler::ProcessEventsToIdle();
CPPUNIT_ASSERT(pNode->GetWrong());
// This was 0 (pending spell checking)
@@ -1945,6 +2095,7 @@ CPPUNIT_TEST_FIXTURE(SwUiWriterTest6, testTdf45949)
// Move down to trigger spell checking
pWrtShell->Down(/*bSelect=*/false, 1);
+ Scheduler::ProcessEventsToIdle();
// Without the fix in place, this test would have failed with
// - Expected: 3
diff --git a/sw/qa/extras/uiwriter/uiwriter8.cxx b/sw/qa/extras/uiwriter/uiwriter8.cxx
index 4fa027b0515b..60b1bd8e9ce6 100644
--- a/sw/qa/extras/uiwriter/uiwriter8.cxx
+++ b/sw/qa/extras/uiwriter/uiwriter8.cxx
@@ -25,6 +25,7 @@
#include <frameformats.hxx>
#include <tools/json_writer.hxx>
#include <unotools/streamwrap.hxx>
+#include <editeng/lrspitem.hxx>
#include <sfx2/linkmgr.hxx>
#include <wrtsh.hxx>
@@ -870,6 +871,126 @@ CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf116315)
}
}
+CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testInsertAutoTextIntoListFromParaStyle)
+{
+ createSwDoc("stylewithlistandindents.fodt");
+ SwDoc* const pDoc = getSwDoc();
+ SwWrtShell* const pWrtShell = pDoc->GetDocShell()->GetWrtShell();
+ CPPUNIT_ASSERT(pWrtShell);
+
+ pWrtShell->FwdPara();
+ pWrtShell->EndPara(/*bSelect=*/false);
+ // expands autotext (via F3)
+ pWrtShell->Insert(" jacr");
+
+ SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument*>(mxComponent.get());
+ pTextDoc->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 0, KEY_F3);
+ Scheduler::ProcessEventsToIdle();
+
+ pWrtShell->SttEndDoc(/*bStt=*/true);
+ pWrtShell->FwdPara();
+
+ SwNumRule* pNumRule;
+ SvxTextLeftMarginItem const* pTextLeftMargin;
+ SvxFirstLineIndentItem const* pFirstLineIndent;
+
+ {
+ SwTextNode& rNode{ *pWrtShell->GetCursor()->GetPoint()->GetNode().GetTextNode() };
+ // numrule from paragraph style, but not from direct formatting
+ auto pSet{ rNode.GetpSwAttrSet() };
+ CPPUNIT_ASSERT(pSet);
+ // list id was set
+ CPPUNIT_ASSERT_EQUAL(SfxItemState::SET, pSet->GetItemState(RES_PARATR_LIST_ID, false));
+ // the numrule is set on the paragraph style, not on the paragraph
+ CPPUNIT_ASSERT_EQUAL(SfxItemState::DEFAULT, pSet->GetItemState(RES_PARATR_NUMRULE, false));
+ CPPUNIT_ASSERT_EQUAL(SfxItemState::SET, pSet->GetItemState(RES_PARATR_NUMRULE, true));
+ CPPUNIT_ASSERT_EQUAL(SfxItemState::DEFAULT,
+ pSet->GetItemState(RES_MARGIN_FIRSTLINE, false));
+ CPPUNIT_ASSERT_EQUAL(SfxItemState::SET, pSet->GetItemState(RES_MARGIN_FIRSTLINE, true));
+ CPPUNIT_ASSERT_EQUAL(SfxItemState::DEFAULT, pSet->GetItemState(RES_MARGIN_TEXTLEFT, false));
+ CPPUNIT_ASSERT_EQUAL(SfxItemState::SET, pSet->GetItemState(RES_MARGIN_TEXTLEFT, true));
+ CPPUNIT_ASSERT_EQUAL(u"ListAndIndents"_ustr, rNode.GetTextColl()->GetName());
+ CPPUNIT_ASSERT_EQUAL(u"Item We confirm receipt of your application material."_ustr,
+ rNode.GetText());
+ pNumRule = rNode.GetNumRule();
+ pTextLeftMargin = &rNode.GetAttr(RES_MARGIN_TEXTLEFT);
+ pFirstLineIndent = &rNode.GetAttr(RES_MARGIN_FIRSTLINE);
+ }
+
+ pWrtShell->FwdPara();
+
+ {
+ SwTextNode& rNode{ *pWrtShell->GetCursor()->GetPoint()->GetNode().GetTextNode() };
+ auto pSet{ rNode.GetpSwAttrSet() };
+ CPPUNIT_ASSERT(pSet);
+ // list id was set
+ CPPUNIT_ASSERT_EQUAL(SfxItemState::SET, pSet->GetItemState(RES_PARATR_LIST_ID, false));
+ // middle paragraph was pasted - has numrule and indents applied directly
+ CPPUNIT_ASSERT_EQUAL(SfxItemState::SET, pSet->GetItemState(RES_PARATR_NUMRULE, false));
+ CPPUNIT_ASSERT_EQUAL(SfxItemState::SET, pSet->GetItemState(RES_MARGIN_FIRSTLINE, false));
+ CPPUNIT_ASSERT_EQUAL(SfxItemState::SET, pSet->GetItemState(RES_MARGIN_TEXTLEFT, false));
+ CPPUNIT_ASSERT_EQUAL(u"Default Paragraph Style"_ustr, rNode.GetTextColl()->GetName());
+ CPPUNIT_ASSERT(rNode.GetText().startsWith("As more applicants applied"));
+ CPPUNIT_ASSERT_EQUAL(pNumRule, rNode.GetNumRule());
+ CPPUNIT_ASSERT_EQUAL(pTextLeftMargin->GetTextLeft(),
+ rNode.GetAttr(RES_MARGIN_TEXTLEFT).GetTextLeft());
+ CPPUNIT_ASSERT_EQUAL(pFirstLineIndent->GetTextFirstLineOffset(),
+ rNode.GetAttr(RES_MARGIN_FIRSTLINE).GetTextFirstLineOffset());
+ }
+
+ pWrtShell->FwdPara();
+
+ {
+ SwTextNode& rNode{ *pWrtShell->GetCursor()->GetPoint()->GetNode().GetTextNode() };
+ // numrule from paragraph style, but not from direct formatting
+ auto pSet{ rNode.GetpSwAttrSet() };
+ CPPUNIT_ASSERT(pSet);
+ // list id was set
+ CPPUNIT_ASSERT_EQUAL(SfxItemState::SET, pSet->GetItemState(RES_PARATR_LIST_ID, false));
+ // the numrule is set on the paragraph style, not on the paragraph
+ CPPUNIT_ASSERT_EQUAL(SfxItemState::DEFAULT, pSet->GetItemState(RES_PARATR_NUMRULE, false));
+ CPPUNIT_ASSERT_EQUAL(SfxItemState::SET, pSet->GetItemState(RES_PARATR_NUMRULE, true));
+ CPPUNIT_ASSERT_EQUAL(SfxItemState::DEFAULT,
+ pSet->GetItemState(RES_MARGIN_FIRSTLINE, false));
+ CPPUNIT_ASSERT_EQUAL(SfxItemState::SET, pSet->GetItemState(RES_MARGIN_FIRSTLINE, true));
+ CPPUNIT_ASSERT_EQUAL(SfxItemState::DEFAULT, pSet->GetItemState(RES_MARGIN_TEXTLEFT, false));
+ CPPUNIT_ASSERT_EQUAL(SfxItemState::SET, pSet->GetItemState(RES_MARGIN_TEXTLEFT, true));
+ CPPUNIT_ASSERT_EQUAL(u"ListAndIndents"_ustr, rNode.GetTextColl()->GetName());
+ CPPUNIT_ASSERT(rNode.GetText().endsWith("as soon as we have come to a decision."));
+ CPPUNIT_ASSERT_EQUAL(pNumRule, rNode.GetNumRule());
+ CPPUNIT_ASSERT_EQUAL(pTextLeftMargin->GetTextLeft(),
+ rNode.GetAttr(RES_MARGIN_TEXTLEFT).GetTextLeft());
+ CPPUNIT_ASSERT_EQUAL(pFirstLineIndent->GetTextFirstLineOffset(),
+ rNode.GetAttr(RES_MARGIN_FIRSTLINE).GetTextFirstLineOffset());
+ }
+
+ pWrtShell->FwdPara();
+
+ {
+ SwTextNode& rNode{ *pWrtShell->GetCursor()->GetPoint()->GetNode().GetTextNode() };
+ // numrule from paragraph style, but not from direct formatting
+ auto pSet{ rNode.GetpSwAttrSet() };
+ CPPUNIT_ASSERT(pSet);
+ // list id was set
+ CPPUNIT_ASSERT_EQUAL(SfxItemState::SET, pSet->GetItemState(RES_PARATR_LIST_ID, false));
+ // the numrule is set on the paragraph style, not on the paragraph
+ CPPUNIT_ASSERT_EQUAL(SfxItemState::DEFAULT, pSet->GetItemState(RES_PARATR_NUMRULE, false));
+ CPPUNIT_ASSERT_EQUAL(SfxItemState::SET, pSet->GetItemState(RES_PARATR_NUMRULE, true));
+ CPPUNIT_ASSERT_EQUAL(SfxItemState::DEFAULT,
+ pSet->GetItemState(RES_MARGIN_FIRSTLINE, false));
+ CPPUNIT_ASSERT_EQUAL(SfxItemState::SET, pSet->GetItemState(RES_MARGIN_FIRSTLINE, true));
+ CPPUNIT_ASSERT_EQUAL(SfxItemState::DEFAULT, pSet->GetItemState(RES_MARGIN_TEXTLEFT, false));
+ CPPUNIT_ASSERT_EQUAL(SfxItemState::SET, pSet->GetItemState(RES_MARGIN_TEXTLEFT, true));
+ CPPUNIT_ASSERT_EQUAL(u"ListAndIndents"_ustr, rNode.GetTextColl()->GetName());
+ CPPUNIT_ASSERT_EQUAL(u"more"_ustr, rNode.GetText()); // pre-exising list item
+ CPPUNIT_ASSERT_EQUAL(pNumRule, rNode.GetNumRule());
+ CPPUNIT_ASSERT_EQUAL(pTextLeftMargin->GetTextLeft(),
+ rNode.GetAttr(RES_MARGIN_TEXTLEFT).GetTextLeft());
+ CPPUNIT_ASSERT_EQUAL(pFirstLineIndent->GetTextFirstLineOffset(),
+ rNode.GetAttr(RES_MARGIN_FIRSTLINE).GetTextFirstLineOffset());
+ }
+}
+
CPPUNIT_TEST_FIXTURE(SwUiWriterTest8, testTdf144364)
{
createSwDoc();
diff --git a/sw/qa/extras/uiwriter/uiwriter9.cxx b/sw/qa/extras/uiwriter/uiwriter9.cxx
index 96ea65e988d9..ca3943639ae6 100644
--- a/sw/qa/extras/uiwriter/uiwriter9.cxx
+++ b/sw/qa/extras/uiwriter/uiwriter9.cxx
@@ -19,6 +19,7 @@
#include <com/sun/star/view/XSelectionSupplier.hpp>
#include <comphelper/propertysequence.hxx>
+#include <comphelper/propertyvalue.hxx>
#include <swdtflvr.hxx>
#include <o3tl/string_view.hxx>
@@ -200,6 +201,20 @@ CPPUNIT_TEST_FIXTURE(SwUiWriterTest9, testTdf159816)
xTransfer->PrivateDrop(*pWrtShell, ptTo, /*bMove=*/true, /*bXSelection=*/true);
}
+CPPUNIT_TEST_FIXTURE(SwUiWriterTest9, testTdf160898)
+{
+ // Given a document with a 1-cell table in another 1-cell table:
+ createSwDoc("table-in-table.fodt");
+ SwXTextDocument* pXTextDocument = dynamic_cast<SwXTextDocument*>(mxComponent.get());
+ SwDocShell* pDocShell = pXTextDocument->GetDocShell();
+ SwWrtShell* pWrtShell = pDocShell->GetWrtShell();
+
+ // Move to the normally hidden paragraph inside the outer table cell, following the inner table
+ pWrtShell->Down(false, 2);
+ // Without the fix, this would crash:
+ pWrtShell->SelAll();
+}
+
CPPUNIT_TEST_FIXTURE(SwUiWriterTest9, testTdf159054_disableOutlineNumbering)
{
createSwDoc("tdf159054_disableOutlineNumbering.docx");
@@ -242,6 +257,75 @@ CPPUNIT_TEST_FIXTURE(SwUiWriterTest9, testTdf159054_disableOutlineNumbering)
CPPUNIT_ASSERT_EQUAL(OUString(""), getProperty<OUString>(xPara2, "ListLabelString"));
CPPUNIT_ASSERT_EQUAL(OUString("A."), getProperty<OUString>(xPara3, "ListLabelString"));
}
+CPPUNIT_TEST_FIXTURE(SwUiWriterTest9, testTdf161172)
+{
+ // Given a paragraph manually made a member of a list:
+ createSwDoc("tdf161172.fodt");
+ auto para = getParagraph(1);
+
+ // Check initial state: the first paragraph has "No_list" para style, "Num_1" numbering style,
+ // numbering level 0, and "Num1_lvl1_1" numbering label.
+ CPPUNIT_ASSERT_EQUAL(u"No_list"_ustr, getProperty<OUString>(para, u"ParaStyleName"_ustr));
+ CPPUNIT_ASSERT_EQUAL(u"Num_1"_ustr, getProperty<OUString>(para, u"NumberingStyleName"_ustr));
+ CPPUNIT_ASSERT_EQUAL(u"Num1_lvl1_1"_ustr, getProperty<OUString>(para, u"ListLabelString"_ustr));
+ CPPUNIT_ASSERT_EQUAL(sal_Int16(0), getProperty<sal_Int16>(para, u"NumberingLevel"_ustr));
+
+ // Assign "Num_1_lvl2" paragraph style to the first paragraph. The style is associated with
+ // "Num_1" numbering style, level 1.
+ dispatchCommand(mxComponent, u".uno:StyleApply"_ustr,
+ { comphelper::makePropertyValue(u"FamilyName"_ustr, u"ParagraphStyles"_ustr),
+ comphelper::makePropertyValue(u"Style"_ustr, u"Num_1_lvl2"_ustr) });
+
+ // Check that the respective properties got correctly applied
+ CPPUNIT_ASSERT_EQUAL(u"Num_1_lvl2"_ustr, getProperty<OUString>(para, u"ParaStyleName"_ustr));
+ CPPUNIT_ASSERT_EQUAL(u"Num_1"_ustr, getProperty<OUString>(para, u"NumberingStyleName"_ustr));
+ CPPUNIT_ASSERT_EQUAL(u"Num1_lvl2_1"_ustr, getProperty<OUString>(para, u"ListLabelString"_ustr));
+ CPPUNIT_ASSERT_EQUAL(sal_Int16(1), getProperty<sal_Int16>(para, u"NumberingLevel"_ustr));
+
+ // Undo
+ dispatchCommand(mxComponent, u".uno:Undo"_ustr, {});
+
+ // Check that the numbering properties got correctly restored
+ CPPUNIT_ASSERT_EQUAL(u"No_list"_ustr, getProperty<OUString>(para, u"ParaStyleName"_ustr));
+ CPPUNIT_ASSERT_EQUAL(u"Num_1"_ustr, getProperty<OUString>(para, u"NumberingStyleName"_ustr));
+ // Without the fix, this would fail with
+ // - Expected: Num1_lvl1_1
+ // - Actual : Num1_lvl2_1
+ CPPUNIT_ASSERT_EQUAL(u"Num1_lvl1_1"_ustr, getProperty<OUString>(para, u"ListLabelString"_ustr));
+ // Without the fix, this would fail with
+ // - Expected: 0
+ // - Actual : 1
+ CPPUNIT_ASSERT_EQUAL(sal_Int16(0), getProperty<sal_Int16>(para, u"NumberingLevel"_ustr));
+}
+
+CPPUNIT_TEST_FIXTURE(SwUiWriterTest9, testTdf144752)
+{
+ // Undoing/redoing a replacement must select the new text
+ createSwDoc();
+ SwXTextDocument* pDoc = dynamic_cast<SwXTextDocument*>(mxComponent.get());
+ CPPUNIT_ASSERT(pDoc);
+ SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
+ CPPUNIT_ASSERT(pWrtShell);
+
+ emulateTyping(*pDoc, u"Some Text");
+ CPPUNIT_ASSERT(!pWrtShell->HasSelection());
+ // Select "Text", and replace with "Word"
+ pWrtShell->Left(SwCursorSkipMode::Chars, /*bSelect*/ true, 4, /*bBasicCall*/ false);
+ pWrtShell->Replace(u"Word"_ustr, false);
+ pWrtShell->EndOfSection();
+ CPPUNIT_ASSERT(!pWrtShell->HasSelection());
+
+ // Undo and check, that the "Text" is selected
+ dispatchCommand(mxComponent, ".uno:Undo", {});
+ // Without the fix, this would fail
+ CPPUNIT_ASSERT(pWrtShell->HasSelection());
+ CPPUNIT_ASSERT_EQUAL(u"Text"_ustr, pWrtShell->GetSelText());
+
+ // Redo and check, that the "Word" is selected
+ dispatchCommand(mxComponent, ".uno:Redo", {});
+ CPPUNIT_ASSERT(pWrtShell->HasSelection());
+ CPPUNIT_ASSERT_EQUAL(u"Word"_ustr, pWrtShell->GetSelText());
+}
} // end of anonymous namespace
CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/sw/qa/extras/unowriter/data/tdf161035.fodt b/sw/qa/extras/unowriter/data/tdf161035.fodt
new file mode 100644
index 000000000000..8f1d53b083d6
--- /dev/null
+++ b/sw/qa/extras/unowriter/data/tdf161035.fodt
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<office:document xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" office:version="1.3" office:mimetype="application/vnd.oasis.opendocument.text">
+ <office:body>
+ <office:text>
+ <text:p>Lorem <text:bookmark text:name="Bookmark"/>ipsum.</text:p>
+ </office:text>
+ </office:body>
+</office:document> \ No newline at end of file
diff --git a/sw/qa/extras/unowriter/unowriter.cxx b/sw/qa/extras/unowriter/unowriter.cxx
index 80b9e556f73b..7175e702d709 100644
--- a/sw/qa/extras/unowriter/unowriter.cxx
+++ b/sw/qa/extras/unowriter/unowriter.cxx
@@ -1222,6 +1222,33 @@ CPPUNIT_TEST_FIXTURE(SwUnoWriter, testTdf160278)
CPPUNIT_ASSERT_EQUAL(u"12test"_ustr, xText->getString());
}
+CPPUNIT_TEST_FIXTURE(SwUnoWriter, testTdf161035)
+{
+ // Given a paragraph with a bookmark:
+ createSwDoc("tdf161035.fodt");
+ auto xModel = mxComponent.queryThrow<frame::XModel>();
+
+ // Create a text view cursor in the paragraph.
+ auto xController = xModel->getCurrentController().queryThrow<text::XTextViewCursorSupplier>();
+ auto xViewCursor = xController->getViewCursor();
+ CPPUNIT_ASSERT(xViewCursor);
+ auto xText = xViewCursor->getText();
+ CPPUNIT_ASSERT(xText);
+ // Create a text cursor from the text view cursor, and move it to the end of the paragraph
+ auto xTextCursor = xText->createTextCursorByRange(xViewCursor);
+ CPPUNIT_ASSERT(xTextCursor);
+ xTextCursor->gotoEnd(false);
+ // Get the first paragraph portion from the text cursor
+ auto xParaEnum = xTextCursor.queryThrow<container::XEnumerationAccess>()->createEnumeration();
+ CPPUNIT_ASSERT(xParaEnum);
+ auto xPara = xParaEnum->nextElement().queryThrow<container::XEnumerationAccess>();
+ // Try to enumerate text portions. Without the fix, it would fail an assertion in debug builds,
+ // and hang in release builds, because the paragraph portion started after the bookmark, and
+ // so the bookmark wasn't processed (expectedly):
+ auto xRunEnum = xPara->createEnumeration();
+ CPPUNIT_ASSERT(!xRunEnum->hasMoreElements()); // Empty enumeration for empty selection
+}
+
CPPUNIT_PLUGIN_IMPLEMENT();
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/qa/extras/ww8export/data/draw-obj-rtl-no-mirror-vml.docx b/sw/qa/extras/ww8export/data/draw-obj-rtl-no-mirror-vml.docx
new file mode 100644
index 000000000000..3b291901f72d
--- /dev/null
+++ b/sw/qa/extras/ww8export/data/draw-obj-rtl-no-mirror-vml.docx
Binary files differ
diff --git a/sw/qa/extras/ww8export/ww8export4.cxx b/sw/qa/extras/ww8export/ww8export4.cxx
index e297ac949afe..b25d3b4a7701 100644
--- a/sw/qa/extras/ww8export/ww8export4.cxx
+++ b/sw/qa/extras/ww8export/ww8export4.cxx
@@ -262,6 +262,30 @@ CPPUNIT_TEST_FIXTURE(Test, testLegalNumbering)
verify();
}
+CPPUNIT_TEST_FIXTURE(Test, testDOCExportDoNotMirrorRtlDrawObjs)
+{
+ // Given a document with a shape, anchored in an RTL paragraph, loaded from DOCX:
+ createSwDoc("draw-obj-rtl-no-mirror-vml.docx");
+
+ // When saving that to DOC:
+ saveAndReload(mpFilter);
+
+ // Then make sure the shape is on the right margin:
+ xmlDocUniquePtr pXmlDoc = parseLayoutDump();
+ sal_Int32 nPageRight = getXPath(pXmlDoc, "//page/infos/bounds"_ostr, "right"_ostr).toInt32();
+ sal_Int32 nBodyRight = getXPath(pXmlDoc, "//body/infos/bounds"_ostr, "right"_ostr).toInt32();
+ sal_Int32 nShapeLeft
+ = getXPath(pXmlDoc, "//SwAnchoredDrawObject/bounds"_ostr, "left"_ostr).toInt32();
+ CPPUNIT_ASSERT_GREATER(nBodyRight, nShapeLeft);
+ sal_Int32 nShapeRight
+ = getXPath(pXmlDoc, "//SwAnchoredDrawObject/bounds"_ostr, "right"_ostr).toInt32();
+ // Without the accompanying fix in place, this test would have failed with:
+ // - Expected less than: 12523
+ // - Actual : 12536
+ // i.e. the shape was outside of the page right margin area, due to an unwanted mapping.
+ CPPUNIT_ASSERT_LESS(nPageRight, nShapeRight);
+}
+
DECLARE_WW8EXPORT_TEST(testNonInlinePageBreakFirstLine, "nonInlinePageBreakFirstLine.doc")
{
SwDoc* pDoc = getSwDoc();
diff --git a/sw/qa/filter/ww8/ww8.cxx b/sw/qa/filter/ww8/ww8.cxx
index af19051a03e5..070565345a2d 100644
--- a/sw/qa/filter/ww8/ww8.cxx
+++ b/sw/qa/filter/ww8/ww8.cxx
@@ -30,6 +30,9 @@
#include <fmtwrapinfluenceonobjpos.hxx>
#include <ftnidx.hxx>
#include <tabfrm.hxx>
+#include <cntfrm.hxx>
+#include <colfrm.hxx>
+#include <fmtftntx.hxx>
namespace
{
@@ -298,7 +301,10 @@ CPPUNIT_TEST_FIXTURE(Test, test3Endnotes)
SwDoc* pDoc = getSwDoc();
SwRootFrame* pLayout = pDoc->getIDocumentLayoutAccess().GetCurrentLayout();
SwPageFrame* pPage = pLayout->GetLastPage();
- SwFootnoteContFrame* pFootnoteCont = pPage->FindFootnoteCont();
+ SwContentFrame* pLastContent = pPage->FindLastBodyContent();
+ SwFrame* pSectionFrame = pLastContent->GetNext();
+ auto pColumnFrame = pSectionFrame->GetLower()->DynCastColumnFrame();
+ SwFootnoteContFrame* pFootnoteCont = pColumnFrame->FindFootnoteCont();
int nEndnotes = 0;
for (SwFrame* pLower = pFootnoteCont->GetLower(); pLower; pLower = pLower->GetNext())
{
@@ -559,6 +565,35 @@ CPPUNIT_TEST_FIXTURE(Test, testNullPointerDereference)
createSwDoc("null-pointer-dereference.doc");
CPPUNIT_ASSERT_EQUAL(6, getPages());
}
+
+CPPUNIT_TEST_FIXTURE(Test, testEndnotesAtSectEnd)
+{
+ // Given a document, endnotes at collected at section end:
+ createSwDoc();
+ SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
+ pWrtShell->SplitNode();
+ pWrtShell->Up(/*bSelect=*/false);
+ pWrtShell->Insert("x");
+ pWrtShell->Left(SwCursorSkipMode::Chars, /*bSelect=*/true, 1, /*bBasicCall=*/false);
+ SwSectionData aSection(SectionType::Content, pWrtShell->GetUniqueSectionName());
+ pWrtShell->StartAction();
+ SfxItemSetFixed<RES_FTN_AT_TXTEND, RES_FRAMEDIR> aSet(pWrtShell->GetAttrPool());
+ aSet.Put(SwFormatEndAtTextEnd(FTNEND_ATTXTEND));
+ pWrtShell->InsertSection(aSection, &aSet);
+ pWrtShell->EndAction();
+ pWrtShell->InsertFootnote(OUString(), /*bEndNote=*/true);
+
+ // When saving to DOCX:
+ save("Office Open XML Text");
+
+ // Then make sure the endnote position is section end:
+ xmlDocUniquePtr pXmlDoc = parseExport("word/settings.xml");
+ OUString aPos = getXPath(pXmlDoc, "/w:settings/w:endnotePr/w:pos"_ostr, "val"_ostr);
+ // Without the accompanying fix in place, this test would have failed with:
+ // - XPath '/w:settings/w:endnotePr/w:pos' number of nodes is incorrect
+ // i.e. the default position was used: document end.
+ CPPUNIT_ASSERT_EQUAL(OUString("sectEnd"), aPos);
+}
}
CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/sw/qa/uibase/uno/uno.cxx b/sw/qa/uibase/uno/uno.cxx
index d38d0bbfc967..3e6d9c93d51c 100644
--- a/sw/qa/uibase/uno/uno.cxx
+++ b/sw/qa/uibase/uno/uno.cxx
@@ -560,6 +560,30 @@ CPPUNIT_TEST_FIXTURE(SwUibaseUnoTest, testAllowTextAfterFloatingTableBreak)
CPPUNIT_ASSERT(bAllowTextAfterFloatingTableBreak);
}
+CPPUNIT_TEST_FIXTURE(SwUibaseUnoTest, testDoNotMirrorRtlDrawObjs)
+{
+ // Given an empty document:
+ createSwDoc();
+
+ // When checking the state of the DoNotMirrorRtlDrawObjs compat flag:
+ uno::Reference<lang::XMultiServiceFactory> xDocument(mxComponent, uno::UNO_QUERY);
+ uno::Reference<beans::XPropertySet> xSettings(
+ xDocument->createInstance("com.sun.star.document.Settings"), uno::UNO_QUERY);
+ bool bDoNotMirrorRtlDrawObjs{};
+ // Without the accompanying fix in place, this test would have failed with:
+ // An uncaught exception of type com.sun.star.beans.UnknownPropertyException
+ // i.e. the compat flag was not recognized.
+ xSettings->getPropertyValue("DoNotMirrorRtlDrawObjs") >>= bDoNotMirrorRtlDrawObjs;
+ // Then make sure it's false by default:
+ CPPUNIT_ASSERT(!bDoNotMirrorRtlDrawObjs);
+
+ // And when setting DoNotMirrorRtlDrawObjs=true:
+ xSettings->setPropertyValue("DoNotMirrorRtlDrawObjs", uno::Any(true));
+ // Then make sure it gets enabled:
+ xSettings->getPropertyValue("DoNotMirrorRtlDrawObjs") >>= bDoNotMirrorRtlDrawObjs;
+ CPPUNIT_ASSERT(bDoNotMirrorRtlDrawObjs);
+}
+
CPPUNIT_PLUGIN_IMPLEMENT();
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/qa/uitest/writer_tests2/formatParagraph.py b/sw/qa/uitest/writer_tests2/formatParagraph.py
index e90d0fd7f980..bfa6eff48dc9 100644
--- a/sw/qa/uitest/writer_tests2/formatParagraph.py
+++ b/sw/qa/uitest/writer_tests2/formatParagraph.py
@@ -177,7 +177,7 @@ class formatParagraph(UITestCase):
self.assertEqual(get_state_as_dict(xspinWidow)["Text"], "2")
self.assertEqual(get_state_as_dict(xcheckWidow)["Selected"], "false")
self.assertEqual(get_state_as_dict(xcheckOrphan)["Selected"], "false")
- self.assertEqual(get_state_as_dict(xcheckSplitPara)["Selected"], "true")
+ self.assertEqual(get_state_as_dict(xcheckSplitPara)["Selected"], "false")
self.assertEqual(get_state_as_dict(xcheckKeepPara)["Selected"], "true")
diff --git a/sw/source/core/access/accfrmobj.cxx b/sw/source/core/access/accfrmobj.cxx
index f78dc2d155db..004ca4ab94e0 100644
--- a/sw/source/core/access/accfrmobj.cxx
+++ b/sw/source/core/access/accfrmobj.cxx
@@ -240,13 +240,16 @@ SwRect SwAccessibleChild::GetBox( const SwAccessibleMap& rAccMap ) const
// by the mpFrame case above b) for genuine SdrObject this must be set
// if it's connected to layout
assert(dynamic_cast<SwDrawContact const*>(pContact));
- SwPageFrame const*const pPage(const_cast<SwAnchoredObject *>(
- pContact->GetAnchoredObj(mpDrawObj))->FindPageFrameOfAnchor());
- if (pPage) // may end up here with partial layout -> not visible
+ if (pContact)
{
- aBox = SwRect( mpDrawObj->GetCurrentBoundRect() );
- // tdf#91260 drawing object may be partially off-page
- aBox.Intersection(pPage->getFrameArea());
+ SwPageFrame const*const pPage(const_cast<SwAnchoredObject *>(
+ pContact->GetAnchoredObj(mpDrawObj))->FindPageFrameOfAnchor());
+ if (pPage) // may end up here with partial layout -> not visible
+ {
+ aBox = SwRect( mpDrawObj->GetCurrentBoundRect() );
+ // tdf#91260 drawing object may be partially off-page
+ aBox.Intersection(pPage->getFrameArea());
+ }
}
}
else if ( mpWindow )
diff --git a/sw/source/core/crsr/crsrsh.cxx b/sw/source/core/crsr/crsrsh.cxx
index b7f6962982b5..51f675adc9dd 100644
--- a/sw/source/core/crsr/crsrsh.cxx
+++ b/sw/source/core/crsr/crsrsh.cxx
@@ -738,9 +738,15 @@ bool SwCursorShell::MoveStartText()
SwTableNode const*const pTable(pStartNode->FindTableNode());
m_pCurrentCursor->GetPoint()->Assign(*pStartNode);
GetDoc()->GetNodes().GoNext(m_pCurrentCursor->GetPoint());
- while (m_pCurrentCursor->GetPoint()->GetNode().FindTableNode() != pTable
- && (!pTable || pTable->GetIndex() < m_pCurrentCursor->GetPoint()->GetNode().FindTableNode()->GetIndex())
- && MoveOutOfTable());
+ while (auto* pFoundTable = m_pCurrentCursor->GetPoint()->GetNode().FindTableNode())
+ {
+ if (pFoundTable == pTable)
+ break;
+ if (pTable && pTable->GetIndex() >= pFoundTable->GetIndex())
+ break;
+ if (!MoveOutOfTable())
+ break;
+ }
UpdateCursor(SwCursorShell::SCROLLWIN|SwCursorShell::CHKRANGE|SwCursorShell::READONLY);
return old != *m_pCurrentCursor->GetPoint();
}
@@ -1909,6 +1915,15 @@ void SwCursorShell::UpdateCursor( sal_uInt16 eFlags, bool bIdleEnd )
return; // if not then no update
}
+ if (m_bNeedLayoutOnCursorUpdate)
+ {
+ // A previous spell check skipped a word that had a spelling error, because that word
+ // had cursor. Now schedule the idle to call SwViewShell::LayoutIdle, to repeat the
+ // spell check, in the hope that the cursor has left the word.
+ m_aLayoutIdle.Start();
+ m_bNeedLayoutOnCursorUpdate = false;
+ }
+
#if !ENABLE_WASM_STRIP_ACCESSIBILITY
SwNotifyAccAboutInvalidTextSelections aInvalidateTextSelections( *this );
#endif
@@ -3299,6 +3314,7 @@ SwCursorShell::SwCursorShell( SwCursorShell& rShell, vcl::Window *pInitWin )
, m_eEnhancedTableSel(SwTable::SEARCH_NONE)
, m_nMarkedListLevel( 0 )
, m_oldColFrame(nullptr)
+ , m_aLayoutIdle("SwCursorShell m_aLayoutIdle")
{
CurrShell aCurr( this );
// only keep the position of the current cursor of the copy shell
@@ -3314,6 +3330,9 @@ SwCursorShell::SwCursorShell( SwCursorShell& rShell, vcl::Window *pInitWin )
m_bSetCursorInReadOnly = true;
m_pVisibleCursor = new SwVisibleCursor( this );
m_bMacroExecAllowed = rShell.IsMacroExecAllowed();
+
+ m_aLayoutIdle.SetPriority(TaskPriority::LOWEST);
+ m_aLayoutIdle.SetInvokeHandler(LINK(this, SwCursorShell, DoLayoutIdle));
}
/// default constructor
@@ -3336,6 +3355,7 @@ SwCursorShell::SwCursorShell( SwDoc& rDoc, vcl::Window *pInitWin,
, m_eEnhancedTableSel(SwTable::SEARCH_NONE)
, m_nMarkedListLevel( 0 )
, m_oldColFrame(nullptr)
+ , m_aLayoutIdle("SwCursorShell m_aLayoutIdle")
{
CurrShell aCurr( this );
// create initial cursor and set it to first content position
@@ -3360,10 +3380,15 @@ SwCursorShell::SwCursorShell( SwDoc& rDoc, vcl::Window *pInitWin,
m_pVisibleCursor = new SwVisibleCursor( this );
m_bMacroExecAllowed = true;
+
+ m_aLayoutIdle.SetPriority(TaskPriority::LOWEST);
+ m_aLayoutIdle.SetInvokeHandler(LINK(this, SwCursorShell, DoLayoutIdle));
}
SwCursorShell::~SwCursorShell()
{
+ m_aLayoutIdle.Stop();
+
// if it is not the last view then at least the field should be updated
if( !unique() )
CheckTableBoxContent( m_pCurrentCursor->GetPoint() );
@@ -3392,6 +3417,8 @@ SwCursorShell::~SwCursorShell()
EndListeningAll();
}
+IMPL_LINK_NOARG(SwCursorShell, DoLayoutIdle, Timer*, void) { LayoutIdle(); }
+
SwShellCursor* SwCursorShell::getShellCursor( bool bBlock )
{
if( m_pTableCursor )
diff --git a/sw/source/core/crsr/viscrs.cxx b/sw/source/core/crsr/viscrs.cxx
index 0385ce85f71c..090d0eb70421 100644
--- a/sw/source/core/crsr/viscrs.cxx
+++ b/sw/source/core/crsr/viscrs.cxx
@@ -1069,33 +1069,6 @@ void SwShellCursor::SaveTableBoxContent( const SwPosition* pPos )
bool SwShellCursor::UpDown( bool bUp, sal_uInt16 nCnt )
{
- // tdf#124603 trigger pending spell checking of the node
- if ( nCnt == 1 )
- {
- SwTextNode* pNode = GetPoint()->GetNode().GetTextNode();
- if( pNode && sw::WrongState::PENDING == pNode->GetWrongDirty() )
- {
- SwWrtShell* pShell = pNode->GetDoc().GetDocShell()->GetWrtShell();
- if ( pShell && !pShell->IsSelection() && !pShell->IsSelFrameMode() )
- {
- const SwViewOption* pVOpt = pShell->GetViewOptions();
- if ( pVOpt && pVOpt->IsOnlineSpell() )
- {
- const bool bOldViewLock = pShell->IsViewLocked();
- pShell->LockView( true );
-
- SwTextFrame* pFrame(
- static_cast<SwTextFrame*>(pNode->getLayoutFrame(GetShell()->GetLayout())));
- SwRect aRepaint(pFrame->AutoSpell_(*pNode, 0));
- if (aRepaint.HasArea())
- pShell->InvalidateWindows(aRepaint);
-
- pShell->LockView( bOldViewLock );
- }
- }
- }
- }
-
return SwCursor::UpDown( bUp, nCnt,
&GetPtPos(), GetShell()->GetUpDownX(),
*GetShell()->GetLayout());
diff --git a/sw/source/core/doc/DocumentContentOperationsManager.cxx b/sw/source/core/doc/DocumentContentOperationsManager.cxx
index 000f5b4c39af..234d73aecb05 100644
--- a/sw/source/core/doc/DocumentContentOperationsManager.cxx
+++ b/sw/source/core/doc/DocumentContentOperationsManager.cxx
@@ -5107,12 +5107,16 @@ bool DocumentContentOperationsManager::CopyImplImpl(SwPaM& rPam, SwPosition& rPo
// bullet list.
// Keep also the <ListId> value for possible propagation.
OUString aListIdToPropagate;
+ SvxTextLeftMarginItem const* pTextLeftMarginToPropagate{nullptr};
+ SvxFirstLineIndentItem const* pFirstLineIndentToPropagate{nullptr};
const SwNumRule* pNumRuleToPropagate =
- rDoc.SearchNumRule( rPos, false, true, false, 0, aListIdToPropagate, nullptr, true );
+ rDoc.SearchNumRule(rPos, false, true, false, 0, aListIdToPropagate, nullptr,
+ true, &pTextLeftMarginToPropagate, &pFirstLineIndentToPropagate);
if ( !pNumRuleToPropagate )
{
pNumRuleToPropagate =
- rDoc.SearchNumRule( rPos, false, false, false, 0, aListIdToPropagate, nullptr, true );
+ rDoc.SearchNumRule(rPos, false, false, false, 0, aListIdToPropagate, nullptr,
+ true, &pTextLeftMarginToPropagate, &pFirstLineIndentToPropagate);
}
// #i86492#
// Do not propagate previous found list, if
@@ -5518,8 +5522,12 @@ bool DocumentContentOperationsManager::CopyImplImpl(SwPaM& rPam, SwPosition& rPo
// #i86492# - use <SwDoc::SetNumRule(..)>, because it also handles the <ListId>
// Don't reset indent attributes, that would mean loss of direct
// formatting.
- rDoc.SetNumRule( *pCopyPam, *pNumRuleToPropagate, false, nullptr,
- aListIdToPropagate, true, /*bResetIndentAttrs=*/false );
+ // It could be that pNumRuleToPropagate is already applied via
+ // the paragraph style, in that case applying it again in mpAttrSet could
+ // override indents, so avoid that.
+ rDoc.SetNumRule(*pCopyPam, *pNumRuleToPropagate,
+ SwDoc::SetNumRuleMode::DontSetIfAlreadyApplied, nullptr, aListIdToPropagate,
+ pTextLeftMarginToPropagate, pFirstLineIndentToPropagate);
}
rDoc.getIDocumentRedlineAccess().SetRedlineFlags_intern( eOld );
diff --git a/sw/source/core/doc/DocumentSettingManager.cxx b/sw/source/core/doc/DocumentSettingManager.cxx
index 661c001e98c2..14cfa5fd3c24 100644
--- a/sw/source/core/doc/DocumentSettingManager.cxx
+++ b/sw/source/core/doc/DocumentSettingManager.cxx
@@ -256,6 +256,8 @@ bool sw::DocumentSettingManager::get(/*[in]*/ DocumentSettingId id) const
return mbDoNotBreakWrappedTables;
case DocumentSettingId::ALLOW_TEXT_AFTER_FLOATING_TABLE_BREAK:
return mbAllowTextAfterFloatingTableBreak;
+ case DocumentSettingId::DO_NOT_MIRROR_RTL_DRAW_OBJS:
+ return mbDoNotMirrorRtlDrawObjs;
case DocumentSettingId::JUSTIFY_LINES_WITH_SHRINKING:
return mbJustifyLinesWithShrinking;
case DocumentSettingId::NO_NUMBERING_SHOW_FOLLOWBY: return mbNoNumberingShowFollowBy;
@@ -450,6 +452,10 @@ void sw::DocumentSettingManager::set(/*[in]*/ DocumentSettingId id, /*[in]*/ boo
mbApplyTextAttrToEmptyLineAtEndOfParagraph = value;
break;
+ case DocumentSettingId::DO_NOT_MIRROR_RTL_DRAW_OBJS:
+ mbDoNotMirrorRtlDrawObjs = value;
+ break;
+
case DocumentSettingId::DO_NOT_BREAK_WRAPPED_TABLES:
mbDoNotBreakWrappedTables = value;
break;
@@ -1097,12 +1103,16 @@ void sw::DocumentSettingManager::dumpAsXml(xmlTextWriterPtr pWriter) const
(void)xmlTextWriterStartElement(pWriter, BAD_CAST("mnImagePreferredDPI"));
(void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("value"),
BAD_CAST(OString::number(mnImagePreferredDPI).getStr()));
+ (void)xmlTextWriterEndElement(pWriter);
(void)xmlTextWriterStartElement(pWriter, BAD_CAST("mbApplyTextAttrToEmptyLineAtEndOfParagraph"));
(void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("value"),
BAD_CAST(OString::boolean(mbApplyTextAttrToEmptyLineAtEndOfParagraph).getStr()));
(void)xmlTextWriterEndElement(pWriter);
+ (void)xmlTextWriterStartElement(pWriter, BAD_CAST("mbDoNotMirrorRtlDrawObjs"));
+ (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("value"),
+ BAD_CAST(OString::boolean(mbDoNotMirrorRtlDrawObjs).getStr()));
(void)xmlTextWriterEndElement(pWriter);
(void)xmlTextWriterEndElement(pWriter);
diff --git a/sw/source/core/doc/docdraw.cxx b/sw/source/core/doc/docdraw.cxx
index 521ca2b0ba15..09b1d9afb697 100644
--- a/sw/source/core/doc/docdraw.cxx
+++ b/sw/source/core/doc/docdraw.cxx
@@ -68,6 +68,9 @@ static void lcl_AdjustPositioningAttr( SwDrawFrameFormat* _pFrameFormat,
const SwContact* pContact = GetUserCall( &_rSdrObj );
OSL_ENSURE( pContact, "<lcl_AdjustPositioningAttr(..)> - missing contact object." );
+ if (!pContact)
+ return;
+
// determine position of new group object relative to its anchor frame position
SwTwips nHoriRelPos = 0;
SwTwips nVertRelPos = 0;
@@ -195,6 +198,9 @@ SwDrawContact* SwDoc::GroupSelection( SdrView& rDrawView )
// Revoke anchor attribute.
SwDrawContact *pMyContact = static_cast<SwDrawContact*>(GetUserCall(pObj));
+ if (!pMyContact)
+ return pNewContact;
+
const SwFormatAnchor aAnch( pMyContact->GetFormat()->GetAnchor() );
std::unique_ptr<SwUndoDrawGroup> pUndo;
@@ -216,6 +222,9 @@ SwDrawContact* SwDoc::GroupSelection( SdrView& rDrawView )
pObj = rMrkList.GetMark( i )->GetMarkedSdrObj();
SwDrawContact *pContact = static_cast<SwDrawContact*>(GetUserCall(pObj));
+ if (!pContact)
+ continue;
+
// #i53320#
#if OSL_DEBUG_LEVEL > 0
SwAnchoredDrawObject* pAnchoredDrawObj =
@@ -352,6 +361,9 @@ void SwDoc::UnGroupSelection( SdrView& rDrawView )
{
SwDrawContact *pContact = static_cast<SwDrawContact*>(GetUserCall(pObj));
+ if (!pContact)
+ continue;
+
std::shared_ptr<SwTextBoxNode> pTextBoxNode;
if (auto pGroupFormat = pContact->GetFormat())
pTextBoxNode = pGroupFormat->GetOtherTextBoxFormats();
diff --git a/sw/source/core/doc/docfmt.cxx b/sw/source/core/doc/docfmt.cxx
index 1c696bebb6a0..3390a506052c 100644
--- a/sw/source/core/doc/docfmt.cxx
+++ b/sw/source/core/doc/docfmt.cxx
@@ -1040,14 +1040,12 @@ static bool lcl_SetTextFormatColl( SwNode* pNode, void* pArgs )
}
}
+ std::optional<SwRegHistory> oRegH;
+ if (pPara->pHistory)
+ oRegH.emplace(&rTNd, rTNd, pPara->pHistory);
+
if ( bChangeOfListStyleAtParagraph )
{
- std::unique_ptr< SwRegHistory > pRegH;
- if ( pPara->pHistory )
- {
- pRegH.reset(new SwRegHistory(&rTNd, rTNd, pPara->pHistory));
- }
-
pCNd->ResetAttr( RES_PARATR_NUMRULE );
// reset all list attributes
diff --git a/sw/source/core/doc/docftn.cxx b/sw/source/core/doc/docftn.cxx
index 16f6694c94c5..f211dcdcc9f4 100644
--- a/sw/source/core/doc/docftn.cxx
+++ b/sw/source/core/doc/docftn.cxx
@@ -35,6 +35,8 @@
#include <ndtxt.hxx>
#include <poolfmt.hxx>
#include <ftninfo.hxx>
+#include <fmtftntx.hxx>
+#include <unoprnms.hxx>
SwEndNoteInfo& SwEndNoteInfo::operator=(const SwEndNoteInfo& rInfo)
{
@@ -130,6 +132,23 @@ void SwEndNoteInfo::ChgPageDesc(SwPageDesc* pDesc)
m_aDepends.StartListening(m_pPageDesc);
}
+SwSection* SwEndNoteInfo::GetSwSection(SwDoc& rDoc) const
+{
+ if (!m_pSwSection)
+ {
+ SwSectionFormat* pFormat = rDoc.MakeSectionFormat();
+ pFormat->SetFormatName(UNO_NAME_ENDNOTE);
+ pFormat->SetFormatAttr(SwFormatEndAtTextEnd(FTNEND_ATTXTEND));
+ m_pSwSection.reset(new SwSection(SectionType::Content, pFormat->GetName(), *pFormat));
+ }
+ return m_pSwSection.get();
+}
+
+void SwEndNoteInfo::ResetSwSection()
+{
+ m_pSwSection.reset();
+}
+
void SwEndNoteInfo::SetFootnoteTextColl(SwTextFormatColl& rFormat)
{
m_aDepends.EndListening(m_pTextFormatColl);
diff --git a/sw/source/core/doc/docnew.cxx b/sw/source/core/doc/docnew.cxx
index d6e885e8219a..bb0cd32d2c19 100644
--- a/sw/source/core/doc/docnew.cxx
+++ b/sw/source/core/doc/docnew.cxx
@@ -503,6 +503,7 @@ SwDoc::~SwDoc()
// do not have any dependencies anymore.
m_pNodes->DelNodes( SwNodeIndex(*m_pNodes), m_pNodes->Count() );
rUndoNodes.DelNodes( SwNodeIndex( rUndoNodes ), rUndoNodes.Count() );
+ mpEndNoteInfo->ResetSwSection();
// clear TOX after nodes - TOXMarks are gone now so SwTOXType has no clients
for (const auto& pType : *mpTOXTypes)
diff --git a/sw/source/core/doc/docnum.cxx b/sw/source/core/doc/docnum.cxx
index 979107c919c5..d323191df6ae 100644
--- a/sw/source/core/doc/docnum.cxx
+++ b/sw/source/core/doc/docnum.cxx
@@ -46,6 +46,7 @@
#include <SwNodeNum.hxx>
#include <list.hxx>
#include <calbck.hxx>
+#include <editeng/lrspitem.hxx>
#include <comphelper/string.hxx>
#include <comphelper/random.hxx>
#include <o3tl/safeint.hxx>
@@ -860,11 +861,11 @@ static void lcl_ChgNumRule( SwDoc& rDoc, const SwNumRule& rRule )
OUString SwDoc::SetNumRule( const SwPaM& rPam,
const SwNumRule& rRule,
- const bool bCreateNewList,
+ SetNumRuleMode eMode,
SwRootFrame const*const pLayout,
const OUString& sContinuedListId,
- bool bSetItem,
- const bool bResetIndentAttrs )
+ SvxTextLeftMarginItem const*const pTextLeftMarginToPropagate,
+ SvxFirstLineIndentItem const*const pFirstLineIndentToPropagate)
{
OUString sListId;
@@ -902,9 +903,9 @@ OUString SwDoc::SetNumRule( const SwPaM& rPam,
}
}
- if ( bSetItem )
+ if (!(eMode & SetNumRuleMode::DontSetItem))
{
- if ( bCreateNewList )
+ if (eMode & SetNumRuleMode::CreateNewList)
{
if ( bNewNumRuleCreated )
{
@@ -944,7 +945,7 @@ OUString SwDoc::SetNumRule( const SwPaM& rPam,
if (pRule && pRule->GetName() == pNewOrChangedNumRule->GetName())
{
- bSetItem = false;
+ eMode |= SetNumRuleMode::DontSetItem;
if ( !pTextNd->IsInList() )
{
pTextNd->AddToList();
@@ -961,21 +962,67 @@ OUString SwDoc::SetNumRule( const SwPaM& rPam,
if ( pCollRule && pCollRule->GetName() == pNewOrChangedNumRule->GetName() )
{
pTextNd->ResetAttr( RES_PARATR_NUMRULE );
- bSetItem = false;
+ eMode |= SetNumRuleMode::DontSetItem;
}
}
}
}
}
- if ( bSetItem )
+ if (!(eMode & SetNumRuleMode::DontSetItem))
{
- getIDocumentContentOperations().InsertPoolItem(aPam,
- SwNumRuleItem(pNewOrChangedNumRule->GetName()),
- SetAttrMode::DEFAULT, pLayout);
+ if (eMode & SetNumRuleMode::DontSetIfAlreadyApplied)
+ {
+ for (SwNodeIndex i = aPam.Start()->nNode; i <= aPam.End()->nNode; ++i)
+ {
+ if (SwTextNode const*const pNode = i.GetNode().GetTextNode())
+ {
+ if (pNode->GetNumRule(true) != pNewOrChangedNumRule)
+ {
+ // only apply if it doesn't already have it - to
+ // avoid overriding indents from style
+ SwPaM const temp(*pNode, 0, *pNode, pNode->Len());
+ getIDocumentContentOperations().InsertPoolItem(temp,
+ SwNumRuleItem(pNewOrChangedNumRule->GetName()),
+ SetAttrMode::DEFAULT, pLayout);
+ // apply provided margins to get visually same result
+ if (pTextLeftMarginToPropagate)
+ {
+ getIDocumentContentOperations().InsertPoolItem(temp,
+ *pTextLeftMarginToPropagate,
+ SetAttrMode::DEFAULT, pLayout);
+ }
+ if (pFirstLineIndentToPropagate)
+ {
+ getIDocumentContentOperations().InsertPoolItem(temp,
+ *pFirstLineIndentToPropagate,
+ SetAttrMode::DEFAULT, pLayout);
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ getIDocumentContentOperations().InsertPoolItem(aPam,
+ SwNumRuleItem(pNewOrChangedNumRule->GetName()),
+ SetAttrMode::DEFAULT, pLayout);
+ if (pTextLeftMarginToPropagate)
+ {
+ getIDocumentContentOperations().InsertPoolItem(aPam,
+ *pTextLeftMarginToPropagate,
+ SetAttrMode::DEFAULT, pLayout);
+ }
+ if (pFirstLineIndentToPropagate)
+ {
+ getIDocumentContentOperations().InsertPoolItem(aPam,
+ *pFirstLineIndentToPropagate,
+ SetAttrMode::DEFAULT, pLayout);
+ }
+ }
}
- if ( bResetIndentAttrs
+ if ((eMode & SetNumRuleMode::ResetIndentAttrs)
&& pNewOrChangedNumRule->Get( 0 ).GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_ALIGNMENT )
{
const o3tl::sorted_vector<sal_uInt16> attrs{ RES_MARGIN_FIRSTLINE, RES_MARGIN_TEXTLEFT, RES_MARGIN_RIGHT };
@@ -1275,7 +1322,7 @@ void SwDoc::MakeUniqueNumRules(const SwPaM & rPaM)
SetNumRule( aPam,
*aListStyleData.pReplaceNumRule,
- aListStyleData.bCreateNewList,
+ aListStyleData.bCreateNewList ? SetNumRuleMode::CreateNewList : SetNumRuleMode::Default,
nullptr,
aListStyleData.sListId );
if ( aListStyleData.bCreateNewList )
@@ -1629,7 +1676,9 @@ const SwNumRule * SwDoc::SearchNumRule(const SwPosition & rPos,
int nNonEmptyAllowed,
OUString& sListId,
SwRootFrame const* pLayout,
- const bool bInvestigateStartNode)
+ const bool bInvestigateStartNode,
+ SvxTextLeftMarginItem const** o_ppTextLeftMargin,
+ SvxFirstLineIndentItem const** o_ppFirstLineIndent)
{
const SwNumRule * pResult = nullptr;
SwTextNode * pTextNd = rPos.GetNode().GetTextNode();
@@ -1666,9 +1715,28 @@ const SwNumRule * SwDoc::SearchNumRule(const SwPosition & rPos,
( ( bNum && pNumRule->Get(0).IsEnumeration()) ||
( !bNum && pNumRule->Get(0).IsItemize() ) ) ) // #i22362#, #i29560#
{
- pResult = pTextNd->GetNumRule();
+ pResult = pNumRule;
// provide also the list id, to which the text node belongs.
sListId = pTextNd->GetListId();
+ // also get the margins that override the numrule
+ int const nListLevel{pTextNd->GetActualListLevel()};
+ if ((o_ppTextLeftMargin || o_ppFirstLineIndent)
+ && 0 <= nListLevel
+ && pNumRule->Get(o3tl::narrowing<sal_uInt16>(nListLevel))
+ .GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_ALIGNMENT)
+ {
+ ::sw::ListLevelIndents const indents{pTextNd->AreListLevelIndentsApplicable()};
+ if (!(indents & ::sw::ListLevelIndents::LeftMargin)
+ && o_ppTextLeftMargin)
+ {
+ *o_ppTextLeftMargin = &pTextNd->SwContentNode::GetAttr(RES_MARGIN_TEXTLEFT);
+ }
+ if (!(indents & ::sw::ListLevelIndents::FirstLine)
+ && o_ppFirstLineIndent)
+ {
+ *o_ppFirstLineIndent = &pTextNd->SwContentNode::GetAttr(RES_MARGIN_FIRSTLINE);
+ }
+ }
}
break;
diff --git a/sw/source/core/doc/doctxm.cxx b/sw/source/core/doc/doctxm.cxx
index d29223050b6a..f9533b37f647 100644
--- a/sw/source/core/doc/doctxm.cxx
+++ b/sw/source/core/doc/doctxm.cxx
@@ -1375,7 +1375,8 @@ void SwTOXBaseSection::UpdateTemplate(const SwTextNode* pOwnChapterNode,
pTextNd->getLayoutFrame(pLayout) &&
pTextNd->GetNodes().IsDocNodes() &&
// tdf#40142 - consider level settings of the various text nodes
- o3tl::make_unsigned(pTextNd->GetAttrOutlineLevel()) <= GetLevel() &&
+ (TOX_CONTENT != SwTOXBase::GetType() ||
+ o3tl::make_unsigned(pTextNd->GetAttrOutlineLevel()) <= GetLevel()) &&
(!pLayout || !pLayout->HasMergedParas()
|| static_cast<SwTextFrame*>(pTextNd->getLayoutFrame(pLayout))->GetTextNodeForParaProps() == pTextNd) &&
(!IsFromChapter() || IsHeadingContained(pOwnChapterNode, *pTextNd)))
diff --git a/sw/source/core/draw/dcontact.cxx b/sw/source/core/draw/dcontact.cxx
index aac8f2393c61..a91e92569f7a 100644
--- a/sw/source/core/draw/dcontact.cxx
+++ b/sw/source/core/draw/dcontact.cxx
@@ -170,12 +170,16 @@ SwRect GetBoundRectOfAnchoredObj( const SdrObject* pObj )
/// Returns the UserCall if applicable from the group object
SwContact* GetUserCall( const SdrObject* pObj )
{
- SdrObject *pTmp;
- while ( !pObj->GetUserCall() && nullptr != (pTmp = pObj->getParentSdrObjectFromSdrObject()) )
- pObj = pTmp;
- assert((!pObj->GetUserCall() || nullptr != dynamic_cast<const SwContact*>(pObj->GetUserCall())) &&
- "<::GetUserCall(..)> - wrong type of found object user call." );
- return static_cast<SwContact*>(pObj->GetUserCall());
+ for (; pObj; pObj = pObj->getParentSdrObjectFromSdrObject())
+ {
+ if (auto pUserCall = pObj->GetUserCall())
+ {
+ assert(dynamic_cast<SwContact*>(pUserCall)
+ && "<::GetUserCall(..)> - wrong type of found object user call.");
+ return static_cast<SwContact*>(pUserCall);
+ }
+ }
+ return nullptr;
}
/// Returns true if the SrdObject is a Marquee-Object (scrolling text)
@@ -2216,8 +2220,9 @@ namespace sdr::contact
void VOCOfDrawVirtObj::createPrimitive2DSequence(const DisplayInfo& rDisplayInfo, drawinglayer::primitive2d::Primitive2DDecompositionVisitor& rVisitor) const
{
- // tdf#91260 have already checked top-level one is on the right page
- assert(isPrimitiveVisible(rDisplayInfo));
+ // this may be called for painting where it's a precondition that
+ // isPrimitiveVisible() is true, or for e.g. getObjectRange() (even
+ // during layout) where there are no preconditions...
// nasty corner case: override to clear page frame to disable the
// sub-objects' anchor check, because their anchor is always on
// the first page that the page style is applied to
diff --git a/sw/source/core/draw/dview.cxx b/sw/source/core/draw/dview.cxx
index fe0db61925c4..5499dad7c9ca 100644
--- a/sw/source/core/draw/dview.cxx
+++ b/sw/source/core/draw/dview.cxx
@@ -210,10 +210,14 @@ void SwDrawView::AddCustomHdl()
{
const SdrMarkList &rMrkList = GetMarkedObjectList();
- if(rMrkList.GetMarkCount() != 1 || !GetUserCall(rMrkList.GetMark( 0 )->GetMarkedSdrObj()))
+ if(rMrkList.GetMarkCount() != 1)
return;
SdrObject *pObj = rMrkList.GetMark(0)->GetMarkedSdrObj();
+ SwContact* pContact = ::GetUserCall( pObj );
+ if (!pContact)
+ return;
+
// make code robust
SwFrameFormat* pFrameFormat( ::FindFrameFormat( pObj ) );
if ( !pFrameFormat )
@@ -236,7 +240,7 @@ void SwDrawView::AddCustomHdl()
{
// #i28701# - use last character rectangle saved at object
// in order to avoid a format of the anchor frame
- SwAnchoredObject* pAnchoredObj = ::GetUserCall( pObj )->GetAnchoredObj( pObj );
+ SwAnchoredObject* pAnchoredObj = pContact->GetAnchoredObj( pObj );
// Invalidate/recalc LastCharRect which can contain invalid frame offset because
// of later frame changes
@@ -360,7 +364,8 @@ void SwDrawView::MoveRepeatedObjs( const SwAnchoredObject& _rMovedAnchoredObj,
{
const SwContact* pContact = ::GetUserCall( _rMovedAnchoredObj.GetDrawObj() );
assert(pContact && "SwDrawView::MoveRepeatedObjs(..) - missing contact object -> crash.");
- pContact->GetAnchoredObjs( aAnchoredObjs );
+ if (pContact)
+ pContact->GetAnchoredObjs( aAnchoredObjs );
}
// check, if 'repeated' objects exists.
@@ -402,7 +407,8 @@ void SwDrawView::MoveRepeatedObjs( const SwAnchoredObject& _rMovedAnchoredObj,
{
const SwContact* pContact = ::GetUserCall( pChildObj );
assert(pContact && "SwDrawView::MoveRepeatedObjs(..) - missing contact object -> crash.");
- pContact->GetAnchoredObjs( aAnchoredObjs );
+ if (pContact)
+ pContact->GetAnchoredObjs( aAnchoredObjs );
}
// move 'repeated' ones to the same order number as the already moved one.
const size_t nTmpNewPos = pChildObj->GetOrdNum();
@@ -449,8 +455,11 @@ void SwDrawView::ObjOrderChanged( SdrObject* pObj, size_t nOldPos,
pDrawPage->RecalcObjOrdNums();
const size_t nObjCount = pDrawPage->GetObjCount();
- SwAnchoredObject* pMovedAnchoredObj =
- ::GetUserCall( pObj )->GetAnchoredObj( pObj );
+ SwContact* pContact = ::GetUserCall( pObj );
+ if (!pContact)
+ return;
+
+ SwAnchoredObject* pMovedAnchoredObj = pContact->GetAnchoredObj( pObj );
const SwFlyFrame* pParentAnchoredObj =
pMovedAnchoredObj->GetAnchorFrame()->FindFlyFrame();
@@ -493,21 +502,22 @@ void SwDrawView::ObjOrderChanged( SdrObject* pObj, size_t nOldPos,
if ( pTmpObj )
{
size_t nTmpNewPos( nNewPos );
- if ( bMovedForward )
- {
- // move before the top 'repeated' object
- const sal_uInt32 nTmpMaxOrdNum =
- ::GetUserCall( pTmpObj )->GetMaxOrdNum();
- if ( nTmpMaxOrdNum > nNewPos )
- nTmpNewPos = nTmpMaxOrdNum;
- }
- else
+ if (const SwContact* pContact2 = ::GetUserCall( pTmpObj ))
{
- // move behind the bottom 'repeated' object
- const sal_uInt32 nTmpMinOrdNum =
- ::GetUserCall( pTmpObj )->GetMinOrdNum();
- if ( nTmpMinOrdNum < nNewPos )
- nTmpNewPos = nTmpMinOrdNum;
+ if ( bMovedForward )
+ {
+ // move before the top 'repeated' object
+ const sal_uInt32 nTmpMaxOrdNum = pContact2->GetMaxOrdNum();
+ if ( nTmpMaxOrdNum > nNewPos )
+ nTmpNewPos = nTmpMaxOrdNum;
+ }
+ else
+ {
+ // move behind the bottom 'repeated' object
+ const sal_uInt32 nTmpMinOrdNum = pContact2->GetMinOrdNum();
+ if ( nTmpMinOrdNum < nNewPos )
+ nTmpNewPos = nTmpMinOrdNum;
+ }
}
if ( nTmpNewPos != nNewPos )
{
@@ -529,18 +539,25 @@ void SwDrawView::ObjOrderChanged( SdrObject* pObj, size_t nOldPos,
{
// determine position before the object before its top 'child' object
const SdrObject* pTmpObj = pDrawPage->GetObj( nMaxChildOrdNum );
- size_t nTmpNewPos = ::GetUserCall( pTmpObj )->GetMaxOrdNum() + 1;
- if ( nTmpNewPos >= nObjCount )
+ if (SwContact* pContact2 = ::GetUserCall( pTmpObj ))
{
- --nTmpNewPos;
+ size_t nTmpNewPos = pContact2->GetMaxOrdNum() + 1;
+ if ( nTmpNewPos >= nObjCount )
+ {
+ --nTmpNewPos;
+ }
+ // assure, that determined position isn't between 'repeated' objects
+ pTmpObj = pDrawPage->GetObj( nTmpNewPos );
+ pContact2 = ::GetUserCall( pTmpObj );
+ if (pContact2)
+ {
+ nTmpNewPos = pContact2->GetMaxOrdNum();
+ // apply new position
+ pDrawPage->SetObjectOrdNum( nNewPos, nTmpNewPos );
+ nNewPos = nTmpNewPos;
+ pDrawPage->RecalcObjOrdNums();
+ }
}
- // assure, that determined position isn't between 'repeated' objects
- pTmpObj = pDrawPage->GetObj( nTmpNewPos );
- nTmpNewPos = ::GetUserCall( pTmpObj )->GetMaxOrdNum();
- // apply new position
- pDrawPage->SetObjectOrdNum( nNewPos, nTmpNewPos );
- nNewPos = nTmpNewPos;
- pDrawPage->RecalcObjOrdNums();
}
}
@@ -564,16 +581,18 @@ void SwDrawView::ObjOrderChanged( SdrObject* pObj, size_t nOldPos,
if ( pTmpParentObj &&
pTmpParentObj->GetFrameFormat() != pParentFrameFormat )
{
- if ( bMovedForward )
+ if (const SwContact* pContact2 = ::GetUserCall( pTmpObj ))
{
- nTmpNewPos = ::GetUserCall( pTmpObj )->GetMaxOrdNum();
- pTmpObj = pDrawPage->GetObj( nTmpNewPos + 1 );
- }
- else
- {
- nTmpNewPos = ::GetUserCall( pTmpParentObj->GetDrawObj() )
- ->GetMinOrdNum();
- pTmpObj = pTmpParentObj->GetDrawObj();
+ if ( bMovedForward )
+ {
+ nTmpNewPos = pContact2->GetMaxOrdNum();
+ pTmpObj = pDrawPage->GetObj( nTmpNewPos + 1 );
+ }
+ else
+ {
+ nTmpNewPos = pContact2->GetMinOrdNum();
+ pTmpObj = pTmpParentObj->GetDrawObj();
+ }
}
}
else
@@ -690,7 +709,7 @@ const SwFrame* SwDrawView::CalcAnchor()
//Search for paragraph bound objects, otherwise only the
//current anchor. Search only if we currently drag.
- const SwFrame* pAnch;
+ const SwFrame* pAnch = nullptr;
tools::Rectangle aMyRect;
auto pFlyDrawObj = dynamic_cast<SwVirtFlyDrawObj *>( pObj );
if ( pFlyDrawObj )
@@ -700,16 +719,18 @@ const SwFrame* SwDrawView::CalcAnchor()
}
else
{
- SwDrawContact *pC = static_cast<SwDrawContact*>(GetUserCall(pObj));
// determine correct anchor position for 'virtual' drawing objects.
// #i26791#
- pAnch = pC->GetAnchorFrame( pObj );
- if( !pAnch )
+ if (SwDrawContact* pContact = static_cast<SwDrawContact*>(GetUserCall(pObj)))
{
- pC->ConnectToLayout();
- // determine correct anchor position for 'virtual' drawing objects.
- // #i26791#
- pAnch = pC->GetAnchorFrame( pObj );
+ pAnch = pContact->GetAnchorFrame( pObj );
+ if( !pAnch )
+ {
+ pContact->ConnectToLayout();
+ // determine correct anchor position for 'virtual' drawing objects.
+ // #i26791#
+ pAnch = pContact->GetAnchorFrame( pObj );
+ }
}
aMyRect = pObj->GetSnapRect();
}
@@ -744,12 +765,14 @@ const SwFrame* SwDrawView::CalcAnchor()
{
const SwRect aRect( aPt.getX(), aPt.getY(), 1, 1 );
- SwDrawContact* pContact = static_cast<SwDrawContact*>(GetUserCall(pObj));
- if ( pContact->GetAnchorFrame( pObj ) &&
- pContact->GetAnchorFrame( pObj )->IsPageFrame() )
- pAnch = pContact->GetPageFrame();
- else
- pAnch = pContact->FindPage( aRect );
+ if (SwDrawContact* pContact = static_cast<SwDrawContact*>(GetUserCall(pObj)))
+ {
+ if ( pContact->GetAnchorFrame( pObj ) &&
+ pContact->GetAnchorFrame( pObj )->IsPageFrame() )
+ pAnch = pContact->GetPageFrame();
+ else
+ pAnch = pContact->FindPage( aRect );
+ }
}
}
if( pAnch && !pAnch->IsProtected() )
diff --git a/sw/source/core/edit/autofmt.cxx b/sw/source/core/edit/autofmt.cxx
index 6fafe1310d72..2082fa3ae4c6 100644
--- a/sw/source/core/edit/autofmt.cxx
+++ b/sw/source/core/edit/autofmt.cxx
@@ -1710,7 +1710,7 @@ void SwAutoFormat::BuildEnum( sal_uInt16 nLvl, sal_uInt16 nDigitLevel )
const_cast<SwTextNode*>(m_pCurTextFrame->GetTextNodeForParaProps())->SetAttrListLevel(nLvl);
// start new list
- m_pDoc->SetNumRule(m_aDelPam, aRule, true, m_pEditShell->GetLayout());
+ m_pDoc->SetNumRule(m_aDelPam, aRule, SwDoc::SetNumRuleMode::CreateNewList, m_pEditShell->GetLayout());
m_aDelPam.DeleteMark();
*m_aDelPam.GetPoint() = m_pCurTextFrame->MapViewToModelPos(TextFrameIndex(0));
diff --git a/sw/source/core/edit/ednumber.cxx b/sw/source/core/edit/ednumber.cxx
index c272aa5f8eec..65391d376b4a 100644
--- a/sw/source/core/edit/ednumber.cxx
+++ b/sw/source/core/edit/ednumber.cxx
@@ -355,7 +355,7 @@ void SwEditShell::SetIndent(short nIndent, const SwPosition & rPos)
// change numbering rule - changed numbering rule is not applied at <aPaM>
SwPaM aPaM(pos);
- GetDoc()->SetNumRule(aPaM, aRule, false, GetLayout(), OUString(), false);
+ GetDoc()->SetNumRule(aPaM, aRule, SwDoc::SetNumRuleMode::DontSetItem, GetLayout(), OUString());
}
EndAllAction();
@@ -751,8 +751,9 @@ void SwEditShell::SetCurNumRule( const SwNumRule& rRule,
for (SwPaM& rPaM : pCursor->GetRingContainer())
{
OUString sListId = GetDoc()->SetNumRule(rPaM, rRule,
- bCreateNewList, GetLayout(), sContinuedListId,
- true, bResetIndentAttrs );
+ (bCreateNewList ? SwDoc::SetNumRuleMode::CreateNewList : SwDoc::SetNumRuleMode::Default)
+ | (bResetIndentAttrs ? SwDoc::SetNumRuleMode::ResetIndentAttrs : SwDoc::SetNumRuleMode::Default),
+ GetLayout(), sContinuedListId);
//tdf#87548 On creating a new list for a multi-selection only
//create a single new list for the multi-selection, not one per selection
@@ -768,8 +769,9 @@ void SwEditShell::SetCurNumRule( const SwNumRule& rRule,
else
{
GetDoc()->SetNumRule( *pCursor, rRule,
- bCreateNewList, GetLayout(), rContinuedListId,
- true, bResetIndentAttrs );
+ (bCreateNewList ? SwDoc::SetNumRuleMode::CreateNewList : SwDoc::SetNumRuleMode::Default)
+ | (bResetIndentAttrs ? SwDoc::SetNumRuleMode::ResetIndentAttrs : SwDoc::SetNumRuleMode::Default),
+ GetLayout(), rContinuedListId);
GetDoc()->SetCounted( *pCursor, true, GetLayout() );
}
GetDoc()->GetIDocumentUndoRedo().EndUndo( SwUndoId::INSATTR, nullptr );
diff --git a/sw/source/core/fields/reffld.cxx b/sw/source/core/fields/reffld.cxx
index 0ee26771bb2c..85a18c78927f 100644
--- a/sw/source/core/fields/reffld.cxx
+++ b/sw/source/core/fields/reffld.cxx
@@ -1220,7 +1220,9 @@ namespace
/// Picks the first text node with a matching style from a double ended queue, starting at the front
/// This allows us to use the deque either as a stack or as a queue depending on whether we want to search up or down
SwTextNode* SearchForStyleAnchor(SwTextNode* pSelf, const std::deque<SwNode*>& pToSearch,
- std::u16string_view rStyleName, bool bCaseSensitive = true)
+ std::u16string_view rStyleName,
+ sal_Int32 *const pStart, sal_Int32 *const pEnd,
+ bool bCaseSensitive = true)
{
std::deque<SwNode*> pSearching(pToSearch);
while (!pSearching.empty())
@@ -1235,15 +1237,38 @@ namespace
if (!pTextNode)
continue;
- if (bCaseSensitive)
+ if (bCaseSensitive
+ ? pTextNode->GetFormatColl()->GetName() == rStyleName
+ : pTextNode->GetFormatColl()->GetName().equalsIgnoreAsciiCase(rStyleName))
{
- if (pTextNode->GetFormatColl()->GetName() == rStyleName)
- return pTextNode;
+ *pStart = 0;
+ if (pEnd)
+ {
+ *pEnd = pTextNode->GetText().getLength();
+ }
+ return pTextNode;
}
- else
+
+ if (auto const pHints = pTextNode->GetpSwpHints())
{
- if (pTextNode->GetFormatColl()->GetName().equalsIgnoreAsciiCase(rStyleName))
- return pTextNode;
+ for (size_t i = 0; i < pHints->Count(); ++i)
+ {
+ auto const*const pHint(pHints->Get(i));
+ if (pHint->Which() == RES_TXTATR_CHARFMT)
+ {
+ if (bCaseSensitive
+ ? pHint->GetCharFormat().GetCharFormat()->HasName(rStyleName)
+ : pHint->GetCharFormat().GetCharFormat()->GetName().equalsIgnoreAsciiCase(rStyleName))
+ {
+ *pStart = pHint->GetStart();
+ if (pEnd)
+ {
+ *pEnd = *pHint->End();
+ }
+ return pTextNode;
+ }
+ }
+ }
}
}
@@ -1505,21 +1530,21 @@ SwTextNode* SwGetRefFieldType::FindAnchor(SwDoc* pDoc, const OUString& rRefMark,
pSearchThird.push_back(nodes[n]);
}
- pTextNd = SearchForStyleAnchor(pSelf, pInPage, rRefMark);
+ pTextNd = SearchForStyleAnchor(pSelf, pInPage, rRefMark, pStt, pEnd);
if (pTextNd)
{
break;
}
// 2. Search up from the top of the page
- pTextNd = SearchForStyleAnchor(pSelf, pSearchSecond, rRefMark);
+ pTextNd = SearchForStyleAnchor(pSelf, pSearchSecond, rRefMark, pStt, pEnd);
if (pTextNd)
{
break;
}
// 3. Search down from the bottom of the page
- pTextNd = SearchForStyleAnchor(pSelf, pSearchThird, rRefMark);
+ pTextNd = SearchForStyleAnchor(pSelf, pSearchThird, rRefMark, pStt, pEnd);
if (pTextNd)
{
break;
@@ -1528,21 +1553,21 @@ SwTextNode* SwGetRefFieldType::FindAnchor(SwDoc* pDoc, const OUString& rRefMark,
// Word has case insensitive styles. LO has case sensitive styles. If we didn't find
// it yet, maybe we could with a case insensitive search. Let's do that
- pTextNd = SearchForStyleAnchor(pSelf, pInPage, rRefMark,
+ pTextNd = SearchForStyleAnchor(pSelf, pInPage, rRefMark, pStt, pEnd,
false /* bCaseSensitive */);
if (pTextNd)
{
break;
}
- pTextNd = SearchForStyleAnchor(pSelf, pSearchSecond, rRefMark,
+ pTextNd = SearchForStyleAnchor(pSelf, pSearchSecond, rRefMark, pStt, pEnd,
false /* bCaseSensitive */);
if (pTextNd)
{
break;
}
- pTextNd = SearchForStyleAnchor(pSelf, pSearchThird, rRefMark,
+ pTextNd = SearchForStyleAnchor(pSelf, pSearchThird, rRefMark, pStt, pEnd,
false /* bCaseSensitive */);
break;
}
@@ -1574,7 +1599,7 @@ SwTextNode* SwGetRefFieldType::FindAnchor(SwDoc* pDoc, const OUString& rRefMark,
// 1. Search up until we hit the top of the document
- pTextNd = SearchForStyleAnchor(pSelf, pSearchFirst, rRefMark);
+ pTextNd = SearchForStyleAnchor(pSelf, pSearchFirst, rRefMark, pStt, pEnd);
if (pTextNd)
{
break;
@@ -1582,7 +1607,7 @@ SwTextNode* SwGetRefFieldType::FindAnchor(SwDoc* pDoc, const OUString& rRefMark,
// 2. Search down until we hit the bottom of the document
- pTextNd = SearchForStyleAnchor(pSelf, pSearchSecond, rRefMark);
+ pTextNd = SearchForStyleAnchor(pSelf, pSearchSecond, rRefMark, pStt, pEnd);
if (pTextNd)
{
break;
@@ -1590,14 +1615,14 @@ SwTextNode* SwGetRefFieldType::FindAnchor(SwDoc* pDoc, const OUString& rRefMark,
// Again, we need to remember that Word styles are not case sensitive
- pTextNd = SearchForStyleAnchor(pSelf, pSearchFirst, rRefMark,
+ pTextNd = SearchForStyleAnchor(pSelf, pSearchFirst, rRefMark, pStt, pEnd,
false /* bCaseSensitive */);
if (pTextNd)
{
break;
}
- pTextNd = SearchForStyleAnchor(pSelf, pSearchSecond, rRefMark,
+ pTextNd = SearchForStyleAnchor(pSelf, pSearchSecond, rRefMark, pStt, pEnd,
false /* bCaseSensitive */);
break;
}
@@ -1605,13 +1630,6 @@ SwTextNode* SwGetRefFieldType::FindAnchor(SwDoc* pDoc, const OUString& rRefMark,
OSL_FAIL("<SwGetRefFieldType::FindAnchor(..)> - unknown getref element type");
}
- if (pTextNd)
- {
- *pStt = 0;
- if (pEnd)
- *pEnd = pTextNd->GetText().getLength();
- }
-
break;
}
diff --git a/sw/source/core/frmedt/fecopy.cxx b/sw/source/core/frmedt/fecopy.cxx
index 69fae8bf0ae0..01eee5072fb6 100644
--- a/sw/source/core/frmedt/fecopy.cxx
+++ b/sw/source/core/frmedt/fecopy.cxx
@@ -195,18 +195,20 @@ void SwFEShell::Copy( SwDoc& rClpDoc, const OUString* pNewClpText )
}
else
{
- SwDrawContact *pContact = static_cast<SwDrawContact*>(GetUserCall( pObj ));
- SwFrameFormat *pFormat = pContact->GetFormat();
- SwFormatAnchor aAnchor( pFormat->GetAnchor() );
- if ((RndStdIds::FLY_AT_PARA == aAnchor.GetAnchorId()) ||
- (RndStdIds::FLY_AT_CHAR == aAnchor.GetAnchorId()) ||
- (RndStdIds::FLY_AT_FLY == aAnchor.GetAnchorId()) ||
- (RndStdIds::FLY_AS_CHAR == aAnchor.GetAnchorId()))
+ if (SwDrawContact *pContact = static_cast<SwDrawContact*>(GetUserCall( pObj )))
{
- aAnchor.SetAnchor( &aPos );
- }
+ SwFrameFormat *pFormat = pContact->GetFormat();
+ SwFormatAnchor aAnchor( pFormat->GetAnchor() );
+ if ((RndStdIds::FLY_AT_PARA == aAnchor.GetAnchorId()) ||
+ (RndStdIds::FLY_AT_CHAR == aAnchor.GetAnchorId()) ||
+ (RndStdIds::FLY_AT_FLY == aAnchor.GetAnchorId()) ||
+ (RndStdIds::FLY_AS_CHAR == aAnchor.GetAnchorId()))
+ {
+ aAnchor.SetAnchor( &aPos );
+ }
- rClpDoc.getIDocumentLayoutAccess().CopyLayoutFormat( *pFormat, aAnchor, true, true );
+ rClpDoc.getIDocumentLayoutAccess().CopyLayoutFormat( *pFormat, aAnchor, true, true );
+ }
}
}
}
@@ -297,6 +299,9 @@ bool SwFEShell::CopyDrawSel( SwFEShell& rDestShell, const Point& rSttPt,
SdrObject *pObj = aMrkList.GetMark( i )->GetMarkedSdrObj();
SwDrawContact *pContact = static_cast<SwDrawContact*>(GetUserCall( pObj ));
+ if (!pContact)
+ continue;
+
SwFrameFormat *pFormat = pContact->GetFormat();
const SwFormatAnchor& rAnchor = pFormat->GetAnchor();
diff --git a/sw/source/core/frmedt/fefly1.cxx b/sw/source/core/frmedt/fefly1.cxx
index 93ad4212cf65..d6ff8b296908 100644
--- a/sw/source/core/frmedt/fefly1.cxx
+++ b/sw/source/core/frmedt/fefly1.cxx
@@ -382,11 +382,13 @@ const SwFrameFormat* SwFEShell::IsFlyInFly()
return nullptr;
return pFly->GetFormat();
}
- else if ( rMrkList.GetMarkCount() != 1 ||
- !GetUserCall(rMrkList.GetMark( 0 )->GetMarkedSdrObj()) )
+ else if ( rMrkList.GetMarkCount() != 1 )
return nullptr;
SdrObject *pObj = rMrkList.GetMark( 0 )->GetMarkedSdrObj();
+ SwContact* pContact = GetUserCall( pObj );
+ if (!pContact)
+ return nullptr;
SwFrameFormat *pFormat = FindFrameFormat( pObj );
if( pFormat && RndStdIds::FLY_AT_FLY == pFormat->GetAnchor().GetAnchorId() )
@@ -398,7 +400,7 @@ const SwFrameFormat* SwFEShell::IsFlyInFly()
}
else
{
- pFly = static_cast<SwDrawContact*>(GetUserCall(pObj))->GetAnchorFrame(pObj);
+ pFly = static_cast<SwDrawContact*>(pContact)->GetAnchorFrame(pObj);
}
OSL_ENSURE( pFly, "IsFlyInFly: Where's my anchor?" );
@@ -491,11 +493,12 @@ Point SwFEShell::FindAnchorPos( const Point& rAbsPos, bool bMoveIt )
SdrObject* pObj = rMrkList.GetMark(0)->GetMarkedSdrObj();
- if (!GetUserCall(pObj))
+ SwContact* pContact = ::GetUserCall( pObj );
+ if (!pContact)
return aRet;
// #i28701#
- SwAnchoredObject* pAnchoredObj = ::GetUserCall( pObj )->GetAnchoredObj( pObj );
+ SwAnchoredObject* pAnchoredObj = pContact->GetAnchoredObj( pObj );
SwFrameFormat* pFormat = pAnchoredObj->GetFrameFormat();
const RndStdIds nAnchorId = pFormat->GetAnchor().GetAnchorId();
@@ -890,6 +893,43 @@ const SwFrameFormat *SwFEShell::NewFlyFrame( const SfxItemSet& rSet, bool bAnchV
return pRet;
}
+namespace
+{
+/// If pCursor points to an as-char anchored graphic node, then set the node's anchor position on
+/// pAnchor and rPam.
+bool SetAnchorOnGrfNodeForAsChar(SwShellCursor *pCursor, SwFormatAnchor* pAnchor, std::optional<SwPaM>& rPam)
+{
+ const SwPosition* pPoint = pCursor->GetPoint();
+ if (pAnchor->GetAnchorId() != RndStdIds::FLY_AS_CHAR)
+ {
+ return false;
+ }
+
+ if (!pPoint->GetNode().IsGrfNode())
+ {
+ return false;
+ }
+
+ SwFrameFormat* pFrameFormat = pPoint->GetNode().GetFlyFormat();
+ if (!pFrameFormat)
+ {
+ return false;
+ }
+
+ const SwPosition* pContentAnchor = pFrameFormat->GetAnchor().GetContentAnchor();
+ if (!pContentAnchor)
+ {
+ return false;
+ }
+
+ SwPosition aPosition(*pContentAnchor);
+ ++aPosition.nContent;
+ pAnchor->SetAnchor(&aPosition);
+ rPam.emplace(aPosition);
+ return true;
+}
+}
+
void SwFEShell::Insert( const OUString& rGrfName, const OUString& rFltName,
const Graphic* pGraphic,
const SfxItemSet* pFlyAttrSet )
@@ -905,6 +945,7 @@ void SwFEShell::Insert( const OUString& rGrfName, const OUString& rFltName,
break;
// Has the anchor not been set or been set incompletely?
+ std::optional<SwPaM> oPam;
if( pFlyAttrSet )
{
if( const SwFormatAnchor* pItem = pFlyAttrSet->GetItemIfSet( RES_ANCHOR, false ) )
@@ -917,6 +958,13 @@ void SwFEShell::Insert( const OUString& rGrfName, const OUString& rFltName,
case RndStdIds::FLY_AS_CHAR:
if( !pAnchor->GetAnchorNode() )
{
+ if (SetAnchorOnGrfNodeForAsChar(pCursor, pAnchor, oPam))
+ {
+ // Don't anchor the image on the previous image, rather insert them next
+ // to each other.
+ break;
+ }
+
pAnchor->SetAnchor( pCursor->GetPoint() );
}
break;
@@ -940,7 +988,7 @@ void SwFEShell::Insert( const OUString& rGrfName, const OUString& rFltName,
}
}
pFormat = GetDoc()->getIDocumentContentOperations().InsertGraphic(
- *pCursor, rGrfName,
+ oPam.has_value() ? *oPam : *pCursor, rGrfName,
rFltName, pGraphic,
pFlyAttrSet,
nullptr, nullptr );
diff --git a/sw/source/core/frmedt/feshview.cxx b/sw/source/core/frmedt/feshview.cxx
index 9154758364fb..353cb5214ea8 100644
--- a/sw/source/core/frmedt/feshview.cxx
+++ b/sw/source/core/frmedt/feshview.cxx
@@ -68,6 +68,7 @@
#include <rootfrm.hxx>
#include <pagefrm.hxx>
#include <sectfrm.hxx>
+#include <rowfrm.hxx>
#include <doc.hxx>
#include <IDocumentUndoRedo.hxx>
#include <dview.hxx>
@@ -376,22 +377,27 @@ bool SwFEShell::MoveAnchor( SwMove nDir )
const SdrMarkList& pMrkList = Imp()->GetDrawView()->GetMarkedObjectList();
if (1 != pMrkList.GetMarkCount())
return false;
+
+ SdrObject *pObj = pMrkList.GetMark( 0 )->GetMarkedSdrObj();
+ SwDrawContact* pContact = static_cast<SwDrawContact*>(GetUserCall(pObj));
+ if (!pContact)
+ return false;
+
SwFrame* pOld;
SwFlyFrame* pFly = nullptr;
- SdrObject *pObj = pMrkList.GetMark( 0 )->GetMarkedSdrObj();
if (SwVirtFlyDrawObj* pVirtO = dynamic_cast<SwVirtFlyDrawObj*>(pObj))
{
pFly = pVirtO->GetFlyFrame();
pOld = pFly->AnchorFrame();
}
else
- pOld = static_cast<SwDrawContact*>(GetUserCall(pObj))->GetAnchorFrame( pObj );
+ pOld = pContact->GetAnchorFrame( pObj );
bool bRet = false;
if( pOld )
{
SwFrame* pNew = pOld;
// #i28701#
- SwAnchoredObject* pAnchoredObj = ::GetUserCall( pObj )->GetAnchoredObj( pObj );
+ SwAnchoredObject* pAnchoredObj = pContact->GetAnchoredObj( pObj );
SwFrameFormat* pFormat = pAnchoredObj->GetFrameFormat();
SwFormatAnchor aAnch( pFormat->GetAnchor() );
RndStdIds nAnchorId = aAnch.GetAnchorId();
@@ -874,7 +880,11 @@ static void lcl_NotifyNeighbours( const SdrMarkList *pLst )
}
else
{
- SwFrame* pAnch = static_cast<SwDrawContact*>( GetUserCall(pO) )->GetAnchorFrame( pO );
+ SwDrawContact* pContact = static_cast<SwDrawContact*>(GetUserCall(pO));
+ if (!pContact)
+ continue;
+
+ SwFrame* pAnch = pContact->GetAnchorFrame( pO );
if( !pAnch )
continue;
pPage = pAnch->FindPageFrame();
@@ -1316,12 +1326,15 @@ bool SwFEShell::ShouldObjectBeSelected(const Point& rPt)
{
if ( pObj->GetLayer() == rIDDMA.GetHellId() )
{
- const SwAnchoredObject* pAnchoredObj = ::GetUserCall( pObj )->GetAnchoredObj( pObj );
- const SwFrameFormat* pFormat = pAnchoredObj->GetFrameFormat();
- const SwFormatSurround& rSurround = pFormat->GetSurround();
- if ( rSurround.GetSurround() == css::text::WrapTextMode_THROUGH )
+ if (const SwContact* pContact = ::GetUserCall( pObj ))
{
- bObjInBackground = true;
+ const SwAnchoredObject* pAnchoredObj = pContact->GetAnchoredObj( pObj );
+ const SwFrameFormat* pFormat = pAnchoredObj->GetFrameFormat();
+ const SwFormatSurround& rSurround = pFormat->GetSurround();
+ if ( rSurround.GetSurround() == css::text::WrapTextMode_THROUGH )
+ {
+ bObjInBackground = true;
+ }
}
}
}
@@ -1392,6 +1405,27 @@ bool SwFEShell::ShouldObjectBeSelected(const Point& rPt)
}
}
}
+
+ // within table row, where image cropped by the fixed table row height,
+ // click position must be in the cell, where the image anchored as character
+ if ( bRet && pContact && pContact->ObjAnchoredAsChar() )
+ {
+ if ( const SwTableBox *pBox = pContact->GetAnchorNode().GetTableBox() )
+ {
+ SwIterator<SwRowFrame, SwFormat> aIter( *pBox->GetUpper()->GetFrameFormat() );
+ bool bContainsClickPosition = false;
+ for (SwRowFrame* pFrame = aIter.First(); pFrame; pFrame = aIter.Next())
+ {
+ if ( pFrame->getFrameArea().Contains( rPt ) )
+ {
+ bContainsClickPosition = true;
+ break;
+ }
+ }
+ if ( !bContainsClickPosition )
+ bRet = false;
+ }
+ }
}
}
@@ -2330,7 +2364,7 @@ bool SwFEShell::IsGroupSelected(bool bAllowDiagams)
// Thus, use corresponding method instead of checking type.
if ( pObj->IsGroupObject() &&
// --> #i38505# No ungroup allowed for 3d objects
- !pObj->Is3DObj() &&
+ !pObj->Is3DObj() && GetUserCall(pObj) &&
RndStdIds::FLY_AS_CHAR != static_cast<SwDrawContact*>(GetUserCall(pObj))->
GetFormat()->GetAnchor().GetAnchorId() )
{
@@ -2659,7 +2693,6 @@ bool SwFEShell::GetObjAttr( SfxItemSet &rSet ) const
{
SdrObject *pObj = rMrkList.GetMark( i )->GetMarkedSdrObj();
SwDrawContact *pContact = static_cast<SwDrawContact*>(GetUserCall(pObj));
- // --> make code robust
OSL_ENSURE( pContact, "<SwFEShell::GetObjAttr(..)> - missing <pContact>." );
if ( pContact )
{
@@ -2689,8 +2722,8 @@ void SwFEShell::SetObjAttr( const SfxItemSet& rSet )
for ( size_t i = 0; i < rMrkList.GetMarkCount(); ++i )
{
SdrObject *pObj = rMrkList.GetMark( i )->GetMarkedSdrObj();
- SwDrawContact *pContact = static_cast<SwDrawContact*>(GetUserCall(pObj));
- GetDoc()->SetAttr( rSet, *pContact->GetFormat() );
+ if (SwDrawContact *pContact = static_cast<SwDrawContact*>(GetUserCall(pObj)))
+ GetDoc()->SetAttr( rSet, *pContact->GetFormat() );
}
EndUndo( SwUndoId::INSATTR );
diff --git a/sw/source/core/inc/DocumentSettingManager.hxx b/sw/source/core/inc/DocumentSettingManager.hxx
index a3395a977f7e..6599c9bf2ad0 100644
--- a/sw/source/core/inc/DocumentSettingManager.hxx
+++ b/sw/source/core/inc/DocumentSettingManager.hxx
@@ -179,6 +179,7 @@ class DocumentSettingManager final :
bool mbAllowTextAfterFloatingTableBreak = false;
bool mbJustifyLinesWithShrinking = false;
bool mbApplyTextAttrToEmptyLineAtEndOfParagraph = true;
+ bool mbDoNotMirrorRtlDrawObjs = false;
// If this is on as_char flys wrapping will be handled the same like in Word
bool mbNoNumberingShowFollowBy;
bool mbDropCapPunctuation; // tdf#150200, tdf#150438
diff --git a/sw/source/core/inc/frame.hxx b/sw/source/core/inc/frame.hxx
index 604488a18c9f..e08c4c9a1e73 100644
--- a/sw/source/core/inc/frame.hxx
+++ b/sw/source/core/inc/frame.hxx
@@ -40,6 +40,7 @@ namespace drawinglayer::processor2d { class BaseProcessor2D; }
class SwLayoutFrame;
class SwRootFrame;
class SwPageFrame;
+class SwColumnFrame;
class SwBodyFrame;
class SwFlyFrame;
class SwSectionFrame;
@@ -876,6 +877,8 @@ public:
const SwTextFrame* DynCastTextFrame() const;
SwPageFrame* DynCastPageFrame();
const SwPageFrame* DynCastPageFrame() const;
+ SwColumnFrame* DynCastColumnFrame();
+ const SwColumnFrame* DynCastColumnFrame() const;
inline bool IsNoTextFrame() const;
// Frames where its PrtArea depends on their neighbors and that are
// positioned in the content flow
@@ -892,6 +895,7 @@ public:
bool IsProtected() const;
virtual bool IsHiddenNow() const;
+ void MakeValidZeroHeight();
bool IsColLocked() const { return mbColLocked; }
virtual bool IsDeleteForbidden() const { return mnForbidDelete > 0; }
@@ -948,6 +952,9 @@ public:
virtual void dumpAsXmlAttributes(xmlTextWriterPtr writer) const;
void dumpChildrenAsXml(xmlTextWriterPtr writer) const;
bool IsCollapse() const;
+
+ /// Determines if the upper margin of this frame should be ignored.
+ bool IsCollapseUpper() const;
};
inline bool SwFrame::IsInDocBody() const
diff --git a/sw/source/core/inc/ftnfrm.hxx b/sw/source/core/inc/ftnfrm.hxx
index 558c4941bf06..7331ef07d100 100644
--- a/sw/source/core/inc/ftnfrm.hxx
+++ b/sw/source/core/inc/ftnfrm.hxx
@@ -51,6 +51,7 @@ public:
SwFootnoteContFrame( SwFrameFormat*, SwFrame* );
const SwFootnoteFrame* FindFootNote() const;
+ const SwFootnoteFrame* FindEndNote() const;
static inline SwFootnoteFrame* AppendChained(SwFrame* pThis, bool bDefaultFormat);
static inline SwFootnoteFrame* PrependChained(SwFrame* pThis, bool bDefaultFormat);
diff --git a/sw/source/core/inc/pagefrm.hxx b/sw/source/core/inc/pagefrm.hxx
index 54458032f188..054495eeea80 100644
--- a/sw/source/core/inc/pagefrm.hxx
+++ b/sw/source/core/inc/pagefrm.hxx
@@ -204,6 +204,7 @@ public:
bool IsEndNotePage() const { return m_bEndNotePage; }
void SetFootnotePage( bool b ) { m_bFootnotePage = b; }
void SetEndNotePage( bool b ) { m_bEndNotePage = b; }
+ SwSectionFrame* GetEndNoteSection();
sal_uInt16 GetPhyPageNum() const { return m_nPhyPageNum;}
void SetPhyPageNum( sal_uInt16 nNum ) { m_nPhyPageNum = nNum;}
diff --git a/sw/source/core/inc/sectfrm.hxx b/sw/source/core/inc/sectfrm.hxx
index 3debf367f05a..ac57bd815d5f 100644
--- a/sw/source/core/inc/sectfrm.hxx
+++ b/sw/source/core/inc/sectfrm.hxx
@@ -52,6 +52,8 @@ class SW_DLLPUBLIC SwSectionFrame final: public SwLayoutFrame, public SwFlowFram
SwSection* m_pSection;
bool m_bFootnoteAtEnd; // footnotes at the end of section
bool m_bEndnAtEnd; // endnotes at the end of section
+ /// If this is a section for endnotes, then the SwSection is not backed by an SwSectionNode.
+ bool m_bEndNoteSection = false;
bool m_bContentLock; // content locked
bool m_bOwnFootnoteNum; // special numbering of footnotes
bool m_bFootnoteLock; // ftn, don't leave this section bwd
@@ -171,6 +173,8 @@ public:
void SetFootnoteLock( bool bNew ) { m_bFootnoteLock = bNew; }
bool IsFootnoteLock() const { return m_bFootnoteLock; }
+ void SetEndNoteSection(bool bEndNoteSection) { m_bEndNoteSection = bEndNoteSection; }
+ bool IsEndNoteSection() const { return m_bEndNoteSection; }
};
inline const SwSectionFrame *SwSectionFrame::GetFollow() const
diff --git a/sw/source/core/inc/txtfrm.hxx b/sw/source/core/inc/txtfrm.hxx
index df11ca589bc6..39f47bce4984 100644
--- a/sw/source/core/inc/txtfrm.hxx
+++ b/sw/source/core/inc/txtfrm.hxx
@@ -353,7 +353,7 @@ public:
*/
void Init();
- /// Is called by DoIdleJob_(), ExecSpellPopup() and UpDown()
+ /// Is called by DoIdleJob_() and ExecSpellPopup()
SwRect AutoSpell_(SwTextNode &, sal_Int32);
/// Is called by DoIdleJob_()
diff --git a/sw/source/core/layout/anchoreddrawobject.cxx b/sw/source/core/layout/anchoreddrawobject.cxx
index 5a9e1245afd8..fe01bbc3b395 100644
--- a/sw/source/core/layout/anchoreddrawobject.cxx
+++ b/sw/source/core/layout/anchoreddrawobject.cxx
@@ -266,6 +266,8 @@ void SwAnchoredDrawObject::MakeObjPos()
SwDrawContact* pDrawContact =
static_cast<SwDrawContact*>(::GetUserCall( GetDrawObj() ));
+ if (!pDrawContact)
+ return;
// --> #i28749# - if anchored drawing object hasn't been yet
// positioned, convert its positioning attributes, if its positioning
@@ -849,6 +851,8 @@ void SwAnchoredDrawObject::SetPositioningAttr()
{
SwDrawContact* pDrawContact =
static_cast<SwDrawContact*>(GetUserCall( GetDrawObj() ));
+ if (!pDrawContact)
+ return;
SwFrameFormat* pObjFormat = GetFrameFormat();
if ( !pDrawContact->ObjAnchoredAsChar() )
diff --git a/sw/source/core/layout/anchoredobject.cxx b/sw/source/core/layout/anchoredobject.cxx
index a74438afb361..43c5baa396c5 100644
--- a/sw/source/core/layout/anchoredobject.cxx
+++ b/sw/source/core/layout/anchoredobject.cxx
@@ -44,10 +44,13 @@ SwObjPositioningInProgress::SwObjPositioningInProgress( SdrObject& _rSdrObj ) :
// --> #i52904#
mbOldObjPositioningInProgress( false )
{
- mpAnchoredObj = ::GetUserCall( &_rSdrObj )->GetAnchoredObj( &_rSdrObj );
- // --> #i52904#
- mbOldObjPositioningInProgress = mpAnchoredObj->IsPositioningInProgress();
- mpAnchoredObj->SetPositioningInProgress( true );
+ if (SwContact* pContact = ::GetUserCall( &_rSdrObj ))
+ {
+ mpAnchoredObj = pContact->GetAnchoredObj( &_rSdrObj );
+ // --> #i52904#
+ mbOldObjPositioningInProgress = mpAnchoredObj->IsPositioningInProgress();
+ mpAnchoredObj->SetPositioningInProgress( true );
+ }
}
SwObjPositioningInProgress::SwObjPositioningInProgress( SwAnchoredObject& _rAnchoredObj ) :
mpAnchoredObj( &_rAnchoredObj ),
diff --git a/sw/source/core/layout/calcmove.cxx b/sw/source/core/layout/calcmove.cxx
index e13fdf012143..0aac409e155b 100644
--- a/sw/source/core/layout/calcmove.cxx
+++ b/sw/source/core/layout/calcmove.cxx
@@ -965,6 +965,9 @@ void SwLayoutFrame::MakeAll(vcl::RenderContext* /*pRenderContext*/)
const SwLayNotify aNotify( this );
bool bVert = IsVertical();
+ if (IsHiddenNow())
+ MakeValidZeroHeight();
+
SwRectFn fnRect = ( IsNeighbourFrame() == bVert )? fnRectHori : ( IsVertLR() ? (IsVertLRBT() ? fnRectVertL2RB2T : fnRectVertL2R) : fnRectVert );
std::optional<SwBorderAttrAccess> oAccess;
@@ -1076,6 +1079,44 @@ bool SwFrame::IsCollapse() const
return pTextFrame->GetText().isEmpty() && pTextNode && pTextNode->IsCollapse();
}
+bool SwFrame::IsCollapseUpper() const
+{
+ const SwTextFrame* pTextFrame = DynCastTextFrame();
+ if (!pTextFrame)
+ {
+ return false;
+ }
+
+ const SwDoc& rDoc = pTextFrame->GetDoc();
+ const IDocumentSettingAccess& rIDSA = rDoc.getIDocumentSettingAccess();
+ if (!rIDSA.get(DocumentSettingId::TAB_OVER_SPACING) || rIDSA.get(DocumentSettingId::TAB_OVER_MARGIN))
+ {
+ // Writer or Word Word <= 2010 style: upper margin is never ignored.
+ return false;
+ }
+
+ if (IsInFly())
+ {
+ // Not in a page's body.
+ return false;
+ }
+
+ // Word >= 2013 style: when we're at the top of the page's body, but not on the first page, then
+ // ignore the upper margin for paragraphs.
+ if (GetPrev() || !GetUpper() || !GetUpper()->IsBodyFrame())
+ {
+ return false;
+ }
+
+ const SwPageFrame* pPageFrame = FindPageFrame();
+ if (!pPageFrame || !pPageFrame->GetPrev())
+ {
+ return false;
+ }
+
+ return true;
+}
+
void SwContentFrame::MakePrtArea( const SwBorderAttrs &rAttrs )
{
if ( isFramePrintAreaValid() )
@@ -1243,6 +1284,9 @@ void SwContentFrame::MakeAll(vcl::RenderContext* /*pRenderContext*/)
return;
}
+ if (IsHiddenNow())
+ MakeValidZeroHeight();
+
std::optional<SwFrameDeleteGuard> oDeleteGuard(std::in_place, this);
LockJoin();
tools::Long nFormatCount = 0;
diff --git a/sw/source/core/layout/findfrm.cxx b/sw/source/core/layout/findfrm.cxx
index 0dd64c6aecff..fc0293381168 100644
--- a/sw/source/core/layout/findfrm.cxx
+++ b/sw/source/core/layout/findfrm.cxx
@@ -18,6 +18,7 @@
*/
#include <pagefrm.hxx>
+#include <colfrm.hxx>
#include <rootfrm.hxx>
#include <cellfrm.hxx>
#include <rowfrm.hxx>
@@ -65,6 +66,29 @@ SwContentFrame *SwPageFrame::FindLastBodyContent()
return pRet;
}
+SwSectionFrame* SwPageFrame::GetEndNoteSection()
+{
+ SwLayoutFrame* pBody = FindBodyCont();
+ if (!pBody)
+ {
+ return nullptr;
+ }
+
+ SwFrame* pLast = pBody->GetLastLower();
+ if (!pLast || !pLast->IsSctFrame())
+ {
+ return nullptr;
+ }
+
+ auto pLastSection = static_cast<SwSectionFrame*>(pLast);
+ if (!pLastSection->IsEndNoteSection())
+ {
+ return nullptr;
+ }
+
+ return pLastSection;
+}
+
/**
* Checks if the frame contains one or more ContentFrame's anywhere in his
* subsidiary structure; if so the first found ContentFrame is returned.
@@ -655,6 +679,17 @@ const SwFootnoteFrame* SwFootnoteContFrame::FindFootNote() const
return nullptr;
}
+const SwFootnoteFrame* SwFootnoteContFrame::FindEndNote() const
+{
+ auto pRet = static_cast<const SwFootnoteFrame*>(Lower());
+ if (pRet && pRet->GetAttr()->GetFootnote().IsEndNote())
+ {
+ return pRet;
+ }
+
+ return nullptr;
+}
+
const SwPageFrame* SwRootFrame::GetPageAtPos( const Point& rPt, const Size* pSize, bool bExtend ) const
{
const SwPageFrame* pRet = nullptr;
@@ -1950,4 +1985,14 @@ const SwPageFrame* SwFrame::DynCastPageFrame() const
return IsPageFrame() ? static_cast<const SwPageFrame*>(this) : nullptr;
}
+SwColumnFrame* SwFrame::DynCastColumnFrame()
+{
+ return IsColumnFrame() ? static_cast<SwColumnFrame*>(this) : nullptr;
+}
+
+const SwColumnFrame* SwFrame::DynCastColumnFrame() const
+{
+ return IsColumnFrame() ? static_cast<const SwColumnFrame*>(this) : nullptr;
+}
+
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/layout/flowfrm.cxx b/sw/source/core/layout/flowfrm.cxx
index 88158161c530..b45c8d100fcb 100644
--- a/sw/source/core/layout/flowfrm.cxx
+++ b/sw/source/core/layout/flowfrm.cxx
@@ -609,7 +609,7 @@ bool SwFlowFrame::PasteTree( SwFrame *pStart, SwLayoutFrame *pParent, SwFrame *p
else
bRet = true;
- nGrowVal += aRectFnSet.GetHeight(pFloat->getFrameArea());
+ nGrowVal = o3tl::saturating_add(nGrowVal, aRectFnSet.GetHeight(pFloat->getFrameArea()));
if ( pFloat->GetNext() )
pFloat = pFloat->GetNext();
else
@@ -1498,6 +1498,9 @@ SwTwips SwFlowFrame::CalcUpperSpace( const SwBorderAttrs *pAttrs,
const SwFrame* pPr,
const bool _bConsiderGrid ) const
{
+ if (m_rThis.IsHiddenNow())
+ return 0;
+
const SwFrame* pPrevFrame = GetPrevFrameForUpperSpaceCalc_( pPr );
std::optional<SwBorderAttrAccess> oAccess;
@@ -1658,6 +1661,11 @@ SwTwips SwFlowFrame::CalcUpperSpace( const SwBorderAttrs *pAttrs,
CastFlowFrame( pOwn )->HasParaSpaceAtPages( m_rThis.IsSctFrame() ) )
{
nUpper = pAttrs->GetULSpace().GetUpper();
+
+ if (m_rThis.IsCollapseUpper())
+ {
+ nUpper = 0;
+ }
}
}
@@ -1798,6 +1806,9 @@ SwTwips SwFlowFrame::GetUpperSpaceAmountConsideredForPrevFrameAndPageGrid() cons
SwTwips SwFlowFrame::CalcLowerSpace( const SwBorderAttrs* _pAttrs ) const
{
+ if (m_rThis.IsHiddenNow())
+ return 0;
+
SwTwips nLowerSpace = 0;
std::optional<SwBorderAttrAccess> oAttrAccess;
@@ -1848,6 +1859,9 @@ SwTwips SwFlowFrame::CalcLowerSpace( const SwBorderAttrs* _pAttrs ) const
SwTwips SwFlowFrame::CalcAddLowerSpaceAsLastInTableCell(
const SwBorderAttrs* _pAttrs ) const
{
+ if (m_rThis.IsHiddenNow())
+ return 0;
+
SwTwips nAdditionalLowerSpace = 0;
IDocumentSettingAccess const& rIDSA(m_rThis.GetUpper()->GetFormat()->getIDocumentSettingAccess());
@@ -2252,18 +2266,47 @@ bool SwFlowFrame::MoveBwd( bool &rbReformat )
const bool bEndnote = pFootnote->GetAttr()->GetFootnote().IsEndNote();
const IDocumentSettingAccess& rSettings
= pFootnote->GetAttrSet()->GetDoc()->getIDocumentSettingAccess();
- if( bEndnote && pFootnote->IsInSct() )
+ bool bContEndnotes = rSettings.get(DocumentSettingId::CONTINUOUS_ENDNOTES);
+ if( bEndnote && pFootnote->IsInSct() && !bContEndnotes)
{
SwSectionFrame* pSect = pFootnote->FindSctFrame();
if( pSect->IsEndnAtEnd() )
// Endnotes at the end of the section.
pRef = pSect->FindLastContent( SwFindMode::LastCnt );
}
- else if (bEndnote && rSettings.get(DocumentSettingId::CONTINUOUS_ENDNOTES))
+ else if (bEndnote && bContEndnotes)
{
// Endnotes at the end of the document.
- SwPageFrame* pPage = m_rThis.getRootFrame()->GetLastPage();
- pRef = pPage->FindLastBodyContent();
+ SwSectionFrame* pSect = pFootnote->FindSctFrame();
+ if (!pSect->GetPrev() && !pSect->FindMaster())
+ {
+ // The section is at the top of the page, and is not a follow of a master section.
+ // See if there is a previous body frame.
+ SwLayoutFrame* pPrev = pSect->GetPrevLayoutLeaf();
+ if (pPrev && pPrev->IsBodyFrame())
+ {
+ // There is, then see if that's on a different page.
+ SwPageFrame* pSectPage = pSect->FindPageFrame();
+ SwPageFrame* pPage = pPrev->FindPageFrame();
+ if (pPage != pSectPage)
+ {
+ // It is, then create a new section frame at the end of that previous body
+ // frame.
+ auto pNew = new SwSectionFrame(*pSect, /*bMaster=*/true);
+ pNew->InsertBehind(pPage->FindBodyCont(), pPage->FindLastBodyContent());
+ pNew->Init();
+ SwFrame* pLower = pNew->GetLower();
+ if (pLower->IsColumnFrame())
+ {
+ pRef = pLower;
+ }
+ }
+ }
+ }
+ else
+ {
+ pRef = pFootnote->FindFootnoteBossFrame();
+ }
}
if( !pRef )
// Endnotes on a separate page.
diff --git a/sw/source/core/layout/fly.cxx b/sw/source/core/layout/fly.cxx
index db50a42de053..fd95ce192cf7 100644
--- a/sw/source/core/layout/fly.cxx
+++ b/sw/source/core/layout/fly.cxx
@@ -70,6 +70,7 @@
#include <basegfx/matrix/b2dhommatrixtools.hxx>
#include <osl/diagnose.h>
#include <o3tl/string_view.hxx>
+#include <rtl/math.hxx>
#include <wrtsh.hxx>
#include <view.hxx>
@@ -2528,8 +2529,8 @@ void SwFrame::AppendDrawObj( SwAnchoredObject& _rNewObj )
assert(!m_pDrawObjs || m_pDrawObjs->is_sorted());
// perform disconnect from layout, if 'master' drawing object is appended
// to a new frame.
- static_cast<SwDrawContact*>(::GetUserCall( _rNewObj.GetDrawObj() ))->
- DisconnectFromLayout( false );
+ if (SwDrawContact* pContact = static_cast<SwDrawContact*>(::GetUserCall( _rNewObj.GetDrawObj() )))
+ pContact->DisconnectFromLayout( false );
assert(!m_pDrawObjs || m_pDrawObjs->is_sorted());
}
@@ -2845,9 +2846,9 @@ Size SwFlyFrame::CalcRel( const SwFormatFrameSize &rSz ) const
}
if ( rSz.GetWidthPercent() && rSz.GetWidthPercent() != SwFormatFrameSize::SYNCED )
- aRet.setWidth( nRelWidth * rSz.GetWidthPercent() / 100 );
+ aRet.setWidth(rtl::math::round(double(nRelWidth) * rSz.GetWidthPercent() / 100));
if ( rSz.GetHeightPercent() && rSz.GetHeightPercent() != SwFormatFrameSize::SYNCED )
- aRet.setHeight( nRelHeight * rSz.GetHeightPercent() / 100 );
+ aRet.setHeight(rtl::math::round(double(nRelHeight) * rSz.GetHeightPercent() / 100));
if ( rSz.GetHeight() && rSz.GetWidthPercent() == SwFormatFrameSize::SYNCED )
{
diff --git a/sw/source/core/layout/flylay.cxx b/sw/source/core/layout/flylay.cxx
index 7ac95d65e0d8..b0ef08a01f75 100644
--- a/sw/source/core/layout/flylay.cxx
+++ b/sw/source/core/layout/flylay.cxx
@@ -1430,27 +1430,30 @@ bool CalcClipRect( const SdrObject *pSdrObj, SwRect &rRect, bool bMove )
}
tools::Long nHeight = (9*aRectFnSet.GetHeight(rRect))/10;
tools::Long nTop;
- const SwFormat *pFormat = GetUserCall(pSdrObj)->GetFormat();
- const SvxULSpaceItem &rUL = pFormat->GetULSpace();
- if( bMove )
+ if (const SwContact* pContact = ::GetUserCall( pSdrObj ))
{
- nTop = aRectFnSet.IsVert() ? static_cast<const SwFlyInContentFrame*>(pFly)->GetRefPoint().X() :
- static_cast<const SwFlyInContentFrame*>(pFly)->GetRefPoint().Y();
- nTop = aRectFnSet.YInc( nTop, -nHeight );
- tools::Long nWidth = aRectFnSet.GetWidth(pFly->getFrameArea());
- aRectFnSet.SetLeftAndWidth( rRect, aRectFnSet.IsVert() ?
- static_cast<const SwFlyInContentFrame*>(pFly)->GetRefPoint().Y() :
- static_cast<const SwFlyInContentFrame*>(pFly)->GetRefPoint().X(), nWidth );
- nHeight = 2*nHeight - rUL.GetLower() - rUL.GetUpper();
- }
- else
- {
- nTop = aRectFnSet.YInc( aRectFnSet.GetBottom(pFly->getFrameArea()),
- rUL.GetLower() - nHeight );
- nHeight = 2*nHeight - aRectFnSet.GetHeight(pFly->getFrameArea())
- - rUL.GetLower() - rUL.GetUpper();
+ const SwFormat *pFormat = pContact->GetFormat();
+ const SvxULSpaceItem &rUL = pFormat->GetULSpace();
+ if( bMove )
+ {
+ nTop = aRectFnSet.IsVert() ? static_cast<const SwFlyInContentFrame*>(pFly)->GetRefPoint().X() :
+ static_cast<const SwFlyInContentFrame*>(pFly)->GetRefPoint().Y();
+ nTop = aRectFnSet.YInc( nTop, -nHeight );
+ tools::Long nWidth = aRectFnSet.GetWidth(pFly->getFrameArea());
+ aRectFnSet.SetLeftAndWidth( rRect, aRectFnSet.IsVert() ?
+ static_cast<const SwFlyInContentFrame*>(pFly)->GetRefPoint().Y() :
+ static_cast<const SwFlyInContentFrame*>(pFly)->GetRefPoint().X(), nWidth );
+ nHeight = 2*nHeight - rUL.GetLower() - rUL.GetUpper();
+ }
+ else
+ {
+ nTop = aRectFnSet.YInc( aRectFnSet.GetBottom(pFly->getFrameArea()),
+ rUL.GetLower() - nHeight );
+ nHeight = 2*nHeight - aRectFnSet.GetHeight(pFly->getFrameArea())
+ - rUL.GetLower() - rUL.GetUpper();
+ }
+ aRectFnSet.SetTopAndHeight( rRect, nTop, nHeight );
}
- aRectFnSet.SetTopAndHeight( rRect, nTop, nHeight );
}
}
else
diff --git a/sw/source/core/layout/frmtool.cxx b/sw/source/core/layout/frmtool.cxx
index baf632d6ebff..38667bd5c428 100644
--- a/sw/source/core/layout/frmtool.cxx
+++ b/sw/source/core/layout/frmtool.cxx
@@ -297,6 +297,8 @@ void SwFrameNotify::ImplDestroy()
bool bNotify = false;
bool bNotifySize = false;
SwContact* pContact = ::GetUserCall( pObj->GetDrawObj() );
+ if (!pContact)
+ continue;
const bool bAnchoredAsChar = pContact->ObjAnchoredAsChar();
if ( !bAnchoredAsChar )
{
@@ -1067,22 +1069,23 @@ void AppendObj(SwFrame *const pFrame, SwPageFrame *const pPage, SwFrameFormat *c
InsertObject(pSdrObj, pSdrObj->GetOrdNumDirect());
}
- SwDrawContact* pNew =
- static_cast<SwDrawContact*>(GetUserCall( pSdrObj ));
- if ( !pNew->GetAnchorFrame() )
- {
- pFrame->AppendDrawObj( *(pNew->GetAnchoredObj( nullptr )) );
- }
- // OD 19.06.2003 #108784# - add 'virtual' drawing object,
- // if necessary. But control objects have to be excluded.
- else if ( !::CheckControlLayer( pSdrObj ) &&
- pNew->GetAnchorFrame() != pFrame &&
- !pNew->GetDrawObjectByAnchorFrame( *pFrame ) )
+ if (SwDrawContact* pNew = static_cast<SwDrawContact*>(GetUserCall( pSdrObj )))
{
- SwDrawVirtObj* pDrawVirtObj = pNew->AddVirtObj(*pFrame);
- pFrame->AppendDrawObj( *(pNew->GetAnchoredObj( pDrawVirtObj )) );
+ if ( !pNew->GetAnchorFrame() )
+ {
+ pFrame->AppendDrawObj( *(pNew->GetAnchoredObj( nullptr )) );
+ }
+ // OD 19.06.2003 #108784# - add 'virtual' drawing object,
+ // if necessary. But control objects have to be excluded.
+ else if ( !::CheckControlLayer( pSdrObj ) &&
+ pNew->GetAnchorFrame() != pFrame &&
+ !pNew->GetDrawObjectByAnchorFrame( *pFrame ) )
+ {
+ SwDrawVirtObj* pDrawVirtObj = pNew->AddVirtObj(*pFrame);
+ pFrame->AppendDrawObj( *(pNew->GetAnchoredObj( pDrawVirtObj )) );
- pDrawVirtObj->ActionChanged();
+ pDrawVirtObj->ActionChanged();
+ }
}
}
else
@@ -3598,8 +3601,13 @@ bool Is_Lower_Of(const SwFrame *pCurrFrame, const SdrObject* pObj)
}
else
{
- pFrame = static_cast<SwDrawContact*>(GetUserCall(pObj))->GetAnchorFrame(pObj);
- aPos = pObj->GetCurrentBoundRect().TopLeft();
+ if (SwDrawContact* pC = static_cast<SwDrawContact*>(GetUserCall(pObj)))
+ {
+ pFrame = pC->GetAnchorFrame(pObj);
+ aPos = pObj->GetCurrentBoundRect().TopLeft();
+ }
+ else
+ return false;
}
OSL_ENSURE( pFrame, "8-( Fly is lost in Space." );
pFrame = GetVirtualUpper( pFrame, aPos );
diff --git a/sw/source/core/layout/ftnfrm.cxx b/sw/source/core/layout/ftnfrm.cxx
index f4e6072498d1..1c6b221cf511 100644
--- a/sw/source/core/layout/ftnfrm.cxx
+++ b/sw/source/core/layout/ftnfrm.cxx
@@ -42,9 +42,41 @@
#include <sal/log.hxx>
#include <IDocumentSettingAccess.hxx>
#include <flyfrm.hxx>
+#include <IDocumentStylePoolAccess.hxx>
+#include <docsh.hxx>
+#include <poolfmt.hxx>
+#include <swfntcch.hxx>
+#include <wrtsh.hxx>
#define ENDNOTE 0x80000000
+namespace
+{
+/// Calculates the height of the line that hosts the separator line (the top margin of the
+/// container), based on the default paragraph style in rDoc.
+bool FootnoteSeparatorHeightFromParagraph(SwDoc& rDoc, SwTwips& rHeight)
+{
+ const SwTextFormatColl* pDefaultParaFormat
+ = rDoc.getIDocumentStylePoolAccess().GetTextCollFromPool(RES_POOLCOLL_STANDARD);
+ if (!pDefaultParaFormat)
+ {
+ return false;
+ }
+
+ SwViewShell* pSh = rDoc.GetDocShell()->GetWrtShell();
+ if (!pSh)
+ {
+ return false;
+ }
+
+ SwFontAccess aFontAccess(pDefaultParaFormat, pSh);
+ SwFont aFont(aFontAccess.Get()->GetFont());
+ OutputDevice& rOut = pSh->GetRefDev();
+ rHeight = aFont.GetHeight(pSh, rOut);
+ return true;
+}
+}
+
/// Search the position of an attribute in the FootnoteArray at the document,
/// because all footnotes are located there, ordered by their index.
static sal_uLong lcl_FindFootnotePos( const SwDoc *pDoc, const SwTextFootnote *pAttr )
@@ -222,8 +254,20 @@ static tools::Long lcl_Undersize( const SwFrame* pFrame )
namespace sw {
-SwTwips FootnoteSeparatorHeight(SwPageFootnoteInfo const& rInf)
+SwTwips FootnoteSeparatorHeight(SwDoc& rDoc, SwPageFootnoteInfo const& rInf)
{
+ const IDocumentSettingAccess& rIDSA = rDoc.getIDocumentSettingAccess();
+ if (rIDSA.get(DocumentSettingId::CONTINUOUS_ENDNOTES))
+ {
+ // Word style: try to calculate the height from the default para format.
+ SwTwips nHeight{};
+ if (FootnoteSeparatorHeightFromParagraph(rDoc, nHeight))
+ {
+ return nHeight;
+ }
+ }
+
+ // Writer style: calculate from the page style.
return rInf.GetTopDist() + rInf.GetBottomDist() + rInf.GetLineWidth();
}
@@ -235,7 +279,8 @@ void SwFootnoteContFrame::Format( vcl::RenderContext* /*pRenderContext*/, const
// calculate total border, only one distance to the top
const SwPageFrame* pPage = FindPageFrame();
const SwPageFootnoteInfo &rInf = pPage->GetPageDesc()->GetFootnoteInfo();
- const SwTwips nBorder = sw::FootnoteSeparatorHeight(rInf);
+ SwDoc* pDoc = getRootFrame()->GetCurrShell()->GetDoc();
+ const SwTwips nBorder = sw::FootnoteSeparatorHeight(*pDoc, rInf);
SwRectFnSet aRectFnSet(this);
if ( !isFramePrintAreaValid() )
@@ -768,26 +813,18 @@ SwLayoutFrame *SwFrame::GetPrevFootnoteLeaf( MakePageType eMakeFootnote )
SwFrame* pTmpRef = nullptr;
const IDocumentSettingAccess& rSettings
= pFootnote->GetAttrSet()->GetDoc()->getIDocumentSettingAccess();
- if( bEndn && pFootnote->IsInSct() )
+ bool bContEndnotes = rSettings.get(DocumentSettingId::CONTINUOUS_ENDNOTES);
+ if( bEndn && pFootnote->IsInSct() && !bContEndnotes)
{
SwSectionFrame* pSect = pFootnote->FindSctFrame();
if( pSect->IsEndnAtEnd() )
// Endnotes at the end of the section.
pTmpRef = pSect->FindLastContent( SwFindMode::LastCnt );
}
- else if (bEndn && rSettings.get(DocumentSettingId::CONTINUOUS_ENDNOTES))
+ else if (bEndn && bContEndnotes)
{
// Endnotes at the end of the document.
- SwPageFrame* pPage = getRootFrame()->GetLastPage();
- assert(pPage);
- SwFrame* pPrevPage = pPage->GetPrev();
- if (pPrevPage)
- {
- // Have a last but one page, use that since we try to get a preceding frame.
- assert(pPrevPage->IsPageFrame());
- pPage = static_cast<SwPageFrame*>(pPrevPage);
- }
- pTmpRef = pPage->FindLastBodyContent();
+ pTmpRef = pFootnote->FindFootnoteBossFrame();
}
if( !pTmpRef )
// Endnotes on a separate page.
@@ -1556,8 +1593,44 @@ void SwFootnoteBossFrame::AppendFootnote( SwContentFrame *pRef, SwTextFootnote *
else if (rSettings.get(DocumentSettingId::CONTINUOUS_ENDNOTES))
{
// Endnotes at the end of the document.
- pBoss = getRootFrame()->GetLastPage();
- pPage = pBoss->FindPageFrame();
+ // Find the first page that hosts an endnote section.
+ SwSectionFrame* pEndnoteSection = pPage->GetEndNoteSection();
+ while (pPage->GetNext() && !pEndnoteSection)
+ {
+ pPage = pPage->GetNext()->DynCastPageFrame();
+ pEndnoteSection = pPage->GetEndNoteSection();
+ }
+ // If there are no endnotes sections yet, create one at the end of the document.
+ // Ignore sections which are already marked for deletion, they don't have an SwSection
+ // anymore, so not usable for us.
+ if (!pEndnoteSection || !pEndnoteSection->GetSection())
+ {
+ SwSection* pSwSection = pDoc->GetEndNoteInfo().GetSwSection(*pDoc);
+ pEndnoteSection = new SwSectionFrame(*pSwSection, pPage);
+ SwLayoutFrame* pParent = pPage->FindBodyCont();
+ SwFrame* pBefore = pPage->FindLastBodyContent();
+ while (pBefore)
+ {
+ // Check if the last content frame is directly under the body frame or there is
+ // something in-between, e.g. a section frame.
+ if (pBefore->GetUpper() == pParent)
+ {
+ break;
+ }
+
+ // If so, insert behind the parent of the content frame, not inside the parent.
+ pBefore = pBefore->GetUpper();
+ }
+ pEndnoteSection->InsertBehind(pParent, pBefore);
+ pEndnoteSection->Init();
+ pEndnoteSection->SetEndNoteSection(true);
+ }
+
+ SwFrame* pColumnFrame = pEndnoteSection->GetLower();
+ if (pColumnFrame->IsColumnFrame())
+ {
+ pBoss = static_cast<SwColumnFrame*>(pColumnFrame);
+ }
}
else
{
@@ -1907,10 +1980,7 @@ void SwFootnoteBossFrame::CollectFootnotes_( const SwContentFrame* _pRef,
bool bCollectFoundFootnote = false;
// Ignore endnotes which are on a separate endnote page.
bool bEndNote = _pFootnote->GetAttr()->GetFootnote().IsEndNote();
- const IDocumentSettingAccess& rSettings
- = _pFootnote->GetAttrSet()->GetDoc()->getIDocumentSettingAccess();
- bool bContinuousEndnotes = rSettings.get(DocumentSettingId::CONTINUOUS_ENDNOTES);
- if (_pFootnote->GetRef() == _pRef && (!bEndNote || bContinuousEndnotes))
+ if (_pFootnote->GetRef() == _pRef && !bEndNote)
{
if (_pRefFootnoteBossFrame)
{
diff --git a/sw/source/core/layout/pagechg.cxx b/sw/source/core/layout/pagechg.cxx
index 6aad283273fc..2575c9827886 100644
--- a/sw/source/core/layout/pagechg.cxx
+++ b/sw/source/core/layout/pagechg.cxx
@@ -446,22 +446,21 @@ static void lcl_MakeObjs(const sw::FrameFormats<sw::SpzFrameFormat*>& rSpzs, SwP
if ( bSdrObj )
{
// OD 23.06.2003 #108784# - consider 'virtual' drawing objects
- SwDrawContact *pContact =
- static_cast<SwDrawContact*>(::GetUserCall(pSdrObj));
- if ( auto pDrawVirtObj = dynamic_cast<SwDrawVirtObj *>( pSdrObj ) )
+ if (SwDrawContact *pContact =
+ static_cast<SwDrawContact*>(::GetUserCall(pSdrObj)))
{
- if ( pContact )
+ if ( auto pDrawVirtObj = dynamic_cast<SwDrawVirtObj *>( pSdrObj ) )
{
pDrawVirtObj->RemoveFromWriterLayout();
pDrawVirtObj->RemoveFromDrawingPage();
pPg->AppendDrawObj( *(pContact->GetAnchoredObj( pDrawVirtObj )) );
}
- }
- else
- {
- if ( pContact->GetAnchorFrame() )
- pContact->DisconnectFromLayout( false );
- pPg->AppendDrawObj( *(pContact->GetAnchoredObj( pSdrObj )) );
+ else
+ {
+ if ( pContact->GetAnchorFrame() )
+ pContact->DisconnectFromLayout( false );
+ pPg->AppendDrawObj( *(pContact->GetAnchoredObj( pSdrObj )) );
+ }
}
}
else
diff --git a/sw/source/core/layout/paintfrm.cxx b/sw/source/core/layout/paintfrm.cxx
index ff5abcfcf898..8564d60b53b3 100644
--- a/sw/source/core/layout/paintfrm.cxx
+++ b/sw/source/core/layout/paintfrm.cxx
@@ -5777,7 +5777,7 @@ void SwFootnoteContFrame::PaintLine( const SwRect& rRect,
SwTwips nPrtWidth = aRectFnSet.GetWidth(getFramePrintArea());
Fraction aFract( nPrtWidth, 1 );
aFract *= rInf.GetWidth();
- const SwTwips nWidth = static_cast<tools::Long>(aFract);
+ SwTwips nWidth = static_cast<tools::Long>(aFract);
SwTwips nX = aRectFnSet.GetPrtLeft(*this);
switch ( rInf.GetAdj() )
@@ -5793,13 +5793,43 @@ void SwFootnoteContFrame::PaintLine( const SwRect& rRect,
assert(false);
}
SwTwips nLineWidth = rInf.GetLineWidth();
- const SwRect aLineRect = aRectFnSet.IsVert() ?
- SwRect( Point(getFrameArea().Left()+getFrameArea().Width()-rInf.GetTopDist()-nLineWidth,
- nX), Size( nLineWidth, nWidth ) )
- : SwRect( Point( nX, getFrameArea().Pos().Y() + rInf.GetTopDist() ),
- Size( nWidth, rInf.GetLineWidth()));
- if ( aLineRect.HasArea() && rInf.GetLineStyle() != SvxBorderLineStyle::NONE)
- PaintBorderLine( rRect, aLineRect , pPage, &rInf.GetLineColor(),
+ std::optional<SwRect> oLineRect;
+ if (aRectFnSet.IsVert())
+ {
+ oLineRect.emplace(Point(getFrameArea().Left()+getFrameArea().Width()-rInf.GetTopDist()-nLineWidth,
+ nX), Size( nLineWidth, nWidth ) );
+ }
+ else
+ {
+ Point aPoint(nX, getFrameArea().Pos().Y() + rInf.GetTopDist());
+ const IDocumentSettingAccess& rIDSA = GetFormat()->getIDocumentSettingAccess();
+ if (rIDSA.get(DocumentSettingId::CONTINUOUS_ENDNOTES))
+ {
+ // Word style: instead of fixed value, upper spacing is 60% of all space.
+ auto nPrintAreaTop = static_cast<double>(getFramePrintArea().Top());
+ aPoint.setY(getFrameArea().Pos().Y() + nPrintAreaTop * 0.6);
+
+ const SwFootnoteFrame* pEndnoteFrame = FindEndNote();
+ bool bEndnoteContinuation = pEndnoteFrame && pEndnoteFrame->GetMaster();
+ if (bEndnoteContinuation)
+ {
+ // Endnote continuation separator is print area wide.
+ nWidth = nPrtWidth;
+ }
+ else
+ {
+ // Length is 2 inches, but don't paint outside the container frame.
+ nWidth = o3tl::convert(2, o3tl::Length::in, o3tl::Length::twip);
+ if (nWidth > nPrtWidth)
+ {
+ nWidth = nPrtWidth;
+ }
+ }
+ }
+ oLineRect.emplace(aPoint, Size(nWidth, rInf.GetLineWidth()));
+ }
+ if ( oLineRect->HasArea() && rInf.GetLineStyle() != SvxBorderLineStyle::NONE)
+ PaintBorderLine( rRect, *oLineRect , pPage, &rInf.GetLineColor(),
rInf.GetLineStyle() );
}
diff --git a/sw/source/core/layout/sectfrm.cxx b/sw/source/core/layout/sectfrm.cxx
index 3967a1f56442..4dc31c4256fd 100644
--- a/sw/source/core/layout/sectfrm.cxx
+++ b/sw/source/core/layout/sectfrm.cxx
@@ -94,6 +94,7 @@ SwSectionFrame::SwSectionFrame( SwSectionFrame &rSect, bool bMaster ) :
m_bOwnFootnoteNum( false ),
m_bFootnoteLock( false )
{
+ m_bEndNoteSection = rSect.m_bEndNoteSection;
StartListening(rSect.GetFormat()->GetNotifier());
mnFrameType = SwFrameType::Section;
@@ -832,6 +833,42 @@ void SwSectionFrame::MakeAll(vcl::RenderContext* pRenderContext)
setFramePrintAreaValid(true);
return;
}
+
+ if (!GetPrev() && !IsFollow() && IsInDocBody() && IsHiddenNow())
+ {
+ // This may be the first frame on a page, and it may had moved to that page because its
+ // content required that (a page break in the first paragraph, or a tall first line, or
+ // "do not break paragraph" setting, or the like). Try to move back, to allow following
+ // frames to move back, if possible. Sections cannot move back; workaround by a call to
+ // GetPrevSctLeaf(), which may return a candidate upper frame on a previous page, or it
+ // may create a new master for this at the end of the previous page. Cut and paste this
+ // appropriately; then drop the temporary, if needed.
+ if (SwLayoutFrame* moveBackPos = GetPrevSctLeaf())
+ {
+ SwLayoutFrame* newUpper = moveBackPos;
+ SwFrame* newSibling = nullptr;
+ const bool temporaryMasterCreated = IsFollow();
+ if (temporaryMasterCreated)
+ {
+ assert(moveBackPos == &GetPrecede()->GetFrame());
+ newUpper = moveBackPos->GetUpper();
+ newSibling = moveBackPos->GetNext(); // actually, will be also nullptr
+ }
+ if (newUpper != GetUpper())
+ {
+ // Can't use MoveSubTree, because the move needs to fire events to re-layout
+ Cut();
+ Paste(newUpper, newSibling);
+ }
+ if (temporaryMasterCreated)
+ {
+ moveBackPos->Cut();
+ DestroyFrame(moveBackPos);
+ }
+ assert(!IsFollow());
+ }
+ }
+
LockJoin(); // I don't let myself to be destroyed on the way
while( GetNext() && GetNext() == GetFollow() )
@@ -842,6 +879,17 @@ void SwSectionFrame::MakeAll(vcl::RenderContext* pRenderContext)
break;
}
+ if (GetFollow() && IsHiddenNow())
+ {
+ // Merge all the follows of this hidden section
+ while (auto* follow = GetFollow())
+ {
+ MergeNext(follow);
+ if (GetFollow() == follow) // failed to merge
+ break; // avoid endless loop
+ }
+ }
+
// OD 2004-03-15 #116561# - In online layout join the follows, if section
// can grow.
const SwViewShell *pSh = getRootFrame()->GetCurrShell();
@@ -1210,7 +1258,7 @@ void SwSectionFrame::SimpleFormat()
SwTwips nDeadLine = aRectFnSet.GetPrtBottom(*GetUpper());
// OD 22.10.2002 #97265# - call always method <lcl_ColumnRefresh(..)>, in
// order to get calculated lowers, not only if there space left in its upper.
- if( aRectFnSet.BottomDist( getFrameArea(), nDeadLine ) >= 0 )
+ if (aRectFnSet.BottomDist(getFrameArea(), nDeadLine) >= 0)
{
{
SwFrameAreaDefinition::FrameAreaWriteAccess aFrm(*this);
@@ -2676,6 +2724,12 @@ void SwSectionFrame::SwClientNotify(const SwModify& rMod, const SfxHint& rHint)
{
InvalidateAll();
InvalidateObjs(false);
+ {
+ // Set it to a huge positive value, to make sure a recalculation fires
+ constexpr SwTwips HUGE_POSITIVE = o3tl::toTwips(100, o3tl::Length::m);
+ SwFrameAreaDefinition::FrameAreaWriteAccess area(*this);
+ SwRectFnSet(this).SetHeight(area, HUGE_POSITIVE);
+ }
for (SwFrame* pLowerFrame = Lower(); pLowerFrame; pLowerFrame = pLowerFrame->GetNext())
{
diff --git a/sw/source/core/layout/tabfrm.cxx b/sw/source/core/layout/tabfrm.cxx
index adffbba17715..13e212f6ea16 100644
--- a/sw/source/core/layout/tabfrm.cxx
+++ b/sw/source/core/layout/tabfrm.cxx
@@ -2239,6 +2239,9 @@ void SwTabFrame::MakeAll(vcl::RenderContext* pRenderContext)
}
}
+ if (IsHiddenNow())
+ MakeValidZeroHeight();
+
int nUnSplitted = 5; // Just another loop control :-(
int nThrowAwayValidLayoutLimit = 5; // And another one :-(
SwRectFnSet aRectFnSet(this);
@@ -3185,6 +3188,16 @@ bool SwTabFrame::CalcFlyOffsets( SwTwips& rUpper,
tools::Long& rRightOffset,
SwTwips *const pSpaceBelowBottom) const
{
+ if (IsHiddenNow())
+ {
+ rUpper = 0;
+ rLeftOffset = 0;
+ rRightOffset = 0;
+ if (pSpaceBelowBottom)
+ *pSpaceBelowBottom = 0;
+ return false;
+ }
+
bool bInvalidatePrtArea = false;
const SwPageFrame *pPage = FindPageFrame();
const SwFlyFrame* pMyFly = FindFlyFrame();
diff --git a/sw/source/core/layout/trvlfrm.cxx b/sw/source/core/layout/trvlfrm.cxx
index 89a5f03302ac..b9e05dd30a40 100644
--- a/sw/source/core/layout/trvlfrm.cxx
+++ b/sw/source/core/layout/trvlfrm.cxx
@@ -70,26 +70,29 @@ namespace {
{
const SwVirtFlyDrawObj* pObj =
static_cast<const SwVirtFlyDrawObj*>(aIter());
- const SwAnchoredObject* pAnchoredObj = GetUserCall( aIter() )->GetAnchoredObj( aIter() );
- 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;
-
- const SwFlyFrame* pFly = pObj ? pObj->GetFlyFrame() : nullptr;
- if ( pFly && bBackgroundMatches &&
- ( ( pCMS && pCMS->m_bSetInReadOnly ) ||
- !pFly->IsProtected() ) &&
- pFly->GetModelPositionForViewPoint( pPos, aPoint, pCMS ) )
+ if (const SwContact* pContact = ::GetUserCall( aIter() ))
{
- bRet = true;
- break;
- }
+ const SwAnchoredObject* pAnchoredObj = pContact->GetAnchoredObj( aIter() );
+ 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;
+
+ const SwFlyFrame* pFly = pObj ? pObj->GetFlyFrame() : nullptr;
+ if ( pFly && bBackgroundMatches &&
+ ( ( pCMS && pCMS->m_bSetInReadOnly ) ||
+ !pFly->IsProtected() ) &&
+ pFly->GetModelPositionForViewPoint( pPos, aPoint, pCMS ) )
+ {
+ bRet = true;
+ break;
+ }
- if ( pCMS && pCMS->m_bStop )
- return false;
+ if ( pCMS && pCMS->m_bStop )
+ return false;
+ }
aIter.Prev();
}
return bRet;
@@ -1734,6 +1737,22 @@ bool SwFrame::IsHiddenNow() const
return false;
}
+void SwFrame::MakeValidZeroHeight()
+{
+ SwRectFnSet aRectFnSet(this);
+ {
+ SwFrameAreaDefinition::FrameAreaWriteAccess area(*this);
+ aRectFnSet.SetHeight(area, 0);
+ }
+ {
+ SwFrameAreaDefinition::FramePrintAreaWriteAccess area(*this);
+ aRectFnSet.SetHeight(area, 0);
+ }
+ setFrameAreaSizeValid(true);
+ setFramePrintAreaValid(true);
+ setFrameAreaPositionValid(false);
+}
+
/** @return the physical page number */
sal_uInt16 SwFrame::GetPhyPageNum() const
{
diff --git a/sw/source/core/objectpositioning/anchoredobjectposition.cxx b/sw/source/core/objectpositioning/anchoredobjectposition.cxx
index ab35ae7af738..4af3af542b27 100644
--- a/sw/source/core/objectpositioning/anchoredobjectposition.cxx
+++ b/sw/source/core/objectpositioning/anchoredobjectposition.cxx
@@ -852,7 +852,10 @@ SwTwips SwAnchoredObjectPosition::CalcRelPosX(
if ( _rHoriOrient.GetHoriOrient() == text::HoriOrientation::NONE )
{
// 'manual' horizontal position
- const bool bR2L = rAnchorFrame.IsRightToLeft();
+ const IDocumentSettingAccess& rIDSA = mpFrameFormat->getIDocumentSettingAccess();
+ // If compat flag is active, then disable automatic mirroring for RTL.
+ bool bMirrorRtlDrawObjs = !rIDSA.get(DocumentSettingId::DO_NOT_MIRROR_RTL_DRAW_OBJS);
+ const bool bR2L = rAnchorFrame.IsRightToLeft() && bMirrorRtlDrawObjs;
if( IsAnchoredToChar() && text::RelOrientation::CHAR == eRelOrient )
{
if( bR2L )
diff --git a/sw/source/core/text/guess.cxx b/sw/source/core/text/guess.cxx
index c3a94187a7ea..c4f74de7cef7 100644
--- a/sw/source/core/text/guess.cxx
+++ b/sw/source/core/text/guess.cxx
@@ -71,15 +71,14 @@ bool hasBlanksInLine(const SwTextFormatInfo& rInf, TextFrameIndex end)
return false;
}
+}
+
// Called for the last text run in a line; if it is block-adjusted, or center / right-adjusted
// with Word compatibility option set, and it has trailing spaces, then the function sets the
// values, and returns 'false' value that SwTextGuess::Guess should return, to create a
// trailing SwHolePortion.
-bool maybeAdjustPositionsForBlockAdjust(TextFrameIndex& rCutPos, TextFrameIndex& rBreakPos,
- TextFrameIndex& rBreakStart, sal_uInt16& rBreakWidth,
- sal_uInt16& rExtraBlankWidth, sal_uInt16& rMaxSizeDiff,
- const SwTextFormatInfo& rInf, const SwScriptInfo& rSI,
- sal_uInt16 maxComp)
+bool SwTextGuess::maybeAdjustPositionsForBlockAdjust(sal_uInt16& rMaxSizeDiff, const SwTextFormatInfo& rInf,
+ const SwScriptInfo& rSI, sal_uInt16 maxComp)
{
const auto& adjObj = rInf.GetTextFrame()->GetTextNodeForParaProps()->GetSwAttrSet().GetAdjust();
const SvxAdjust& adjust = adjObj.GetAdjust();
@@ -98,7 +97,7 @@ bool maybeAdjustPositionsForBlockAdjust(TextFrameIndex& rCutPos, TextFrameIndex&
if (rInf.GetTextFrame()->IsRightToLeft())
return true;
}
- if (auto ch = rInf.GetChar(rCutPos); !ch) // end of paragraph - last line
+ if (auto ch = rInf.GetChar(m_nCutPos); !ch) // end of paragraph - last line
{
if (adjust == SvxAdjust::Block)
{
@@ -123,7 +122,7 @@ bool maybeAdjustPositionsForBlockAdjust(TextFrameIndex& rCutPos, TextFrameIndex&
// tdf#57187: block-adjusted line shorter than full width, terminated by manual
// line break, must not use trailing spaces for adjustment
TextFrameIndex breakPos;
- TextFrameIndex newCutPos = AdjustCutPos(rCutPos, breakPos, rInf);
+ TextFrameIndex newCutPos = AdjustCutPos(m_nCutPos, breakPos, rInf);
if (auto ch = rInf.GetChar(newCutPos); ch && ch != CH_BREAK)
return true; // next is neither line break nor paragraph end
@@ -135,19 +134,19 @@ bool maybeAdjustPositionsForBlockAdjust(TextFrameIndex& rCutPos, TextFrameIndex&
// Some trailing spaces actually found, and in case of block adjustment, the text portion
// itself has spaces to be able to block-adjust, or single word is allowed to adjust
- rBreakStart = rCutPos = newCutPos;
- rBreakPos = breakPos;
+ m_nBreakStart = m_nCutPos = newCutPos;
+ m_nBreakPos = breakPos;
+ // throw away old m_xHyphWord because the current break pos is now between words
+ m_xHyphWord = nullptr;
- rInf.GetTextSize(&rSI, rInf.GetIdx(), breakPos - rInf.GetIdx(), maxComp, rBreakWidth,
+ rInf.GetTextSize(&rSI, rInf.GetIdx(), breakPos - rInf.GetIdx(), maxComp, m_nBreakWidth,
rMaxSizeDiff, rInf.GetCachedVclData().get());
- rInf.GetTextSize(&rSI, breakPos, rBreakStart - breakPos, maxComp, rExtraBlankWidth,
+ rInf.GetTextSize(&rSI, breakPos, m_nBreakStart - breakPos, maxComp, m_nExtraBlankWidth,
rMaxSizeDiff, rInf.GetCachedVclData().get());
return false; // require SwHolePortion creation
}
-}
-
// provides information for line break calculation
// returns true if no line break has to be performed
// otherwise possible break or hyphenation position is determined
@@ -254,9 +253,7 @@ bool SwTextGuess::Guess( const SwTextPortion& rPor, SwTextFormatInfo &rInf,
// portion fits to line
m_nCutPos = rInf.GetIdx() + nMaxLen;
bool bRet = rPor.InFieldGrp()
- || maybeAdjustPositionsForBlockAdjust(m_nCutPos, m_nBreakPos, m_nBreakStart,
- m_nBreakWidth, m_nExtraBlankWidth,
- nMaxSizeDiff, rInf, rSI, nMaxComp);
+ || maybeAdjustPositionsForBlockAdjust(nMaxSizeDiff, rInf, rSI, nMaxComp);
if( nItalic &&
(m_nCutPos >= TextFrameIndex(rInf.GetText().getLength()) ||
// #i48035# Needed for CalcFitToContent
@@ -410,9 +407,7 @@ bool SwTextGuess::Guess( const SwTextPortion& rPor, SwTextFormatInfo &rInf,
if ( m_nBreakWidth <= nLineWidth )
{
bool bRet = rPor.InFieldGrp()
- || maybeAdjustPositionsForBlockAdjust(m_nCutPos, m_nBreakPos, m_nBreakStart,
- m_nBreakWidth, m_nExtraBlankWidth,
- nMaxSizeDiff, rInf, rSI, nMaxComp);
+ || maybeAdjustPositionsForBlockAdjust(nMaxSizeDiff, rInf, rSI, nMaxComp);
if (nItalic && (m_nBreakPos + TextFrameIndex(1)) >= TextFrameIndex(rInf.GetText().getLength()))
m_nBreakWidth += nItalic;
@@ -443,6 +438,8 @@ bool SwTextGuess::Guess( const SwTextPortion& rPor, SwTextFormatInfo &rInf,
{
m_nCutPos = m_nBreakStart = AdjustCutPos(m_nCutPos, m_nBreakPos, rInf);
nPorLen = m_nBreakPos - rInf.GetIdx();
+ // throw away old m_xHyphWord when m_nBreakStart changes
+ m_xHyphWord = nullptr;
}
else
{
diff --git a/sw/source/core/text/guess.hxx b/sw/source/core/text/guess.hxx
index 5a7a9ac1cfa2..4bc122960389 100644
--- a/sw/source/core/text/guess.hxx
+++ b/sw/source/core/text/guess.hxx
@@ -59,7 +59,9 @@ public:
TextFrameIndex FieldDiff() const {return m_nFieldDiff; }
const css::uno::Reference< css::linguistic2::XHyphenatedWord >& HyphWord() const
{ return m_xHyphWord; }
+private:
+ bool maybeAdjustPositionsForBlockAdjust(sal_uInt16& rMaxSizeDiff, const SwTextFormatInfo& rInf,
+ const SwScriptInfo& rSI, sal_uInt16 maxComp);
};
-
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/text/inftxt.hxx b/sw/source/core/text/inftxt.hxx
index 2ddaee7b2e8f..cb11d02b1e8d 100644
--- a/sw/source/core/text/inftxt.hxx
+++ b/sw/source/core/text/inftxt.hxx
@@ -71,8 +71,8 @@ class SwLineInfo
void CtorInitLineInfo( const SwAttrSet& rAttrSet,
const SwTextNode& rTextNode );
- SwLineInfo();
- ~SwLineInfo();
+ SW_DLLPUBLIC SwLineInfo();
+ SW_DLLPUBLIC ~SwLineInfo();
public:
// #i24363# tab stops relative to indent - returns the tab stop following nSearchPos or NULL
const SvxTabStop* GetTabStop(const SwTwips nSearchPos, SwTwips& nRight) const;
@@ -183,7 +183,7 @@ public:
SwTextSizeInfo( const SwTextSizeInfo &rInf );
SwTextSizeInfo( const SwTextSizeInfo &rInf, const OUString* pText,
TextFrameIndex nIdx = TextFrameIndex(0) );
- SwTextSizeInfo(SwTextFrame *pTextFrame, TextFrameIndex nIndex = TextFrameIndex(0));
+ SW_DLLPUBLIC SwTextSizeInfo(SwTextFrame *pTextFrame, TextFrameIndex nIndex = TextFrameIndex(0));
// GetMultiAttr returns the text attribute of the multiportion,
// if rPos is inside any multi-line part.
diff --git a/sw/source/core/text/itratr.hxx b/sw/source/core/text/itratr.hxx
index eb15400cf5d8..9a5f0b3f01cc 100644
--- a/sw/source/core/text/itratr.hxx
+++ b/sw/source/core/text/itratr.hxx
@@ -29,7 +29,7 @@ class SwRedlineItr;
class SwViewShell;
class SwTextFrame;
-class SwAttrIter
+class SW_DLLPUBLIC SwAttrIter
{
friend class SwFontSave;
protected:
diff --git a/sw/source/core/text/itrtxt.hxx b/sw/source/core/text/itrtxt.hxx
index 8db063d616e8..b5ea78369d5f 100644
--- a/sw/source/core/text/itrtxt.hxx
+++ b/sw/source/core/text/itrtxt.hxx
@@ -156,7 +156,7 @@ protected:
// For FormatQuoVadis
void Right( const SwTwips nNew ) { mnRight = nNew; }
- void CtorInitTextMargin( SwTextFrame *pFrame, SwTextSizeInfo *pInf );
+ SW_DLLPUBLIC void CtorInitTextMargin( SwTextFrame *pFrame, SwTextSizeInfo *pInf );
explicit SwTextMargin(SwTextNode const * pTextNode)
: SwTextIter(pTextNode)
, mnLeft(0)
diff --git a/sw/source/core/text/txtfly.cxx b/sw/source/core/text/txtfly.cxx
index 7c4d9a2e160d..45eea8eeee53 100644
--- a/sw/source/core/text/txtfly.cxx
+++ b/sw/source/core/text/txtfly.cxx
@@ -1051,6 +1051,13 @@ SwTwips SwTextFly::GetMaxBottom(const SwBreakPortion& rPortion, const SwTextForm
continue;
}
+ const SwFormatSurround& rSurround = pAnchoredObj->GetFrameFormat()->GetSurround();
+ if (rSurround.GetValue() == text::WrapTextMode_THROUGH)
+ {
+ // Wrap through has no influence on clearing breaks.
+ continue;
+ }
+
SwRect aRect(pAnchoredObj->GetObjRectWithSpaces());
if (m_pCurrFrame->IsVertical())
diff --git a/sw/source/core/text/txtftn.cxx b/sw/source/core/text/txtftn.cxx
index c1fa749c93f5..255329857a36 100644
--- a/sw/source/core/text/txtftn.cxx
+++ b/sw/source/core/text/txtftn.cxx
@@ -598,8 +598,6 @@ void SwTextFrame::ConnectFootnote( SwTextFootnote *pFootnote, const SwTwips nDea
mbFootnote = true;
mbInFootnoteConnect = true; // Just reset!
// See if pFootnote is an endnote on a separate endnote page.
- const IDocumentSettingAccess& rSettings = GetDoc().getIDocumentSettingAccess();
- const bool bContinuousEndnotes = rSettings.get(DocumentSettingId::CONTINUOUS_ENDNOTES);
const bool bEnd = pFootnote->GetFootnote().IsEndNote();
// We want to store this value, because it is needed as a fallback
@@ -630,15 +628,11 @@ void SwTextFrame::ConnectFootnote( SwTextFootnote *pFootnote, const SwTwips nDea
if( bDocEnd )
{
- if ((pSect || bContinuousEndnotes) && pSrcFrame)
+ if (pSect && pSrcFrame)
{
SwFootnoteFrame *pFootnoteFrame = SwFootnoteBossFrame::FindFootnote( pSrcFrame, pFootnote );
- if (pFootnoteFrame && (pFootnoteFrame->IsInSct() || bContinuousEndnotes))
+ if (pFootnoteFrame && pFootnoteFrame->IsInSct())
{
- // We either have a foot/endnote that goes to the end of the section or are in Word
- // compatibility mode where endnotes go to the end of the document. Handle both
- // cases by removing the footnote here, then later appending them to the correct
- // last page of the document or section.
pBoss->RemoveFootnote( pSrcFrame, pFootnote );
pSrcFrame = nullptr;
}
diff --git a/sw/source/core/txtnode/atrflyin.cxx b/sw/source/core/txtnode/atrflyin.cxx
index 28eb7b38e530..fbefb76fa851 100644
--- a/sw/source/core/txtnode/atrflyin.cxx
+++ b/sw/source/core/txtnode/atrflyin.cxx
@@ -197,7 +197,8 @@ void SwTextFlyCnt::SetAnchor( const SwTextNode *pNode )
{
if (SdrObject const*const pObj = pFormat->FindSdrObject())
{ // tdf#123259 disconnect with *old* anchor position
- static_cast<SwDrawContact*>(::GetUserCall(pObj))->DisconnectFromLayout(false);
+ if (SwDrawContact* pContact = static_cast<SwDrawContact*>(::GetUserCall( pObj )))
+ pContact->DisconnectFromLayout(false);
}
}
pFormat->SetFormatAttr( aAnchor ); // only set the anchor
diff --git a/sw/source/core/txtnode/thints.cxx b/sw/source/core/txtnode/thints.cxx
index cf5e1ff1cccf..c499294f4f26 100644
--- a/sw/source/core/txtnode/thints.cxx
+++ b/sw/source/core/txtnode/thints.cxx
@@ -1700,7 +1700,9 @@ bool SwTextNode::InsertHint( SwTextAttr * const pAttr, const SetAttrMode nMode )
// for all of its content.
auto* pTextContentControl = static_txtattr_cast<SwTextContentControl*>(
GetTextAttrAt(pAttr->GetStart(), RES_TXTATR_CONTENTCONTROL, ::sw::GetTextAttrMode::Parent));
- if (pTextContentControl)
+ // If the caller is SwTextNode::CopyText, we just copy an existing attribute, no need to
+ // correct it.
+ if (pTextContentControl && !(nMode & SetAttrMode::NOTXTATRCHR))
{
auto& rFormatContentControl
= static_cast<SwFormatContentControl&>(pTextContentControl->GetAttr());
diff --git a/sw/source/core/txtnode/txtedt.cxx b/sw/source/core/txtnode/txtedt.cxx
index 2f3e7aa6db86..a1bfb0c0f3c1 100644
--- a/sw/source/core/txtnode/txtedt.cxx
+++ b/sw/source/core/txtnode/txtedt.cxx
@@ -1490,6 +1490,14 @@ SwRect SwTextFrame::AutoSpell_(SwTextNode & rNode, sal_Int32 nActPos)
: sw::WrongState::DONE);
if( !pNode->GetWrong()->Count() && ! pNode->IsWrongDirty() )
pNode->ClearWrong();
+
+ if (bPending && getRootFrame())
+ {
+ if (SwViewShell* pViewSh = getRootFrame()->GetCurrShell())
+ {
+ pViewSh->OnSpellWrongStatePending();
+ }
+ }
}
else
pNode->SetWrongDirty(sw::WrongState::DONE);
diff --git a/sw/source/core/undo/undraw.cxx b/sw/source/core/undo/undraw.cxx
index 134c6862971e..73a58a0f52e5 100644
--- a/sw/source/core/undo/undraw.cxx
+++ b/sw/source/core/undo/undraw.cxx
@@ -274,6 +274,8 @@ void SwUndoDrawGroup::RedoImpl(::sw::UndoRedoContext &)
SdrObject* pObj = rSave.pObj;
SwDrawContact *pContact = static_cast<SwDrawContact*>(GetUserCall(pObj));
+ if (!pContact)
+ continue;
// Save the textboxes
if (auto pOldTextBoxNode = rSave.pFormat->GetOtherTextBoxFormats())
@@ -350,23 +352,25 @@ SwUndoDrawUnGroup::SwUndoDrawUnGroup( SdrObjGroup* pObj, const SwDoc& rDoc )
m_nSize = o3tl::narrowing<sal_uInt16>(pObj->GetSubList()->GetObjCount()) + 1;
m_pObjArray.reset( new SwUndoGroupObjImpl[ m_nSize ] );
- SwDrawContact *pContact = static_cast<SwDrawContact*>(GetUserCall(pObj));
- SwDrawFrameFormat* pFormat = static_cast<SwDrawFrameFormat*>(pContact->GetFormat());
+ if (SwDrawContact *pContact = static_cast<SwDrawContact*>(GetUserCall(pObj)))
+ {
+ SwDrawFrameFormat* pFormat = static_cast<SwDrawFrameFormat*>(pContact->GetFormat());
- m_pObjArray[0].pObj = pObj;
- m_pObjArray[0].pFormat = pFormat;
+ m_pObjArray[0].pObj = pObj;
+ m_pObjArray[0].pFormat = pFormat;
- // object will destroy itself
- pContact->Changed( *pObj, SdrUserCallType::Delete, pObj->GetLastBoundRect() );
- pObj->SetUserCall( nullptr );
+ // object will destroy itself
+ pContact->Changed( *pObj, SdrUserCallType::Delete, pObj->GetLastBoundRect() );
+ pObj->SetUserCall( nullptr );
- ::lcl_SaveAnchor( pFormat, m_pObjArray[0].nNodeIdx );
+ ::lcl_SaveAnchor( pFormat, m_pObjArray[0].nNodeIdx );
- pFormat->RemoveAllUnos();
+ pFormat->RemoveAllUnos();
- // remove from array
- sw::SpzFrameFormats& rFlyFormats = *pFormat->GetDoc()->GetSpzFrameFormats();
- rFlyFormats.erase( std::find( rFlyFormats.begin(), rFlyFormats.end(), pFormat ));
+ // remove from array
+ sw::SpzFrameFormats& rFlyFormats = *pFormat->GetDoc()->GetSpzFrameFormats();
+ rFlyFormats.erase( std::find( rFlyFormats.begin(), rFlyFormats.end(), pFormat ));
+ }
}
SwUndoDrawUnGroup::~SwUndoDrawUnGroup()
@@ -622,6 +626,9 @@ void SwUndoDrawDelete::RedoImpl(::sw::UndoRedoContext & rContext)
SwUndoGroupObjImpl& rSave = m_pObjArray[n];
SdrObject *pObj = rSave.pObj;
SwDrawContact *pContact = static_cast<SwDrawContact*>(GetUserCall(pObj));
+ if (!pContact)
+ continue;
+
SwDrawFrameFormat *pFormat = static_cast<SwDrawFrameFormat*>(pContact->GetFormat());
// object will destroy itself
diff --git a/sw/source/core/undo/unins.cxx b/sw/source/core/undo/unins.cxx
index bf6c2877b2d4..ff6dbeb74c4f 100644
--- a/sw/source/core/undo/unins.cxx
+++ b/sw/source/core/undo/unins.cxx
@@ -672,7 +672,10 @@ void SwUndoReplace::Impl::UndoImpl(::sw::UndoRedoContext & rContext)
rPam.GetPoint()->Assign( m_nEndNd - m_nOffset, m_nEndCnt );
pDoc->getIDocumentContentOperations().DeleteAndJoin(rPam);
}
- rPam.DeleteMark();
+ if (*rPam.GetMark() == *rPam.GetPoint())
+ rPam.DeleteMark();
+ else
+ rPam.Normalize(false);
pNd = pDoc->GetNodes()[ m_nSttNd - m_nOffset ]->GetTextNode();
OSL_ENSURE( pNd, "Dude, where's my TextNode?" );
}
@@ -712,8 +715,6 @@ void SwUndoReplace::Impl::UndoImpl(::sw::UndoRedoContext & rContext)
}
}
}
-
- rPam.GetPoint()->Assign( m_nSttNd, m_nSttCnt );
}
void SwUndoReplace::Impl::RedoImpl(::sw::UndoRedoContext & rContext)
@@ -751,7 +752,10 @@ void SwUndoReplace::Impl::RedoImpl(::sw::UndoRedoContext & rContext)
}
rDoc.getIDocumentContentOperations().ReplaceRange( rPam, m_sIns, m_bRegExp );
- rPam.DeleteMark();
+ if (*rPam.GetMark() == *rPam.GetPoint())
+ rPam.DeleteMark();
+ else
+ rPam.Normalize(false);
}
void SwUndoReplace::Impl::SetEnd(SwPaM const& rPam)
diff --git a/sw/source/core/undo/unnum.cxx b/sw/source/core/undo/unnum.cxx
index 1251635a3135..a0aa39f3fcb3 100644
--- a/sw/source/core/undo/unnum.cxx
+++ b/sw/source/core/undo/unnum.cxx
@@ -112,7 +112,7 @@ void SwUndoInsNum::RedoImpl(::sw::UndoRedoContext & rContext)
else
{
// #i42921# - adapt to changed signature
- rDoc.SetNumRule(rPam, m_aNumRule, false);
+ rDoc.SetNumRule(rPam, m_aNumRule, SwDoc::SetNumRuleMode::Default);
}
}
}
@@ -131,7 +131,7 @@ void SwUndoInsNum::RepeatImpl(::sw::RepeatContext & rContext)
if( m_sReplaceRule.isEmpty() )
{
// #i42921# - adapt to changed signature
- rDoc.SetNumRule(rContext.GetRepeatPaM(), m_aNumRule, false);
+ rDoc.SetNumRule(rContext.GetRepeatPaM(), m_aNumRule, SwDoc::SetNumRuleMode::Default);
}
}
else
diff --git a/sw/source/core/unocore/unocrsrhelper.cxx b/sw/source/core/unocore/unocrsrhelper.cxx
index 30f6d6e6190e..deb0d443b5e5 100644
--- a/sw/source/core/unocore/unocrsrhelper.cxx
+++ b/sw/source/core/unocore/unocrsrhelper.cxx
@@ -905,14 +905,14 @@ void setNumberingProperty(const Any& rValue, SwPaM& rPam)
for ( size_t n = 0; n < aRangeArr.Count(); ++n )
{
// no start of a new list
- rDoc.SetNumRule( aRangeArr.SetPam( n, aPam ), aRule, false );
+ rDoc.SetNumRule(aRangeArr.SetPam( n, aPam ), aRule, SwDoc::SetNumRuleMode::Default);
}
rDoc.GetIDocumentUndoRedo().EndUndo( SwUndoId::END, nullptr );
}
else
{
// no start of a new list
- rDoc.SetNumRule( rPam, aRule, false );
+ rDoc.SetNumRule(rPam, aRule, SwDoc::SetNumRuleMode::Default);
}
}
@@ -923,7 +923,7 @@ void setNumberingProperty(const Any& rValue, SwPaM& rPam)
if ( !pRule )
throw RuntimeException();
// no start of a new list
- rDoc.SetNumRule( rPam, *pRule, false );
+ rDoc.SetNumRule(rPam, *pRule, SwDoc::SetNumRuleMode::Default);
}
else
{
@@ -933,7 +933,7 @@ void setNumberingProperty(const Any& rValue, SwPaM& rPam)
SwNumRule* pRule = rDoc.GetOutlineNumRule();
if(!pRule)
throw RuntimeException();
- rDoc.SetNumRule( rPam, *pRule, false );
+ rDoc.SetNumRule(rPam, *pRule, SwDoc::SetNumRuleMode::Default);
}
}
}
diff --git a/sw/source/core/unocore/unoportenum.cxx b/sw/source/core/unocore/unoportenum.cxx
index 709d79ef4d4b..9177765c0e32 100644
--- a/sw/source/core/unocore/unoportenum.cxx
+++ b/sw/source/core/unocore/unoportenum.cxx
@@ -608,7 +608,9 @@ static void lcl_ExportBookmark(
const SwXBookmarkPortion_ImplSharedPtr& pPtr = *aIter;
if ( nIndex > pPtr->getIndex() )
{
- assert(!"Some bookmarks were not consumed earlier");
+ // We may get here, if SwXTextPortionEnumeration ctor was called with nStart greater
+ // than this bookmark's index. Just drop it.
+ aIter = rBkmArr.erase(aIter);
continue;
}
if ( nIndex < pPtr->getIndex() )
diff --git a/sw/source/filter/basflt/fltshell.cxx b/sw/source/filter/basflt/fltshell.cxx
index 901614897f18..c8b7ac205890 100644
--- a/sw/source/filter/basflt/fltshell.cxx
+++ b/sw/source/filter/basflt/fltshell.cxx
@@ -538,7 +538,7 @@ void SwFltControlStack::SetAttrInDoc(const SwPosition& rTmpPos,
{
SwPaM aTmpPam( aTmpStart, aTmpEnd );
// no start of a new list
- m_rDoc.SetNumRule( aTmpPam, *pNumRule, false );
+ m_rDoc.SetNumRule(aTmpPam, *pNumRule, SwDoc::SetNumRuleMode::Default);
aTmpStart = aTmpEnd; // here starts the next range
++aTmpStart;
diff --git a/sw/source/filter/html/htmlctxt.cxx b/sw/source/filter/html/htmlctxt.cxx
index 80245ba2ea6a..0e87b83644f8 100644
--- a/sw/source/filter/html/htmlctxt.cxx
+++ b/sw/source/filter/html/htmlctxt.cxx
@@ -656,7 +656,8 @@ void SwHTMLParser::InsertAttrs( SfxItemSet &rItemSet,
}
#endif
- for (const SfxPoolItem* pItem = aIter.GetCurItem(); pItem; pItem = aIter.NextItem())
+ SfxItemIter aIter2(rItemSet);
+ for (const SfxPoolItem* pItem = aIter2.GetCurItem(); pItem; pItem = aIter2.NextItem())
{
HTMLAttr **ppAttr = nullptr;
diff --git a/sw/source/filter/ww8/docxattributeoutput.cxx b/sw/source/filter/ww8/docxattributeoutput.cxx
index 9b8c4dbceb2b..2f77cf07b06a 100644
--- a/sw/source/filter/ww8/docxattributeoutput.cxx
+++ b/sw/source/filter/ww8/docxattributeoutput.cxx
@@ -127,6 +127,7 @@
#include <docsh.hxx>
#include <docary.hxx>
#include <fmtclbl.hxx>
+#include <fmtftntx.hxx>
#include <IDocumentSettingAccess.hxx>
#include <IDocumentRedlineAccess.hxx>
#include <grfatr.hxx>
@@ -8722,7 +8723,15 @@ void DocxAttributeOutput::FootnotesEndnotes( bool bFootnotes )
bSeparator = rFootnoteInfo.GetLineStyle() != SvxBorderLineStyle::NONE
&& rFootnoteInfo.GetLineWidth() > 0
&& double(rFootnoteInfo.GetWidth()) > 0;
- nHeight = sw::FootnoteSeparatorHeight(rFootnoteInfo);
+ nHeight = sw::FootnoteSeparatorHeight(m_rExport.m_rDoc, rFootnoteInfo);
+
+ const IDocumentSettingAccess& rIDSA = m_rExport.m_rDoc.getIDocumentSettingAccess();
+ if (rIDSA.get(DocumentSettingId::CONTINUOUS_ENDNOTES))
+ {
+ // Don't request separator if this is a Word-style separator, which is handled at a
+ // layout level.
+ nHeight = 0;
+ }
}
WriteFootnoteSeparatorHeight(m_pSerializer, nHeight);
@@ -8778,6 +8787,18 @@ void DocxAttributeOutput::WriteFootnoteEndnotePr( ::sax_fastparser::FSHelperPtr
const SwEndNoteInfo& info, int listtag )
{
fs->startElementNS(XML_w, tag);
+
+ SwSectionFormats& rSections = m_rExport.m_rDoc.GetSections();
+ if (!rSections.empty())
+ {
+ SwSectionFormat* pFormat = rSections[0];
+ bool bEndnAtEnd = pFormat->GetEndAtTextEnd().IsAtEnd();
+ if (bEndnAtEnd)
+ {
+ fs->singleElementNS(XML_w, XML_pos, FSNS(XML_w, XML_val), "sectEnd");
+ }
+ }
+
OString aCustomFormat;
OString fmt = lcl_ConvertNumberingType(info.m_aFormat.GetNumberingType(), nullptr, aCustomFormat);
if (!fmt.isEmpty() && aCustomFormat.isEmpty())
diff --git a/sw/source/filter/ww8/docxattributeoutput.hxx b/sw/source/filter/ww8/docxattributeoutput.hxx
index 10f39debc2a0..b23f5b98ee7e 100644
--- a/sw/source/filter/ww8/docxattributeoutput.hxx
+++ b/sw/source/filter/ww8/docxattributeoutput.hxx
@@ -1109,7 +1109,7 @@ public:
void FootnotesEndnotes( bool bFootnotes );
/// writes the footnotePr/endnotePr (depending on tag) section
- static void WriteFootnoteEndnotePr( ::sax_fastparser::FSHelperPtr const & fs, int tag, const SwEndNoteInfo& info, int listtag );
+ void WriteFootnoteEndnotePr( ::sax_fastparser::FSHelperPtr const & fs, int tag, const SwEndNoteInfo& info, int listtag );
bool HasPostitFields() const;
enum class hasProperties { no, yes };
diff --git a/sw/source/filter/ww8/docxexport.cxx b/sw/source/filter/ww8/docxexport.cxx
index e84bbc48eb20..c02703184fc1 100644
--- a/sw/source/filter/ww8/docxexport.cxx
+++ b/sw/source/filter/ww8/docxexport.cxx
@@ -1220,11 +1220,11 @@ void DocxExport::WriteSettings()
// Has Footnotes
if( m_pAttrOutput->HasFootnotes())
- DocxAttributeOutput::WriteFootnoteEndnotePr( pFS, XML_footnotePr, m_rDoc.GetFootnoteInfo(), XML_footnote );
+ m_pAttrOutput->WriteFootnoteEndnotePr( pFS, XML_footnotePr, m_rDoc.GetFootnoteInfo(), XML_footnote );
// Has Endnotes
if( m_pAttrOutput->HasEndnotes())
- DocxAttributeOutput::WriteFootnoteEndnotePr( pFS, XML_endnotePr, m_rDoc.GetEndNoteInfo(), XML_endnote );
+ m_pAttrOutput->WriteFootnoteEndnotePr( pFS, XML_endnotePr, m_rDoc.GetEndNoteInfo(), XML_endnote );
// Has themeFontLang information
uno::Reference< beans::XPropertySet > xPropSet( pDocShell->GetBaseModel(), uno::UNO_QUERY_THROW );
diff --git a/sw/source/filter/ww8/wrtw8esh.cxx b/sw/source/filter/ww8/wrtw8esh.cxx
index f9e1082f9276..3e7087221db0 100644
--- a/sw/source/filter/ww8/wrtw8esh.cxx
+++ b/sw/source/filter/ww8/wrtw8esh.cxx
@@ -577,6 +577,12 @@ void WW8Export::MiserableRTLFrameFormatHack(SwTwips &rLeft, SwTwips &rRight,
if (SvxFrameDirection::Horizontal_RL_TB != m_rDoc.GetTextDirection(rFrameFormat.GetPosition()))
return;
+ if (m_rDoc.getIDocumentSettingAccess().get(DocumentSettingId::DO_NOT_MIRROR_RTL_DRAW_OBJS))
+ {
+ // Swap is handled at a layout-level, no need to compensate for it at export time.
+ return;
+ }
+
SwTwips nWidth = rRight - rLeft;
SwTwips nPageLeft, nPageRight;
SwTwips nPageSize = CurrentPageWidth(nPageLeft, nPageRight);
diff --git a/sw/source/filter/ww8/wrtww8.cxx b/sw/source/filter/ww8/wrtww8.cxx
index d79876eb5524..32581a995a9c 100644
--- a/sw/source/filter/ww8/wrtww8.cxx
+++ b/sw/source/filter/ww8/wrtww8.cxx
@@ -3515,13 +3515,11 @@ bool SwWW8Writer::InitStd97CodecUpdateMedium( ::msfilter::MSCodec_Std97& rCodec
if ( pPasswordItem && !pPasswordItem->GetValue().isEmpty() && pPasswordItem->GetValue().getLength() <= 15 )
{
// Generate random number with a seed of time as salt.
- rtlRandomPool aRandomPool = rtl_random_createPool ();
sal_uInt8 pDocId[ 16 ];
- if (rtl_random_getBytes(aRandomPool, pDocId, 16) != rtl_Random_E_None)
+ if (rtl_random_getBytes(nullptr, 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 a2d959d7d3f7..3f18c2058122 100644
--- a/sw/source/filter/ww8/ww8par.cxx
+++ b/sw/source/filter/ww8/ww8par.cxx
@@ -5195,13 +5195,6 @@ ErrCode SwWW8ImplReader::CoreLoad(WW8Glossary const *pGloss)
if( m_xWDop->nEdn )
aInfo.m_nFootnoteOffset = m_xWDop->nEdn - 1;
m_rDoc.SetEndNoteInfo( aInfo );
-
- if (m_xSBase->GetEndnoteCount() > 2)
- {
- // This compatibility flag only works in easy cases, disable it for anything non-trivial
- // for now.
- m_rDoc.getIDocumentSettingAccess().set(DocumentSettingId::CONTINUOUS_ENDNOTES, false);
- }
}
if (m_xWwFib->m_lcbPlcfhdd)
@@ -5672,13 +5665,11 @@ namespace
// in the MediaDescriptor
::msfilter::MSCodec_Std97 aCodec97;
- rtlRandomPool aRandomPool = rtl_random_createPool();
sal_uInt8 pDocId[ 16 ];
- if (rtl_random_getBytes(aRandomPool, pDocId, 16) != rtl_Random_E_None)
+ if (rtl_random_getBytes(nullptr, pDocId, 16) != rtl_Random_E_None)
{
throw uno::RuntimeException("rtl_random_getBytes failed");
}
- rtl_random_destroyPool( aRandomPool );
sal_uInt16 pStd97Pass[16] = {};
for( sal_Int32 nChar = 0; nChar < nLen; ++nChar )
diff --git a/sw/source/filter/xml/xmlexp.cxx b/sw/source/filter/xml/xmlexp.cxx
index 434eb8c07312..fa6f0d1dda9d 100644
--- a/sw/source/filter/xml/xmlexp.cxx
+++ b/sw/source/filter/xml/xmlexp.cxx
@@ -397,6 +397,7 @@ void SwXMLExport::GetConfigurationSettings( Sequence < PropertyValue >& rProps)
static const std::initializer_list<std::u16string_view> vOmitFalseValues = {
u"DoNotBreakWrappedTables",
u"AllowTextAfterFloatingTableBreak",
+ u"DoNotMirrorRtlDrawObjs",
};
SvXMLUnitConverter::convertPropertySet( rProps, xProps, &vOmitFalseValues );
diff --git a/sw/source/filter/xml/xmlimp.cxx b/sw/source/filter/xml/xmlimp.cxx
index 5074a3c4a94d..aa670c8f92af 100644
--- a/sw/source/filter/xml/xmlimp.cxx
+++ b/sw/source/filter/xml/xmlimp.cxx
@@ -1306,6 +1306,7 @@ void SwXMLImport::SetConfigurationSettings(const Sequence < PropertyValue > & aC
bool bDoNotBreakWrappedTables = false;
bool bAllowTextAfterFloatingTableBreak = false;
bool bDropCapPunctuation = false;
+ bool bDoNotMirrorRtlDrawObjs = false;
const PropertyValue* currentDatabaseDataSource = nullptr;
const PropertyValue* currentDatabaseCommand = nullptr;
@@ -1417,6 +1418,10 @@ void SwXMLImport::SetConfigurationSettings(const Sequence < PropertyValue > & aC
}
else if ( rValue.Name == "DropCapPunctuation" )
bDropCapPunctuation = true;
+ else if (rValue.Name == "DoNotMirrorRtlDrawObjs")
+ {
+ rValue.Value >>= bDoNotMirrorRtlDrawObjs;
+ }
}
catch( Exception& )
{
@@ -1589,6 +1594,11 @@ void SwXMLImport::SetConfigurationSettings(const Sequence < PropertyValue > & aC
xProps->setPropertyValue("ApplyTextAttrToEmptyLineAtEndOfParagraph", Any(false));
}
+ if (bDoNotMirrorRtlDrawObjs)
+ {
+ xProps->setPropertyValue("DoNotMirrorRtlDrawObjs", Any(true));
+ }
+
if (bDoNotBreakWrappedTables)
{
xProps->setPropertyValue("DoNotBreakWrappedTables", Any(true));
diff --git a/sw/source/ui/frmdlg/frmpage.cxx b/sw/source/ui/frmdlg/frmpage.cxx
index b3e2a873ad18..8a7ec8d4ffe0 100644
--- a/sw/source/ui/frmdlg/frmpage.cxx
+++ b/sw/source/ui/frmdlg/frmpage.cxx
@@ -2306,6 +2306,8 @@ void SwFramePage::Init(const SfxItemSet& rSet)
if (SfxItemState::SET == rSet.GetItemState(FN_KEEP_ASPECT_RATIO))
m_xFixedRatioCB->set_active(rSet.Get(FN_KEEP_ASPECT_RATIO).GetValue());
+ // see tdf#132591 and tdf#151382 for some examples of FN_KEEP_ASPECT_RATIO cases
+ m_xFixedRatioCB->save_state();
// columns
SwFormatCol aCol( rSet.Get(RES_COL) );
@@ -2364,7 +2366,6 @@ void SwFramePage::Init(const SfxItemSet& rSet)
if (rSize.GetWidthPercent() == SwFormatFrameSize::SYNCED || rSize.GetHeightPercent() == SwFormatFrameSize::SYNCED)
m_xFixedRatioCB->set_active(true);
- m_xFixedRatioCB->save_state();
if (rSize.GetWidthPercent() && rSize.GetWidthPercent() != SwFormatFrameSize::SYNCED &&
!m_xRelWidthCB->get_active())
{
diff --git a/sw/source/ui/misc/pgfnote.cxx b/sw/source/ui/misc/pgfnote.cxx
index 14eec4b21be1..8da1597882d7 100644
--- a/sw/source/ui/misc/pgfnote.cxx
+++ b/sw/source/ui/misc/pgfnote.cxx
@@ -29,6 +29,7 @@
#include <svx/pageitem.hxx>
#include <svl/eitem.hxx>
#include <editeng/ulspitem.hxx>
+#include <svl/grabbagitem.hxx>
#include <uitool.hxx>
#include <pagedesc.hxx>
#include <pgfnote.hxx>
@@ -99,13 +100,17 @@ SwFootNotePage::SwFootNotePage(weld::Container* pPage, weld::DialogController* p
, m_xMaxHeightPageBtn(m_xBuilder->weld_radio_button("maxheightpage"))
, m_xMaxHeightBtn(m_xBuilder->weld_radio_button("maxheight"))
, m_xMaxHeightEdit(m_xBuilder->weld_metric_spin_button("maxheightsb", FieldUnit::CM))
+ , m_xDistLabel(m_xBuilder->weld_label("spacetotextlabel"))
, m_xDistEdit(m_xBuilder->weld_metric_spin_button("spacetotext", FieldUnit::CM))
+ , m_xLinePosLabel(m_xBuilder->weld_label("positionlabel"))
, m_xLinePosBox(m_xBuilder->weld_combo_box("position"))
, m_xLineTypeBox(new SvtLineListBox(m_xBuilder->weld_menu_button("style")))
, m_xLineWidthEdit(m_xBuilder->weld_metric_spin_button("thickness", FieldUnit::POINT))
, m_xLineColorBox(new ColorListBox(m_xBuilder->weld_menu_button("color"),
[this]{ return GetDialogController()->getDialog(); }))
+ , m_xLineLengthLabel(m_xBuilder->weld_label("lengthlabel"))
, m_xLineLengthEdit(m_xBuilder->weld_metric_spin_button("length", FieldUnit::PERCENT))
+ , m_xLineDistLabel(m_xBuilder->weld_label("spacingtocontentslabel"))
, m_xLineDistEdit(m_xBuilder->weld_metric_spin_button("spacingtocontents", FieldUnit::CM))
{
SetExchangeSupport();
@@ -116,6 +121,30 @@ SwFootNotePage::SwFootNotePage(weld::Container* pPage, weld::DialogController* p
MeasurementSystem eSys = SvtSysLocale().GetLocaleData().getMeasurementSystemEnum();
tools::Long nHeightValue = MeasurementSystem::Metric != eSys ? 1440 : 1134;
m_xMaxHeightEdit->set_value(m_xMaxHeightEdit->normalize(nHeightValue),FieldUnit::TWIP);
+
+ bool bContinuousEndnotes = false;
+ if (const SfxGrabBagItem* pGragbagItem = rSet.GetItemIfSet(SID_ATTR_CHAR_GRABBAG))
+ {
+ auto it = pGragbagItem->GetGrabBag().find("ContinuousEndnotes");
+ if (it != pGragbagItem->GetGrabBag().end())
+ {
+ it->second >>= bContinuousEndnotes;
+ }
+ }
+
+ if (bContinuousEndnotes)
+ {
+ // These are ignored in SwFootnoteContFrame::Format() and SwFootnoteContFrame::PaintLine(),
+ // hide them.
+ m_xDistLabel->set_visible(false);
+ m_xDistEdit->set_visible(false);
+ m_xLinePosLabel->set_visible(false);
+ m_xLinePosBox->set_visible(false);
+ m_xLineLengthLabel->set_visible(false);
+ m_xLineLengthEdit->set_visible(false);
+ m_xLineDistLabel->set_visible(false);
+ m_xLineDistEdit->set_visible(false);
+ }
}
SwFootNotePage::~SwFootNotePage()
diff --git a/sw/source/ui/table/instable.cxx b/sw/source/ui/table/instable.cxx
index a5aa4cd83853..03cdadacc678 100644
--- a/sw/source/ui/table/instable.cxx
+++ b/sw/source/ui/table/instable.cxx
@@ -31,6 +31,8 @@ void SwInsTableDlg::GetValues( OUString& rName, sal_uInt16& rRow, sal_uInt16& rC
std::unique_ptr<SwTableAutoFormat>& prTAFormat )
{
SwInsertTableFlags nInsMode = SwInsertTableFlags::NONE;
+ if (comphelper::LibreOfficeKit::isActive())
+ nInsMode = SwInsertTableFlags::DefaultBorder;
rName = m_xNameEdit->get_text();
rRow = m_xRowSpinButton->get_value();
rCol = m_xColSpinButton->get_value();
@@ -43,7 +45,7 @@ void SwInsTableDlg::GetValues( OUString& rName, sal_uInt16& rRow, sal_uInt16& rC
rInsTableOpts.mnRowsToRepeat = 0;
if (!m_xDontSplitCB->get_active())
nInsMode |= SwInsertTableFlags::SplitLayout;
- if( m_xTAutoFormat )
+ if (m_xTAutoFormat && !comphelper::LibreOfficeKit::isActive())
{
prTAFormat.reset(new SwTableAutoFormat( *m_xTAutoFormat ));
rAutoName = prTAFormat->GetName();
@@ -151,8 +153,8 @@ void SwInsTableDlg::InitAutoTableFormat()
// 1 means default table style
// unfortunately when the table has a style sw/qa/uitest/writer_tests4/tdf115573.py fails
// because tables that have pre-applied style resets the style of the elements in their cells
- // when a new row is inserted and the ui test above relies on that. For now this is LOK only
- m_lbIndex = comphelper::LibreOfficeKit::isActive() ? 1 : 0;
+ // when a new row is inserted and the ui test above relies on that.
+ m_lbIndex = 0;
m_xLbFormat->select(m_lbIndex);
m_tbIndex = lbIndexToTableIndex(m_lbIndex);
diff --git a/sw/source/uibase/docvw/AnnotationWin.cxx b/sw/source/uibase/docvw/AnnotationWin.cxx
index 714c1419d2ed..426c097e9e58 100644
--- a/sw/source/uibase/docvw/AnnotationWin.cxx
+++ b/sw/source/uibase/docvw/AnnotationWin.cxx
@@ -120,9 +120,12 @@ SwAnnotationWin::SwAnnotationWin( SwEditWin& rEditWin,
}
#if !ENABLE_WASM_STRIP_ACCESSIBILITY
- mrMgr.ConnectSidebarWinToFrame( *(mrSidebarItem.maLayoutInfo.mpAnchorFrame),
- mrSidebarItem.GetFormatField(),
- *this );
+ if (rSidebarItem.maLayoutInfo.mpAnchorFrame)
+ {
+ mrMgr.ConnectSidebarWinToFrame( *(rSidebarItem.maLayoutInfo.mpAnchorFrame),
+ mrSidebarItem.GetFormatField(),
+ *this );
+ }
#endif
if (SupportsDoubleBuffering())
diff --git a/sw/source/uibase/docvw/AnnotationWin2.cxx b/sw/source/uibase/docvw/AnnotationWin2.cxx
index 6b8895f1d9d2..73c035abdaf7 100644
--- a/sw/source/uibase/docvw/AnnotationWin2.cxx
+++ b/sw/source/uibase/docvw/AnnotationWin2.cxx
@@ -1049,6 +1049,7 @@ void SwAnnotationWin::ExecuteCommand(sal_uInt16 nSlot)
case FN_POSTIT:
case FN_REPLY:
{
+ const bool bReply = nSlot == FN_REPLY;
// if this note is empty, it will be deleted once losing the focus, so no reply, but only a new note
// will be created
if (!mpOutliner->GetEditEngine().GetText().isEmpty())
@@ -1059,15 +1060,32 @@ void SwAnnotationWin::ExecuteCommand(sal_uInt16 nSlot)
if (mrMgr.HasActiveSidebarWin())
mrMgr.SetActiveSidebarWin(nullptr);
SwitchToFieldPos();
+
+ SwDocShell* pShell = mrView.GetDocShell();
+ if (bReply)
+ pShell->GetDoc()->GetIDocumentUndoRedo().StartUndo(SwUndoId::INSERT, nullptr);
+
+ // synchronous dispatch
mrView.GetViewFrame().GetDispatcher()->Execute(FN_POSTIT);
- if (nSlot == FN_REPLY)
+ if (bReply)
{
// Get newly created SwPostItField and set its paraIdParent
auto pPostItField = mrMgr.GetLatestPostItField();
pPostItField->SetParentId(GetTopReplyNote()->GetParaId());
pPostItField->SetParentPostItId(GetTopReplyNote()->GetPostItField()->GetPostItId());
+ this->GeneratePostItName();
pPostItField->SetParentName(GetTopReplyNote()->GetPostItField()->GetName());
+
+ // In this case, force generating the associated window
+ // synchronously so we can bundle its use of the registered
+ // "Answer" into the same undo group that the synchronous
+ // FN_POSTIT was put in
+ mrMgr.GetOrCreateAnnotationWindowForLatestPostItField();
+
+ SwRewriter aRewriter;
+ aRewriter.AddRule(UndoArg1, pPostItField->GetDescription());
+ pShell->GetDoc()->GetIDocumentUndoRedo().EndUndo(SwUndoId::INSERT, &aRewriter);
}
break;
}
@@ -1395,7 +1413,7 @@ void SwAnnotationWin::ChangeSidebarItem( SwSidebarItem const & rSidebarItem )
{
#if !ENABLE_WASM_STRIP_ACCESSIBILITY
const bool bAnchorChanged = mpAnchorFrame != rSidebarItem.maLayoutInfo.mpAnchorFrame;
- if ( bAnchorChanged )
+ if (bAnchorChanged && mpAnchorFrame)
{
mrMgr.DisconnectSidebarWinFromFrame( *mpAnchorFrame, *this );
}
@@ -1403,6 +1421,7 @@ void SwAnnotationWin::ChangeSidebarItem( SwSidebarItem const & rSidebarItem )
mrSidebarItem = rSidebarItem;
mpAnchorFrame = mrSidebarItem.maLayoutInfo.mpAnchorFrame;
+ assert(mpAnchorFrame);
#if !ENABLE_WASM_STRIP_ACCESSIBILITY
if (mxSidebarWinAccessible)
diff --git a/sw/source/uibase/docvw/PostItMgr.cxx b/sw/source/uibase/docvw/PostItMgr.cxx
index d9eaa7fa324a..f712188bcba2 100644
--- a/sw/source/uibase/docvw/PostItMgr.cxx
+++ b/sw/source/uibase/docvw/PostItMgr.cxx
@@ -698,6 +698,28 @@ void SwPostItMgr::PreparePageContainer()
}
}
+VclPtr<SwAnnotationWin> SwPostItMgr::GetOrCreateAnnotationWindow(SwSidebarItem& rItem)
+{
+ VclPtr<SwAnnotationWin> pPostIt = rItem.mpPostIt;
+ if (!pPostIt)
+ {
+ pPostIt = rItem.GetSidebarWindow( mpView->GetEditWin(),
+ *this );
+ pPostIt->InitControls();
+ pPostIt->SetReadonly(mbReadOnly);
+ rItem.mpPostIt = pPostIt;
+ if (mpAnswer)
+ {
+ if (pPostIt->GetPostItField()->GetParentPostItId() != 0) //do we really have another note in front of this one
+ {
+ pPostIt->InitAnswer(*mpAnswer);
+ }
+ mpAnswer.reset();
+ }
+ }
+ return rItem.mpPostIt;
+}
+
void SwPostItMgr::LayoutPostIts()
{
const bool bLoKitActive = comphelper::LibreOfficeKit::isActive();
@@ -727,24 +749,9 @@ void SwPostItMgr::LayoutPostIts()
for (auto const& pItem : pPage->mvSidebarItems)
{
- VclPtr<SwAnnotationWin> pPostIt = pItem->mpPostIt;
-
if (pItem->mbShow)
{
- if (!pPostIt)
- {
- pPostIt = pItem->GetSidebarWindow( mpView->GetEditWin(),
- *this );
- pPostIt->InitControls();
- pPostIt->SetReadonly(mbReadOnly);
- pItem->mpPostIt = pPostIt;
- if (mpAnswer)
- {
- if (pPostIt->GetPostItField()->GetParentPostItId() != 0) //do we really have another note in front of this one
- pPostIt->InitAnswer(*mpAnswer);
- mpAnswer.reset();
- }
- }
+ VclPtr<SwAnnotationWin> pPostIt = GetOrCreateAnnotationWindow(*pItem);
pPostIt->SetChangeTracking(
pItem->mLayoutStatus,
@@ -811,6 +818,7 @@ void SwPostItMgr::LayoutPostIts()
}
else // we don't want to see it
{
+ VclPtr<SwAnnotationWin> pPostIt = pItem->mpPostIt;
if (pPostIt)
pPostIt->HideNote();
}
@@ -1846,6 +1854,11 @@ SwPostItField* SwPostItMgr::GetLatestPostItField()
return static_cast<SwPostItField*>(mvPostItFields.back()->GetFormatField().GetField());
}
+sw::annotation::SwAnnotationWin* SwPostItMgr::GetOrCreateAnnotationWindowForLatestPostItField()
+{
+ return GetOrCreateAnnotationWindow(*mvPostItFields.back());
+}
+
SwAnnotationWin* SwPostItMgr::GetNextPostIt( sal_uInt16 aDirection,
SwAnnotationWin* aPostIt )
{
diff --git a/sw/source/uibase/docvw/edtwin.cxx b/sw/source/uibase/docvw/edtwin.cxx
index 24358cf5505a..178e4d631806 100644
--- a/sw/source/uibase/docvw/edtwin.cxx
+++ b/sw/source/uibase/docvw/edtwin.cxx
@@ -3112,9 +3112,12 @@ void SwEditWin::MouseButtonDown(const MouseEvent& _rMEvt)
SwTab nMouseTabCol = SwTab::COL_NONE;
const bool bTmp = !rSh.IsDrawCreate() && !m_pApplyTempl && !rSh.IsInSelect()
&& aMEvt.GetClicks() == 1 && MOUSE_LEFT == aMEvt.GetButtons();
+
if ( bTmp &&
SwTab::COL_NONE != (nMouseTabCol = rSh.WhichMouseTabCol( aDocPos ) ) &&
- !rSh.IsObjSelectable( aDocPos ) )
+ ( !rSh.IsObjSelectable( aDocPos ) ||
+ // allow resizing row height, if the image is anchored as character in the cell
+ !( SwTab::COL_VERT == nMouseTabCol || SwTab::COL_HORI == nMouseTabCol ) ) )
{
// Enhanced table selection
if ( SwTab::SEL_HORI <= nMouseTabCol && SwTab::COLSEL_VERT >= nMouseTabCol )
@@ -3983,8 +3986,11 @@ bool SwEditWin::changeMousePointer(Point const & rDocPoint)
SwWrtShell & rShell = m_rView.GetWrtShell();
SwTab nMouseTabCol;
+
if ( SwTab::COL_NONE != (nMouseTabCol = rShell.WhichMouseTabCol( rDocPoint ) ) &&
- !rShell.IsObjSelectable( rDocPoint ) )
+ ( !rShell.IsObjSelectable( rDocPoint ) ||
+ // allow resizing row height, if the image is anchored as character in the cell
+ !( SwTab::COL_VERT == nMouseTabCol || SwTab::COL_HORI == nMouseTabCol ) ) )
{
PointerStyle nPointer = PointerStyle::Null;
bool bChkTableSel = false;
diff --git a/sw/source/uibase/inc/pgfnote.hxx b/sw/source/uibase/inc/pgfnote.hxx
index c239f1ed292f..0abb09a80a9d 100644
--- a/sw/source/uibase/inc/pgfnote.hxx
+++ b/sw/source/uibase/inc/pgfnote.hxx
@@ -44,12 +44,16 @@ private:
std::unique_ptr<weld::RadioButton> m_xMaxHeightPageBtn;
std::unique_ptr<weld::RadioButton> m_xMaxHeightBtn;
std::unique_ptr<weld::MetricSpinButton> m_xMaxHeightEdit;
+ std::unique_ptr<weld::Label> m_xDistLabel;
std::unique_ptr<weld::MetricSpinButton> m_xDistEdit;
+ std::unique_ptr<weld::Label> m_xLinePosLabel;
std::unique_ptr<weld::ComboBox> m_xLinePosBox;
std::unique_ptr<SvtLineListBox> m_xLineTypeBox;
std::unique_ptr<weld::MetricSpinButton> m_xLineWidthEdit;
std::unique_ptr<ColorListBox> m_xLineColorBox;
+ std::unique_ptr<weld::Label> m_xLineLengthLabel;
std::unique_ptr<weld::MetricSpinButton> m_xLineLengthEdit;
+ std::unique_ptr<weld::Label> m_xLineDistLabel;
std::unique_ptr<weld::MetricSpinButton> m_xLineDistEdit;
DECL_LINK(HeightPage, weld::Toggleable&, void);
diff --git a/sw/source/uibase/inc/swruler.hxx b/sw/source/uibase/inc/swruler.hxx
index 6c903f9ca9a5..2dc14e98fd87 100644
--- a/sw/source/uibase/inc/swruler.hxx
+++ b/sw/source/uibase/inc/swruler.hxx
@@ -18,7 +18,6 @@ class SwViewShell;
class View;
namespace vcl { class Window; }
class SwEditWin;
-namespace tools { class JsonWriter; }
/**
* An horizontal ruler with a control for comment panel visibility for Writer.
@@ -43,7 +42,6 @@ public:
* \param rRect ignored
*/
virtual void Paint( vcl::RenderContext& rRenderContext, const tools::Rectangle& rRect ) override;
- void CreateJsonNotification(tools::JsonWriter& rJsonWriter);
private:
SwViewShell * mpViewShell; //< Shell to check if there is any comments on doc and their visibility
@@ -53,7 +51,6 @@ private:
int mnFadeRate; //< From 0 to 100. 0 means not highlighted.
ScopedVclPtr<VirtualDevice> maVirDev; //< VirtualDevice of this window. Just for convenience.
- void NotifyKit();
/**
* Callback function to handle a mouse button down event.
*
diff --git a/sw/source/uibase/misc/swruler.cxx b/sw/source/uibase/misc/swruler.cxx
index 0ccdec2f46a5..ac2e0a89ea78 100644
--- a/sw/source/uibase/misc/swruler.cxx
+++ b/sw/source/uibase/misc/swruler.cxx
@@ -17,15 +17,12 @@
#include <view.hxx>
#include <cmdid.h>
#include <sfx2/request.hxx>
-#include <tools/UnitConversion.hxx>
#include <vcl/commandevent.hxx>
#include <vcl/event.hxx>
#include <vcl/window.hxx>
#include <vcl/settings.hxx>
-#include <tools/json_writer.hxx>
#include <strings.hrc>
#include <comphelper/lok.hxx>
-#include <LibreOfficeKit/LibreOfficeKitEnums.h>
#define CONTROL_BORDER_WIDTH 1
@@ -233,69 +230,12 @@ void SwCommentRuler::MouseButtonDown(const MouseEvent& rMEvt)
Invalidate();
}
-void SwCommentRuler::CreateJsonNotification(tools::JsonWriter& rJsonWriter)
-{
- // Note that GetMargin1(), GetMargin2(), GetNullOffset(), and GetPageOffset() return values in
- // pixels. Not twips. So "converting" the returned values with convertTwipToMm100() is quite
- // wrong. (Also, even if the return values actually were in twips, it is questionable why we
- // would want to pass them in mm100, as all other length values in the LOKit protocol apparently
- // are in twips.)
-
- // Anyway, as the consuming code in Online mostly seems to work anyway, it is likely that it
- // would work as well even if the values in pixels were passed without a bogus "conversion" to
- // mm100. But let's keep this as is for now.
-
- // Also note that in desktop LibreOffice, these pixel values for the ruler of course change as
- // one changes the zoom level. (Can be seen if one temporarily modifies the NotifyKit() function
- // below to call this CreateJsonNotification() function and print its result in all cases even
- // without LibreOfficeKit::isActive().) But in both web-based Online and in the iOS app, the
- // zoom level from the point of view of this code here apparently does not change even if one
- // zooms from the Online code's point of view.
- rJsonWriter.put("margin1", convertTwipToMm100(GetMargin1()));
- rJsonWriter.put("margin2", convertTwipToMm100(GetMargin2()));
- rJsonWriter.put("leftOffset", convertTwipToMm100(GetNullOffset()));
- rJsonWriter.put("pageOffset", convertTwipToMm100(GetPageOffset()));
-
- // GetPageWidth() on the other hand does return a value in twips.
- // So here convertTwipToMm100() really does produce actual mm100. Fun.
- rJsonWriter.put("pageWidth", convertTwipToMm100(GetPageWidth()));
-
- {
- auto tabsNode = rJsonWriter.startNode("tabs");
-
- // The RulerTab array elements that GetTabs() returns have their nPos field in twips. So these
- // too are actual mm100.
- for (auto const& tab : GetTabs())
- {
- auto tabNode = rJsonWriter.startNode("");
- rJsonWriter.put("position", convertTwipToMm100(tab.nPos));
- rJsonWriter.put("style", tab.nStyle);
- }
- }
-
- RulerUnitData aUnitData = GetCurrentRulerUnit();
- rJsonWriter.put("unit", aUnitData.aUnitStr);
-}
-
-void SwCommentRuler::NotifyKit()
-{
- if (!comphelper::LibreOfficeKit::isActive())
- return;
-
- tools::JsonWriter aJsonWriter;
- CreateJsonNotification(aJsonWriter);
- OString pJsonData = aJsonWriter.finishAndGetAsOString();
- mpViewShell->GetSfxViewShell()->libreOfficeKitViewCallback(LOK_CALLBACK_RULER_UPDATE,
- pJsonData);
-}
-
void SwCommentRuler::Update()
{
tools::Rectangle aPreviousControlRect = GetCommentControlRegion();
SvxRuler::Update();
if (aPreviousControlRect != GetCommentControlRegion())
Invalidate();
- NotifyKit();
}
void SwCommentRuler::UpdateCommentHelpText()
diff --git a/sw/source/uibase/shells/drwbassh.cxx b/sw/source/uibase/shells/drwbassh.cxx
index d5eec2132093..c98e97eb7aba 100644
--- a/sw/source/uibase/shells/drwbassh.cxx
+++ b/sw/source/uibase/shells/drwbassh.cxx
@@ -60,6 +60,8 @@
#include <fmtfollowtextflow.hxx>
#include <textboxhelper.hxx>
#include <svx/diagram/IDiagramHelper.hxx>
+#include <svl/grabbagitem.hxx>
+#include <IDocumentSettingAccess.hxx>
using namespace ::com::sun::star;
using namespace css::beans;
@@ -235,6 +237,14 @@ void SwDrawBaseShell::Execute(SfxRequest const &rReq)
aSet.Put(SfxBoolItem(SID_ATTR_TRANSFORM_HORI_MIRROR, aHOrient.IsPosToggle()));
aSet.Put(SfxInt32Item(SID_ATTR_TRANSFORM_HORI_POSITION, aHOrient.GetPos()));
+ const IDocumentSettingAccess& rIDSA = pFrameFormat->getIDocumentSettingAccess();
+ if (rIDSA.get(DocumentSettingId::DO_NOT_MIRROR_RTL_DRAW_OBJS))
+ {
+ SfxGrabBagItem aItem(RES_CHRATR_GRABBAG);
+ aItem.GetGrabBag()["DoNotMirrorRtlDrawObjs"] <<= true;
+ aSet.Put(aItem);
+ }
+
aSet.Put(SfxUInt16Item(SID_HTML_MODE, nHtmlMode));
pDlg->SetInputSet( &aSet );
@@ -584,29 +594,38 @@ void SwDrawBaseShell::Execute(SfxRequest const &rReq)
if(1 == pSdrView->GetMarkedObjectCount())
{
// #i68101#
- SdrObject* pSelected = pSdrView->GetMarkedObjectByIndex(0);
+ rtl::Reference<SdrObject> pSelected = pSdrView->GetMarkedObjectByIndex(0);
OSL_ENSURE(pSelected, "DrawViewShell::FuTemp03: nMarkCount, but no object (!)");
- OUString aName(pSelected->GetName());
+ OUString aOrigName(pSelected->GetName());
SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
- ScopedVclPtr<AbstractSvxObjectNameDialog> pDlg(pFact->CreateSvxObjectNameDialog(GetView().GetFrameWeld(), aName));
+ VclPtr<AbstractSvxObjectNameDialog> pDlg(pFact->CreateSvxObjectNameDialog(GetView().GetFrameWeld(), aOrigName));
pDlg->SetCheckNameHdl(LINK(this, SwDrawBaseShell, CheckGroupShapeNameHdl));
- if(RET_OK == pDlg->Execute())
- {
- const OUString aOrigName = aName;
- pDlg->GetName(aName);
- pSelected->SetName(aName);
- pSh->SetModified();
-
- // update accessibility sidebar object name if we modify the object name on the navigator bar
- if (!aName.isEmpty() && aOrigName != aName)
+ pDlg->StartExecuteAsync(
+ [pDlg, pSelected, pSh, aOrigName] (sal_Int32 nResult)->void
{
- if (SwNode* pSwNode = FindFrameFormat(pSelected)->GetAnchor().GetAnchorNode())
- pSwNode->resetAndQueueAccessibilityCheck(true);
+ if (nResult == RET_OK)
+ {
+ OUString aNewName = pDlg->GetName();
+ pSelected->SetName(aNewName);
+ pSh->SetModified();
+
+ // update accessibility sidebar object name if we modify the object name on the navigator bar
+ if (!aNewName.isEmpty() && aOrigName != aNewName)
+ {
+ auto pFrameFormat = FindFrameFormat(pSelected.get());
+ if (pFrameFormat)
+ {
+ if (SwNode* pSwNode = pFrameFormat->GetAnchor().GetAnchorNode())
+ pSwNode->resetAndQueueAccessibilityCheck(true);
+ }
+ }
+ }
+ pDlg->disposeOnce();
}
- }
+ );
}
break;
@@ -619,28 +638,38 @@ void SwDrawBaseShell::Execute(SfxRequest const &rReq)
if(1 == pSdrView->GetMarkedObjectCount())
{
- SdrObject* pSelected = pSdrView->GetMarkedObjectByIndex(0);
+ rtl::Reference<SdrObject> pSelected = pSdrView->GetMarkedObjectByIndex(0);
OSL_ENSURE(pSelected, "DrawViewShell::FuTemp03: nMarkCount, but no object (!)");
OUString aTitle(pSelected->GetTitle());
OUString aDescription(pSelected->GetDescription());
bool isDecorative(pSelected->IsDecorative());
SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
- ScopedVclPtr<AbstractSvxObjectTitleDescDialog> pDlg(pFact->CreateSvxObjectTitleDescDialog(GetView().GetFrameWeld(),
+ VclPtr<AbstractSvxObjectTitleDescDialog> pDlg(pFact->CreateSvxObjectTitleDescDialog(GetView().GetFrameWeld(),
aTitle, aDescription, isDecorative));
- if(RET_OK == pDlg->Execute())
- {
- pDlg->GetTitle(aTitle);
- pDlg->GetDescription(aDescription);
- pDlg->IsDecorative(isDecorative);
+ pDlg->StartExecuteAsync(
+ [pDlg, pSelected, pSh] (sal_Int32 nResult)->void
+ {
+ if (nResult == RET_OK)
+ {
+ OUString aNewTitle;
+ OUString aNewDescription;
+ bool newIsDecorative;
- pSelected->SetTitle(aTitle);
- pSelected->SetDescription(aDescription);
- pSelected->SetDecorative(isDecorative);
+ pDlg->GetTitle(aNewTitle);
+ pDlg->GetDescription(aNewDescription);
+ pDlg->IsDecorative(newIsDecorative);
- pSh->SetModified();
- }
+ pSelected->SetTitle(aNewTitle);
+ pSelected->SetDescription(aNewDescription);
+ pSelected->SetDecorative(newIsDecorative);
+
+ pSh->SetModified();
+ }
+ pDlg->disposeOnce();
+ }
+ );
}
break;
@@ -717,8 +746,7 @@ IMPL_LINK( SwDrawBaseShell, CheckGroupShapeNameHdl, AbstractSvxObjectNameDialog&
OSL_ENSURE(rMarkList.GetMarkCount() == 1, "wrong draw selection");
SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj();
const OUString sCurrentName = pObj->GetName();
- OUString sNewName;
- rNameDialog.GetName(sNewName);
+ OUString sNewName = rNameDialog.GetName();
bool bRet = false;
if (sNewName.isEmpty() || sCurrentName == sNewName)
bRet = true;
diff --git a/sw/source/uibase/shells/frmsh.cxx b/sw/source/uibase/shells/frmsh.cxx
index ac5ee0d80835..fc41058cd62e 100644
--- a/sw/source/uibase/shells/frmsh.cxx
+++ b/sw/source/uibase/shells/frmsh.cxx
@@ -675,14 +675,17 @@ void SwFrameShell::Execute(SfxRequest &rReq)
{
OUString aName(rSh.GetFlyName());
SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
- ScopedVclPtr<AbstractSvxObjectNameDialog> pDlg(
+ VclPtr<AbstractSvxObjectNameDialog> pDlg(
pFact->CreateSvxObjectNameDialog(GetView().GetFrameWeld(), aName));
- if ( pDlg->Execute() == RET_OK )
- {
- pDlg->GetName(aName);
- rSh.SetFlyName(aName);
- }
+ pDlg->StartExecuteAsync(
+ [this, pDlg] (sal_Int32 nResult)->void
+ {
+ if (nResult == RET_OK)
+ GetShell().SetFlyName(pDlg->GetName());
+ pDlg->disposeOnce();
+ }
+ );
}
}
break;
diff --git a/sw/source/uibase/sidebar/A11yCheckIssuesPanel.cxx b/sw/source/uibase/sidebar/A11yCheckIssuesPanel.cxx
index a1907c9b6306..129b37713fe8 100644
--- a/sw/source/uibase/sidebar/A11yCheckIssuesPanel.cxx
+++ b/sw/source/uibase/sidebar/A11yCheckIssuesPanel.cxx
@@ -19,9 +19,13 @@
#include <officecfg/Office/Common.hxx>
#include <sfx2/bindings.hxx>
+#include <sfx2/viewsh.hxx>
#include <sfx2/AccessibilityIssue.hxx>
#include <unotools/configmgr.hxx>
+#include <vcl/ptrstyle.hxx>
#include <vcl/svapp.hxx>
+#include <o3tl/enumrange.hxx>
+#include <comphelper/lok.hxx>
#include "A11yCheckIssuesPanel.hxx"
@@ -80,13 +84,15 @@ AccessibilityCheckEntry::AccessibilityCheckEntry(
IMPL_LINK_NOARG(AccessibilityCheckEntry, GotoButtonClicked, weld::LinkButton&, bool)
{
- m_pAccessibilityIssue->gotoIssue();
+ if (m_pAccessibilityIssue)
+ m_pAccessibilityIssue->gotoIssue();
return true;
}
IMPL_LINK_NOARG(AccessibilityCheckEntry, FixButtonClicked, weld::Button&, void)
{
- m_pAccessibilityIssue->quickFixIssue();
+ if (m_pAccessibilityIssue)
+ m_pAccessibilityIssue->quickFixIssue();
}
std::unique_ptr<PanelLayout> A11yCheckIssuesPanel::Create(weld::Widget* pParent,
@@ -100,32 +106,40 @@ std::unique_ptr<PanelLayout> A11yCheckIssuesPanel::Create(weld::Widget* pParent,
A11yCheckIssuesPanel::A11yCheckIssuesPanel(weld::Widget* pParent, SfxBindings* pBindings)
: PanelLayout(pParent, "A11yCheckIssuesPanel", "modules/swriter/ui/a11ycheckissuespanel.ui")
- , m_xExpanderDocument(m_xBuilder->weld_expander("expand_document"))
- , m_xExpanderStyles(m_xBuilder->weld_expander("expand_styles"))
- , m_xExpanderLinked(m_xBuilder->weld_expander("expand_linked"))
- , m_xExpanderNoAlt(m_xBuilder->weld_expander("expand_no_alt"))
- , m_xExpanderTable(m_xBuilder->weld_expander("expand_table"))
- , m_xExpanderFormatting(m_xBuilder->weld_expander("expand_formatting"))
- , m_xExpanderHyperlink(m_xBuilder->weld_expander("expand_hyperlink"))
- , m_xExpanderFakes(m_xBuilder->weld_expander("expand_fakes"))
- , m_xExpanderNumbering(m_xBuilder->weld_expander("expand_numbering"))
- , m_xExpanderOther(m_xBuilder->weld_expander("expand_other"))
- , m_xBoxDocument(m_xBuilder->weld_box("box_document"))
- , m_xBoxStyles(m_xBuilder->weld_box("box_styles"))
- , m_xBoxLinked(m_xBuilder->weld_box("box_linked"))
- , m_xBoxNoAlt(m_xBuilder->weld_box("box_no_alt"))
- , m_xBoxTable(m_xBuilder->weld_box("box_table"))
- , m_xBoxFormatting(m_xBuilder->weld_box("box_formatting"))
- , m_xBoxHyperlink(m_xBuilder->weld_box("box_hyperlink"))
- , m_xBoxFakes(m_xBuilder->weld_box("box_fakes"))
- , m_xBoxNumbering(m_xBuilder->weld_box("box_numbering"))
- , m_xBoxOther(m_xBuilder->weld_box("box_other"))
+ , mxAccessibilityBox(m_xBuilder->weld_box("accessibilityCheckBox"))
+ , mxUpdateBox(m_xBuilder->weld_box("updateBox"))
+ , mxUpdateLinkButton(m_xBuilder->weld_link_button("updateLinkButton"))
, mpBindings(pBindings)
, mpDoc(nullptr)
, maA11yCheckController(FN_STAT_ACCESSIBILITY_CHECK, *pBindings, *this)
, mnIssueCount(0)
, mbAutomaticCheckEnabled(false)
{
+ m_xExpanders[0] = m_xBuilder->weld_expander("expand_document");
+ m_xExpanders[1] = m_xBuilder->weld_expander("expand_styles");
+ m_xExpanders[2] = m_xBuilder->weld_expander("expand_linked");
+ m_xExpanders[3] = m_xBuilder->weld_expander("expand_no_alt");
+ m_xExpanders[4] = m_xBuilder->weld_expander("expand_table");
+ m_xExpanders[5] = m_xBuilder->weld_expander("expand_formatting");
+ m_xExpanders[6] = m_xBuilder->weld_expander("expand_hyperlink");
+ m_xExpanders[7] = m_xBuilder->weld_expander("expand_fakes");
+ m_xExpanders[8] = m_xBuilder->weld_expander("expand_numbering");
+ m_xExpanders[9] = m_xBuilder->weld_expander("expand_other");
+
+ m_xBoxes[0] = m_xBuilder->weld_box("box_document");
+ m_xBoxes[1] = m_xBuilder->weld_box("box_styles");
+ m_xBoxes[2] = m_xBuilder->weld_box("box_linked");
+ m_xBoxes[3] = m_xBuilder->weld_box("box_no_alt");
+ m_xBoxes[4] = m_xBuilder->weld_box("box_table");
+ m_xBoxes[5] = m_xBuilder->weld_box("box_formatting");
+ m_xBoxes[6] = m_xBuilder->weld_box("box_hyperlink");
+ m_xBoxes[7] = m_xBuilder->weld_box("box_fakes");
+ m_xBoxes[8] = m_xBuilder->weld_box("box_numbering");
+ m_xBoxes[9] = m_xBuilder->weld_box("box_other");
+
+ mxUpdateLinkButton->connect_activate_link(
+ LINK(this, A11yCheckIssuesPanel, UpdateLinkButtonClicked));
+
SwDocShell* pDocSh = dynamic_cast<SwDocShell*>(SfxObjectShell::Current());
if (!pDocSh)
return;
@@ -144,9 +158,31 @@ A11yCheckIssuesPanel::A11yCheckIssuesPanel(weld::Widget* pParent, SfxBindings* p
mpDoc = pDocSh->GetDoc();
- populateIssues();
+ // If LOKit is enabled, then enable the update button and don't run the accessibility check.
+ // In desktop don't show the update button and schedule to run the accessibility check async
+ if (comphelper::LibreOfficeKit::isActive())
+ {
+ mxAccessibilityBox->hide();
+ mxUpdateBox->show();
+ }
+ else
+ {
+ mxAccessibilityBox->show();
+ mxUpdateBox->hide();
+ Application::PostUserEvent(LINK(this, A11yCheckIssuesPanel, PopulateIssuesHdl));
+ }
}
+IMPL_LINK_NOARG(A11yCheckIssuesPanel, UpdateLinkButtonClicked, weld::LinkButton&, bool)
+{
+ mxAccessibilityBox->show();
+ mxUpdateBox->hide();
+ Application::PostUserEvent(LINK(this, A11yCheckIssuesPanel, PopulateIssuesHdl));
+ return true;
+}
+
+IMPL_LINK_NOARG(A11yCheckIssuesPanel, PopulateIssuesHdl, void*, void) { populateIssues(); }
+
void A11yCheckIssuesPanel::ImplDestroy()
{
// Restore state when this panel is no longer used
@@ -158,93 +194,55 @@ void A11yCheckIssuesPanel::ImplDestroy()
batch->commit();
mpBindings->Invalidate(SID_ACCESSIBILITY_CHECK_ONLINE);
}
- m_xExpanderDocument.reset();
- m_xExpanderStyles.reset();
- m_xExpanderLinked.reset();
- m_xExpanderNoAlt.reset();
- m_xExpanderTable.reset();
- m_xExpanderFormatting.reset();
- m_xExpanderHyperlink.reset();
- m_xExpanderFakes.reset();
- m_xExpanderNumbering.reset();
- m_xExpanderOther.reset();
- m_xBoxDocument.reset();
- m_xBoxStyles.reset();
- m_xBoxLinked.reset();
- m_xBoxNoAlt.reset();
- m_xBoxTable.reset();
- m_xBoxFormatting.reset();
- m_xBoxHyperlink.reset();
- m_xBoxFakes.reset();
- m_xBoxNumbering.reset();
- m_xBoxOther.reset();
+
+ for (auto& xExapnder : m_xExpanders)
+ xExapnder.reset();
+
+ for (auto& xBox : m_xBoxes)
+ xBox.reset();
}
A11yCheckIssuesPanel::~A11yCheckIssuesPanel() { suppress_fun_call_w_exception(ImplDestroy()); }
-void A11yCheckIssuesPanel::removeOldWidgets()
+void A11yCheckIssuesPanel::removeAllEntries()
{
- for (auto const& xEntry : m_aDocumentEntries)
- m_xBoxDocument->move(xEntry->get_widget(), nullptr);
- m_xExpanderDocument->set_visible(false);
-
- for (auto const& xEntry : m_aStylesEntries)
- m_xBoxStyles->move(xEntry->get_widget(), nullptr);
- m_xExpanderStyles->set_visible(false);
-
- for (auto const& xEntry : m_aLinkedEntries)
- m_xBoxLinked->move(xEntry->get_widget(), nullptr);
- m_xExpanderLinked->set_visible(false);
-
- for (auto const& xEntry : m_aNoAltEntries)
- m_xBoxNoAlt->move(xEntry->get_widget(), nullptr);
- m_xExpanderNoAlt->set_visible(false);
-
- for (auto const& xEntry : m_aTableEntries)
- m_xBoxTable->move(xEntry->get_widget(), nullptr);
- m_xExpanderTable->set_visible(false);
-
- for (auto const& xEntry : m_aFormattingEntries)
- m_xBoxFormatting->move(xEntry->get_widget(), nullptr);
- m_xExpanderFormatting->set_visible(false);
-
- for (auto const& xEntry : m_aHyperlinkEntries)
- m_xBoxHyperlink->move(xEntry->get_widget(), nullptr);
- m_xExpanderHyperlink->set_visible(false);
-
- for (auto const& xEntry : m_aFakesEntries)
- m_xBoxFakes->move(xEntry->get_widget(), nullptr);
- m_xExpanderFakes->set_visible(false);
-
- for (auto const& xEntry : m_aNumberingEntries)
- m_xBoxNumbering->move(xEntry->get_widget(), nullptr);
- m_xExpanderNumbering->set_visible(false);
+ for (auto eGroup : o3tl::enumrange<AccessibilityCheckGroups>())
+ {
+ auto nGroupIndex = size_t(eGroup);
+ for (auto const& xEntry : m_aEntries[nGroupIndex])
+ m_xBoxes[nGroupIndex]->move(xEntry->get_widget(), nullptr);
+ }
+}
- for (auto const& xEntry : m_aOtherEntries)
- m_xBoxOther->move(xEntry->get_widget(), nullptr);
- m_xExpanderOther->set_visible(false);
+void A11yCheckIssuesPanel::addEntryForGroup(AccessibilityCheckGroups eGroup,
+ std::vector<sal_Int32>& rIndices,
+ std::shared_ptr<sfx::AccessibilityIssue> const& pIssue)
+{
+ auto nGroupIndex = size_t(eGroup);
+ auto xEntry = std::make_unique<AccessibilityCheckEntry>(m_xBoxes[nGroupIndex].get(), pIssue);
+ m_xBoxes[nGroupIndex]->reorder_child(xEntry->get_widget(), rIndices[nGroupIndex]++);
+ m_aEntries[nGroupIndex].push_back(std::move(xEntry));
}
void A11yCheckIssuesPanel::populateIssues()
{
- if (!mpDoc)
+ if (!mpDoc || !mxAccessibilityBox->is_visible())
return;
+
+ SfxViewShell* pViewShell = SfxViewShell::Current();
+ auto* pWindow = pViewShell ? pViewShell->GetWindow() : nullptr;
+
+ if (pWindow)
+ pWindow->SetPointer(PointerStyle::Wait);
+
sw::AccessibilityCheck aCheck(mpDoc);
aCheck.check();
m_aIssueCollection = aCheck.getIssueCollection();
- removeOldWidgets();
-
- sal_Int32 iDocument = 0;
- sal_Int32 iStyles = 0;
- sal_Int32 iLinked = 0;
- sal_Int32 iNoAlt = 0;
- sal_Int32 iTable = 0;
- sal_Int32 iFormatting = 0;
- sal_Int32 iHyperlink = 0;
- sal_Int32 iFakes = 0;
- sal_Int32 iNumbering = 0;
- sal_Int32 iOther = 0;
+ removeAllEntries();
+
+ std::vector<sal_Int32> nIndices(10, 0);
+
for (std::shared_ptr<sfx::AccessibilityIssue> const& pIssue : m_aIssueCollection.getIssues())
{
switch (pIssue->m_eIssueID)
@@ -253,91 +251,57 @@ void A11yCheckIssuesPanel::populateIssues()
case sfx::AccessibilityIssueID::DOCUMENT_LANGUAGE:
case sfx::AccessibilityIssueID::DOCUMENT_BACKGROUND:
{
- auto xEntry
- = std::make_unique<AccessibilityCheckEntry>(m_xBoxDocument.get(), pIssue);
- m_xBoxDocument->reorder_child(xEntry->get_widget(), iDocument++);
- m_xExpanderDocument->set_visible(true);
- m_aDocumentEntries.push_back(std::move(xEntry));
+ addEntryForGroup(AccessibilityCheckGroups::Document, nIndices, pIssue);
}
break;
case sfx::AccessibilityIssueID::STYLE_LANGUAGE:
{
- auto xEntry = std::make_unique<AccessibilityCheckEntry>(m_xBoxStyles.get(), pIssue);
- m_xBoxStyles->reorder_child(xEntry->get_widget(), iStyles++);
- m_xExpanderStyles->set_visible(true);
- m_aStylesEntries.push_back(std::move(xEntry));
+ addEntryForGroup(AccessibilityCheckGroups::Styles, nIndices, pIssue);
}
break;
case sfx::AccessibilityIssueID::LINKED_GRAPHIC:
{
- auto xEntry = std::make_unique<AccessibilityCheckEntry>(m_xBoxLinked.get(), pIssue);
- m_xBoxLinked->reorder_child(xEntry->get_widget(), iLinked++);
- m_xExpanderLinked->set_visible(true);
- m_aLinkedEntries.push_back(std::move(xEntry));
+ addEntryForGroup(AccessibilityCheckGroups::Linked, nIndices, pIssue);
}
break;
case sfx::AccessibilityIssueID::NO_ALT_OLE:
case sfx::AccessibilityIssueID::NO_ALT_GRAPHIC:
case sfx::AccessibilityIssueID::NO_ALT_SHAPE:
{
- auto xEntry = std::make_unique<AccessibilityCheckEntry>(m_xBoxNoAlt.get(), pIssue);
- m_xBoxNoAlt->reorder_child(xEntry->get_widget(), iNoAlt++);
- m_xExpanderNoAlt->set_visible(true);
- m_aNoAltEntries.push_back(std::move(xEntry));
+ addEntryForGroup(AccessibilityCheckGroups::NoAlt, nIndices, pIssue);
}
break;
case sfx::AccessibilityIssueID::TABLE_MERGE_SPLIT:
{
- auto xEntry = std::make_unique<AccessibilityCheckEntry>(m_xBoxTable.get(), pIssue);
- m_xBoxTable->reorder_child(xEntry->get_widget(), iTable++);
- m_xExpanderTable->set_visible(true);
- m_aTableEntries.push_back(std::move(xEntry));
+ addEntryForGroup(AccessibilityCheckGroups::Table, nIndices, pIssue);
}
break;
case sfx::AccessibilityIssueID::TEXT_FORMATTING:
case sfx::AccessibilityIssueID::TABLE_FORMATTING:
{
- auto xEntry
- = std::make_unique<AccessibilityCheckEntry>(m_xBoxFormatting.get(), pIssue);
- m_xBoxFormatting->reorder_child(xEntry->get_widget(), iFormatting++);
- m_xExpanderFormatting->set_visible(true);
- m_aFormattingEntries.push_back(std::move(xEntry));
+ addEntryForGroup(AccessibilityCheckGroups::Formatting, nIndices, pIssue);
}
break;
case sfx::AccessibilityIssueID::HYPERLINK_IS_TEXT:
case sfx::AccessibilityIssueID::HYPERLINK_SHORT:
{
- auto xEntry
- = std::make_unique<AccessibilityCheckEntry>(m_xBoxHyperlink.get(), pIssue);
- m_xBoxHyperlink->reorder_child(xEntry->get_widget(), iHyperlink++);
- m_xExpanderHyperlink->set_visible(true);
- m_aHyperlinkEntries.push_back(std::move(xEntry));
+ addEntryForGroup(AccessibilityCheckGroups::Hyperlink, nIndices, pIssue);
}
break;
case sfx::AccessibilityIssueID::FAKE_FOOTNOTE:
case sfx::AccessibilityIssueID::FAKE_CAPTION:
{
- auto xEntry = std::make_unique<AccessibilityCheckEntry>(m_xBoxFakes.get(), pIssue);
- m_xBoxFakes->reorder_child(xEntry->get_widget(), iFakes++);
- m_xExpanderFakes->set_visible(true);
- m_aFakesEntries.push_back(std::move(xEntry));
+ addEntryForGroup(AccessibilityCheckGroups::Fakes, nIndices, pIssue);
}
break;
case sfx::AccessibilityIssueID::MANUAL_NUMBERING:
{
- auto xEntry
- = std::make_unique<AccessibilityCheckEntry>(m_xBoxNumbering.get(), pIssue);
- m_xBoxNumbering->reorder_child(xEntry->get_widget(), iNumbering++);
- m_xExpanderNumbering->set_visible(true);
- m_aNumberingEntries.push_back(std::move(xEntry));
+ addEntryForGroup(AccessibilityCheckGroups::Numbering, nIndices, pIssue);
}
break;
case sfx::AccessibilityIssueID::UNSPECIFIED:
{
- auto xEntry = std::make_unique<AccessibilityCheckEntry>(m_xBoxOther.get(), pIssue);
- m_xBoxOther->reorder_child(xEntry->get_widget(), iOther++);
- m_xExpanderOther->set_visible(true);
- m_aOtherEntries.push_back(std::move(xEntry));
+ addEntryForGroup(AccessibilityCheckGroups::Other, nIndices, pIssue);
}
break;
default:
@@ -348,6 +312,18 @@ void A11yCheckIssuesPanel::populateIssues()
break;
};
}
+ size_t nGroupIndex = 0;
+ for (sal_Int32 nIndex : nIndices)
+ {
+ if (nIndex > 0)
+ m_xExpanders[nGroupIndex]->show();
+ else
+ m_xExpanders[nGroupIndex]->hide();
+ nGroupIndex++;
+ }
+
+ if (pWindow)
+ pWindow->SetPointer(PointerStyle::Arrow);
}
void A11yCheckIssuesPanel::NotifyItemUpdate(const sal_uInt16 nSid, const SfxItemState /* eState */,
diff --git a/sw/source/uibase/sidebar/A11yCheckIssuesPanel.hxx b/sw/source/uibase/sidebar/A11yCheckIssuesPanel.hxx
index 7f569e16ef85..ef8d4da0e186 100644
--- a/sw/source/uibase/sidebar/A11yCheckIssuesPanel.hxx
+++ b/sw/source/uibase/sidebar/A11yCheckIssuesPanel.hxx
@@ -31,7 +31,7 @@ private:
std::unique_ptr<weld::LinkButton> m_xGotoButton;
std::unique_ptr<weld::Button> m_xFixButton;
- std::shared_ptr<sfx::AccessibilityIssue> const& m_pAccessibilityIssue;
+ std::shared_ptr<sfx::AccessibilityIssue> m_pAccessibilityIssue;
public:
AccessibilityCheckEntry(weld::Container* pParent,
@@ -43,6 +43,21 @@ public:
DECL_LINK(FixButtonClicked, weld::Button&, void);
};
+enum class AccessibilityCheckGroups : size_t
+{
+ Document = 0,
+ Styles = 1,
+ Linked = 2,
+ NoAlt = 3,
+ Table = 4,
+ Formatting = 5,
+ Hyperlink = 6,
+ Fakes = 7,
+ Numbering = 8,
+ Other = 9,
+ LAST = Other
+};
+
class A11yCheckIssuesPanel : public PanelLayout,
public ::sfx2::sidebar::ControllerItem::ItemUpdateReceiverInterface
{
@@ -60,40 +75,23 @@ public:
virtual ~A11yCheckIssuesPanel() override;
private:
- std::vector<std::unique_ptr<AccessibilityCheckEntry>> m_aDocumentEntries;
- std::vector<std::unique_ptr<AccessibilityCheckEntry>> m_aStylesEntries;
- std::vector<std::unique_ptr<AccessibilityCheckEntry>> m_aLinkedEntries;
- std::vector<std::unique_ptr<AccessibilityCheckEntry>> m_aNoAltEntries;
- std::vector<std::unique_ptr<AccessibilityCheckEntry>> m_aTableEntries;
- std::vector<std::unique_ptr<AccessibilityCheckEntry>> m_aFormattingEntries;
- std::vector<std::unique_ptr<AccessibilityCheckEntry>> m_aHyperlinkEntries;
- std::vector<std::unique_ptr<AccessibilityCheckEntry>> m_aFakesEntries;
- std::vector<std::unique_ptr<AccessibilityCheckEntry>> m_aNumberingEntries;
- std::vector<std::unique_ptr<AccessibilityCheckEntry>> m_aOtherEntries;
- std::unique_ptr<weld::Expander> m_xExpanderDocument;
- std::unique_ptr<weld::Expander> m_xExpanderStyles;
- std::unique_ptr<weld::Expander> m_xExpanderLinked;
- std::unique_ptr<weld::Expander> m_xExpanderNoAlt;
- std::unique_ptr<weld::Expander> m_xExpanderTable;
- std::unique_ptr<weld::Expander> m_xExpanderFormatting;
- std::unique_ptr<weld::Expander> m_xExpanderHyperlink;
- std::unique_ptr<weld::Expander> m_xExpanderFakes;
- std::unique_ptr<weld::Expander> m_xExpanderNumbering;
- std::unique_ptr<weld::Expander> m_xExpanderOther;
- std::unique_ptr<weld::Box> m_xBoxDocument;
- std::unique_ptr<weld::Box> m_xBoxStyles;
- std::unique_ptr<weld::Box> m_xBoxLinked;
- std::unique_ptr<weld::Box> m_xBoxNoAlt;
- std::unique_ptr<weld::Box> m_xBoxTable;
- std::unique_ptr<weld::Box> m_xBoxFormatting;
- std::unique_ptr<weld::Box> m_xBoxHyperlink;
- std::unique_ptr<weld::Box> m_xBoxFakes;
- std::unique_ptr<weld::Box> m_xBoxNumbering;
- std::unique_ptr<weld::Box> m_xBoxOther;
+ std::array<std::vector<std::unique_ptr<AccessibilityCheckEntry>>, 10> m_aEntries;
+ std::array<std::unique_ptr<weld::Expander>, 10> m_xExpanders;
+ std::array<std::unique_ptr<weld::Box>, 10> m_xBoxes;
+ std::unique_ptr<weld::Box> mxAccessibilityBox;
+ std::unique_ptr<weld::Box> mxUpdateBox;
+ std::unique_ptr<weld::LinkButton> mxUpdateLinkButton;
+
sfx::AccessibilityIssueCollection m_aIssueCollection;
- void removeOldWidgets();
+ void removeAllEntries();
void populateIssues();
+ DECL_LINK(UpdateLinkButtonClicked, weld::LinkButton&, bool);
+ DECL_LINK(PopulateIssuesHdl, void*, void);
+
+ void addEntryForGroup(AccessibilityCheckGroups eGroup, std::vector<sal_Int32>& rIndices,
+ std::shared_ptr<sfx::AccessibilityIssue> const& pIssue);
+
SfxBindings* mpBindings;
SwDoc* mpDoc;
::sfx2::sidebar::ControllerItem maA11yCheckController;
diff --git a/sw/source/uibase/uiview/view.cxx b/sw/source/uibase/uiview/view.cxx
index 8583fc004a5a..7ed676df1aca 100644
--- a/sw/source/uibase/uiview/view.cxx
+++ b/sw/source/uibase/uiview/view.cxx
@@ -767,11 +767,6 @@ SwView::SwView(SfxViewFrame& _rFrame, SfxViewShell* pOldSh)
m_pFormShell(nullptr),
m_pHScrollbar(nullptr),
m_pVScrollbar(nullptr),
- m_pVRuler(VclPtr<SvxRuler>::Create(&GetViewFrame().GetWindow(), m_pEditWin,
- SvxRulerSupportFlags::TABS | SvxRulerSupportFlags::PARAGRAPH_MARGINS_VERTICAL|
- SvxRulerSupportFlags::BORDERS | SvxRulerSupportFlags::REDUCED_METRIC,
- GetViewFrame().GetBindings(),
- WB_VSCROLL | WB_EXTRAFIELD | WB_BORDER )),
m_pLastTableFormat(nullptr),
m_pLastFlyFormat(nullptr),
m_pFormatClipboard(new SwFormatClipboard()),
@@ -943,6 +938,15 @@ SwView::SwView(SfxViewFrame& _rFrame, SfxViewShell* pOldSh)
GetViewFrame().GetBindings(),
WB_STDRULER | WB_EXTRAFIELD | WB_BORDER);
+ m_pVRuler = VclPtr<SvxRuler>::Create(&GetViewFrame().GetWindow(), m_pEditWin,
+ SvxRulerSupportFlags::TABS |
+ SvxRulerSupportFlags::PARAGRAPH_MARGINS_VERTICAL |
+ SvxRulerSupportFlags::BORDERS |
+ SvxRulerSupportFlags::NEGATIVE_MARGINS|
+ SvxRulerSupportFlags::REDUCED_METRIC,
+ GetViewFrame().GetBindings(),
+ WB_VSCROLL | WB_EXTRAFIELD | WB_BORDER);
+
// assure that modified state of document
// isn't reset, if document is already modified.
const bool bIsDocModified = m_pWrtShell->GetDoc()->getIDocumentState().IsModified();
diff --git a/sw/source/uibase/uiview/viewtab.cxx b/sw/source/uibase/uiview/viewtab.cxx
index 52a26eabb672..1bf1e27a2a66 100644
--- a/sw/source/uibase/uiview/viewtab.cxx
+++ b/sw/source/uibase/uiview/viewtab.cxx
@@ -1034,7 +1034,7 @@ void SwView::ExecTabWin( SfxRequest const & rReq )
{
SvxColumnItem aColItem(static_cast<const SvxColumnItem&>(pReqArgs->Get(nSlot)));
- if( m_bSetTabColFromDoc || (!bSect && rSh.GetTableFormat()) )
+ if( m_bSetTabColFromDoc || m_bSetTabRowFromDoc || (!bSect && rSh.GetTableFormat()) )
{
OSL_ENSURE(aColItem.Count(), "ColDesc is empty!!");
@@ -1169,7 +1169,15 @@ void SwView::ExecTabWin( SfxRequest const & rReq )
auto & rEntry = aTabRows.GetEntry(nIndex);
tools::Long nNewPosition = rEntry.nPos + nOffset;
nNewPosition = std::clamp(nNewPosition, rEntry.nMin, rEntry.nMax - constDistanceOffset);
+ tools::Long nActualOffset = nNewPosition - rEntry.nPos;
rEntry.nPos = nNewPosition;
+ // Maintain the size of the other rows
+ for (size_t i = nIndex + 1; i < aTabRows.Count(); ++i)
+ {
+ auto& rNextEntry = aTabRows.GetEntry(i);
+ rNextEntry.nPos += nActualOffset;
+ }
+ aTabRows.SetRight(aTabRows.GetRight() + nActualOffset);
}
rSh.SetTabRows(aTabRows, false);
diff --git a/sw/source/uibase/uno/SwXDocumentSettings.cxx b/sw/source/uibase/uno/SwXDocumentSettings.cxx
index 4c6e85cc6613..3c0a8bbbf2a4 100644
--- a/sw/source/uibase/uno/SwXDocumentSettings.cxx
+++ b/sw/source/uibase/uno/SwXDocumentSettings.cxx
@@ -160,6 +160,7 @@ enum SwDocumentSettingsPropertyHandles
HANDLE_DROP_CAP_PUNCTUATION,
HANDLE_USE_VARIABLE_WIDTH_NBSP,
HANDLE_APPLY_TEXT_ATTR_TO_EMPTY_LINE_AT_END_OF_PARAGRAPH,
+ HANDLE_DO_NOT_MIRROR_RTL_DRAW_OBJS,
};
}
@@ -266,6 +267,7 @@ static rtl::Reference<MasterPropertySetInfo> lcl_createSettingsInfo()
{ OUString("DropCapPunctuation"), HANDLE_DROP_CAP_PUNCTUATION, cppu::UnoType<bool>::get(), 0 },
{ OUString("UseVariableWidthNBSP"), HANDLE_USE_VARIABLE_WIDTH_NBSP, cppu::UnoType<bool>::get(), 0 },
{ OUString("ApplyTextAttrToEmptyLineAtEndOfParagraph"), HANDLE_APPLY_TEXT_ATTR_TO_EMPTY_LINE_AT_END_OF_PARAGRAPH, cppu::UnoType<bool>::get(), 0 },
+ { OUString("DoNotMirrorRtlDrawObjs"), HANDLE_DO_NOT_MIRROR_RTL_DRAW_OBJS, cppu::UnoType<bool>::get(), 0 },
/*
* As OS said, we don't have a view when we need to set this, so I have to
@@ -1086,6 +1088,16 @@ void SwXDocumentSettings::_setSingleValue( const comphelper::PropertyInfo & rInf
}
}
break;
+ case HANDLE_DO_NOT_MIRROR_RTL_DRAW_OBJS:
+ {
+ bool bTmp;
+ if (rValue >>= bTmp)
+ {
+ mpDoc->getIDocumentSettingAccess().set(
+ DocumentSettingId::DO_NOT_MIRROR_RTL_DRAW_OBJS, bTmp);
+ }
+ }
+ break;
case HANDLE_DO_NOT_BREAK_WRAPPED_TABLES:
{
bool bTmp;
@@ -1674,6 +1686,12 @@ void SwXDocumentSettings::_getSingleValue( const comphelper::PropertyInfo & rInf
DocumentSettingId::APPLY_TEXT_ATTR_TO_EMPTY_LINE_AT_END_OF_PARAGRAPH);
}
break;
+ case HANDLE_DO_NOT_MIRROR_RTL_DRAW_OBJS:
+ {
+ rValue <<= mpDoc->getIDocumentSettingAccess().get(
+ DocumentSettingId::DO_NOT_MIRROR_RTL_DRAW_OBJS);
+ }
+ break;
case HANDLE_DO_NOT_BREAK_WRAPPED_TABLES:
{
rValue <<= mpDoc->getIDocumentSettingAccess().get(
diff --git a/sw/source/uibase/utlui/content.cxx b/sw/source/uibase/utlui/content.cxx
index 4e6704140334..c75f08430cea 100644
--- a/sw/source/uibase/utlui/content.cxx
+++ b/sw/source/uibase/utlui/content.cxx
@@ -1010,7 +1010,7 @@ void SwContentType::FillMemberList(bool* pbContentChanged)
for (const rtl::Reference<SdrObject>& pTemp : *pPage)
{
// #i51726# - all drawing objects can be named now
- if (!pTemp->GetName().isEmpty())
+ if (!pTemp->IsVirtualObj() && !pTemp->GetName().isEmpty())
{
tools::Long nYPos = LONG_MIN;
const bool bIsVisible = rIDDMA.IsVisibleLayerId(pTemp->GetLayer());
diff --git a/sw/source/uibase/utlui/uitool.cxx b/sw/source/uibase/utlui/uitool.cxx
index dfaffe3480c8..2ae72943497b 100644
--- a/sw/source/uibase/utlui/uitool.cxx
+++ b/sw/source/uibase/utlui/uitool.cxx
@@ -68,6 +68,7 @@
#include <SwStyleNameMapper.hxx>
#include <strings.hrc>
#include <docmodel/color/ComplexColor.hxx>
+#include <IDocumentSettingAccess.hxx>
// 50 cm 28350
#define MAXHEIGHT 28350
@@ -634,6 +635,12 @@ void PageDescToItemSet( const SwPageDesc& rPageDesc, SfxItemSet& rSet)
<<= rMaster.GetAttrSet().GetItem<SfxBoolItem>(RES_RTL_GUTTER)->GetValue();
}
+ const IDocumentSettingAccess& rIDSA = rMaster.getIDocumentSettingAccess();
+ if (rIDSA.get(DocumentSettingId::CONTINUOUS_ENDNOTES))
+ {
+ oGrabBag->GetGrabBag()["ContinuousEndnotes"] <<= true;
+ }
+
rSet.Put(*oGrabBag);
}
diff --git a/sw/source/uibase/utlui/unotools.cxx b/sw/source/uibase/utlui/unotools.cxx
index 93edfaad30a7..3105fa9607be 100644
--- a/sw/source/uibase/utlui/unotools.cxx
+++ b/sw/source/uibase/utlui/unotools.cxx
@@ -408,7 +408,7 @@ IMPL_LINK( SwOneExampleFrame, TimeoutHdl, Timer*, pTimer, void )
if (pDoc)
{
SwEditShell* pSh = pDoc->GetEditShell();
- if( pSh->ActionCount() )
+ if( pSh && pSh->ActionCount() )
{
pSh->EndAllAction();
pSh->UnlockPaint();
diff --git a/sw/uiconfig/swriter/ui/a11ycheckissuespanel.ui b/sw/uiconfig/swriter/ui/a11ycheckissuespanel.ui
index 6657b8c80c4b..3918611f7590 100644
--- a/sw/uiconfig/swriter/ui/a11ycheckissuespanel.ui
+++ b/sw/uiconfig/swriter/ui/a11ycheckissuespanel.ui
@@ -318,5 +318,31 @@
<property name="position">0</property>
</packing>
</child>
+ <child>
+ <object class="GtkBox" id="updateBox">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <object class="GtkLinkButton" id="updateLinkButton">
+ <property name="label" translatable="yes" context="a11ycheckissuespanel|updateLinkButton">Click to update...</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">True</property>
+ <property name="relief">none</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
</object>
</interface>
diff --git a/sw/uiconfig/swriter/ui/footnoteareapage.ui b/sw/uiconfig/swriter/ui/footnoteareapage.ui
index 2ff598640f58..103cf90dce72 100644
--- a/sw/uiconfig/swriter/ui/footnoteareapage.ui
+++ b/sw/uiconfig/swriter/ui/footnoteareapage.ui
@@ -99,7 +99,7 @@
</packing>
</child>
<child>
- <object class="GtkLabel" id="label3">
+ <object class="GtkLabel" id="spacetotextlabel">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes" context="footnoteareapage|label3">Space to text</property>
@@ -190,7 +190,7 @@
<property name="margin-start">12</property>
<property name="margin-top">6</property>
<child>
- <object class="GtkLabel" id="label4">
+ <object class="GtkLabel" id="positionlabel">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes" context="footnoteareapage|label4">_Position</property>
@@ -246,7 +246,7 @@
</packing>
</child>
<child>
- <object class="GtkLabel" id="label8">
+ <object class="GtkLabel" id="lengthlabel">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes" context="footnoteareapage|label8">_Length</property>
@@ -260,7 +260,7 @@
</packing>
</child>
<child>
- <object class="GtkLabel" id="label9">
+ <object class="GtkLabel" id="spacingtocontentslabel">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes" context="footnoteareapage|label9">_Spacing to footnote contents</property>