svx/source/svdraw/svdotextdecomposition.cxx          |    8 
 sw/inc/crsrsh.hxx                                    |    2 
 sw/inc/doc.hxx                                       |    1 
 sw/qa/extras/uiwriter/data/table-at-end-of-cell.fodt |  219 ++++++++++++++
 sw/qa/extras/uiwriter/uiwriter.cxx                   |   18 +
 sw/source/core/crsr/crsrsh.cxx                       |   38 +-
 sw/source/core/docnode/ndtbl.cxx                     |  288 ++++++++++---------
 sw/source/core/edit/eddel.cxx                        |   25 +
 sw/source/core/edit/edglss.cxx                       |    8 
 sw/source/core/txtnode/fntcache.cxx                  |   10 
 ucb/source/ucp/webdav-curl/CurlSession.cxx           |    4 
 vcl/inc/sallayout.hxx                                |    1 
 vcl/source/gdi/CommonSalLayout.cxx                   |    2 
 vcl/source/gdi/sallayout.cxx                         |   66 ++--
 14 files changed, 513 insertions(+), 177 deletions(-)

New commits:
commit 03c28615c1bb1c899e72d6363f67f9e85e52a356
Author:     Michael Stahl <michael.st...@allotropia.de>
AuthorDate: Thu Jun 15 13:13:05 2023 +0200
Commit:     Andras Timar <andras.ti...@collabora.com>
CommitDate: Mon Jun 26 09:27:05 2023 +0200

    tdf#155685 sw: ExtendedSelectAll with tables, group the Undo objects
    
    Change-Id: I2fba70968c97cd9704212cd799b333d2d158a042
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/153115
    Tested-by: Jenkins
    Reviewed-by: Michael Stahl <michael.st...@allotropia.de>
    (cherry picked from commit 5ab4fb27f4232fe0f36cfc079acb065d1712a355)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/153131
    Reviewed-by: Caolán McNamara <caolan.mcnam...@collabora.com>

diff --git a/sw/source/core/edit/eddel.cxx b/sw/source/core/edit/eddel.cxx
index b7997dbafa86..6cbce339615c 100644
--- a/sw/source/core/edit/eddel.cxx
+++ b/sw/source/core/edit/eddel.cxx
@@ -97,6 +97,12 @@ void SwEditShell::DeleteSel(SwPaM& rPam, bool const 
isArtificialSelection, bool
         SwPaM * pPam = &rPam;
         if (oSelectAll)
         {
+            if (!oSelectAll->second.empty())
+            {
+                SwRewriter aRewriter;
+                aRewriter.AddRule(UndoArg1, SwResId(STR_MULTISEL));
+                GetDoc()->GetIDocumentUndoRedo().StartUndo(SwUndoId::DELETE, 
&aRewriter);
+            }
             // tdf#155685 tables at the end must be deleted separately
             for (SwTableNode *const pTable : oSelectAll->second)
             {
@@ -113,6 +119,10 @@ void SwEditShell::DeleteSel(SwPaM& rPam, bool const 
isArtificialSelection, bool
         GetDoc()->getIDocumentContentOperations().DeleteAndJoin(*pPam,
             isArtificialSelection ? SwDeleteFlags::ArtificialSelection : 
SwDeleteFlags::Default);
         SaveTableBoxContent( pPam->GetPoint() );
+        if (oSelectAll && !oSelectAll->second.empty())
+        {
+            GetDoc()->GetIDocumentUndoRedo().EndUndo(SwUndoId::END, nullptr);
+        }
     }
 
     // Selection is not needed anymore
commit 280136fb683f4f37474b3c4fdfab6d452ddae3d4
Author:     Michael Stahl <michael.st...@allotropia.de>
AuthorDate: Thu Jun 15 12:22:11 2023 +0200
Commit:     Andras Timar <andras.ti...@collabora.com>
CommitDate: Mon Jun 26 09:27:04 2023 +0200

    tdf#155685 sw: fix another ExtendedSelectAll Redo crash w table at end
    
    This can be reproduced with a table containing in the last cell a
    paragraph followed by a table, then ExtendedSelectAll in the cell and
    delete.
    
    On Redo of the SwUndoDelete:
    
      warn:legacy.osl:326138:326138:sw/source/core/frmedt/tblsel.cxx:1775: 
MakeSelUnions with pStart or pEnd not in CellFrame
      In function:
        const_reference std::vector<SwTableBox *>::operator[](size_type) const
        [_Tp = SwTableBox *, _Allocator = std::allocator<SwTableBox *>]
      Error: attempt to subscript container with out-of-bounds index 0, but
      container only holds 0 elements.
    
    The problem is that DelTable() calls PaMCorrAbs() with a target that is
    outside of the outer table, so the SwEditShell::DeleteSel() rPam has one
    end in the last table cell and other end outside the table.
    
    Change-Id: Ia2764a4c99ba12102957153e005284a44be04fd0
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/153114
    Tested-by: Jenkins
    Reviewed-by: Michael Stahl <michael.st...@allotropia.de>
    (cherry picked from commit 4ef548a672658ab164e45e45ebd1b9f0b9282019)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/153130
    Reviewed-by: Caolán McNamara <caolan.mcnam...@collabora.com>

diff --git a/sw/qa/extras/uiwriter/data/table-at-end-of-cell.fodt 
b/sw/qa/extras/uiwriter/data/table-at-end-of-cell.fodt
new file mode 100644
index 000000000000..4e18f7dc2ce4
--- /dev/null
+++ b/sw/qa/extras/uiwriter/data/table-at-end-of-cell.fodt
@@ -0,0 +1,219 @@
+<?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:c
 alcext="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-15T12:29:51.722401974</meta:creation-date><dc:date>2023-06-15T12:30:57.494419372</dc:date><meta:editing-duration>PT1M13S</meta:editing-duration><meta:editing-cycles>1</meta:editing-cycles><meta:document-statistic
 meta:table-count="2" meta:image-count="0" meta:object-count="0" 
meta:page-count="1" meta:paragraph-count="0" meta:word-count="0" 
meta:character-count="0" 
meta:non-whitespace-character-count="0"/><meta:generator>LibreOfficeDev/7.6.0.0.alpha0$Linux_X86_64
 
LibreOffice_project/2e5dbe93649ec8043e9da75ddc01c486dbbf18e0</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="Lohit Devanagari1" svg:font-family="'Lohit 
Devanagari'" style:font-family-generic="system" style:font-pitch="variable"/>
+  <style:font-face style:name="Noto Sans CJK SC" svg:font-family="'Noto Sans 
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 Sans CJK SC" style:font-size-asian="10.5pt" 
style:language-asian="zh" style:country-asian="CN" 
style:font-name-complex="Lohit Devanagari1" style:font-size-complex="12pt" 
style:language-complex="hi" style:country-complex="IN"/>
+  </style:default-style>
+  <style:default-style style:family="paragraph">
+   <style:paragraph-properties fo:orphans="2" fo:widows="2" 
fo:hyphenation-ladder-count="no-limit" style:text-autospace="ideograph-alpha" 
style:punctuation-wrap="hanging" style:line-break="strict" 
style:tab-stop-distance="1.251cm" style:writing-mode="page"/>
+   <style:text-properties style:use-window-font-color="true" 
loext:opacity="0%" style:font-name="Liberation Serif" fo:font-size="12pt" 
fo:language="de" fo:country="DE" style:letter-kerning="true" 
style:font-name-asian="Noto Sans CJK SC" style:font-size-asian="10.5pt" 
style:language-asian="zh" style:country-asian="CN" 
style:font-name-complex="Lohit Devanagari1" 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="Table_20_Contents" style:display-name="Table 
Contents" style:family="paragraph" style:parent-style-name="Standard" 
style:class="extra">
+   <style:paragraph-properties fo:orphans="0" fo:widows="0" 
text:number-lines="false" text:line-number="0"/>
+  </style:style>
+  <text: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: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"/>
+  <loext:theme loext:name="Office Theme">
+   <loext:color-table loext:name="LibreOffice">
+    <loext:color loext:name="dk1" loext:color="#000000"/>
+    <loext:color loext:name="lt1" loext:color="#ffffff"/>
+    <loext:color loext:name="dk2" loext:color="#000000"/>
+    <loext:color loext:name="lt2" loext:color="#ffffff"/>
+    <loext:color loext:name="accent1" loext:color="#18a303"/>
+    <loext:color loext:name="accent2" loext:color="#0369a3"/>
+    <loext:color loext:name="accent3" loext:color="#a33e03"/>
+    <loext:color loext:name="accent4" loext:color="#8e03a3"/>
+    <loext:color loext:name="accent5" loext:color="#c99c00"/>
+    <loext:color loext:name="accent6" loext:color="#c9211e"/>
+    <loext:color loext:name="hlink" loext:color="#0000ee"/>
+    <loext:color loext:name="folHlink" loext:color="#551a8b"/>
+   </loext:color-table>
+  </loext:theme>
+ </office:styles>
+ <office:automatic-styles>
+  <style:style style:name="Table1" style:family="table">
+   <style:table-properties style:width="17cm" table:align="margins"/>
+  </style:style>
+  <style:style style:name="Table1.A" style:family="table-column">
+   <style:table-column-properties style:column-width="8.5cm" 
style:rel-column-width="32767*"/>
+  </style:style>
+  <style:style style:name="Table1.A1" style:family="table-cell">
+   <style:table-cell-properties fo:padding="0.097cm" fo:border-left="0.5pt 
solid #000000" fo:border-right="none" fo:border-top="0.5pt solid #000000" 
fo:border-bottom="0.5pt solid #000000"/>
+  </style:style>
+  <style:style style:name="Table1.B1" style:family="table-cell">
+   <style:table-cell-properties fo:padding="0.097cm" fo:border="0.5pt solid 
#000000"/>
+  </style:style>
+  <style:style style:name="Table1.A2" style:family="table-cell">
+   <style:table-cell-properties fo:padding="0.097cm" fo:border-left="0.5pt 
solid #000000" fo:border-right="none" fo:border-top="none" 
fo:border-bottom="0.5pt solid #000000"/>
+  </style:style>
+  <style:style style:name="Table1.B2" style:family="table-cell">
+   <style:table-cell-properties fo:padding="0.097cm" fo:border-left="0.5pt 
solid #000000" fo:border-right="0.5pt solid #000000" fo:border-top="none" 
fo:border-bottom="0.5pt solid #000000"/>
+  </style:style>
+  <style:style style:name="Table2" style:family="table">
+   <style:table-properties style:width="8.306cm" table:align="margins"/>
+  </style:style>
+  <style:style style:name="Table2.A" style:family="table-column">
+   <style:table-column-properties style:column-width="4.154cm" 
style:rel-column-width="32767*"/>
+  </style:style>
+  <style:style style:name="Table2.A1" style:family="table-cell">
+   <style:table-cell-properties fo:padding="0.097cm" fo:border-left="0.5pt 
solid #000000" fo:border-right="none" fo:border-top="0.5pt solid #000000" 
fo:border-bottom="0.5pt solid #000000"/>
+  </style:style>
+  <style:style style:name="Table2.B1" style:family="table-cell">
+   <style:table-cell-properties fo:padding="0.097cm" fo:border="0.5pt solid 
#000000"/>
+  </style:style>
+  <style:style style:name="Table2.A2" style:family="table-cell">
+   <style:table-cell-properties fo:padding="0.097cm" fo:border-left="0.5pt 
solid #000000" fo:border-right="none" fo:border-top="none" 
fo:border-bottom="0.5pt solid #000000"/>
+  </style:style>
+  <style:style style:name="Table2.B2" style:family="table-cell">
+   <style:table-cell-properties fo:padding="0.097cm" fo:border-left="0.5pt 
solid #000000" fo:border-right="0.5pt solid #000000" fo:border-top="none" 
fo:border-bottom="0.5pt solid #000000"/>
+  </style:style>
+  <style:style style:name="Table2" style:family="table">
+   <style:table-properties style:width="8.306cm" table:align="margins"/>
+  </style:style>
+  <style:style style:name="Table2.A" style:family="table-column">
+   <style:table-column-properties style:column-width="4.154cm" 
style:rel-column-width="32767*"/>
+  </style:style>
+  <style:style style:name="Table2.A1" style:family="table-cell">
+   <style:table-cell-properties fo:padding="0.097cm" fo:border-left="0.5pt 
solid #000000" fo:border-right="none" fo:border-top="0.5pt solid #000000" 
fo:border-bottom="0.5pt solid #000000"/>
+  </style:style>
+  <style:style style:name="Table2.B1" style:family="table-cell">
+   <style:table-cell-properties fo:padding="0.097cm" fo:border="0.5pt solid 
#000000"/>
+  </style:style>
+  <style:style style:name="Table2.A2" style:family="table-cell">
+   <style:table-cell-properties fo:padding="0.097cm" fo:border-left="0.5pt 
solid #000000" fo:border-right="none" fo:border-top="none" 
fo:border-bottom="0.5pt solid #000000"/>
+  </style:style>
+  <style:style style:name="Table2.B2" style:family="table-cell">
+   <style:table-cell-properties fo:padding="0.097cm" fo:border-left="0.5pt 
solid #000000" fo:border-right="0.5pt solid #000000" fo:border-top="none" 
fo:border-bottom="0.5pt solid #000000"/>
+  </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>
+   <table:table table:name="Table1" table:style-name="Table1">
+    <table:table-column table:style-name="Table1.A" 
table:number-columns-repeated="2"/>
+    <table:table-row>
+     <table:table-cell table:style-name="Table1.A1" office:value-type="string">
+      <text:p text:style-name="Table_20_Contents"/>
+     </table:table-cell>
+     <table:table-cell table:style-name="Table1.B1" office:value-type="string">
+      <text:p text:style-name="Table_20_Contents"/>
+     </table:table-cell>
+    </table:table-row>
+    <table:table-row>
+     <table:table-cell table:style-name="Table1.A2" office:value-type="string">
+      <text:p text:style-name="Table_20_Contents"/>
+     </table:table-cell>
+     <table:table-cell table:style-name="Table1.B2" office:value-type="string">
+      <text:p text:style-name="Standard"/>
+      <table:table table:name="Table2" table:style-name="Table2">
+       <table:table-column table:style-name="Table2.A" 
table:number-columns-repeated="2"/>
+       <table:table-row>
+        <table:table-cell table:style-name="Table2.A1" 
office:value-type="string">
+         <text:p text:style-name="Table_20_Contents"/>
+        </table:table-cell>
+        <table:table-cell table:style-name="Table2.B1" 
office:value-type="string">
+         <text:p text:style-name="Table_20_Contents"/>
+        </table:table-cell>
+       </table:table-row>
+       <table:table-row>
+        <table:table-cell table:style-name="Table2.A2" 
office:value-type="string">
+         <text:p text:style-name="Table_20_Contents"/>
+        </table:table-cell>
+        <table:table-cell table:style-name="Table2.B2" 
office:value-type="string">
+         <text:p text:style-name="Table_20_Contents"/>
+        </table:table-cell>
+       </table:table-row>
+      </table:table>
+     </table:table-cell>
+    </table:table-row>
+   </table:table>
+   <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/uiwriter.cxx 
b/sw/qa/extras/uiwriter/uiwriter.cxx
index 363a6cf06c4c..622272e47ce5 100644
--- a/sw/qa/extras/uiwriter/uiwriter.cxx
+++ b/sw/qa/extras/uiwriter/uiwriter.cxx
@@ -533,6 +533,24 @@ CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testTdf67238)
     
CPPUNIT_ASSERT(!((rTable.GetTableBox("C3"))->GetFrameFormat()->GetProtect()).IsContentProtected());
 }
 
+CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testTdf155685)
+{
+    createSwDoc("table-at-end-of-cell.fodt");
+    SwDoc* pDoc = getSwDoc();
+    SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
+    pWrtShell->GoNextCell();
+    pWrtShell->GoNextCell();
+    pWrtShell->GoNextCell();
+    pWrtShell->SelAll();
+    pWrtShell->Delete();
+    // this crashed
+    pWrtShell->Undo();
+    pWrtShell->Undo();
+    pWrtShell->Redo();
+    // this crashed
+    pWrtShell->Redo();
+}
+
 CPPUNIT_TEST_FIXTURE(SwUiWriterTest, testTdf147220)
 {
     createSwDoc();
diff --git a/sw/source/core/docnode/ndtbl.cxx b/sw/source/core/docnode/ndtbl.cxx
index dccb8c2b92f9..d004bbc32055 100644
--- a/sw/source/core/docnode/ndtbl.cxx
+++ b/sw/source/core/docnode/ndtbl.cxx
@@ -1967,15 +1967,28 @@ void SwDoc::DelTable(SwTableNode *const pTableNd)
         }
 
         // Save the cursors (UNO and otherwise)
-        SwPaM aSavePaM( *pTableNd->EndOfSectionNode() );
-        if (! aSavePaM.Move(fnMoveForward, GoInNode))
+        SwPaM const* pSavePaM(nullptr);
+        SwPaM forwardPaM(*pTableNd->EndOfSectionNode());
+        if (forwardPaM.Move(fnMoveForward, GoInNode))
         {
-            aSavePaM.GetMark()->Assign( *pTableNd );
-            aSavePaM.Move( fnMoveBackward, GoInNode );
+            pSavePaM = &forwardPaM;
         }
+        SwPaM backwardPaM(*pTableNd);
+        if (backwardPaM.Move(fnMoveBackward, GoInNode))
+        {
+            if (pSavePaM == nullptr
+                    // try to stay in the same outer table cell
+                || (forwardPaM.GetPoint()->GetNode().FindTableNode() != 
pTableNd->StartOfSectionNode()->FindTableNode()
+                    && forwardPaM.GetPoint()->GetNode().StartOfSectionIndex()
+                        < 
backwardPaM.GetPoint()->GetNode().StartOfSectionIndex()))
+            {
+                pSavePaM = &backwardPaM;
+            }
+        }
+        assert(pSavePaM); // due to bNewTextNd this must succeed
         {
             SwPaM const tmpPaM(*pTableNd, *pTableNd->EndOfSectionNode());
-            ::PaMCorrAbs(tmpPaM, *aSavePaM.GetMark());
+            ::PaMCorrAbs(tmpPaM, *pSavePaM->GetPoint());
         }
 
         // Move hard PageBreaks to the succeeding Node
@@ -2017,15 +2030,28 @@ void SwDoc::DelTable(SwTableNode *const pTableNd)
         }
 
         // Save the cursors (UNO and otherwise)
-        SwPaM aSavePaM( *pTableNd->EndOfSectionNode() );
-        if (! aSavePaM.Move(fnMoveForward, GoInNode))
+        SwPaM const* pSavePaM(nullptr);
+        SwPaM forwardPaM(*pTableNd->EndOfSectionNode());
+        if (forwardPaM.Move(fnMoveForward, GoInNode))
         {
-            aSavePaM.GetMark()->Assign( *pTableNd );
-            aSavePaM.Move( fnMoveBackward, GoInNode );
+            pSavePaM = &forwardPaM;
+        }
+        SwPaM backwardPaM(*pTableNd);
+        if (backwardPaM.Move(fnMoveBackward, GoInNode))
+        {
+            if (pSavePaM == nullptr
+                    // try to stay in the same outer table cell
+                || (forwardPaM.GetPoint()->GetNode().FindTableNode() != 
pTableNd->StartOfSectionNode()->FindTableNode()
+                    && forwardPaM.GetPoint()->GetNode().StartOfSectionIndex()
+                        < 
backwardPaM.GetPoint()->GetNode().StartOfSectionIndex()))
+            {
+                pSavePaM = &backwardPaM;
+            }
         }
+        assert(pSavePaM); // due to bNewTextNd this must succeed
         {
             SwPaM const tmpPaM(*pTableNd, *pTableNd->EndOfSectionNode());
-            ::PaMCorrAbs(tmpPaM, *aSavePaM.GetMark());
+            ::PaMCorrAbs(tmpPaM, *pSavePaM->GetPoint());
         }
 
         // Move hard PageBreaks to the succeeding Node
commit c59ed7701605effde73782db18da3293ea30c12d
Author:     Khaled Hosny <kha...@libreoffice.org>
AuthorDate: Tue Jun 20 10:17:49 2023 +0300
Commit:     Andras Timar <andras.ti...@collabora.com>
CommitDate: Mon Jun 26 09:27:04 2023 +0200

    tdf#107718: Fix script itemization of vertical text
    
    Mixed script vertical text was not correctly splitting runs at script
    changes, resulting in Hangul text being mixed with Han text in the same
    run breaking the Hangul composition.
    
    Change-Id: I09c3f799bede6aa8a19684779d500504a9813af7
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/153313
    Tested-by: Jenkins
    Reviewed-by: خالد حسني <kha...@libreoffice.org>
    (cherry picked from commit 1afc13b0b84353109827d78807836c01f030ab66)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/153335
    Reviewed-by: Caolán McNamara <caolan.mcnam...@collabora.com>

diff --git a/vcl/source/gdi/CommonSalLayout.cxx 
b/vcl/source/gdi/CommonSalLayout.cxx
index 5cac0ebdb6b0..754b228f8ad3 100644
--- a/vcl/source/gdi/CommonSalLayout.cxx
+++ b/vcl/source/gdi/CommonSalLayout.cxx
@@ -391,7 +391,7 @@ bool 
GenericSalLayout::LayoutText(vcl::text::ImplLayoutArgs& rArgs, const SalLay
                             aDirection = bRightToLeft ? HB_DIRECTION_RTL : 
HB_DIRECTION_LTR;
                         }
 
-                        if (aSubRuns.empty() || aSubRuns.back().maDirection != 
aDirection)
+                        if (aSubRuns.empty() || aSubRuns.back().maDirection != 
aDirection || aSubRuns.back().maScript != aScript)
                             aSubRuns.push_back({ nPrevIdx, nIdx, aScript, 
aDirection });
                         else
                             aSubRuns.back().mnEnd = nIdx;
commit f923efb8e3781f13b8814b3f9179e2442a20ca5e
Author:     Khaled Hosny <kha...@libreoffice.org>
AuthorDate: Mon Jun 12 22:29:11 2023 +0300
Commit:     Andras Timar <andras.ti...@collabora.com>
CommitDate: Mon Jun 26 09:27:04 2023 +0200

    tdf#152048: Fix measuring text width with font fallback
    
    This is a regression from:
    
    commit 43a5400063b17ed4ba4cbb38bdf5da4a991f60e2
    Author: Khaled Hosny <kha...@libreoffice.org>
    Date:   Thu May 25 10:59:18 2023 +0300
    
        tdf#152048: Fix underline width for Kashida-justified text
    
    It fixed measuring width when there is Kashida justification, but broke
    it for font fallback, because of the way MultiSalLayout measures the
    text width takes the maximum of the text widths for all its layouts, but
    layouts with missing glyphs are now giving wrong text width as they are
    measuring the width of .notdef (GID 0) glyph.
    
    This change makes MultiSalLayout measure the text width by iterating
    over all its valid glyphs.
    
    Change-Id: I8b19e0d44326c6f0afe6e504ab6d90c6fb3575f9
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/152933
    Tested-by: Jenkins
    Reviewed-by: خالد حسني <kha...@libreoffice.org>
    (cherry picked from commit 38b5e9bc7d45f52f11bad125a584ad2261383de6)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/152920
    Reviewed-by: Caolán McNamara <caolan.mcnam...@collabora.com>

diff --git a/vcl/inc/sallayout.hxx b/vcl/inc/sallayout.hxx
index 35496750c286..d48edaaf67f2 100644
--- a/vcl/inc/sallayout.hxx
+++ b/vcl/inc/sallayout.hxx
@@ -62,6 +62,7 @@ class MultiSalLayout final : public SalLayout
 public:
     void            DrawText(SalGraphics&) const override;
     sal_Int32       GetTextBreak(DeviceCoordinate nMaxWidth, DeviceCoordinate 
nCharExtra, int nFactor) const override;
+    DeviceCoordinate GetTextWidth() const final override;
     DeviceCoordinate FillDXArray(std::vector<DeviceCoordinate>* pDXArray, 
const OUString& rStr) const override;
     void            GetCaretPositions(int nArraySize, sal_Int32* pCaretXArray) 
const override;
     bool            GetNextGlyph(const GlyphItem** pGlyph, DevicePoint& rPos, 
int& nStart,
diff --git a/vcl/source/gdi/sallayout.cxx b/vcl/source/gdi/sallayout.cxx
index 1ed2a37ad71b..3cdd71642b5b 100644
--- a/vcl/source/gdi/sallayout.cxx
+++ b/vcl/source/gdi/sallayout.cxx
@@ -1009,45 +1009,53 @@ sal_Int32 MultiSalLayout::GetTextBreak( 
DeviceCoordinate nMaxWidth, DeviceCoordi
     return -1;
 }
 
-DeviceCoordinate MultiSalLayout::FillDXArray( std::vector<DeviceCoordinate>* 
pCharWidths, const OUString& rStr ) const
+DeviceCoordinate MultiSalLayout::GetTextWidth() const
 {
-    DeviceCoordinate nMaxWidth = 0;
+    // Measure text width. There might be holes in each SalLayout due to
+    // missing chars, so we use GetNextGlyph() to get the glyphs across all
+    // layouts.
+    int nStart = 0;
+    DevicePoint aPos;
+    const GlyphItem* pGlyphItem;
 
-    // prepare merging of fallback levels
-    std::vector<DeviceCoordinate> aTempWidths;
-    const int nCharCount = mnEndCharPos - mnMinCharPos;
-    if( pCharWidths )
+    DeviceCoordinate nWidth = 0;
+    while (GetNextGlyph(&pGlyphItem, aPos, nStart))
+        nWidth += pGlyphItem->newWidth();
+
+    return nWidth;
+}
+
+DeviceCoordinate MultiSalLayout::FillDXArray( std::vector<DeviceCoordinate>* 
pCharWidths, const OUString& rStr ) const
+{
+    if (pCharWidths)
     {
+        // prepare merging of fallback levels
+        std::vector<DeviceCoordinate> aTempWidths;
+        const int nCharCount = mnEndCharPos - mnMinCharPos;
         pCharWidths->clear();
         pCharWidths->resize(nCharCount, 0);
-    }
 
-    for( int n = mnLevel; --n >= 0; )
-    {
-        // query every fallback level
-        DeviceCoordinate nTextWidth = mpLayouts[n]->FillDXArray( &aTempWidths, 
rStr );
-        if( !nTextWidth )
-            continue;
-        // merge results from current level
-        if( nMaxWidth < nTextWidth )
-            nMaxWidth = nTextWidth;
-        if( !pCharWidths )
-            continue;
-        // calculate virtual char widths using most probable fallback layout
-        for( int i = 0; i < nCharCount; ++i )
+        for (int n = mnLevel; --n >= 0;)
         {
-            // #i17359# restriction:
-            // one char cannot be resolved from different fallbacks
-            if( (*pCharWidths)[i] != 0 )
-                continue;
-            DeviceCoordinate nCharWidth = aTempWidths[i];
-            if( !nCharWidth )
-                continue;
-            (*pCharWidths)[i] = nCharWidth;
+            // query every fallback level
+            mpLayouts[n]->FillDXArray(&aTempWidths, rStr);
+
+            // calculate virtual char widths using most probable fallback 
layout
+            for (int i = 0; i < nCharCount; ++i)
+            {
+                // #i17359# restriction:
+                // one char cannot be resolved from different fallbacks
+                if ((*pCharWidths)[i] != 0)
+                    continue;
+                DeviceCoordinate nCharWidth = aTempWidths[i];
+                if (!nCharWidth)
+                    continue;
+                (*pCharWidths)[i] = nCharWidth;
+            }
         }
     }
 
-    return nMaxWidth;
+    return GetTextWidth();
 }
 
 void MultiSalLayout::GetCaretPositions( int nMaxIndex, sal_Int32* pCaretXArray 
) const
commit 95a2b31b2245daca3e833628be2d48d9f09995ea
Author:     Khaled Hosny <kha...@libreoffice.org>
AuthorDate: Thu Jun 8 16:41:18 2023 +0300
Commit:     Andras Timar <andras.ti...@collabora.com>
CommitDate: Mon Jun 26 09:27:04 2023 +0200

    tdf#151968: Fix vertical position of RTL spelling wavy line
    
    Second try. This time making sure start > end even for RTL text.
    
    This also now works for horizontal, vertical and rotated Arabic text, in
    Writer and Edit Engine.
    
    Change-Id: I6fe1e9dbb9c071287054200a58d4ddddee073311
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/152820
    Tested-by: Jenkins
    Reviewed-by: Caolán McNamara <caolan.mcnam...@collabora.com>

diff --git a/svx/source/svdraw/svdotextdecomposition.cxx 
b/svx/source/svdraw/svdotextdecomposition.cxx
index 138b709e9769..726ee850eb8b 100644
--- a/svx/source/svdraw/svdotextdecomposition.cxx
+++ b/svx/source/svdraw/svdotextdecomposition.cxx
@@ -427,8 +427,12 @@ namespace
                         // full portion width
                         const double fTextWidth(aDXArray[aDXArray.size() - 1]);
 
-                        fStart = fTextWidth - fStart;
-                        fEnd = fTextWidth - fEnd;
+                        // tdf#151968
+                        // if start < end, OutputDevice::DrawWaveLine() will
+                        // think it is a rotated line, so we swap fStart and
+                        // fEnd to avoid this.
+                        fStart = fTextWidth - fEnd;
+                        fEnd = fTextWidth - fStart;
                     }
 
                     // need to take FontScaling out of values; it's already 
part of
diff --git a/sw/source/core/txtnode/fntcache.cxx 
b/sw/source/core/txtnode/fntcache.cxx
index e6958ec6cb90..47f7e8eb71de 100644
--- a/sw/source/core/txtnode/fntcache.cxx
+++ b/sw/source/core/txtnode/fntcache.cxx
@@ -241,10 +241,20 @@ static void lcl_calcLinePos( const CalcLinePosData &rData,
         break;
     }
 
+    // tdf#151968
+    // if start < end, OutputDevice::DrawWaveLine() will think it is a rotated
+    // line, so we swap nStart and nEnd to avoid this.
+    if ( rData.bBidiPor )
+        std::swap(rStart, rEnd);
+
     if ( rData.bSwitchL2R )
     {
         rData.rInf.GetFrame()->SwitchLTRtoRTL( rStart );
         rData.rInf.GetFrame()->SwitchLTRtoRTL( rEnd );
+
+        // tdf#151968
+        // We need to do this here as well for LTR text in a RTL paragraph.
+        std::swap(rStart, rEnd);
     }
 
     if ( rData.bSwitchH2V )
commit 766e051f5069b925b0ac2e86043b475eda6db24a
Author:     Michael Stahl <michael.st...@allotropia.de>
AuthorDate: Tue Jun 6 14:06:35 2023 +0200
Commit:     Andras Timar <andras.ti...@collabora.com>
CommitDate: Mon Jun 26 09:27:04 2023 +0200

    ucb: webdav-curl: auth data is invalid when receiving 401
    
    Even if it used to be valid before; unfortunately newly entered
    credentials weren't actually used because the flag was never reset.
    
    Change-Id: Ib36689f40ff780596b9cfe6fe589a6f2e79cfcd2
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/152679
    Tested-by: Jenkins
    Reviewed-by: Michael Stahl <michael.st...@allotropia.de>
    (cherry picked from commit 7efdacc1cd529e1801c9adf803a1a2db8334e67a)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/152658
    Tested-by: Caolán McNamara <caolan.mcnam...@collabora.com>
    Reviewed-by: Caolán McNamara <caolan.mcnam...@collabora.com>

diff --git a/ucb/source/ucp/webdav-curl/CurlSession.cxx 
b/ucb/source/ucp/webdav-curl/CurlSession.cxx
index dcf71a8869b3..98be7579a423 100644
--- a/ucb/source/ucp/webdav-curl/CurlSession.cxx
+++ b/ucb/source/ucp/webdav-curl/CurlSession.cxx
@@ -1397,6 +1397,10 @@ auto CurlProcessor::ProcessRequest(
                     case SC_UNAUTHORIZED:
                     case SC_PROXY_AUTHENTICATION_REQUIRED:
                     {
+                        (statusCode != SC_PROXY_AUTHENTICATION_REQUIRED
+                             ? rSession.m_isAuthenticated
+                             : rSession.m_isAuthenticatedProxy)
+                            = false; // any auth data in m_pCurl is invalid
                         auto& rnAuthRequests(statusCode == SC_UNAUTHORIZED ? 
nAuthRequests
                                                                            : 
nAuthRequestsProxy);
                         if (rnAuthRequests == 10)
commit 2748f9c1a2e35c6c23caccdd27369ffb8561e03b
Author:     Michael Stahl <michael.st...@allotropia.de>
AuthorDate: Mon Jun 5 20:24:45 2023 +0200
Commit:     Andras Timar <andras.ti...@collabora.com>
CommitDate: Mon Jun 26 09:27:04 2023 +0200

    tdf#155685 sw: fix crash on undo of ExtendedSelectAll with table at end
    
    While the selection with table at the end works for Copy, unfortunately
    it doesn't work for Delete, because SwUndoDelete can't handle it,
    and an empty SwTableNode+SwEndNode pair remains.
    
    This needs some extra code, extract a SwDoc::DelTable() out of
    SwDoc::DeleteRowCol() and call it from SwEditShell::DeleteSel() to
    create separate SwUndoDelete objects per table, which appears to work.
    
    (regression from commit d81379db730a163c5ff75d4f3a3cddbd7b5eddda)
    
    Change-Id: I1534b100d31bc279bce298d3c2bd235cffc1f9d5
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/152628
    Tested-by: Jenkins
    Reviewed-by: Michael Stahl <michael.st...@allotropia.de>
    (cherry picked from commit 16e40e8d6e6d606cd239331ad7d4c409b3add8e6)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/152652
    Reviewed-by: Caolán McNamara <caolan.mcnam...@collabora.com>

diff --git a/sw/inc/crsrsh.hxx b/sw/inc/crsrsh.hxx
index 2df21e824314..83fe5fec632d 100644
--- a/sw/inc/crsrsh.hxx
+++ b/sw/inc/crsrsh.hxx
@@ -331,7 +331,7 @@ public:
     // only for usage in special cases allowed!
     void ExtendedSelectAll(bool bFootnotes = true);
     /// If ExtendedSelectAll() was called and selection didn't change since 
then.
-    SwNode const* ExtendedSelectedAll() const;
+    ::std::optional<::std::pair<SwNode const*, ::std::vector<SwTableNode*>>> 
ExtendedSelectedAll() const;
     enum class StartsWith { None, Table, HiddenPara };
     /// If document body starts with a table or starts/ends with hidden 
paragraph.
     StartsWith StartsWith_();
diff --git a/sw/inc/doc.hxx b/sw/inc/doc.hxx
index d74f45d805f9..e577bda4ba3c 100644
--- a/sw/inc/doc.hxx
+++ b/sw/inc/doc.hxx
@@ -1206,6 +1206,7 @@ public:
 
     // Delete Columns/Rows in table.
     enum class RowColMode { DeleteRow = 0, DeleteColumn = 1, DeleteProtected = 
2 };
+    void DelTable(SwTableNode * pTable);
     bool DeleteRowCol(const SwSelBoxes& rBoxes, RowColMode eMode = 
RowColMode::DeleteRow);
     void DeleteRow( const SwCursor& rCursor );
     void DeleteCol( const SwCursor& rCursor );
diff --git a/sw/source/core/crsr/crsrsh.cxx b/sw/source/core/crsr/crsrsh.cxx
index bd6ef9e94507..ccf4964bc549 100644
--- a/sw/source/core/crsr/crsrsh.cxx
+++ b/sw/source/core/crsr/crsrsh.cxx
@@ -819,11 +819,12 @@ static typename SwCursorShell::StartsWith 
EndsWith(SwStartNode const& rStart)
 
 // return the node that is the start of the extended selection (to include 
table
 // or section start nodes; looks like extending for end nodes is not required)
-SwNode const* SwCursorShell::ExtendedSelectedAll() const
+::std::optional<::std::pair<SwNode const*, ::std::vector<SwTableNode*>>>
+SwCursorShell::ExtendedSelectedAll() const
 {
     if (m_pTableCursor)
     {
-        return nullptr;
+        return {};
     }
 
     SwNodes& rNodes = GetDoc()->GetNodes();
@@ -834,27 +835,48 @@ SwNode const* SwCursorShell::ExtendedSelectedAll() const
     SwContentNode* pStart = rNodes.GoNext(&nNode);
     if (!pStart)
     {
-        return nullptr;
+        return {};
     }
 
     nNode = *pStartNode->EndOfSectionNode();
     SwContentNode* pEnd = SwNodes::GoPrevious(&nNode);
     if (!pEnd)
     {
-        return nullptr;
+        return {};
     }
 
     SwPosition aStart(*pStart, 0);
     SwPosition aEnd(*pEnd, pEnd->Len());
     if (!(aStart == *pShellCursor->Start() && aEnd == *pShellCursor->End()))
     {
-        return nullptr;
+        return {};
     }
 
+    auto const ends(::EndsWith(*pStartNode));
     if (::StartsWith(*pStartNode) == StartsWith::None
-        && ::EndsWith(*pStartNode) == StartsWith::None)
+        && ends == StartsWith::None)
     {
-        return nullptr; // "ordinary" selection will work
+        return {}; // "ordinary" selection will work
+    }
+
+    ::std::vector<SwTableNode*> tablesAtEnd;
+    if (ends == StartsWith::Table)
+    {
+        SwNode * pLastNode(rNodes[pStartNode->EndOfSectionIndex() - 1]);
+        while (pLastNode->IsEndNode())
+        {
+            SwNode *const pNode(pLastNode->StartOfSectionNode());
+            if (pNode->IsTableNode())
+            {
+                tablesAtEnd.push_back(pNode->GetTableNode());
+                pLastNode = rNodes[pNode->GetIndex() - 1];
+            }
+            else if (pNode->IsSectionNode())
+            {
+                pLastNode = rNodes[pLastNode->GetIndex() - 1];
+            }
+        }
+        assert(!tablesAtEnd.empty());
     }
 
     // tdf#133990 ensure directly containing section is included in 
SwUndoDelete
@@ -867,7 +889,7 @@ SwNode const* SwCursorShell::ExtendedSelectedAll() const
 
     // pStartNode is the node that fully contains the selection - the first
     // node of the selection is the first node inside pStartNode
-    return pStartNode->GetNodes()[pStartNode->GetIndex() + 1];
+    return ::std::make_pair(rNodes[pStartNode->GetIndex() + 1], tablesAtEnd);
 }
 
 typename SwCursorShell::StartsWith SwCursorShell::StartsWith_()
diff --git a/sw/source/core/docnode/ndtbl.cxx b/sw/source/core/docnode/ndtbl.cxx
index 946abf3eb289..dccb8c2b92f9 100644
--- a/sw/source/core/docnode/ndtbl.cxx
+++ b/sw/source/core/docnode/ndtbl.cxx
@@ -1924,6 +1924,140 @@ void SwDoc::DeleteCol( const SwCursor& rCursor )
     GetIDocumentUndoRedo().EndUndo(SwUndoId::COL_DELETE, nullptr);
 }
 
+void SwDoc::DelTable(SwTableNode *const pTableNd)
+{
+    bool bNewTextNd = false;
+    // Is it alone in a FlyFrame?
+    SwNodeIndex aIdx( *pTableNd, -1 );
+    const SwStartNode* pSttNd = aIdx.GetNode().GetStartNode();
+    if (pSttNd)
+    {
+        const SwNodeOffset nTableEnd = pTableNd->EndOfSectionIndex() + 1;
+        const SwNodeOffset nSectEnd = pSttNd->EndOfSectionIndex();
+        if (nTableEnd == nSectEnd)
+        {
+            if (SwFlyStartNode == pSttNd->GetStartNodeType())
+            {
+                SwFrameFormat* pFormat = pSttNd->GetFlyFormat();
+                if (pFormat)
+                {
+                    // That's the FlyFormat we're looking for
+                    getIDocumentLayoutAccess().DelLayoutFormat( pFormat );
+                    return;
+                }
+            }
+            // No Fly? Thus Header or Footer: always leave a TextNode
+            // We can forget about Undo then!
+            bNewTextNd = true;
+        }
+    }
+
+    // No Fly? Then it is a Header or Footer, so keep always a TextNode
+    ++aIdx;
+    if (GetIDocumentUndoRedo().DoesUndo())
+    {
+        GetIDocumentUndoRedo().ClearRedo();
+        SwPaM aPaM( *pTableNd->EndOfSectionNode(), aIdx.GetNode() );
+
+        if (bNewTextNd)
+        {
+            const SwNodeIndex aTmpIdx( *pTableNd->EndOfSectionNode(), 1 );
+            GetNodes().MakeTextNode( aTmpIdx.GetNode(),
+                        getIDocumentStylePoolAccess().GetTextCollFromPool( 
RES_POOLCOLL_STANDARD ) );
+        }
+
+        // Save the cursors (UNO and otherwise)
+        SwPaM aSavePaM( *pTableNd->EndOfSectionNode() );
+        if (! aSavePaM.Move(fnMoveForward, GoInNode))
+        {
+            aSavePaM.GetMark()->Assign( *pTableNd );
+            aSavePaM.Move( fnMoveBackward, GoInNode );
+        }
+        {
+            SwPaM const tmpPaM(*pTableNd, *pTableNd->EndOfSectionNode());
+            ::PaMCorrAbs(tmpPaM, *aSavePaM.GetMark());
+        }
+
+        // Move hard PageBreaks to the succeeding Node
+        bool bSavePageBreak = false, bSavePageDesc = false;
+        SwNodeOffset nNextNd = pTableNd->EndOfSectionIndex()+1;
+        SwContentNode* pNextNd = GetNodes()[ nNextNd ]->GetContentNode();
+        if (pNextNd)
+        {
+            SwFrameFormat* pTableFormat = 
pTableNd->GetTable().GetFrameFormat();
+            const SfxPoolItem *pItem;
+            if (SfxItemState::SET == pTableFormat->GetItemState(RES_PAGEDESC,
+                    false, &pItem))
+            {
+                pNextNd->SetAttr( *pItem );
+                bSavePageDesc = true;
+            }
+
+            if (SfxItemState::SET == pTableFormat->GetItemState(RES_BREAK,
+                    false, &pItem))
+            {
+                pNextNd->SetAttr( *pItem );
+                bSavePageBreak = true;
+            }
+        }
+        std::unique_ptr<SwUndoDelete> pUndo(new SwUndoDelete(aPaM, 
SwDeleteFlags::Default));
+        if (bNewTextNd)
+            pUndo->SetTableDelLastNd();
+        pUndo->SetPgBrkFlags( bSavePageBreak, bSavePageDesc );
+        pUndo->SetTableName(pTableNd->GetTable().GetFrameFormat()->GetName());
+        GetIDocumentUndoRedo().AppendUndo( std::move(pUndo) );
+    }
+    else
+    {
+        if (bNewTextNd)
+        {
+            const SwNodeIndex aTmpIdx( *pTableNd->EndOfSectionNode(), 1 );
+            GetNodes().MakeTextNode( aTmpIdx.GetNode(),
+                        getIDocumentStylePoolAccess().GetTextCollFromPool( 
RES_POOLCOLL_STANDARD ) );
+        }
+
+        // Save the cursors (UNO and otherwise)
+        SwPaM aSavePaM( *pTableNd->EndOfSectionNode() );
+        if (! aSavePaM.Move(fnMoveForward, GoInNode))
+        {
+            aSavePaM.GetMark()->Assign( *pTableNd );
+            aSavePaM.Move( fnMoveBackward, GoInNode );
+        }
+        {
+            SwPaM const tmpPaM(*pTableNd, *pTableNd->EndOfSectionNode());
+            ::PaMCorrAbs(tmpPaM, *aSavePaM.GetMark());
+        }
+
+        // Move hard PageBreaks to the succeeding Node
+        SwContentNode* pNextNd = GetNodes()[ pTableNd->EndOfSectionIndex()+1 
]->GetContentNode();
+        if (pNextNd)
+        {
+            SwFrameFormat* pTableFormat = 
pTableNd->GetTable().GetFrameFormat();
+            const SfxPoolItem *pItem;
+            if (SfxItemState::SET == pTableFormat->GetItemState(RES_PAGEDESC,
+                    false, &pItem))
+            {
+                pNextNd->SetAttr( *pItem );
+            }
+
+            if (SfxItemState::SET == pTableFormat->GetItemState(RES_BREAK,
+                    false, &pItem))
+            {
+                pNextNd->SetAttr( *pItem );
+            }
+        }
+
+        pTableNd->DelFrames();
+        getIDocumentContentOperations().DeleteSection( pTableNd );
+    }
+
+    if (SwFEShell* pFEShell = GetDocShell()->GetFEShell())
+        pFEShell->UpdateTableStyleFormatting();
+
+    getIDocumentState().SetModified();
+    getIDocumentFieldsAccess().SetFieldsDirty( true, nullptr, SwNodeOffset(0) 
);
+}
+
 bool SwDoc::DeleteRowCol(const SwSelBoxes& rBoxes, RowColMode const eMode)
 {
     if (!(eMode & SwDoc::RowColMode::DeleteProtected)
@@ -1963,133 +2097,7 @@ bool SwDoc::DeleteRowCol(const SwSelBoxes& rBoxes, 
RowColMode const eMode)
         aSelBoxes[0]->GetSttIdx()-1 == nTmpIdx1 &&
         nTmpIdx2 == pTableNd->EndOfSectionIndex() )
     {
-        bool bNewTextNd = false;
-        // Is it alone in a FlyFrame?
-        SwNodeIndex aIdx( *pTableNd, -1 );
-        const SwStartNode* pSttNd = aIdx.GetNode().GetStartNode();
-        if( pSttNd )
-        {
-            const SwNodeOffset nTableEnd = pTableNd->EndOfSectionIndex() + 1;
-            const SwNodeOffset nSectEnd = pSttNd->EndOfSectionIndex();
-            if( nTableEnd == nSectEnd )
-            {
-                if( SwFlyStartNode == pSttNd->GetStartNodeType() )
-                {
-                    SwFrameFormat* pFormat = pSttNd->GetFlyFormat();
-                    if( pFormat )
-                    {
-                        // That's the FlyFormat we're looking for
-                        getIDocumentLayoutAccess().DelLayoutFormat( pFormat );
-                        return true;
-                    }
-                }
-                // No Fly? Thus Header or Footer: always leave a TextNode
-                // We can forget about Undo then!
-                bNewTextNd = true;
-            }
-        }
-
-        // No Fly? Then it is a Header or Footer, so keep always a TextNode
-        ++aIdx;
-        if (GetIDocumentUndoRedo().DoesUndo())
-        {
-            GetIDocumentUndoRedo().ClearRedo();
-            SwPaM aPaM( *pTableNd->EndOfSectionNode(), aIdx.GetNode() );
-
-            if( bNewTextNd )
-            {
-                const SwNodeIndex aTmpIdx( *pTableNd->EndOfSectionNode(), 1 );
-                GetNodes().MakeTextNode( aTmpIdx.GetNode(),
-                            getIDocumentStylePoolAccess().GetTextCollFromPool( 
RES_POOLCOLL_STANDARD ) );
-            }
-
-            // Save the cursors (UNO and otherwise)
-            SwPaM aSavePaM( *pTableNd->EndOfSectionNode() );
-            if( ! aSavePaM.Move( fnMoveForward, GoInNode ) )
-            {
-                aSavePaM.GetMark()->Assign( *pTableNd );
-                aSavePaM.Move( fnMoveBackward, GoInNode );
-            }
-            {
-                SwPaM const tmpPaM(*pTableNd, *pTableNd->EndOfSectionNode());
-                ::PaMCorrAbs(tmpPaM, *aSavePaM.GetMark());
-            }
-
-            // Move hard PageBreaks to the succeeding Node
-            bool bSavePageBreak = false, bSavePageDesc = false;
-            SwNodeOffset nNextNd = pTableNd->EndOfSectionIndex()+1;
-            SwContentNode* pNextNd = GetNodes()[ nNextNd ]->GetContentNode();
-            if( pNextNd )
-            {
-                SwFrameFormat* pTableFormat = 
pTableNd->GetTable().GetFrameFormat();
-                const SfxPoolItem *pItem;
-                if( SfxItemState::SET == pTableFormat->GetItemState( 
RES_PAGEDESC,
-                    false, &pItem ) )
-                {
-                    pNextNd->SetAttr( *pItem );
-                    bSavePageDesc = true;
-                }
-
-                if( SfxItemState::SET == pTableFormat->GetItemState( RES_BREAK,
-                    false, &pItem ) )
-                {
-                    pNextNd->SetAttr( *pItem );
-                    bSavePageBreak = true;
-                }
-            }
-            std::unique_ptr<SwUndoDelete> pUndo(new SwUndoDelete(aPaM, 
SwDeleteFlags::Default));
-            if( bNewTextNd )
-                pUndo->SetTableDelLastNd();
-            pUndo->SetPgBrkFlags( bSavePageBreak, bSavePageDesc );
-            
pUndo->SetTableName(pTableNd->GetTable().GetFrameFormat()->GetName());
-            GetIDocumentUndoRedo().AppendUndo( std::move(pUndo) );
-        }
-        else
-        {
-            if( bNewTextNd )
-            {
-                const SwNodeIndex aTmpIdx( *pTableNd->EndOfSectionNode(), 1 );
-                GetNodes().MakeTextNode( aTmpIdx.GetNode(),
-                            getIDocumentStylePoolAccess().GetTextCollFromPool( 
RES_POOLCOLL_STANDARD ) );
-            }
-
-            // Save the cursors (UNO and otherwise)
-            SwPaM aSavePaM( *pTableNd->EndOfSectionNode() );
-            if( ! aSavePaM.Move( fnMoveForward, GoInNode ) )
-            {
-                aSavePaM.GetMark()->Assign( *pTableNd );
-                aSavePaM.Move( fnMoveBackward, GoInNode );
-            }
-            {
-                SwPaM const tmpPaM(*pTableNd, *pTableNd->EndOfSectionNode());
-                ::PaMCorrAbs(tmpPaM, *aSavePaM.GetMark());
-            }
-
-            // Move hard PageBreaks to the succeeding Node
-            SwContentNode* pNextNd = GetNodes()[ 
pTableNd->EndOfSectionIndex()+1 ]->GetContentNode();
-            if( pNextNd )
-            {
-                SwFrameFormat* pTableFormat = 
pTableNd->GetTable().GetFrameFormat();
-                const SfxPoolItem *pItem;
-                if( SfxItemState::SET == pTableFormat->GetItemState( 
RES_PAGEDESC,
-                    false, &pItem ) )
-                    pNextNd->SetAttr( *pItem );
-
-                if( SfxItemState::SET == pTableFormat->GetItemState( RES_BREAK,
-                    false, &pItem ) )
-                    pNextNd->SetAttr( *pItem );
-            }
-
-            pTableNd->DelFrames();
-            getIDocumentContentOperations().DeleteSection( pTableNd );
-        }
-
-        if (SwFEShell* pFEShell = GetDocShell()->GetFEShell())
-            pFEShell->UpdateTableStyleFormatting();
-
-        getIDocumentState().SetModified();
-        getIDocumentFieldsAccess().SetFieldsDirty( true, nullptr, 
SwNodeOffset(0) );
-
+        DelTable(pTableNd);
         return true;
     }
 
diff --git a/sw/source/core/edit/eddel.cxx b/sw/source/core/edit/eddel.cxx
index 22783ec0241f..b7997dbafa86 100644
--- a/sw/source/core/edit/eddel.cxx
+++ b/sw/source/core/edit/eddel.cxx
@@ -33,9 +33,9 @@
 
 void SwEditShell::DeleteSel(SwPaM& rPam, bool const isArtificialSelection, 
bool *const pUndo)
 {
-    SwNode const*const pSelectAllStart(StartsWith_() != 
SwCursorShell::StartsWith::None
+    auto const oSelectAll(StartsWith_() != SwCursorShell::StartsWith::None
         ? ExtendedSelectedAll()
-        : nullptr);
+        : ::std::optional<::std::pair<SwNode const*, ::std::vector<SwTableNode 
*>>>{});
     // only for selections
     if (!rPam.HasMark()
         || (*rPam.GetPoint() == *rPam.GetMark()
@@ -51,7 +51,7 @@ void SwEditShell::DeleteSel(SwPaM& rPam, bool const 
isArtificialSelection, bool
     // 3. Point and Mark are at the document start and end, Point is in a 
table: delete selection as usual
     if( rPam.GetPointNode().FindTableNode() &&
         rPam.GetPointNode().StartOfSectionNode() !=
-        rPam.GetMarkNode().StartOfSectionNode() && pSelectAllStart == nullptr)
+        rPam.GetMarkNode().StartOfSectionNode() && !oSelectAll)
     {
         // group the Undo in the table
         if( pUndo && !*pUndo )
@@ -95,13 +95,18 @@ void SwEditShell::DeleteSel(SwPaM& rPam, bool const 
isArtificialSelection, bool
     {
         std::optional<SwPaM> pNewPam;
         SwPaM * pPam = &rPam;
-        if (pSelectAllStart)
+        if (oSelectAll)
         {
+            // tdf#155685 tables at the end must be deleted separately
+            for (SwTableNode *const pTable : oSelectAll->second)
+            {
+                GetDoc()->DelTable(pTable);
+            }
             assert(dynamic_cast<SwShellCursor*>(&rPam)); // must be corrected 
pam
             pNewPam.emplace(*rPam.GetMark(), *rPam.GetPoint());
             // Selection starts at the first para of the first cell, but we
             // want to delete the table node before the first cell as well.
-            pNewPam->Start()->Assign(*pSelectAllStart);
+            pNewPam->Start()->Assign(*oSelectAll->first);
             pPam = &*pNewPam;
         }
         // delete everything
diff --git a/sw/source/core/edit/edglss.cxx b/sw/source/core/edit/edglss.cxx
index 7edf5e823410..6e0728b8da31 100644
--- a/sw/source/core/edit/edglss.cxx
+++ b/sw/source/core/edit/edglss.cxx
@@ -197,9 +197,9 @@ bool SwEditShell::CopySelToDoc( SwDoc& rInsDoc )
         bool bColSel = GetCursor_()->IsColumnSelection();
         if( bColSel && rInsDoc.IsClipBoard() )
             rInsDoc.SetColumnSelection( true );
-        SwNode const*const pSelectAllStart(StartsWith_() != 
SwCursorShell::StartsWith::None
+        auto const oSelectAll(StartsWith_() != SwCursorShell::StartsWith::None
             ? ExtendedSelectedAll()
-            : nullptr);
+            : ::std::optional<::std::pair<SwNode const*, 
::std::vector<SwTableNode*>>>{});
         {
             for(SwPaM& rPaM : GetCursor()->GetRingContainer())
             {
@@ -223,12 +223,12 @@ bool SwEditShell::CopySelToDoc( SwDoc& rInsDoc )
                     // for the purpose of copying, our shell cursor is not 
touched.
                     // (Otherwise we would have to restore it.)
                     SwPaM aPaM(*rPaM.GetMark(), *rPaM.GetPoint());
-                    if (pSelectAllStart)
+                    if (oSelectAll)
                     {
                         // Selection starts at the first para of the first 
cell,
                         // but we want to copy the table and the start node 
before
                         // the first cell as well.
-                        aPaM.Start()->Assign(*pSelectAllStart);
+                        aPaM.Start()->Assign(*oSelectAll->first);
                     }
                     bRet = 
GetDoc()->getIDocumentContentOperations().CopyRange( aPaM, aPos, 
SwCopyFlags::CheckPosInFly)
                         || bRet;

Reply via email to